edytor 5.0.0 → 6.0.0
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/README.md +2 -2
- package/dist/cloudflare/room/context.d.ts +62 -74
- package/dist/crdt/doc/history.js +2 -3
- package/dist/crdt/doc/ops.d.ts +81 -0
- package/dist/crdt/doc/ops.js +1898 -0
- package/dist/crdt/edytor-doc.d.ts +156 -156
- package/dist/crdt/edytor-doc.js +14 -42
- package/dist/crdt/flow.d.ts +4 -46
- package/dist/crdt/flow.js +2 -262
- package/dist/crdt/index.d.ts +62 -74
- package/dist/crdt/operations.d.ts +1 -1
- package/dist/crdt/placement/resolve.d.ts +1 -1
- package/dist/crdt/protocols/awareness.js +46 -81
- package/dist/crdt/providers/index.d.ts +10 -22
- package/dist/crdt/providers/indexeddb.d.ts +6 -10
- package/dist/crdt/providers/indexeddb.js +10 -16
- package/dist/crdt/providers/room.d.ts +11 -0
- package/dist/crdt/providers/room.js +26 -12
- package/dist/crdt/providers/websocket.d.ts +6 -12
- package/dist/crdt/providers/websocket.js +8 -15
- package/dist/crdt/rangeDelete.d.ts +2 -47
- package/dist/crdt/rangeDelete.js +1 -169
- package/dist/crdt/text/index/build.d.ts +125 -0
- package/dist/crdt/text/index/build.js +2895 -0
- package/dist/crdt/text/index/shared.d.ts +2 -6
- package/dist/crdt/text/index/shared.js +2 -5
- package/dist/crdt/text/model.js +2 -3
- package/dist/crdt/text/runs.d.ts +9 -12
- package/dist/crdt/text/runs.js +2 -165
- package/dist/events/domTextOffset.d.ts +2 -0
- package/dist/events/domTextOffset.js +8 -0
- package/dist/export/forms.d.ts +50 -50
- package/dist/plugins/richtext/RichTextPlugin.svelte +63 -61
- package/dist/plugins/richtext/richTextOperations.js +26 -32
- package/dist/selection/selection.utils.js +5 -8
- package/dist/session/handles.js +3 -7
- package/dist/surface/observer.svelte.js +15 -30
- package/dist/surface/projector.svelte.js +2 -2
- package/dist/utils.d.ts +5 -0
- package/dist/utils.js +7 -0
- package/package.json +1 -1
- package/dist/crdt/doc/capability.d.ts +0 -56
- package/dist/crdt/doc/capability.js +0 -207
- package/dist/crdt/doc/content.d.ts +0 -16
- package/dist/crdt/doc/content.js +0 -77
- package/dist/crdt/doc/delete.d.ts +0 -15
- package/dist/crdt/doc/delete.js +0 -84
- package/dist/crdt/doc/layout.d.ts +0 -9
- package/dist/crdt/doc/layout.js +0 -178
- package/dist/crdt/doc/meta.d.ts +0 -19
- package/dist/crdt/doc/meta.js +0 -198
- package/dist/crdt/doc/moves.d.ts +0 -21
- package/dist/crdt/doc/moves.js +0 -274
- package/dist/crdt/doc/split-merge.d.ts +0 -10
- package/dist/crdt/doc/split-merge.js +0 -179
- package/dist/crdt/doc/steps.d.ts +0 -65
- package/dist/crdt/doc/steps.js +0 -311
- package/dist/crdt/text/index/cache.d.ts +0 -16
- package/dist/crdt/text/index/cache.js +0 -175
- package/dist/crdt/text/index/claims.d.ts +0 -18
- package/dist/crdt/text/index/claims.js +0 -203
- package/dist/crdt/text/index/fold.d.ts +0 -21
- package/dist/crdt/text/index/fold.js +0 -656
- package/dist/crdt/text/index/layout.d.ts +0 -22
- package/dist/crdt/text/index/layout.js +0 -258
- package/dist/crdt/text/index/placement.d.ts +0 -47
- package/dist/crdt/text/index/placement.js +0 -738
- package/dist/crdt/text/index/records.d.ts +0 -13
- package/dist/crdt/text/index/records.js +0 -139
- package/dist/crdt/text/index/report.d.ts +0 -18
- package/dist/crdt/text/index/report.js +0 -337
- package/dist/crdt/text/index/state.d.ts +0 -197
- package/dist/crdt/text/index/state.js +0 -116
- package/dist/crdt/text/index/streams.d.ts +0 -25
- package/dist/crdt/text/index/streams.js +0 -248
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { EngineNode } from '../../engine-api.js';
|
|
2
2
|
import type { BlockId, BlockRec } from '../../placement/model.js';
|
|
3
3
|
import type { ContentRun, DisplayRoles } from '../runs.js';
|
|
4
|
-
import type { SelfChecks } from './
|
|
4
|
+
import type { IndexFacts, SelfChecks } from './build.js';
|
|
5
5
|
/**
|
|
6
6
|
* The facet name of a block's registry entry itself (inserted or removed) —
|
|
7
7
|
* every other facet is named by the block attr it entered through.
|
|
@@ -65,12 +65,8 @@ export declare const sameShape: (roles: DisplayRoles, a: string, b: string) => b
|
|
|
65
65
|
*/
|
|
66
66
|
export declare const indexChecks: {
|
|
67
67
|
on: boolean;
|
|
68
|
-
of?: (
|
|
68
|
+
of?: (facts: IndexFacts) => SelfChecks;
|
|
69
69
|
};
|
|
70
|
-
/** `ix`'s checker ({@link indexChecks}), built on its first check. */
|
|
71
|
-
export declare const checksOf: (ix: {
|
|
72
|
-
checks: SelfChecks | null;
|
|
73
|
-
}) => SelfChecks;
|
|
74
70
|
/** Add `value` to `key`'s set in `index`. */
|
|
75
71
|
export declare const addTo: <K, V>(index: Map<K, Set<V>>, key: K, value: V) => void;
|
|
76
72
|
/** Remove `value` from `key`'s set in `index` (the set goes once empty). */
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { cloneJsonSafe } from '../../../utils/json.js';
|
|
7
7
|
import { CONTENT, DATA, DATA_LEAF_PREFIX, ID, LAST_CHANGED_ATTR, TYPE } from '../../schema.js';
|
|
8
|
+
import { getOr } from '../../../utils.js';
|
|
8
9
|
/**
|
|
9
10
|
* The facet name of a block's registry entry itself (inserted or removed) —
|
|
10
11
|
* every other facet is named by the block attr it entered through.
|
|
@@ -93,13 +94,9 @@ export const sameShape = (roles, a, b) => {
|
|
|
93
94
|
* difference; after every report, the published tree.
|
|
94
95
|
*/
|
|
95
96
|
export const indexChecks = { on: false };
|
|
96
|
-
/** `ix`'s checker ({@link indexChecks}), built on its first check. */
|
|
97
|
-
export const checksOf = (ix) => (ix.checks ??= indexChecks.of(ix));
|
|
98
97
|
/** Add `value` to `key`'s set in `index`. */
|
|
99
98
|
export const addTo = (index, key, value) => {
|
|
100
|
-
|
|
101
|
-
if (set === undefined)
|
|
102
|
-
index.set(key, (set = new Set()));
|
|
99
|
+
const set = getOr(index, key, () => new Set());
|
|
103
100
|
set.add(value);
|
|
104
101
|
};
|
|
105
102
|
/** Remove `value` from `key`'s set in `index` (the set goes once empty). */
|
package/dist/crdt/text/model.js
CHANGED
|
@@ -7,6 +7,7 @@ import { fitMarks, writeMarks } from './marks.js';
|
|
|
7
7
|
import { nodeStart } from './items.js';
|
|
8
8
|
import { readRange } from './ranges.js';
|
|
9
9
|
import { claimsIn, delimiters, displayOf, locate, ownedLength, pieces, placeText, rangesOf, removedKeys, scanText } from './streams.js';
|
|
10
|
+
import { getOr } from '../../utils.js';
|
|
10
11
|
export { isBoundary, isClaimItem, isRowMark, nodeStart } from './items.js';
|
|
11
12
|
export { canonKey, deepFreeze, inlineItemOf, protectItems, readRange } from './ranges.js';
|
|
12
13
|
export { byId, claimsIn, delimiters, displayOf, locate, ownedLength, pieces, placeText, removedKeys, scanText } from './streams.js';
|
|
@@ -107,9 +108,7 @@ export const readSegs = (segs, stats) => {
|
|
|
107
108
|
const out = [];
|
|
108
109
|
const cursors = new Map();
|
|
109
110
|
for (const seg of segs) {
|
|
110
|
-
|
|
111
|
-
if (cur === undefined)
|
|
112
|
-
cursors.set(seg.text, (cur = openRangeCursor(seg.text)));
|
|
111
|
+
const cur = getOr(cursors, seg.text, () => openRangeCursor(seg.text));
|
|
113
112
|
readRange(cur, seg.i0, seg.i1, stats, out);
|
|
114
113
|
}
|
|
115
114
|
return out;
|
package/dist/crdt/text/runs.d.ts
CHANGED
|
@@ -53,17 +53,16 @@
|
|
|
53
53
|
* advancing the published tree in place (after a whole rebuild, the
|
|
54
54
|
* reachable tree is compared).
|
|
55
55
|
*
|
|
56
|
-
* The index is
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
* the
|
|
60
|
-
*
|
|
61
|
-
* cache (`cache.ts`), the fold (`fold.ts`), the change report
|
|
62
|
-
* (`report.ts`); the self-checks a test lane installs are `indexChecks`. This module declares the
|
|
63
|
-
* index's types and wires the parts into the doc's one index.
|
|
56
|
+
* The index is one closure (`index/build.ts`) over its state: the claim
|
|
57
|
+
* graph, the stream table and each block's claims, the layout rules,
|
|
58
|
+
* placements and the children index, block records, the run cache, the fold
|
|
59
|
+
* and the change report; the self-checks a test lane installs are
|
|
60
|
+
* `indexChecks`. This module declares the index's types.
|
|
64
61
|
*/
|
|
65
|
-
import type { EngineApi
|
|
62
|
+
import type { EngineApi } from '../engine-api.js';
|
|
66
63
|
import type { BlockId, ContentItem, ModelView, ProjectedBlock } from '../placement/model.js';
|
|
64
|
+
import { indexOf } from './index/build.js';
|
|
65
|
+
export { indexOf };
|
|
67
66
|
export { CONTENT_ATTR, ENTRY_FACET, SEQ_FACET, indexChecks } from './index/shared.js';
|
|
68
67
|
/**
|
|
69
68
|
* One visible run of a block — the maintained form of `ContentItem`.
|
|
@@ -257,9 +256,7 @@ export type DisplayRoles = {
|
|
|
257
256
|
of: (type: string | null) => KindRole;
|
|
258
257
|
declared: () => DeclaredKinds;
|
|
259
258
|
};
|
|
260
|
-
/** The doc's index — built on first use, torn down when the doc is destroyed. */
|
|
261
|
-
export declare const indexOf: (doc: EngineDoc) => RunView;
|
|
262
259
|
/** The index binding (the public binding's `runs`): {@link indexOf}. */
|
|
263
260
|
export declare const bindRuns: (_Y: EngineApi) => {
|
|
264
|
-
attach: (doc: EngineDoc) => RunView;
|
|
261
|
+
attach: (doc: import("../engine-api.js").EngineDoc) => RunView;
|
|
265
262
|
};
|
package/dist/crdt/text/runs.js
CHANGED
|
@@ -1,168 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
import { indexState } from './index/state.js';
|
|
4
|
-
import { indexClaims } from './index/claims.js';
|
|
5
|
-
import { indexStreams } from './index/streams.js';
|
|
6
|
-
import { indexLayout } from './index/layout.js';
|
|
7
|
-
import { indexPlacement } from './index/placement.js';
|
|
8
|
-
import { indexRecords } from './index/records.js';
|
|
9
|
-
import { indexCache } from './index/cache.js';
|
|
10
|
-
import { indexFold } from './index/fold.js';
|
|
11
|
-
import { indexReporter } from './index/report.js';
|
|
1
|
+
import { indexOf } from './index/build.js';
|
|
2
|
+
export { indexOf };
|
|
12
3
|
export { CONTENT_ATTR, ENTRY_FACET, SEQ_FACET, indexChecks } from './index/shared.js';
|
|
13
|
-
/** One index per engine doc, shared by every binding (the doc's lifetime). */
|
|
14
|
-
const indexes = new WeakMap();
|
|
15
|
-
/** The doc's index — built on first use, torn down when the doc is destroyed. */
|
|
16
|
-
export const indexOf = (doc) => {
|
|
17
|
-
let index = indexes.get(doc);
|
|
18
|
-
if (index === undefined)
|
|
19
|
-
indexes.set(doc, (index = buildView(doc)));
|
|
20
|
-
return index;
|
|
21
|
-
};
|
|
22
4
|
/** The index binding (the public binding's `runs`): {@link indexOf}. */
|
|
23
5
|
export const bindRuns = (_Y) => ({ attach: indexOf });
|
|
24
|
-
const buildView = (doc) => {
|
|
25
|
-
// The index's parts, each over the state and the parts before it (`index/*`).
|
|
26
|
-
const ix0 = indexState(doc);
|
|
27
|
-
const ix1 = Object.assign(ix0, indexClaims(ix0));
|
|
28
|
-
const ix2 = Object.assign(ix1, indexStreams(ix1));
|
|
29
|
-
const ix4 = Object.assign(ix2, indexLayout(ix2));
|
|
30
|
-
const ix5 = Object.assign(ix4, indexPlacement(ix4));
|
|
31
|
-
const ix6 = Object.assign(ix5, indexRecords(ix5));
|
|
32
|
-
const ix7 = Object.assign(ix6, indexCache(ix6));
|
|
33
|
-
const ix8 = Object.assign(ix7, indexFold(ix7));
|
|
34
|
-
const ix = Object.assign(ix8, indexReporter(ix8));
|
|
35
|
-
const { registry, blocks, rows, homeOfText, shells, placementsMap, frames, displays, ownShim, ensurePlacements, typeOf, order, rebuildTable, scanRow, applyReclaims, updateBlockRec, syncIncarnations, intern, debug, runs, settle, syncPending, syncAll, openTx, onCommit, committed, itemsOf, projectBlock, publish, onUpdate, onReport, hasSubscribers } = ix;
|
|
36
|
-
const ctx = {
|
|
37
|
-
blocks,
|
|
38
|
-
own: ownShim,
|
|
39
|
-
get placements() {
|
|
40
|
-
ensurePlacements();
|
|
41
|
-
return placementsMap;
|
|
42
|
-
},
|
|
43
|
-
get kids() {
|
|
44
|
-
ensurePlacements();
|
|
45
|
-
return ix.kidsMap;
|
|
46
|
-
},
|
|
47
|
-
get order() {
|
|
48
|
-
ensurePlacements();
|
|
49
|
-
return order();
|
|
50
|
-
},
|
|
51
|
-
// The publication boundary shares THIS interner, so a payload
|
|
52
|
-
// emitted by `project()`/`contentItems()` is `===` the runs' one.
|
|
53
|
-
intern,
|
|
54
|
-
displays,
|
|
55
|
-
accepted: (id) => {
|
|
56
|
-
ensurePlacements();
|
|
57
|
-
return ix.rejected.has(id) ? null : (ix.edges.get(id) ?? null);
|
|
58
|
-
}
|
|
59
|
-
};
|
|
60
|
-
// ── initial scan: index every existing block ────────────────────
|
|
61
|
-
registry.forEachAttr((v, id) => {
|
|
62
|
-
if (!isNodeLike(v))
|
|
63
|
-
return;
|
|
64
|
-
updateBlockRec(id);
|
|
65
|
-
for (const b of [id, ...syncIncarnations(id)]) {
|
|
66
|
-
const row = scanRow(b);
|
|
67
|
-
if (row !== undefined) {
|
|
68
|
-
rows.set(b, row);
|
|
69
|
-
homeOfText.set(row.text, b);
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
});
|
|
73
|
-
rebuildTable(new Set());
|
|
74
|
-
applyReclaims(null);
|
|
75
|
-
settle(shells, null);
|
|
76
|
-
// Every commit folds once, before the document's `afterTransaction` listeners.
|
|
77
|
-
doc.on('commit', onCommit);
|
|
78
|
-
/** Derived state lives exactly as long as the doc. */
|
|
79
|
-
const teardown = () => {
|
|
80
|
-
doc.off('commit', onCommit);
|
|
81
|
-
doc.off('destroy', teardown);
|
|
82
|
-
doc.off('update', onUpdate);
|
|
83
|
-
indexes.delete(doc);
|
|
84
|
-
};
|
|
85
|
-
doc.on('destroy', teardown);
|
|
86
|
-
// ── public surface ───────────────────────────────────────────────
|
|
87
|
-
const view = {
|
|
88
|
-
version: () => {
|
|
89
|
-
syncAll();
|
|
90
|
-
return ix.version;
|
|
91
|
-
},
|
|
92
|
-
runs,
|
|
93
|
-
contentItems: (b) => {
|
|
94
|
-
syncAll();
|
|
95
|
-
return blocks.get(b)?.deleted === false ? itemsOf(b) : [];
|
|
96
|
-
},
|
|
97
|
-
// Inline atoms always carry `data` (`{}` when absent) — the public
|
|
98
|
-
// `JSONInlineBlock` shape of `edytor.value`.
|
|
99
|
-
contentJSON: (b) => runs(b).map((r) => r.kind === 'text'
|
|
100
|
-
? { text: r.text, ...(r.marks !== undefined && { marks: cloneJsonSafe(r.marks) }) }
|
|
101
|
-
: { id: r.id, type: r.type, data: r.data === undefined ? {} : cloneJsonSafe(r.data) }),
|
|
102
|
-
view: (tr) => {
|
|
103
|
-
syncAll();
|
|
104
|
-
if (tr !== undefined && !committed.has(tr))
|
|
105
|
-
syncPending(tr);
|
|
106
|
-
return ctx;
|
|
107
|
-
},
|
|
108
|
-
displayType: (id) => {
|
|
109
|
-
if (ix.roles === null)
|
|
110
|
-
return undefined;
|
|
111
|
-
syncAll();
|
|
112
|
-
ensurePlacements();
|
|
113
|
-
const shown = blocks.has(id) ? typeOf(id) : undefined;
|
|
114
|
-
return shown === blocks.get(id)?.type ? undefined : shown;
|
|
115
|
-
},
|
|
116
|
-
dissolved: (id) => {
|
|
117
|
-
syncAll();
|
|
118
|
-
ensurePlacements();
|
|
119
|
-
return ix.dissolved.has(id);
|
|
120
|
-
},
|
|
121
|
-
project: (root) => {
|
|
122
|
-
syncAll();
|
|
123
|
-
ensurePlacements();
|
|
124
|
-
return root === undefined
|
|
125
|
-
? (ix.kidsMap.get(null) ?? []).map((k) => projectBlock(k.id))
|
|
126
|
-
: [projectBlock(root)];
|
|
127
|
-
},
|
|
128
|
-
roles: (next) => {
|
|
129
|
-
ix.roles = next;
|
|
130
|
-
ix.placementFull = true;
|
|
131
|
-
ix.version++;
|
|
132
|
-
// No commit carries a role change: report it now (not inside a
|
|
133
|
-
// transaction, whose commit reports it), so every view follows.
|
|
134
|
-
if (hasSubscribers() && !openTx())
|
|
135
|
-
publish(null, false);
|
|
136
|
-
},
|
|
137
|
-
track: () => {
|
|
138
|
-
syncAll();
|
|
139
|
-
const f = { touched: new Map(), wrote: false };
|
|
140
|
-
frames.add(f);
|
|
141
|
-
return {
|
|
142
|
-
end: () => {
|
|
143
|
-
syncAll();
|
|
144
|
-
frames.delete(f);
|
|
145
|
-
return f;
|
|
146
|
-
},
|
|
147
|
-
quiet: (write) => {
|
|
148
|
-
syncAll();
|
|
149
|
-
const g = { touched: new Map(), wrote: false };
|
|
150
|
-
frames.delete(f);
|
|
151
|
-
frames.add(g);
|
|
152
|
-
try {
|
|
153
|
-
write();
|
|
154
|
-
syncAll();
|
|
155
|
-
}
|
|
156
|
-
finally {
|
|
157
|
-
frames.delete(g);
|
|
158
|
-
frames.add(f);
|
|
159
|
-
f.wrote ||= g.wrote;
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
};
|
|
163
|
-
},
|
|
164
|
-
onReport,
|
|
165
|
-
debug
|
|
166
|
-
};
|
|
167
|
-
return view;
|
|
168
|
-
};
|
|
@@ -10,3 +10,5 @@
|
|
|
10
10
|
* through its child index); a disconnected one keeps its offset.
|
|
11
11
|
*/
|
|
12
12
|
export declare const getTextContentOffsetAtPoint: (textNode: Node, node: Node, offset: number) => number;
|
|
13
|
+
/** `element`'s text nodes in document order: the leaves the offsets above count. */
|
|
14
|
+
export declare const textLeaves: (element: Node) => CharacterData[];
|
|
@@ -22,3 +22,11 @@ export const getTextContentOffsetAtPoint = (textNode, node, offset) => {
|
|
|
22
22
|
range.setEnd(node, at);
|
|
23
23
|
return range.toString().length;
|
|
24
24
|
};
|
|
25
|
+
/** `element`'s text nodes in document order: the leaves the offsets above count. */
|
|
26
|
+
export const textLeaves = (element) => {
|
|
27
|
+
const walker = (element.ownerDocument ?? document).createTreeWalker(element, NodeFilter.SHOW_TEXT);
|
|
28
|
+
const leaves = [];
|
|
29
|
+
while (walker.nextNode())
|
|
30
|
+
leaves.push(walker.currentNode);
|
|
31
|
+
return leaves;
|
|
32
|
+
};
|