Server side ProseMirorr document editing

I posted this question in an old thread that was related, but I’ve concluded that it’s better to start a new thread.

I need to do server side manipulation of ProseMirror documents stored as JSON. I think it would be cleanest to use the ProseMirror model, schema, etc. to do that. It seems that it should be possible by running a Javascript interpreter embedded in my Python server. I tried PyMiniRacer (V8), which died of a stack overflow seg fault during creation of a small schema, and js2py which died while translating the ProseMirror code bundle.

I’d like to inquire about whether anyone has had success in using the ProseMirror Javascript code in a server-side interpreter. Any pointers would be appreciated.

I don’t have much experience with running JS from Python, but my intuition would be that running node.js as a subprocess would be the easiest approach (because it doesn’t involve any experimental/tricky code)

3 Likes

This is what we’ve had to do in past (shell out to node.js) (tried with MiniRacer and other runtimes in Ruby with limited success), but that’s admittedly pretty slow. What we do now is run a separate node process with a simple expressjs service for importing html server-side. For manipulation we have a simple ruby library that lets us manipulate the json.

1 Like

Thanks for sharing your experience. I’ve also used direct JSON manipulation on the documents, but I’ve occasionally produced docs that violate the schema when the editor tries to load them. It would be nice to avoid that by using the editor code on the server side.

That is the tricky part of schema’s having executable JS in them. It’d be nice if we could validate with something like the jsonschema spec that’s supported across various runtimes and languages, but I think I get why that’s not practical.

Server-side Javascript seems like it should be a good solution, except that there’s no good support for Python servers.

Yesterday I messed with a newly released JS interpreter called QuickJS (article here https://hub.packtpub.com/introducing-quickjs-a-small-and-easily-embeddable-javascript-engine/ and manual here https://bellard.org/quickjs/quickjs.html ). Unlike py_mini_racer it does not blow up on the non-UI ProseMirror code, at least for simple schema. I’ll likely try to use an external process for a QuickJS interpreter and hope for (or make) python bindings similar to py_mini-racer but w/o the stack overflow SEGV.

Hi @elgow,

I had proof of concept execution of javascript code within python process using execjs

from execjs import get
runtime = get('Node')

context = runtime.compile('''
		module.paths.push('%s');
		module.paths.push('%s');
		module.paths.push('%s');

		prosemirrorConverters = require('prosemirrorConverters');

		htmlToJson = prosemirrorConverters.htmlToJson;
		jsonToText = prosemirrorConverters.jsonToText;
		jsonToHtml = prosemirrorConverters.jsonToHtml;
	''' % (
	os.path.join(BASE_DIR, prosemirror_dist), # ProseMirror - src js files hosted here in python static files
	os.path.join(BASE_DIR, 'src/util'),  # ProseMirrorConverter
	os.path.join(BASE_DIR, 'src/lib'),   # jsdom
)

# Example usage
def jsonToText(node):
    # Runs jsonToText which is loaded above and runs with 1st argument `text_json` json object	 
    node.plain_text = context.call('jsonToText', node.text_json)\


But it was messy (and also incurred a large cost, based on what I read about execjs) so I decided to host a nodeJS server in parallel with my python server, which is much more maintable and usable.

A colleague of mine has done some great work to translate ProseMirror’s models and transforms to Python. It is passing the full test suite from the upstream implementation, and we will be keeping the library up to date with any changes since we will be using it in production soon. You can see it here: https://github.com/fellowinsights/prosemirror-py

1 Like

Wow. Thank you very much. It will be very useful to be able to manipulate ProseMirror docs on the server side with confidence that schema integrity will be maintained.