@kerebron/extension-yjs 0.4.26 → 0.4.27

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kerebron/extension-yjs",
3
- "version": "0.4.26",
3
+ "version": "0.4.27",
4
4
  "license": "MIT",
5
5
  "module": "./esm/ExtensionYjs.js",
6
6
  "exports": {
@@ -12,9 +12,10 @@
12
12
  }
13
13
  },
14
14
  "scripts": {},
15
+ "files": [],
15
16
  "dependencies": {
16
- "@kerebron/editor": "0.4.26",
17
- "@kerebron/extension-basic-editor": "0.4.26",
17
+ "@kerebron/editor": "0.4.27",
18
+ "@kerebron/extension-basic-editor": "0.4.27",
18
19
  "lib0": "0.2.109",
19
20
  "prosemirror-model": "1.25.3",
20
21
  "prosemirror-state": "1.4.3",
@@ -1,17 +0,0 @@
1
- import type { Plugin } from 'prosemirror-state';
2
- import * as awarenessProtocol from 'y-protocols/awareness';
3
- import { Extension } from '@kerebron/editor';
4
- import type { CommandFactories, CommandShortcuts } from '@kerebron/editor/commands';
5
- export interface YjsProvider {
6
- on(eventName: string, callback: (event: any) => void): void;
7
- awareness: awarenessProtocol.Awareness;
8
- }
9
- export declare class ExtensionYjs extends Extension {
10
- name: string;
11
- conflicts: string[];
12
- requires: string[];
13
- getCommandFactories(): Partial<CommandFactories>;
14
- getKeyboardShortcuts(): Partial<CommandShortcuts>;
15
- getProseMirrorPlugins(): Plugin[];
16
- }
17
- //# sourceMappingURL=ExtensionYjs.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ExtensionYjs.d.ts","sourceRoot":"","sources":["../src/ExtensionYjs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAGhD,OAAO,KAAK,iBAAiB,MAAM,uBAAuB,CAAC;AAE3D,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAE7C,OAAO,KAAK,EACV,gBAAgB,EAChB,gBAAgB,EACjB,MAAM,2BAA2B,CAAC;AAMnC,MAAM,WAAW,WAAW;IAC1B,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,GAAG,IAAI,CAAC;IAC5D,SAAS,EAAE,iBAAiB,CAAC,SAAS,CAAC;CACxC;AAED,qBAAa,YAAa,SAAQ,SAAS;IACzC,IAAI,SAAS;IAEJ,SAAS,WAAe;IACjC,QAAQ,WAAwB;IAGvB,mBAAmB,IAAI,OAAO,CAAC,gBAAgB,CAAC;IAOhD,oBAAoB,IAAI,OAAO,CAAC,gBAAgB,CAAC;IAOjD,qBAAqB,IAAI,MAAM,EAAE;CAY3C"}
@@ -1,33 +0,0 @@
1
- import { Extension } from '@kerebron/editor';
2
- import { ySyncPlugin } from './ySyncPlugin.js';
3
- import { yPositionPlugin } from './yPositionPlugin.js';
4
- import { redo, undo, yUndoPlugin } from './yUndoPlugin.js';
5
- import { initProseMirrorDoc } from './convertUtils.js';
6
- export class ExtensionYjs extends Extension {
7
- name = 'yjs';
8
- conflicts = ['history'];
9
- requires = ['remote-selection'];
10
- // declare type Command = (state: EditorState, dispatch?: (tr: Transaction) => void, view?: EditorView) => boolean;
11
- getCommandFactories() {
12
- return {
13
- 'undo': () => undo,
14
- 'redo': () => redo,
15
- };
16
- }
17
- getKeyboardShortcuts() {
18
- return {
19
- 'Mod-z': 'undo',
20
- 'Mod-y': 'redo',
21
- };
22
- }
23
- getProseMirrorPlugins() {
24
- const ydoc = this.config.ydoc;
25
- const fragment = ydoc.getXmlFragment('prosemirror');
26
- const { mapping } = initProseMirrorDoc(fragment, this.editor.schema);
27
- return [
28
- ySyncPlugin(fragment, { mapping }),
29
- yPositionPlugin(this.config.provider.awareness, this.editor),
30
- yUndoPlugin(),
31
- ];
32
- }
33
- }
@@ -1,59 +0,0 @@
1
- import * as Y from 'yjs';
2
- import { Fragment, Node, type Schema } from 'prosemirror-model';
3
- import { BindingMetadata } from './ySyncPlugin.js';
4
- export declare const createEmptyMeta: () => BindingMetadata;
5
- /**
6
- * Utility function for converting an Y.Fragment to a ProseMirror fragment.
7
- */
8
- export declare const yXmlFragmentToProseMirrorFragment: (yXmlFragment: Y.XmlFragment, schema: Schema) => Fragment;
9
- /**
10
- * Utility function for converting an Y.Fragment to a ProseMirror node.
11
- */
12
- export declare const yXmlFragmentToProseMirrorRootNode: (yXmlFragment: Y.XmlFragment, schema: Schema) => Node;
13
- /**
14
- * The initial ProseMirror content should be supplied by Yjs. This function transforms a Y.Fragment
15
- * to a ProseMirror Doc node and creates a mapping that is used by the sync plugin.
16
- *
17
- * @todo deprecate mapping property
18
- */
19
- export declare const initProseMirrorDoc: (yXmlFragment: Y.XmlFragment, schema: Schema) => {
20
- doc: Node;
21
- meta: BindingMetadata;
22
- mapping: Map<Y.AbstractType<any>, Node | Node[]>;
23
- };
24
- /**
25
- * Utility method to convert a Prosemirror Doc Node into a Y.Doc.
26
- *
27
- * This can be used when importing existing content to Y.Doc for the first time,
28
- * note that this should not be used to rehydrate a Y.Doc from a database once
29
- * collaboration has begun as all history will be lost
30
- */
31
- export declare function prosemirrorToYDoc(doc: Node, xmlFragment?: string): Y.Doc;
32
- /**
33
- * Utility method to update an empty Y.XmlFragment with content from a Prosemirror Doc Node.
34
- *
35
- * This can be used when importing existing content to Y.Doc for the first time,
36
- * note that this should not be used to rehydrate a Y.Doc from a database once
37
- * collaboration has begun as all history will be lost
38
- *
39
- * Note: The Y.XmlFragment does not need to be part of a Y.Doc document at the time that this
40
- * method is called, but it must be added before any other operations are performed on it.
41
- */
42
- export declare function prosemirrorToYXmlFragment(doc: Node, xmlFragment: Y.XmlFragment): Y.XmlFragment;
43
- /**
44
- * Utility method to convert Prosemirror compatible JSON into a Y.Doc.
45
- *
46
- * This can be used when importing existing content to Y.Doc for the first time,
47
- * note that this should not be used to rehydrate a Y.Doc from a database once
48
- * collaboration has begun as all history will be lost
49
- */
50
- export declare function prosemirrorJSONToYDoc(schema: Schema, state: any, xmlFragment?: string): Y.Doc;
51
- /**
52
- * Utility method to convert Prosemirror compatible JSON to a Y.XmlFragment
53
- *
54
- * This can be used when importing existing content to Y.Doc for the first time,
55
- * note that this should not be used to rehydrate a Y.Doc from a database once
56
- * collaboration has begun as all history will be lost
57
- */
58
- export declare function prosemirrorJSONToYXmlFragment(schema: Schema, state: any, xmlFragment: Y.XmlFragment): Y.XmlFragment;
59
- //# sourceMappingURL=convertUtils.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"convertUtils.d.ts","sourceRoot":"","sources":["../src/convertUtils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AACzB,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAChE,OAAO,EACL,eAAe,EAIhB,MAAM,kBAAkB,CAAC;AAE1B,eAAO,MAAM,eAAe,QAAO,eAGjC,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,iCAAiC,GAC5C,cAAc,CAAC,CAAC,WAAW,EAC3B,QAAQ,MAAM,aAUf,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,iCAAiC,GAC5C,cAAc,CAAC,CAAC,WAAW,EAC3B,QAAQ,MAAM,SAKb,CAAC;AAEJ;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,GAC7B,cAAc,CAAC,CAAC,WAAW,EAC3B,QAAQ,MAAM;;;;CAef,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,IAAI,EACT,WAAW,GAAE,MAAsB,GAClC,CAAC,CAAC,GAAG,CAUP;AAED;;;;;;;;;GASG;AACH,wBAAgB,yBAAyB,CACvC,GAAG,EAAE,IAAI,EACT,WAAW,EAAE,CAAC,CAAC,WAAW,GACzB,CAAC,CAAC,WAAW,CAOf;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,GAAG,EACV,WAAW,GAAE,MAAsB,GAClC,CAAC,CAAC,GAAG,CAGP;AAED;;;;;;GAMG;AACH,wBAAgB,6BAA6B,CAC3C,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,GAAG,EACV,WAAW,EAAE,CAAC,CAAC,WAAW,GACzB,CAAC,CAAC,WAAW,CAGf"}
@@ -1,88 +0,0 @@
1
- import * as Y from 'yjs';
2
- import { Fragment, Node } from 'prosemirror-model';
3
- import { createNodeFromYElement, updateYFragment, } from './ySyncPlugin.js';
4
- export const createEmptyMeta = () => ({
5
- mapping: new Map(),
6
- isOMark: new Map(),
7
- });
8
- /**
9
- * Utility function for converting an Y.Fragment to a ProseMirror fragment.
10
- */
11
- export const yXmlFragmentToProseMirrorFragment = (yXmlFragment, schema) => {
12
- const fragmentContent = yXmlFragment.toArray().map((t) => createNodeFromYElement(
13
- /** @type {Y.XmlElement} */ (t), schema, createEmptyMeta())).filter((n) => n !== null);
14
- return Fragment.fromArray(fragmentContent);
15
- };
16
- /**
17
- * Utility function for converting an Y.Fragment to a ProseMirror node.
18
- */
19
- export const yXmlFragmentToProseMirrorRootNode = (yXmlFragment, schema) => schema.topNodeType.create(null, yXmlFragmentToProseMirrorFragment(yXmlFragment, schema));
20
- /**
21
- * The initial ProseMirror content should be supplied by Yjs. This function transforms a Y.Fragment
22
- * to a ProseMirror Doc node and creates a mapping that is used by the sync plugin.
23
- *
24
- * @todo deprecate mapping property
25
- */
26
- export const initProseMirrorDoc = (yXmlFragment, schema) => {
27
- const meta = createEmptyMeta();
28
- const fragmentContent = yXmlFragment.toArray().map((t) => createNodeFromYElement(t, schema, meta)).filter((n) => n !== null);
29
- const doc = schema.topNodeType.create(null, Fragment.fromArray(fragmentContent));
30
- return { doc, meta, mapping: meta.mapping };
31
- };
32
- /**
33
- * Utility method to convert a Prosemirror Doc Node into a Y.Doc.
34
- *
35
- * This can be used when importing existing content to Y.Doc for the first time,
36
- * note that this should not be used to rehydrate a Y.Doc from a database once
37
- * collaboration has begun as all history will be lost
38
- */
39
- export function prosemirrorToYDoc(doc, xmlFragment = 'prosemirror') {
40
- const ydoc = new Y.Doc();
41
- const type =
42
- /** @type {Y.XmlFragment} */ (ydoc.get(xmlFragment, Y.XmlFragment));
43
- if (!type.doc) {
44
- return ydoc;
45
- }
46
- prosemirrorToYXmlFragment(doc, type);
47
- return type.doc;
48
- }
49
- /**
50
- * Utility method to update an empty Y.XmlFragment with content from a Prosemirror Doc Node.
51
- *
52
- * This can be used when importing existing content to Y.Doc for the first time,
53
- * note that this should not be used to rehydrate a Y.Doc from a database once
54
- * collaboration has begun as all history will be lost
55
- *
56
- * Note: The Y.XmlFragment does not need to be part of a Y.Doc document at the time that this
57
- * method is called, but it must be added before any other operations are performed on it.
58
- */
59
- export function prosemirrorToYXmlFragment(doc, xmlFragment) {
60
- const type = xmlFragment || new Y.XmlFragment();
61
- const ydoc = type.doc
62
- ? type.doc
63
- : { transact: (transaction) => transaction(undefined) };
64
- updateYFragment(ydoc, type, doc, { mapping: new Map(), isOMark: new Map() });
65
- return type;
66
- }
67
- /**
68
- * Utility method to convert Prosemirror compatible JSON into a Y.Doc.
69
- *
70
- * This can be used when importing existing content to Y.Doc for the first time,
71
- * note that this should not be used to rehydrate a Y.Doc from a database once
72
- * collaboration has begun as all history will be lost
73
- */
74
- export function prosemirrorJSONToYDoc(schema, state, xmlFragment = 'prosemirror') {
75
- const doc = Node.fromJSON(schema, state);
76
- return prosemirrorToYDoc(doc, xmlFragment);
77
- }
78
- /**
79
- * Utility method to convert Prosemirror compatible JSON to a Y.XmlFragment
80
- *
81
- * This can be used when importing existing content to Y.Doc for the first time,
82
- * note that this should not be used to rehydrate a Y.Doc from a database once
83
- * collaboration has begun as all history will be lost
84
- */
85
- export function prosemirrorJSONToYXmlFragment(schema, state, xmlFragment) {
86
- const doc = Node.fromJSON(schema, state);
87
- return prosemirrorToYXmlFragment(doc, xmlFragment);
88
- }
package/esm/keys.d.ts DELETED
@@ -1,11 +0,0 @@
1
- import { PluginKey } from 'prosemirror-state';
2
- import { UndoPluginState } from './yUndoPlugin.js';
3
- /**
4
- * The unique prosemirror plugin key for syncPlugin
5
- */
6
- export declare const ySyncPluginKey: PluginKey<any>;
7
- /**
8
- * The unique prosemirror plugin key for undoPlugin
9
- */
10
- export declare const yUndoPluginKey: PluginKey<UndoPluginState>;
11
- //# sourceMappingURL=keys.d.ts.map
package/esm/keys.d.ts.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"keys.d.ts","sourceRoot":"","sources":["../src/keys.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAEnD;;GAEG;AACH,eAAO,MAAM,cAAc,gBAA0B,CAAC;AAEtD;;GAEG;AACH,eAAO,MAAM,cAAc,EAAE,SAAS,CAAC,eAAe,CAErD,CAAC"}
package/esm/keys.js DELETED
@@ -1,9 +0,0 @@
1
- import { PluginKey } from 'prosemirror-state';
2
- /**
3
- * The unique prosemirror plugin key for syncPlugin
4
- */
5
- export const ySyncPluginKey = new PluginKey('y-sync');
6
- /**
7
- * The unique prosemirror plugin key for undoPlugin
8
- */
9
- export const yUndoPluginKey = new PluginKey('y-undo');
package/esm/lib.d.ts DELETED
@@ -1,15 +0,0 @@
1
- import * as Y from 'yjs';
2
- import { type EditorView } from 'prosemirror-view';
3
- import { type Node } from 'prosemirror-model';
4
- /**
5
- * Either a node if type is YXmlElement or an Array of text nodes if YXmlText
6
- */
7
- type ProsemirrorMapping = Map<Y.AbstractType<any>, Node>;
8
- export declare const setMeta: (view: EditorView, key: any, value: any) => void;
9
- /**
10
- * Transforms a Prosemirror based absolute position to a Yjs Cursor (relative position in the Yjs model).
11
- */
12
- export declare const absolutePositionToRelativePosition: (pos: number, type: Y.XmlFragment, mapping: ProsemirrorMapping) => any;
13
- export declare const relativePositionToAbsolutePosition: (yDoc: Y.Doc, documentType: Y.XmlFragment, relPos: any, mapping: ProsemirrorMapping) => null | number;
14
- export {};
15
- //# sourceMappingURL=lib.d.ts.map
package/esm/lib.d.ts.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"lib.d.ts","sourceRoot":"","sources":["../src/lib.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AACzB,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,KAAK,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAI9C;;GAEG;AACH,KAAK,kBAAkB,GAAG,GAAG,CAAC,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC;AA2BzD,eAAO,MAAM,OAAO,GAAI,MAAM,UAAU,EAAE,QAAG,EAAE,UAAK,SAYnD,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,kCAAkC,GAC7C,KAAK,MAAM,EACX,MAAM,CAAC,CAAC,WAAW,EACnB,SAAS,kBAAkB,KAC1B,GA+FF,CAAC;AAaF,eAAO,MAAM,kCAAkC,GAC7C,MAAM,CAAC,CAAC,GAAG,EACX,cAAc,CAAC,CAAC,WAAW,EAC3B,QAAQ,GAAG,EACX,SAAS,kBAAkB,KAC1B,IAAI,GAAG,MA2DT,CAAC"}
package/esm/lib.js DELETED
@@ -1,190 +0,0 @@
1
- import * as Y from 'yjs';
2
- import { ySyncPluginKey } from './keys.js';
3
- /**
4
- * Is null if no timeout is in progress.
5
- * Is defined if a timeout is in progress.
6
- * Maps from view
7
- */
8
- let viewsToUpdate = null;
9
- const updateMetas = () => {
10
- const ups = viewsToUpdate;
11
- viewsToUpdate = null;
12
- if (!ups) {
13
- return;
14
- }
15
- ups.forEach((metas, view) => {
16
- const tr = view.state.tr;
17
- const syncState = ySyncPluginKey.getState(view.state);
18
- if (syncState && syncState.binding && !syncState.binding.isDestroyed) {
19
- metas.forEach((val, key) => {
20
- tr.setMeta(key, val);
21
- });
22
- view.dispatch(tr);
23
- }
24
- });
25
- };
26
- export const setMeta = (view, key, value) => {
27
- if (!viewsToUpdate) {
28
- viewsToUpdate = new Map();
29
- setTimeout(updateMetas, 0);
30
- }
31
- let subMap = viewsToUpdate.get(view);
32
- if (subMap === undefined) {
33
- subMap = new Map();
34
- viewsToUpdate.set(view, subMap);
35
- }
36
- subMap.set(key, value);
37
- };
38
- /**
39
- * Transforms a Prosemirror based absolute position to a Yjs Cursor (relative position in the Yjs model).
40
- */
41
- export const absolutePositionToRelativePosition = (pos, type, mapping) => {
42
- if (pos === 0) {
43
- // if the type is later populated, we want to retain the 0 position (hence assoc=-1)
44
- return Y.createRelativePositionFromTypeIndex(type, 0, type.length === 0 ? -1 : 0);
45
- }
46
- let n = type._first === null
47
- ? null
48
- : /** @type {Y.ContentType} */ (type._first.content).type;
49
- while (n !== null && type !== n) {
50
- if (n instanceof Y.XmlText) {
51
- if (n._length >= pos) {
52
- return Y.createRelativePositionFromTypeIndex(n, pos, type.length === 0 ? -1 : 0);
53
- }
54
- else {
55
- pos -= n._length;
56
- }
57
- if (n._item !== null && n._item.next !== null) {
58
- n = /** @type {Y.ContentType} */ (n._item.next.content).type;
59
- }
60
- else {
61
- do {
62
- n = n._item === null ? null : n._item.parent;
63
- pos--;
64
- } while (n !== type && n !== null && n._item !== null && n._item.next === null);
65
- if (n !== null && n !== type) {
66
- // @ts-gnore we know that n.next !== null because of above loop conditition
67
- n = n._item === null
68
- ? null
69
- : /** @type {Y.ContentType} */ ( /** @type Y.Item */(n._item.next)
70
- .content).type;
71
- }
72
- }
73
- }
74
- else {
75
- const pNodeSize =
76
- /** @type {any} */ (mapping.get(n) || { nodeSize: 0 }).nodeSize;
77
- if (n._first !== null && pos < pNodeSize) {
78
- n = /** @type {Y.ContentType} */ (n._first.content).type;
79
- pos--;
80
- }
81
- else {
82
- if (pos === 1 && n._length === 0 && pNodeSize > 1) {
83
- // edge case, should end in this paragraph
84
- return new Y.RelativePosition(n._item === null ? null : n._item.id, n._item === null ? Y.findRootTypeKey(n) : null, null);
85
- }
86
- pos -= pNodeSize;
87
- if (n._item !== null && n._item.next !== null) {
88
- n = /** @type {Y.ContentType} */ (n._item.next.content).type;
89
- }
90
- else {
91
- if (pos === 0) {
92
- // set to end of n.parent
93
- n = n._item === null ? n : n._item.parent;
94
- return new Y.RelativePosition(n._item === null ? null : n._item.id, n._item === null ? Y.findRootTypeKey(n) : null, null);
95
- }
96
- do {
97
- n = n._item.parent;
98
- pos--;
99
- } while (n !== type && /** @type {Y.Item} */ (n._item).next === null);
100
- // if n is null at this point, we have an unexpected case
101
- if (n !== type) {
102
- // We know that n._item.next is defined because of above loop condition
103
- n =
104
- /** @type {Y.ContentType} */ ( /** @type {Y.Item} */( /** @type {Y.Item} */(n
105
- ._item).next).content).type;
106
- }
107
- }
108
- }
109
- }
110
- if (n === null) {
111
- throw new Error('Unexpected case');
112
- }
113
- if (pos === 0 && n.constructor !== Y.XmlText && n !== type) { // TODO: set to <= 0
114
- return createRelativePosition(n._item.parent, n._item);
115
- }
116
- }
117
- return Y.createRelativePositionFromTypeIndex(type, type._length, type.length === 0 ? -1 : 0);
118
- };
119
- const createRelativePosition = (type, item) => {
120
- let typeid = null;
121
- let tname = null;
122
- if (type._item === null) {
123
- tname = Y.findRootTypeKey(type);
124
- }
125
- else {
126
- typeid = Y.createID(type._item.id.client, type._item.id.clock);
127
- }
128
- return new Y.RelativePosition(typeid, tname, item.id);
129
- };
130
- export const relativePositionToAbsolutePosition = (yDoc, documentType, relPos, mapping) => {
131
- const decodedPos = Y.createAbsolutePositionFromRelativePosition(relPos, yDoc);
132
- if (decodedPos === null ||
133
- (decodedPos.type !== documentType &&
134
- !Y.isParentOf(documentType, decodedPos.type._item))) {
135
- return null;
136
- }
137
- let type = decodedPos.type;
138
- let pos = 0;
139
- if (type instanceof Y.XmlText) {
140
- pos = decodedPos.index;
141
- }
142
- else if (type._item === null || !type._item.deleted) {
143
- let n = type._first;
144
- let i = 0;
145
- while (i < type._length && i < decodedPos.index && n !== null) {
146
- if (!n.deleted) {
147
- const t = n.content.type;
148
- i++;
149
- if (t instanceof Y.XmlText) {
150
- pos += t._length;
151
- }
152
- else {
153
- const node = mapping.get(t);
154
- pos += node?.nodeSize || 0;
155
- }
156
- }
157
- n = n.right;
158
- }
159
- pos += 1; // increase because we go out of n
160
- }
161
- while (type !== documentType && type._item !== null) {
162
- const parent = type._item.parent;
163
- if (parent instanceof Y.ID || parent === null) {
164
- continue;
165
- }
166
- if (parent._item === null || !parent._item.deleted) {
167
- pos += 1; // the start tag
168
- let n = /** @type {Y.AbstractType} */ (parent)._first;
169
- // now iterate until we found type
170
- while (n !== null) {
171
- const contentType = n.content.type;
172
- if (contentType === type) {
173
- break;
174
- }
175
- if (!n.deleted) {
176
- if (contentType instanceof Y.XmlText) {
177
- pos += contentType._length;
178
- }
179
- else {
180
- const node = mapping.get(contentType);
181
- pos += node?.nodeSize || 0;
182
- }
183
- }
184
- n = n.right;
185
- }
186
- }
187
- type = parent;
188
- }
189
- return pos - 1; // we don't count the most outer tag, because it is a fragment
190
- };
package/esm/package.json DELETED
@@ -1,3 +0,0 @@
1
- {
2
- "type": "module"
3
- }
@@ -1,5 +0,0 @@
1
- export declare const userColors: {
2
- color: string;
3
- light: string;
4
- }[];
5
- //# sourceMappingURL=userColors.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"userColors.d.ts","sourceRoot":"","sources":["../src/userColors.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,UAAU;;;GAStB,CAAC"}
package/esm/userColors.js DELETED
@@ -1,10 +0,0 @@
1
- export const userColors = [
2
- { color: '#30bced', light: '#30bced33' },
3
- { color: '#6eeb83', light: '#6eeb8333' },
4
- { color: '#ffbc42', light: '#ffbc4233' },
5
- { color: '#ecd444', light: '#ecd44433' },
6
- { color: '#ee6352', light: '#ee635233' },
7
- { color: '#9ac2c9', light: '#9ac2c933' },
8
- { color: '#8acb88', light: '#8acb8833' },
9
- { color: '#1be7ff', light: '#1be7ff33' },
10
- ];
package/esm/utils.d.ts DELETED
@@ -1,2 +0,0 @@
1
- export declare const hashOfJSON: (json: any) => string;
2
- //# sourceMappingURL=utils.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAWA,eAAO,MAAM,UAAU,GAAI,MAAM,GAAG,WAC0B,CAAC"}
package/esm/utils.js DELETED
@@ -1,10 +0,0 @@
1
- import * as sha256 from 'lib0/hash/sha256';
2
- import * as buf from 'lib0/buffer';
3
- const _convolute = (digest) => {
4
- const N = 6;
5
- for (let i = N; i < digest.length; i++) {
6
- digest[i % N] = digest[i % N] ^ digest[i];
7
- }
8
- return digest.slice(0, N);
9
- };
10
- export const hashOfJSON = (json) => buf.toBase64(_convolute(sha256.digest(buf.encodeAny(json))));
@@ -1,14 +0,0 @@
1
- import * as awarenessProtocol from 'y-protocols/awareness';
2
- import { Plugin, PluginKey } from 'prosemirror-state';
3
- import type { CoreEditor } from '@kerebron/editor';
4
- export declare const yPositionPluginKey: PluginKey<any>;
5
- interface PositionPluginConfig {
6
- getSelection?: (arg0: any) => any;
7
- }
8
- /**
9
- * Default awareness state filter
10
- */
11
- export declare const defaultAwarenessStateFilter: (currentClientId: number, userClientId: number, _user: any) => boolean;
12
- export declare const yPositionPlugin: (awareness: awarenessProtocol.Awareness, editor: CoreEditor, { getSelection, }?: PositionPluginConfig, cursorStateField?: string) => Plugin<any>;
13
- export {};
14
- //# sourceMappingURL=yPositionPlugin.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"yPositionPlugin.d.ts","sourceRoot":"","sources":["../src/yPositionPlugin.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,iBAAiB,MAAM,uBAAuB,CAAC;AAE3D,OAAO,EAAe,MAAM,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAEnE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAcnD,eAAO,MAAM,kBAAkB,gBAAgC,CAAC;AAYhE,UAAU,oBAAoB;IAC5B,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,GAAG,CAAC;CACnC;AAED;;GAEG;AACH,eAAO,MAAM,2BAA2B,GACtC,iBAAiB,MAAM,EACvB,cAAc,MAAM,EACpB,OAAO,GAAG,KACT,OAA2C,CAAC;AAE/C,eAAO,MAAM,eAAe,GAC1B,WAAW,iBAAiB,CAAC,SAAS,EACtC,QAAQ,UAAU,EAClB,oBAEG,oBAAyB,EAC5B,mBAAkB,MAAiB,gBAiLpC,CAAC"}
@@ -1,121 +0,0 @@
1
- import * as Y from 'yjs';
2
- import { Plugin, PluginKey } from 'prosemirror-state';
3
- import { remoteSelectionPluginKey } from '@kerebron/extension-basic-editor/ExtensionRemoteSelection';
4
- import { absolutePositionToRelativePosition, relativePositionToAbsolutePosition, setMeta, } from './lib.js';
5
- import { ySyncPluginKey } from './keys.js';
6
- export const yPositionPluginKey = new PluginKey('yjs-position');
7
- /**
8
- * Default awareness state filter
9
- */
10
- export const defaultAwarenessStateFilter = (currentClientId, userClientId, _user) => currentClientId !== userClientId;
11
- export const yPositionPlugin = (awareness, editor, { getSelection = (state) => state.selection, } = {}, cursorStateField = 'cursor') => {
12
- return new Plugin({
13
- key: yPositionPluginKey,
14
- view: (view) => {
15
- const extension = editor.getExtension('remote-selection');
16
- const awarenessListener = ({ added, updated, removed }) => {
17
- const clients = added.concat(updated).concat(removed);
18
- if (clients.findIndex((id) => id !== awareness.doc.clientID) ===
19
- -1) {
20
- return;
21
- }
22
- if (view.docView) {
23
- setMeta(view, remoteSelectionPluginKey, {
24
- remotePositionUpdated: true,
25
- });
26
- }
27
- const remoteStates = [];
28
- const ystate = ySyncPluginKey.getState(view.state);
29
- const y = ystate.doc;
30
- awareness.getStates().forEach((aw, clientId) => {
31
- if (!defaultAwarenessStateFilter(y.clientID, clientId, aw)) {
32
- return;
33
- }
34
- if (!aw.cursor) {
35
- return;
36
- }
37
- let anchor = relativePositionToAbsolutePosition(y, ystate.type, Y.createRelativePositionFromJSON(aw.cursor.anchor), ystate.binding.mapping);
38
- let head = relativePositionToAbsolutePosition(y, ystate.type, Y.createRelativePositionFromJSON(aw.cursor.head), ystate.binding.mapping);
39
- if (anchor !== null && head !== null) {
40
- remoteStates.push({
41
- clientId,
42
- user: {
43
- name: aw.user?.name,
44
- color: aw.user?.color,
45
- colorLight: aw.user?.colorLight,
46
- },
47
- cursor: {
48
- anchor,
49
- head,
50
- },
51
- });
52
- }
53
- });
54
- extension.setRemoteStates(remoteStates);
55
- // view.dispatch({ annotations: [yRemoteSelectionsAnnotation.of([])] });
56
- };
57
- {
58
- // if (
59
- // ystate.snapshot != null || ystate.prevSnapshot != null ||
60
- // ystate.binding.mapping.size === 0
61
- // ) {
62
- // // do not render cursors while snapshot is active
63
- // return DecorationSet.create(state.doc, []);
64
- // }
65
- }
66
- const updateAwareness = (selectionAnchor, selectionHead) => {
67
- const ystate = ySyncPluginKey.getState(view.state);
68
- const current = awareness.getLocalState() || {};
69
- const anchor = absolutePositionToRelativePosition(selectionAnchor, ystate.type, ystate.binding.mapping);
70
- const head = absolutePositionToRelativePosition(selectionHead, ystate.type, ystate.binding.mapping);
71
- if (current.cursor == null ||
72
- !Y.compareRelativePositions(Y.createRelativePositionFromJSON(current.cursor.anchor), anchor) ||
73
- !Y.compareRelativePositions(Y.createRelativePositionFromJSON(current.cursor.head), head)) {
74
- awareness.setLocalStateField(cursorStateField, {
75
- anchor,
76
- head,
77
- });
78
- }
79
- };
80
- const clearAwareness = () => {
81
- const ystate = ySyncPluginKey.getState(view.state);
82
- const current = awareness.getLocalState() || {};
83
- if (current.cursor != null &&
84
- relativePositionToAbsolutePosition(ystate.doc, ystate.type, Y.createRelativePositionFromJSON(current.cursor.anchor), ystate.binding.mapping) !== null) {
85
- // delete cursor information if current cursor information is owned by this editor binding
86
- awareness.setLocalStateField(cursorStateField, null);
87
- }
88
- };
89
- const updateCursorInfo = () => {
90
- if (view.hasFocus()) {
91
- const selection = getSelection(view.state);
92
- updateAwareness(selection.anchor, selection.head);
93
- }
94
- else {
95
- // clearAwareness();
96
- }
97
- };
98
- const localPositionChangedListener = (event) => {
99
- const { detail } = event;
100
- updateAwareness(detail.anchor, detail.head);
101
- };
102
- editor.addEventListener('localPositionChanged', localPositionChangedListener);
103
- awareness.on('change', awarenessListener);
104
- view.dom.addEventListener('focusin', updateCursorInfo);
105
- view.dom.addEventListener('focusout', updateCursorInfo);
106
- return {
107
- update: updateCursorInfo,
108
- destroy: () => {
109
- view.dom.removeEventListener('focusin', updateCursorInfo);
110
- view.dom.removeEventListener('focusout', updateCursorInfo);
111
- awareness.off('change', awarenessListener);
112
- awareness.setLocalStateField(cursorStateField, null);
113
- editor.removeEventListener('localPositionChanged', localPositionChangedListener);
114
- },
115
- };
116
- },
117
- updateCursorInfo(state) {
118
- throw new Error('TODO: merge with updateCursorInfo above');
119
- },
120
- });
121
- };