edytor 4.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/block/block.svelte.js +6 -21
- package/dist/block/inlineBlock.svelte.js +4 -6
- package/dist/clipboard/moveText.js +6 -8
- package/dist/cloudflare/DocumentRoom.d.ts +10 -3
- package/dist/cloudflare/index.d.ts +1 -1
- package/dist/cloudflare/room/access.d.ts +8 -3
- package/dist/cloudflare/room/access.js +44 -20
- package/dist/cloudflare/room/admission.js +28 -5
- package/dist/cloudflare/room/comments.js +28 -1
- package/dist/cloudflare/room/context.d.ts +106 -109
- package/dist/cloudflare/room/context.js +10 -3
- package/dist/cloudflare/room/forged.d.ts +14 -0
- package/dist/cloudflare/room/forged.js +30 -2
- package/dist/cloudflare/room/frames.d.ts +4 -0
- package/dist/cloudflare/room/frames.js +5 -1
- package/dist/cloudflare/room/purge.js +2 -1
- package/dist/cloudflare/room/replicas.d.ts +4 -2
- package/dist/cloudflare/room/replicas.js +8 -3
- package/dist/cloudflare/room/suggest.d.ts +7 -0
- package/dist/cloudflare/room/suggest.js +143 -0
- package/dist/cloudflare/routeDocumentSocket.d.ts +10 -1
- package/dist/cloudflare/routeDocumentSocket.js +5 -3
- package/dist/components/Content.svelte +9 -1
- package/dist/crdt/anchors.js +3 -2
- package/dist/crdt/attribution/attribution.d.ts +3 -0
- package/dist/crdt/attribution/attribution.js +3 -3
- package/dist/crdt/doc/funnel.d.ts +1 -1
- package/dist/crdt/doc/funnel.js +5 -2
- package/dist/crdt/doc/gate.d.ts +1 -1
- package/dist/crdt/doc/history.d.ts +6 -0
- package/dist/crdt/doc/history.js +79 -59
- package/dist/crdt/doc/ops.d.ts +81 -0
- package/dist/crdt/doc/ops.js +1898 -0
- package/dist/crdt/doc/reads.d.ts +2 -2
- package/dist/crdt/doc/reads.js +18 -28
- package/dist/crdt/doc/suggest.d.ts +167 -0
- package/dist/crdt/doc/suggest.js +579 -0
- package/dist/crdt/document.d.ts +10 -1
- package/dist/crdt/document.js +19 -11
- package/dist/crdt/edytor-doc.d.ts +294 -272
- package/dist/crdt/edytor-doc.js +123 -108
- package/dist/crdt/engine-api.d.ts +8 -2
- package/dist/crdt/engine.d.ts +2 -1
- package/dist/crdt/engine.js +3 -1
- package/dist/crdt/flow.d.ts +5 -47
- package/dist/crdt/flow.js +3 -269
- package/dist/crdt/index.d.ts +102 -108
- package/dist/crdt/index.js +3 -0
- package/dist/crdt/operations.d.ts +13 -4
- package/dist/crdt/parts.d.ts +43 -0
- package/dist/crdt/parts.js +44 -0
- package/dist/crdt/placement/display.d.ts +1 -1
- package/dist/crdt/placement/display.js +3 -3
- package/dist/crdt/placement/keys.d.ts +5 -0
- package/dist/crdt/placement/keys.js +5 -0
- package/dist/crdt/placement/resolve.d.ts +1 -1
- package/dist/crdt/placement/resolve.js +2 -1
- package/dist/crdt/protocol.d.ts +1 -1
- package/dist/crdt/protocol.js +1 -1
- package/dist/crdt/protocols/auth.d.ts +11 -1
- package/dist/crdt/protocols/auth.js +17 -1
- package/dist/crdt/protocols/awareness.js +46 -81
- package/dist/crdt/protocols/comments.d.ts +16 -1
- package/dist/crdt/protocols/comments.js +9 -1
- package/dist/crdt/providers/index.d.ts +12 -22
- package/dist/crdt/providers/index.js +3 -1
- 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 +8 -12
- package/dist/crdt/providers/websocket.js +17 -19
- package/dist/crdt/purge.d.ts +7 -1
- package/dist/crdt/purge.js +32 -2
- package/dist/crdt/rangeDelete.d.ts +2 -47
- package/dist/crdt/rangeDelete.js +1 -169
- package/dist/crdt/restore.d.ts +2 -1
- package/dist/crdt/restore.js +9 -0
- package/dist/crdt/schema.d.ts +9 -1
- package/dist/crdt/schema.js +13 -3
- package/dist/crdt/structs.d.ts +2 -0
- package/dist/crdt/structs.js +2 -0
- 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 +19 -19
- package/dist/crdt/text/model.d.ts +10 -0
- package/dist/crdt/text/model.js +10 -4
- package/dist/crdt/text/runs.d.ts +43 -42
- package/dist/crdt/text/runs.js +2 -165
- package/dist/crdt/vendor/yjs/UPSTREAM.md +83 -0
- package/dist/crdt/vendor/yjs/dts/index.d.ts +1 -1
- package/dist/crdt/vendor/yjs/dts/structs/Item.d.ts +6 -3
- package/dist/crdt/vendor/yjs/dts/ynode.d.ts +13 -2
- package/dist/crdt/vendor/yjs/src/index.js +1 -1
- package/dist/crdt/vendor/yjs/src/structs/Item.js +44 -5
- package/dist/crdt/vendor/yjs/src/ynode.js +29 -7
- package/dist/edytor.svelte.d.ts +1 -1
- package/dist/edytor.svelte.js +100 -75
- package/dist/events/beforeInputCommands.d.ts +2 -2
- package/dist/events/domTextOffset.d.ts +2 -0
- package/dist/events/domTextOffset.js +8 -0
- package/dist/events/nativeInteractiveControl.d.ts +11 -1
- package/dist/events/nativeInteractiveControl.js +41 -1
- package/dist/events/onBeforeInput.js +3 -3
- package/dist/events/onFocus.js +9 -11
- package/dist/export/forms.d.ts +75 -75
- package/dist/index.d.ts +4 -2
- package/dist/index.js +1 -1
- package/dist/labels.d.ts +8 -0
- package/dist/labels.js +6 -1
- package/dist/plugins/comments/CommentsController.svelte.d.ts +5 -1
- package/dist/plugins/comments/CommentsController.svelte.js +14 -4
- package/dist/plugins/find/search.js +2 -2
- package/dist/plugins/index.d.ts +1 -0
- package/dist/plugins/index.js +1 -0
- package/dist/plugins/richtext/RichTextPlugin.svelte +63 -61
- package/dist/plugins/richtext/richTextOperations.js +26 -32
- package/dist/plugins/suggestions/SuggestionBars.svelte +40 -23
- package/dist/plugins/suggestions/SuggestionBars.svelte.d.ts +3 -1
- package/dist/plugins/suggestions/SuggestionRuns.svelte +77 -0
- package/dist/plugins/suggestions/SuggestionRuns.svelte.d.ts +9 -0
- package/dist/plugins/suggestions/shared.svelte.d.ts +58 -0
- package/dist/plugins/suggestions/shared.svelte.js +421 -0
- package/dist/plugins/suggestions/suggestionsPlugin.d.ts +15 -4
- package/dist/selection/domSelection.d.ts +2 -0
- package/dist/selection/domSelection.js +6 -2
- package/dist/selection/pointer.svelte.js +75 -48
- package/dist/selection/replaceSelection.js +2 -6
- package/dist/selection/selection.svelte.d.ts +3 -3
- package/dist/selection/selection.svelte.js +39 -32
- package/dist/selection/selection.utils.d.ts +14 -0
- package/dist/selection/selection.utils.js +33 -11
- package/dist/session/commands.js +21 -11
- package/dist/session/composition.svelte.d.ts +5 -3
- package/dist/session/composition.svelte.js +21 -17
- package/dist/session/handles.d.ts +4 -17
- package/dist/session/handles.js +14 -44
- package/dist/session/navigation.js +6 -9
- package/dist/session/selection.d.ts +11 -5
- package/dist/session/selection.js +14 -48
- package/dist/session/suggestions.svelte.d.ts +38 -9
- package/dist/session/suggestions.svelte.js +37 -18
- package/dist/session/virtual.d.ts +1 -1
- package/dist/surface/attributes.d.ts +5 -0
- package/dist/surface/attributes.js +2 -2
- package/dist/surface/cells.d.ts +2 -26
- package/dist/surface/cells.js +2 -33
- package/dist/surface/observer.svelte.d.ts +6 -1
- package/dist/surface/observer.svelte.js +143 -111
- package/dist/surface/pin.svelte.d.ts +9 -9
- package/dist/surface/pin.svelte.js +15 -22
- package/dist/surface/projector.svelte.js +10 -16
- package/dist/text/text.svelte.js +14 -19
- package/dist/themes/notion.css +29 -0
- package/dist/utils.d.ts +5 -0
- package/dist/utils.js +7 -0
- package/package.json +3 -1
- package/dist/crdt/doc/capability.d.ts +0 -56
- package/dist/crdt/doc/capability.js +0 -211
- 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 -199
- 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 -225
- 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 -24
- package/dist/crdt/text/index/layout.js +0 -271
- package/dist/crdt/text/index/placement.d.ts +0 -47
- package/dist/crdt/text/index/placement.js +0 -741
- 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
package/dist/crdt/edytor-doc.js
CHANGED
|
@@ -23,18 +23,16 @@
|
|
|
23
23
|
* `doc/types.ts` — the public types; `doc/plan.ts` — op results, a plan's
|
|
24
24
|
* effect, ingress normalization.
|
|
25
25
|
* - `doc/reads.ts` (`DocBase`: the doc, its engine, its index and
|
|
26
|
-
* roles) — the reads, roles and document order
|
|
27
|
-
* structural capability (`canPlace`, `fits`, `canMerge`, the island and
|
|
28
|
-
* void rules).
|
|
26
|
+
* roles) — the reads, roles and document order.
|
|
29
27
|
* - `doc/funnel.ts` — the write funnel (`write`, `apply`, attribution);
|
|
30
28
|
* `doc/events.ts` — `onChange`; `doc/history.ts` —
|
|
31
29
|
* `createUndoManager`; `doc/anchors.ts` — caret anchors.
|
|
32
|
-
* - `doc/
|
|
33
|
-
*
|
|
34
|
-
* (
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
* `rangeDelete.ts` and `flow.ts
|
|
30
|
+
* - `doc/ops.ts` — one closure over the reads: the structural capability
|
|
31
|
+
* (`canPlace`, `fits`, `canMerge`, the island and void rules), the step
|
|
32
|
+
* writers every op composes (ranks, settle, emptying, dissolving) and the
|
|
33
|
+
* prepared op families (placement, layout, split and merge, delete, type
|
|
34
|
+
* and data, text, atoms and marks), then range deletion and flow placement
|
|
35
|
+
* over them (their types in `rangeDelete.ts` and `flow.ts`).
|
|
38
36
|
*
|
|
39
37
|
* ── Identity discipline ────────────────────────────────────────────────
|
|
40
38
|
*
|
|
@@ -56,24 +54,15 @@ import { bindPurge, readHorizon } from './purge.js';
|
|
|
56
54
|
import { restoreDocument } from './restore.js';
|
|
57
55
|
import { bindRuns, indexOf } from './text/runs.js';
|
|
58
56
|
import { bindBlockAttribution, blockAttributionOf } from './attribution/block.js';
|
|
59
|
-
import { rangeDeleteOps } from './rangeDelete.js';
|
|
60
|
-
import { flowOps } from './flow.js';
|
|
61
57
|
import { assertSchema, checkSchema, isInitialized, META_KEY, registryEmpty, SCHEMA_NAME, SCHEMA_VERSION, SchemaMismatchError, schemaVersion } from './doc/gate.js';
|
|
62
58
|
import { bindSeed, restore } from './doc/seed.js';
|
|
63
59
|
import { applied, ref } from './doc/plan.js';
|
|
64
60
|
import { docReads } from './doc/reads.js';
|
|
65
|
-
import { docCapability } from './doc/capability.js';
|
|
66
61
|
import { writeFunnel } from './doc/funnel.js';
|
|
67
62
|
import { docEvents } from './doc/events.js';
|
|
68
63
|
import { docHistory } from './doc/history.js';
|
|
69
64
|
import { docAnchors } from './doc/anchors.js';
|
|
70
|
-
import {
|
|
71
|
-
import { moveOps } from './doc/moves.js';
|
|
72
|
-
import { layoutOps } from './doc/layout.js';
|
|
73
|
-
import { splitMergeOps } from './doc/split-merge.js';
|
|
74
|
-
import { deleteOps } from './doc/delete.js';
|
|
75
|
-
import { metaOps } from './doc/meta.js';
|
|
76
|
-
import { contentOps } from './doc/content.js';
|
|
65
|
+
import { docOps } from './doc/ops.js';
|
|
77
66
|
// ── schema manifest and gate (`doc/gate.ts`) ────────────────────────────
|
|
78
67
|
export { SCHEMA };
|
|
79
68
|
export { assertSchema, checkSchema, isInitialized, META_KEY, registryEmpty, SCHEMA_NAME, SCHEMA_VERSION, SchemaMismatchError, schemaVersion };
|
|
@@ -105,7 +94,7 @@ export const docFacade = (Y, layers) => {
|
|
|
105
94
|
// per-doc (WeakMap-keyed), so facades on the same doc share it.
|
|
106
95
|
const BA = bindBlockAttribution(Y);
|
|
107
96
|
const { init, seed } = bindSeed(Y, BA);
|
|
108
|
-
|
|
97
|
+
const create = (doc, config = {}) => {
|
|
109
98
|
adoptRules(doc);
|
|
110
99
|
setMarkEdges(doc, config.markEdge ?? (() => undefined));
|
|
111
100
|
const roleOf = config.roleOf ?? (() => undefined);
|
|
@@ -123,30 +112,52 @@ export const docFacade = (Y, layers) => {
|
|
|
123
112
|
// A layout displays only its items — its
|
|
124
113
|
// `defaultChild` kind — and only two or more (`layout.*`). A table
|
|
125
114
|
// displays only its rows and a row only its cells (`table.*`).
|
|
115
|
+
let kinds = new Map();
|
|
116
|
+
let declared;
|
|
126
117
|
const roles = {
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
118
|
+
of: (type) => {
|
|
119
|
+
let k = kinds.get(type);
|
|
120
|
+
if (k === undefined) {
|
|
121
|
+
const role = type === null ? undefined : roleOf(type);
|
|
122
|
+
const own = type === null ? undefined : defaultChildOf(type);
|
|
123
|
+
const renders = type === null || rendersContentOf(type);
|
|
124
|
+
kinds.set(type, (k = {
|
|
125
|
+
childless: role?.void === true,
|
|
126
|
+
island: role?.island === true,
|
|
127
|
+
container: !renders && role?.void !== true && role?.island !== true,
|
|
128
|
+
rendersContent: renders,
|
|
129
|
+
child: own ?? defaultType,
|
|
130
|
+
line: role?.island === true && role.lines === true ? own : undefined,
|
|
131
|
+
layout: role?.layout === true ? own : undefined,
|
|
132
|
+
table: role?.table === true ? own : undefined
|
|
133
|
+
}));
|
|
134
|
+
}
|
|
135
|
+
return k;
|
|
135
136
|
},
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
137
|
+
declared: () => {
|
|
138
|
+
if (declared === undefined) {
|
|
139
|
+
const all = [...(config.kinds?.() ?? [])].map(roles.of);
|
|
140
|
+
const rows = new Map(all.flatMap((k) => (k.table ? [[k.table, roles.of(k.table).child]] : [])));
|
|
141
|
+
declared = {
|
|
142
|
+
lines: new Set(all.flatMap((k) => k.line ?? [])),
|
|
143
|
+
layouts: [...(config.kinds?.() ?? [])].filter((t) => roles.of(t).layout !== undefined),
|
|
144
|
+
items: new Set(all.flatMap((k) => k.layout ?? [])),
|
|
145
|
+
rows,
|
|
146
|
+
cells: new Set(rows.values())
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
return declared;
|
|
150
|
+
}
|
|
141
151
|
};
|
|
142
152
|
if (config.roleOf)
|
|
143
153
|
runsView.roles(roles);
|
|
144
154
|
// The facade's parts, each over the ones before it (`doc/*`).
|
|
145
155
|
const base = { Y, doc, runsView, roles, roleOf, rendersContentOf };
|
|
146
156
|
const reads = { ...base, ...docReads(base) };
|
|
147
|
-
|
|
157
|
+
// The capability, the step writers and the prepared op families (`doc/ops.ts`).
|
|
158
|
+
const ops = { ...reads, ...docOps(reads) };
|
|
148
159
|
const { blockJSON, view, blockTypeOf, blockDataOf, docData, dataItemIds, dataPreview, childrenIds, positionOf, pathOf, ancestorsOf, slotOf, isVoid, isIsland, isLines, islandOf, insideIsland, isLayout, isLayoutItem, order, compare, next, previous, displayLength, contentItems, hasBlock, live } = reads;
|
|
149
|
-
const { canPlace, fits, nestParent, canMerge, defaultChild } =
|
|
160
|
+
const { canPlace, fits, nestParent, canMerge, defaultChild, plan, landingOf, besideAt } = ops;
|
|
150
161
|
const funnel = writeFunnel({ ...reads, BA, config });
|
|
151
162
|
const { write, apply } = funnel;
|
|
152
163
|
const events = docEvents({ runsView });
|
|
@@ -157,53 +168,34 @@ export const docFacade = (Y, layers) => {
|
|
|
157
168
|
};
|
|
158
169
|
const { createUndoManager } = docHistory({ ...base, ...funnel, init });
|
|
159
170
|
const { anchorAt, followUndo, resolveAnchor } = docAnchors(reads);
|
|
160
|
-
const steps = { ...shape, ...planSteps(shape) };
|
|
161
|
-
const { plan } = steps;
|
|
162
|
-
// The prepared op families (`OpsContext`: the reads, capability and step writers).
|
|
163
|
-
const { insertBlocks, moveBlocks, unNestBlocks, unNestBlock, landingOf, liftOut, duplicateBlock } = moveOps(steps);
|
|
164
|
-
const { besideAt, placeBeside, wrapInLayout } = layoutOps(steps);
|
|
165
|
-
const { splitBlock, mergeBlocks, mergeBackward, mergeForward } = splitMergeOps(steps);
|
|
166
|
-
const { deleteBlocks, deleteBlock } = deleteOps(steps);
|
|
167
|
-
const { dataSteps, replaceData, setBlockType, patchData, setBlock } = metaOps(steps);
|
|
168
|
-
const { insertText, deleteText, formatRange, clearMarks, insertInline, removeInline } = contentOps(steps);
|
|
169
|
-
/** What range deletion and flow placement compose: the step writers and the ops. */
|
|
170
|
-
const ops = { ...steps, insertBlocks, deleteBlocks, dataSteps, replaceData };
|
|
171
171
|
/** Every document op, prepared — `apply(prepare.op(…))` is the op. */
|
|
172
172
|
const prepare = {
|
|
173
|
-
|
|
174
|
-
moveBlocks,
|
|
173
|
+
...ops.prepare,
|
|
175
174
|
/**
|
|
176
175
|
* Move `id` to the last position under `parent` — under a container
|
|
177
176
|
* it is no item of, under its last item (`nestParent`: Tab after a list).
|
|
178
177
|
*/
|
|
179
178
|
nestBlock: (id, parent) => {
|
|
180
179
|
const at = nestParent([ref(id)], ref(parent));
|
|
181
|
-
return moveBlocks([id], { parent: at, index: childrenIds(at).length });
|
|
180
|
+
return ops.prepare.moveBlocks([id], { parent: at, index: childrenIds(at).length });
|
|
182
181
|
},
|
|
183
|
-
unNestBlock,
|
|
184
|
-
unNestBlocks,
|
|
185
|
-
liftOut,
|
|
186
|
-
placeBeside,
|
|
187
|
-
wrapInLayout,
|
|
188
|
-
splitBlock,
|
|
189
|
-
mergeBlocks,
|
|
190
|
-
mergeBackward,
|
|
191
|
-
mergeForward,
|
|
192
|
-
deleteBlock,
|
|
193
|
-
setBlock,
|
|
194
|
-
setBlockType,
|
|
195
|
-
patchData,
|
|
196
|
-
duplicateBlock,
|
|
197
|
-
insertText,
|
|
198
|
-
deleteText,
|
|
199
|
-
formatRange,
|
|
200
|
-
clearMarks,
|
|
201
|
-
insertInline,
|
|
202
|
-
removeInline,
|
|
203
182
|
/** Delete a block selection — one plan; only the members leave (`deleteBlocks` above). */
|
|
204
|
-
deleteBlocks: (ids) => deleteBlocks(ids)
|
|
205
|
-
|
|
206
|
-
|
|
183
|
+
deleteBlocks: (ids) => ops.prepare.deleteBlocks(ids)
|
|
184
|
+
};
|
|
185
|
+
/**
|
|
186
|
+
* What a part built over this document reads beyond the facade (the
|
|
187
|
+
* shared suggestions, `doc/suggest.ts`): the reads, a facade over
|
|
188
|
+
* another doc (`create`, with this `config`);
|
|
189
|
+
* `v` counts its changes no index fact shows (in `version`), and
|
|
190
|
+
* `base`, when set, is the export `toJSON()` gives unless asked for
|
|
191
|
+
* the suggestions.
|
|
192
|
+
*/
|
|
193
|
+
const part = {
|
|
194
|
+
...reads,
|
|
195
|
+
config,
|
|
196
|
+
create: create,
|
|
197
|
+
v: 0,
|
|
198
|
+
base: undefined
|
|
207
199
|
};
|
|
208
200
|
/**
|
|
209
201
|
* Plans prepared at one version, as one plan (refused if any part is;
|
|
@@ -226,7 +218,11 @@ export const docFacade = (Y, layers) => {
|
|
|
226
218
|
* omitted when empty): the one serializer, {@link blockJSON}, over the
|
|
227
219
|
* root's visible children.
|
|
228
220
|
*/
|
|
229
|
-
const toJSON = () => {
|
|
221
|
+
const toJSON = (options) => {
|
|
222
|
+
// A part's export first (the shared suggestions': without the pending ones, `sugg.json.base`).
|
|
223
|
+
const base = !options?.suggestions && part.base?.();
|
|
224
|
+
if (base)
|
|
225
|
+
return base;
|
|
230
226
|
const data = docData();
|
|
231
227
|
const children = childrenIds(null).map(blockJSON);
|
|
232
228
|
return Object.keys(data).length > 0
|
|
@@ -236,32 +232,17 @@ export const docFacade = (Y, layers) => {
|
|
|
236
232
|
// ── facade object ─────────────────────────────────────────────────
|
|
237
233
|
/** A read taking an id first: the id normalizes at ingress. */
|
|
238
234
|
const byRef = (f) => (id, ...rest) => f(ref(id), ...rest);
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
/** Replicated `meta.v` schema version (the module-level read, bound). */
|
|
246
|
-
schemaVersion: () => schemaVersion(doc),
|
|
247
|
-
/**
|
|
248
|
-
* The schema gate for this doc — throws {@link SchemaMismatchError}
|
|
249
|
-
* on unversioned-content or unsupported-version state. Consumers
|
|
250
|
-
* (`Edytor.sync()`, packed consumers) call it before trusting
|
|
251
|
-
* a synced doc.
|
|
252
|
-
*/
|
|
253
|
-
checkSchema: () => checkSchema(doc),
|
|
254
|
-
assertSchema: () => assertSchema(doc),
|
|
255
|
-
dispose,
|
|
256
|
-
createUndoManager,
|
|
235
|
+
/**
|
|
236
|
+
* The public operations (`DocumentOperations`), each name once: what
|
|
237
|
+
* an `EdytorDocument` forwards. The facade has them and the internal
|
|
238
|
+
* members below.
|
|
239
|
+
*/
|
|
240
|
+
const api = {
|
|
257
241
|
// reads — every id argument normalizes at ingress
|
|
258
242
|
project: () => project(doc),
|
|
259
243
|
toJSON,
|
|
260
244
|
blockJSON: byRef(blockJSON),
|
|
261
245
|
childrenIds: byRef(childrenIds),
|
|
262
|
-
/** Visible children of `parent` with their ranks, in `(rank, id)` order. */
|
|
263
|
-
childSlots: (parent) => view().kids.get(parent) ?? [],
|
|
264
|
-
slotOf: byRef(slotOf),
|
|
265
246
|
positionOf: byRef(positionOf),
|
|
266
247
|
pathOf: byRef(pathOf),
|
|
267
248
|
parentOf: byRef((id) => positionOf(id)?.parent ?? null),
|
|
@@ -279,8 +260,6 @@ export const docFacade = (Y, layers) => {
|
|
|
279
260
|
* O(1) per call; live-replicated (remote values read the same).
|
|
280
261
|
*/
|
|
281
262
|
blockAttribution: byRef((id) => blockAttributionOf(doc, id)),
|
|
282
|
-
crdtId: byRef((id) => crdtId(doc, id)),
|
|
283
|
-
resolveBlock: byRef((id) => resolveBlock(doc, id)),
|
|
284
263
|
displayLength: byRef(displayLength),
|
|
285
264
|
contentItems: byRef(contentItems),
|
|
286
265
|
hasBlock: byRef(hasBlock),
|
|
@@ -292,10 +271,6 @@ export const docFacade = (Y, layers) => {
|
|
|
292
271
|
// caret anchors — backing-text-bound selection endpoints
|
|
293
272
|
anchorAt: byRef(anchorAt),
|
|
294
273
|
resolveAnchor,
|
|
295
|
-
followUndo,
|
|
296
|
-
// roles
|
|
297
|
-
/** Re-read the roles after `roleOf` answers differently (roles adopted later). */
|
|
298
|
-
rolesChanged: () => runsView.roles(roles),
|
|
299
274
|
isVoid: byRef(isVoid),
|
|
300
275
|
isIsland: byRef(isIsland),
|
|
301
276
|
isLines: byRef(isLines),
|
|
@@ -331,10 +306,8 @@ export const docFacade = (Y, layers) => {
|
|
|
331
306
|
nestParent: (ids, parent) => nestParent(ids.map(ref), ref(parent)),
|
|
332
307
|
/** Where a block of `kind` at `id`'s place lands, and the containers it leaves (`liftOut`). */
|
|
333
308
|
landingOf: (id, kind, after) => landingOf(ref(id), ref(kind), after),
|
|
334
|
-
defaultChild: byRef(defaultChild),
|
|
335
309
|
// maintained runs (bound to this doc)
|
|
336
310
|
runs: byRef(runsView.runs),
|
|
337
|
-
contentJSON: byRef(runsView.contentJSON),
|
|
338
311
|
// events
|
|
339
312
|
onChange,
|
|
340
313
|
// every op — each returns an {@link OpResult}; `apply(prepare.op(…))`
|
|
@@ -347,10 +320,6 @@ export const docFacade = (Y, layers) => {
|
|
|
347
320
|
// transactions (composed ops already run in one; expose for callers
|
|
348
321
|
// that batch several ops into one undo step / one event)
|
|
349
322
|
transact: (fn, origin) => write(() => doc.transact(fn, origin)),
|
|
350
|
-
// escape hatch for the history and debugging — the bound engine layers.
|
|
351
|
-
model: layers.model,
|
|
352
|
-
text: layers.text,
|
|
353
|
-
runsView,
|
|
354
323
|
// ── model-state version ─────────────────────────────
|
|
355
324
|
/**
|
|
356
325
|
* The index version — bumps on every fold that changed derived
|
|
@@ -359,11 +328,57 @@ export const docFacade = (Y, layers) => {
|
|
|
359
328
|
* post-write state — this is the read-your-writes contract.
|
|
360
329
|
*/
|
|
361
330
|
get version() {
|
|
362
|
-
|
|
331
|
+
// A part's change may show in no index fact (a suggestion's decision).
|
|
332
|
+
return runsView.version() + part.v;
|
|
363
333
|
}
|
|
364
334
|
};
|
|
365
|
-
|
|
335
|
+
const internal = {
|
|
336
|
+
// lifecycle
|
|
337
|
+
init: (opts) => write(() => init(doc, opts)),
|
|
338
|
+
/** Apply the deterministic seed of `value` and the document's `data` — the document's seed decision. */
|
|
339
|
+
seed: (value, data) => write(() => seed(doc, value, defaultType, data)),
|
|
340
|
+
isInitialized: () => isInitialized(doc),
|
|
341
|
+
/** Replicated `meta.v` schema version (the module-level read, bound). */
|
|
342
|
+
schemaVersion: () => schemaVersion(doc),
|
|
343
|
+
/**
|
|
344
|
+
* The schema gate for this doc — throws {@link SchemaMismatchError}
|
|
345
|
+
* on unversioned-content or unsupported-version state. Consumers
|
|
346
|
+
* (`Edytor.sync()`, packed consumers) call it before trusting
|
|
347
|
+
* a synced doc.
|
|
348
|
+
*/
|
|
349
|
+
checkSchema: () => checkSchema(doc),
|
|
350
|
+
assertSchema: () => assertSchema(doc),
|
|
351
|
+
dispose,
|
|
352
|
+
createUndoManager,
|
|
353
|
+
/** @internal What a part built over the document reads and writes (`doc/suggest.ts`). */
|
|
354
|
+
part,
|
|
355
|
+
/** Visible children of `parent` with their ranks, in `(rank, id)` order. */
|
|
356
|
+
childSlots: (parent) => view().kids.get(parent) ?? [],
|
|
357
|
+
slotOf: byRef(slotOf),
|
|
358
|
+
crdtId: byRef((id) => crdtId(doc, id)),
|
|
359
|
+
resolveBlock: byRef((id) => resolveBlock(doc, id)),
|
|
360
|
+
followUndo,
|
|
361
|
+
// roles
|
|
362
|
+
/** Re-read the roles after `roleOf` answers differently (roles adopted later). */
|
|
363
|
+
rolesChanged: (place = true) => {
|
|
364
|
+
kinds = new Map();
|
|
365
|
+
declared = undefined;
|
|
366
|
+
if (place)
|
|
367
|
+
runsView.roles(roles);
|
|
368
|
+
},
|
|
369
|
+
defaultChild: byRef(defaultChild),
|
|
370
|
+
contentJSON: byRef(runsView.contentJSON),
|
|
371
|
+
// escape hatch for the history and debugging — the bound engine layers.
|
|
372
|
+
model: layers.model,
|
|
373
|
+
text: layers.text,
|
|
374
|
+
runsView,
|
|
375
|
+
/** The public members' names (`EdytorDocument` forwards them). */
|
|
376
|
+
api: api
|
|
377
|
+
};
|
|
378
|
+
// The public members joined as they are (the `version` getter stays one).
|
|
379
|
+
return Object.defineProperties(internal, Object.getOwnPropertyDescriptors(api));
|
|
366
380
|
};
|
|
381
|
+
return create;
|
|
367
382
|
};
|
|
368
383
|
/**
|
|
369
384
|
* Bind the assembled model to a concrete engine surface. `Y` must be the
|
|
@@ -78,9 +78,15 @@ export interface EngineNode {
|
|
|
78
78
|
* Delete `length` live units at `index`. With `into` (the document's
|
|
79
79
|
* records list), they are held by one record appended there instead (a
|
|
80
80
|
* delete its writer can take back), except those `fresh` names, which are
|
|
81
|
-
* removed.
|
|
81
|
+
* removed. With `propose` (a suggestion's delete), each
|
|
82
|
+
* unit is sorted: `1` held as above (its author's own), `2` proposed (an
|
|
83
|
+
* id list appended to `propose.into`) or `3` stepped over; proposed and
|
|
84
|
+
* stepped-over units read gone until the engine's `unhide`.
|
|
82
85
|
*/
|
|
83
|
-
delete(index: number, length?: number, into?: EngineNode | null, fresh?: unknown
|
|
86
|
+
delete(index: number, length?: number, into?: EngineNode | null, fresh?: unknown, propose?: {
|
|
87
|
+
into: EngineNode;
|
|
88
|
+
sort: (client: number, clock: number) => number;
|
|
89
|
+
} | null): void;
|
|
84
90
|
/** Append one hold record of `ids` (`client, clock, len` triples) to this records list: they read as deleted while it lives. */
|
|
85
91
|
hold(ids: number[]): void;
|
|
86
92
|
/**
|
package/dist/crdt/engine.d.ts
CHANGED
package/dist/crdt/engine.js
CHANGED
|
@@ -45,5 +45,7 @@ export const Y = {
|
|
|
45
45
|
followRedone: V.followRedone,
|
|
46
46
|
isParentOf: V.isParentOf,
|
|
47
47
|
mergeIdSets: V.mergeIdSets,
|
|
48
|
-
createID: V.createID
|
|
48
|
+
createID: V.createID,
|
|
49
|
+
// a suggestion's proposed deletion reads gone until its plan ends (fork patch YP32)
|
|
50
|
+
unhide: V.unhide
|
|
49
51
|
};
|
package/dist/crdt/flow.d.ts
CHANGED
|
@@ -1,47 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
* `docs/editor-delete-contract.md`:
|
|
5
|
-
*
|
|
6
|
-
* - a flow is lines with fresh ids: a kinded block, or an inline run (no
|
|
7
|
-
* `type`); an empty flow changes nothing (`flow.shape`);
|
|
8
|
-
* - one line joins the text at the position; an empty block takes a kinded
|
|
9
|
-
* line's kind (`flow.inline`);
|
|
10
|
-
* - several lines split the block: the first joins the head, the last is the
|
|
11
|
-
* tail's block and takes the text after the position and the block's
|
|
12
|
-
* children, the rest go between (`flow.split`) — children the view
|
|
13
|
-
* hides (a closed toggle's body) stay with the head, as Enter keeps them;
|
|
14
|
-
* - a line that joins no text (a list, a code block, a divider: it renders
|
|
15
|
-
* none of its own, or is a void or an island) is placed as a block, never
|
|
16
|
-
* joined; the text after the position stays in a shown line of the
|
|
17
|
-
* block's kind (`flow.apart`), and the caret ends the last pasted
|
|
18
|
-
* shown line;
|
|
19
|
-
* - in a code line (a `lines` island) the lines, nested ones included, are
|
|
20
|
-
* placed as plain lines (`flow.lines`);
|
|
21
|
-
* - a `whole` flow (a block-selection copy) goes after the block, replacing
|
|
22
|
-
* it when empty (`flow.whole`); over selected blocks the lines take their
|
|
23
|
-
* slot (`flow.slot`), and at a slot they are placed with nothing replaced
|
|
24
|
-
* (`flow.place`: an accepted suggestion), as plain inserts (`insertBlocks`: their order
|
|
25
|
-
* against a peer's split beside them is not claimed); a void
|
|
26
|
-
* takes one run (`flow.void`);
|
|
27
|
-
* - a table's cell is never split: it takes the lines a flow shows, nested
|
|
28
|
-
* ones and a pasted table's cells included, as one text joined by line
|
|
29
|
-
* breaks; a cell outside a row (cells copied out of a table) is a line of
|
|
30
|
-
* text, and a row outside a table its cells (`table.paste`);
|
|
31
|
-
* - a plain line that lands directly in a container takes its item kind
|
|
32
|
-
* (the document's `fitted`: a pasted paragraph in a list is its item),
|
|
33
|
-
* and so does a line of the list's flat item kind (the view's
|
|
34
|
-
* `itemKind`: a pasted numbered item in an `ordered-list`); any
|
|
35
|
-
* other kind keeps its kind and data (a pasted image stays an image, a
|
|
36
|
-
* bulleted item in an `ordered-list` a bulleted item).
|
|
2
|
+
* The types flow placement (`insertFlow`: the `flow.*` rows, prepared in
|
|
3
|
+
* `doc/ops.ts`) reads, and where the caret ends a placed block.
|
|
37
4
|
*/
|
|
38
5
|
import type { BlockId, BlockSpec, Destination } from './placement/model.js';
|
|
39
|
-
import type { Prepared } from './edytor-doc.js';
|
|
40
6
|
import type { DocPosition, RangeView } from './rangeDelete.js';
|
|
41
|
-
import type { OpsContext } from './doc/steps.js';
|
|
42
|
-
import type { MoveOps } from './doc/moves.js';
|
|
43
|
-
import type { DeleteOps } from './doc/delete.js';
|
|
44
|
-
import type { MetaOps } from './doc/meta.js';
|
|
45
7
|
/** One line of a flow: a kinded block, or an inline run when it has no `type`. */
|
|
46
8
|
export type FlowLine = Omit<BlockSpec, 'type'> & {
|
|
47
9
|
type?: string;
|
|
@@ -72,8 +34,8 @@ export type FlowTarget = DocPosition | {
|
|
|
72
34
|
} | {
|
|
73
35
|
slot: Destination;
|
|
74
36
|
};
|
|
75
|
-
/**
|
|
76
|
-
export
|
|
37
|
+
/** The units of a line's content (an atom counts 1). */
|
|
38
|
+
export declare const lengthOf: (l: FlowLine) => number;
|
|
77
39
|
/**
|
|
78
40
|
* Where the caret ends a placed block: its own content's end when it shows a
|
|
79
41
|
* line (renders its content, no void; a toggle's header, never its body),
|
|
@@ -82,10 +44,6 @@ export type FlowContext = OpsContext & Pick<MoveOps, 'insertBlocks'> & Pick<Dele
|
|
|
82
44
|
* paragraph (`doc.empty.virtual`) place the caret by it.
|
|
83
45
|
*/
|
|
84
46
|
export declare const placedEnd: (roleOf: (kind: string) => {
|
|
85
|
-
|
|
47
|
+
childless: boolean;
|
|
86
48
|
rendersContent: boolean;
|
|
87
49
|
}) => (s: BlockSpec) => DocPosition | undefined;
|
|
88
|
-
/** `insertFlow`, prepared. */
|
|
89
|
-
export declare const flowOps: (c: FlowContext) => {
|
|
90
|
-
insertFlow: (target: FlowTarget, flow: Flow, view?: FlowView) => Prepared;
|
|
91
|
-
};
|