@atlaskit/editor-plugin-collab-edit
Version:
Collab Edit plugin for @atlaskit/editor-core
108 lines (105 loc) • 5.14 kB
JavaScript
;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.initialize = void 0;
var _memoizeOne = _interopRequireDefault(require("memoize-one"));
var _transform = require("@atlaskit/editor-prosemirror/transform");
var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
var _pluginKey = require("../main/plugin-key");
var _trackNcsInitialization = require("../track-ncs-initialization");
var _handlers = require("./handlers");
var initCollab = function initCollab(collabEditProvider, view) {
if (collabEditProvider.initialize) {
collabEditProvider.initialize(function () {
return view.state;
}, function (json) {
return _transform.Step.fromJSON(view.state.schema, json);
});
}
};
var initNewCollab = function initNewCollab(collabEditProvider, view, editorApi, onSyncUpError) {
collabEditProvider.setup({
getState: function getState() {
return view.state;
},
editorApi: editorApi,
onSyncUpError: onSyncUpError
});
};
var initCollabMemo = (0, _memoizeOne.default)(initCollab);
var initialize = exports.initialize = function initialize(_ref) {
var options = _ref.options,
providerFactory = _ref.providerFactory,
view = _ref.view,
featureFlags = _ref.featureFlags,
editorAnalyticsApi = _ref.editorAnalyticsApi,
pluginInjectionApi = _ref.pluginInjectionApi;
return function (provider) {
// eslint-disable-next-line prefer-const
var cleanup;
var pluginState = _pluginKey.pluginKey.getState(view.state);
if (pluginState !== null && pluginState !== void 0 && pluginState.isReady && cleanup) {
cleanup();
}
cleanup = (0, _handlers.subscribe)(view, provider, options, featureFlags, providerFactory, editorAnalyticsApi);
// Initialize provider
if (options.useNativePlugin) {
// ED-13912 For NCS we don't want to use memoizeOne because it causes
// infinite text while changing page-width
initNewCollab(provider, view, pluginInjectionApi, options.onSyncUpError);
} else {
/**
* We only want to initialise once, if we reload/reconfigure this plugin
* We dont want to re-init collab, it would break existing sessions
*/
initCollabMemo(provider, view);
}
// Rebind path: if the provider has already initialised (i.e. this view()
// is running because the editor preset was reconfigured or the EditorView
// was recreated mid-session, e.g. on a rich-text → markdown-mode flip),
// the provider's `init` event has already fired and won't fire again.
// Without intervention the freshly-attached collab plugin view never sees
// `collabInitialised`, so `filterTransaction` silently drops every
// doc-changing transaction and the editor appears read-only.
//
// PM `state.reconfigure` preserves plugin state by key, so in many cases
// the plugin state survives and no action is needed; we only seed when
// state was actually lost (e.g. EditorView recreated from scratch).
//
// Gated behind `cc-markdown-mode` (the same experiment that drives the
// preset rebuild on convert); when off, behaviour is unchanged. Uses
// `expValEquals` (not `*NoExposure`) so the editor's statsig client
// enrols the user — otherwise an early rebind can race the FE-side
// exposure and read the default (false), defeating the gate. The
// experiment check is last so legacy providers (no `getInitPayload`)
// short-circuit and don't fire an exposure.
if (provider.getInitPayload && (0, _expValEquals.expValEquals)('cc-markdown-mode', 'isEnabled', true)) {
var cachedInit = provider.getInitPayload();
if (cachedInit) {
// Defer one microtask so the new pluginView is fully registered
// before we dispatch (mirrors the timing of a real `init` event).
Promise.resolve().then(function () {
if (view.isDestroyed) {
return;
}
var currentCollabState = _pluginKey.pluginKey.getState(view.state);
var currentTrackState = _trackNcsInitialization.trackNCSInitializationPluginKey.getState(view.state);
// State was preserved across reconfigure → nothing to do.
if (currentCollabState !== null && currentCollabState !== void 0 && currentCollabState.isReady && currentTrackState !== null && currentTrackState !== void 0 && currentTrackState.collabInitialisedAt) {
return;
}
// Seed the freshly-attached pluginView so `isReady` flips to true,
// `data-has-collab-initialised` becomes "true", and downstream
// listeners (analytics, sweet-state, track-ncs) re-receive init.
// Note: we intentionally do NOT replay `handleInit` (which would
// call `replaceDocument`) — the document is already in the editor
// and replacing it would clobber any in-flight local steps.
view.dispatch(view.state.tr.setMeta('collabInitialised', true));
});
}
}
return cleanup;
};
};