Working with keyed plugins

So, I can make a plugin that defines a PluginKey. However, I don’t get how I then use this key… If my plugin is named "myPlugin", how do I retrieve it from the state or view?

1 Like

With the key object’s get method, or getState to get the state value associated with the plugin.

If I have to pass the PluginKey object around, what advantage does that give over just passing around the plugin and using plugin.getState ?

None, if your plugin is a singleton. If it’s initialized by some factory function you might not have easy access to the precise instance.

When I don’t have direct access to the key, I wonder what I should do. For example in the case of undo – how can I check whether a given tr is part of the undo of the history plugin? It seems I can do tr.getMeta('history$'). But is that how it’s supposed to be done?

That’s not reliable—depending on what other plugins are loaded, the property name might be different.

Why do you need access to the plugin’s private meta properties?

That’s what I thought. It may still work, because I will always be the one in control of what plugins are loaded and they’ll always be the same ones, but it would be nicer with a solution where I don’t touch on hidden parts of the API.

I need this information because I want to treat transactions that are part of history operations undo and redo differently than other transactions. For example, I ad marks to new content added by a user under certain circumstances. But I don’t want to do that if the user is using redo/undo.

Could we not simply export the plugin key for the history plugin?

That doesn’t sound great, since when that property is present and what it means is an internal detail of the history plugin. Have you considered wrapping the undo and redo commands to add an additional meta property to the resulting transactions?

I had not. If I add this to clicks on menu buttons for redo/undo and keymaps, then I would be guaranteed that it would be invoked with every transaction that does undo/redo?

I guess that would also entail recreating parts of the buildKeymap function of prosemirror-example-setup, including an OS check for mac/pc. I guess that would still be doable.

The core library won’t invoke these commands, so yes, if you only bind your wrapper to buttons and keymaps, that’s the only thing that’ll be called.

Great! This seems to be working.

And it’s also then guaranteed that the history plugin itself or other core plugins won’t ever use appendTransaction or similar to add history related transactions some time in the future?

Other plugins can’t (due to the key being private), and I don’t see a reason why the history plugin would ever need to do that.

You’re right.

Ok, given that this is not the first time I have wanted to know what the user intention was when dealing with a transaction, I have now added a meta “inputType” (borrowed from the W3C input events spec). I probably won’t be adding input types to all actions for now, but whenever it is needed it seemed to be a good idea to have them under the same meta keyword rather than a bunch of different ones.

Anyway, thanks for advice, I can see how this is actually cleaner of dealing with it.