edytor 4.0.0 → 5.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 +115 -106
- 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/capability.js +9 -13
- 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 +77 -56
- package/dist/crdt/doc/layout.js +5 -5
- package/dist/crdt/doc/meta.js +6 -7
- package/dist/crdt/doc/reads.d.ts +2 -2
- package/dist/crdt/doc/reads.js +18 -28
- package/dist/crdt/doc/steps.js +4 -4
- 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 +355 -333
- package/dist/crdt/edytor-doc.js +125 -82
- 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 +1 -1
- package/dist/crdt/flow.js +4 -10
- package/dist/crdt/index.d.ts +111 -105
- package/dist/crdt/index.js +3 -0
- package/dist/crdt/operations.d.ts +12 -3
- 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.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/comments.d.ts +16 -1
- package/dist/crdt/protocols/comments.js +9 -1
- package/dist/crdt/providers/index.d.ts +6 -4
- package/dist/crdt/providers/index.js +3 -1
- package/dist/crdt/providers/websocket.d.ts +6 -4
- package/dist/crdt/providers/websocket.js +9 -4
- package/dist/crdt/purge.d.ts +7 -1
- package/dist/crdt/purge.js +32 -2
- 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/claims.js +1 -23
- package/dist/crdt/text/index/layout.d.ts +2 -4
- package/dist/crdt/text/index/layout.js +9 -22
- package/dist/crdt/text/index/placement.js +21 -24
- package/dist/crdt/text/index/shared.js +17 -14
- package/dist/crdt/text/model.d.ts +10 -0
- package/dist/crdt/text/model.js +8 -1
- package/dist/crdt/text/runs.d.ts +34 -30
- 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/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 +25 -25
- 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/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 +28 -3
- 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 +11 -37
- 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 +128 -81
- package/dist/surface/pin.svelte.d.ts +9 -9
- package/dist/surface/pin.svelte.js +15 -22
- package/dist/surface/projector.svelte.js +8 -14
- package/dist/text/text.svelte.js +14 -19
- package/dist/themes/notion.css +29 -0
- package/package.json +3 -1
package/dist/crdt/edytor-doc.js
CHANGED
|
@@ -105,7 +105,7 @@ export const docFacade = (Y, layers) => {
|
|
|
105
105
|
// per-doc (WeakMap-keyed), so facades on the same doc share it.
|
|
106
106
|
const BA = bindBlockAttribution(Y);
|
|
107
107
|
const { init, seed } = bindSeed(Y, BA);
|
|
108
|
-
|
|
108
|
+
const create = (doc, config = {}) => {
|
|
109
109
|
adoptRules(doc);
|
|
110
110
|
setMarkEdges(doc, config.markEdge ?? (() => undefined));
|
|
111
111
|
const roleOf = config.roleOf ?? (() => undefined);
|
|
@@ -123,21 +123,42 @@ export const docFacade = (Y, layers) => {
|
|
|
123
123
|
// A layout displays only its items — its
|
|
124
124
|
// `defaultChild` kind — and only two or more (`layout.*`). A table
|
|
125
125
|
// displays only its rows and a row only its cells (`table.*`).
|
|
126
|
+
let kinds = new Map();
|
|
127
|
+
let declared;
|
|
126
128
|
const roles = {
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
129
|
+
of: (type) => {
|
|
130
|
+
let k = kinds.get(type);
|
|
131
|
+
if (k === undefined) {
|
|
132
|
+
const role = type === null ? undefined : roleOf(type);
|
|
133
|
+
const own = type === null ? undefined : defaultChildOf(type);
|
|
134
|
+
const renders = type === null || rendersContentOf(type);
|
|
135
|
+
kinds.set(type, (k = {
|
|
136
|
+
childless: role?.void === true,
|
|
137
|
+
island: role?.island === true,
|
|
138
|
+
container: !renders && role?.void !== true && role?.island !== true,
|
|
139
|
+
rendersContent: renders,
|
|
140
|
+
child: own ?? defaultType,
|
|
141
|
+
line: role?.island === true && role.lines === true ? own : undefined,
|
|
142
|
+
layout: role?.layout === true ? own : undefined,
|
|
143
|
+
table: role?.table === true ? own : undefined
|
|
144
|
+
}));
|
|
145
|
+
}
|
|
146
|
+
return k;
|
|
135
147
|
},
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
148
|
+
declared: () => {
|
|
149
|
+
if (declared === undefined) {
|
|
150
|
+
const all = [...(config.kinds?.() ?? [])].map(roles.of);
|
|
151
|
+
const rows = new Map(all.flatMap((k) => (k.table ? [[k.table, roles.of(k.table).child]] : [])));
|
|
152
|
+
declared = {
|
|
153
|
+
lines: new Set(all.flatMap((k) => k.line ?? [])),
|
|
154
|
+
layouts: [...(config.kinds?.() ?? [])].filter((t) => roles.of(t).layout !== undefined),
|
|
155
|
+
items: new Set(all.flatMap((k) => k.layout ?? [])),
|
|
156
|
+
rows,
|
|
157
|
+
cells: new Set(rows.values())
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
return declared;
|
|
161
|
+
}
|
|
141
162
|
};
|
|
142
163
|
if (config.roleOf)
|
|
143
164
|
runsView.roles(roles);
|
|
@@ -159,52 +180,51 @@ export const docFacade = (Y, layers) => {
|
|
|
159
180
|
const { anchorAt, followUndo, resolveAnchor } = docAnchors(reads);
|
|
160
181
|
const steps = { ...shape, ...planSteps(shape) };
|
|
161
182
|
const { plan } = steps;
|
|
162
|
-
// The prepared op families (`OpsContext`: the reads, capability and step
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
const {
|
|
166
|
-
const {
|
|
167
|
-
const { dataSteps, replaceData,
|
|
168
|
-
const
|
|
183
|
+
// The prepared op families (`OpsContext`: the reads, capability and step
|
|
184
|
+
// writers): every op they answer is a document write, but for the reads
|
|
185
|
+
// and step writers taken out here.
|
|
186
|
+
const { landingOf, ...moves } = moveOps(steps);
|
|
187
|
+
const { besideAt, ...layouts } = layoutOps(steps);
|
|
188
|
+
const { dataSteps, replaceData, ...metas } = metaOps(steps);
|
|
189
|
+
const deletes = deleteOps(steps);
|
|
169
190
|
/** What range deletion and flow placement compose: the step writers and the ops. */
|
|
170
|
-
const ops = { ...steps,
|
|
191
|
+
const ops = { ...steps, ...moves, ...deletes, dataSteps, replaceData };
|
|
171
192
|
/** Every document op, prepared — `apply(prepare.op(…))` is the op. */
|
|
172
193
|
const prepare = {
|
|
173
|
-
|
|
174
|
-
|
|
194
|
+
...moves,
|
|
195
|
+
...layouts,
|
|
196
|
+
...splitMergeOps(steps),
|
|
197
|
+
...deletes,
|
|
198
|
+
...metas,
|
|
199
|
+
...contentOps(steps),
|
|
175
200
|
/**
|
|
176
201
|
* Move `id` to the last position under `parent` — under a container
|
|
177
202
|
* it is no item of, under its last item (`nestParent`: Tab after a list).
|
|
178
203
|
*/
|
|
179
204
|
nestBlock: (id, parent) => {
|
|
180
205
|
const at = nestParent([ref(id)], ref(parent));
|
|
181
|
-
return moveBlocks([id], { parent: at, index: childrenIds(at).length });
|
|
206
|
+
return moves.moveBlocks([id], { parent: at, index: childrenIds(at).length });
|
|
182
207
|
},
|
|
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
208
|
/** Delete a block selection — one plan; only the members leave (`deleteBlocks` above). */
|
|
204
|
-
deleteBlocks: (ids) => deleteBlocks(ids),
|
|
209
|
+
deleteBlocks: (ids) => deletes.deleteBlocks(ids),
|
|
205
210
|
...rangeDeleteOps(ops),
|
|
206
211
|
...flowOps(ops)
|
|
207
212
|
};
|
|
213
|
+
/**
|
|
214
|
+
* What a part built over this document reads beyond the facade (the
|
|
215
|
+
* shared suggestions, `doc/suggest.ts`): the reads, a facade over
|
|
216
|
+
* another doc (`create`, with this `config`);
|
|
217
|
+
* `v` counts its changes no index fact shows (in `version`), and
|
|
218
|
+
* `base`, when set, is the export `toJSON()` gives unless asked for
|
|
219
|
+
* the suggestions.
|
|
220
|
+
*/
|
|
221
|
+
const part = {
|
|
222
|
+
...reads,
|
|
223
|
+
config,
|
|
224
|
+
create: create,
|
|
225
|
+
v: 0,
|
|
226
|
+
base: undefined
|
|
227
|
+
};
|
|
208
228
|
/**
|
|
209
229
|
* Plans prepared at one version, as one plan (refused if any part is;
|
|
210
230
|
* stamped with the oldest part's version, so `apply` refuses a stale
|
|
@@ -226,7 +246,11 @@ export const docFacade = (Y, layers) => {
|
|
|
226
246
|
* omitted when empty): the one serializer, {@link blockJSON}, over the
|
|
227
247
|
* root's visible children.
|
|
228
248
|
*/
|
|
229
|
-
const toJSON = () => {
|
|
249
|
+
const toJSON = (options) => {
|
|
250
|
+
// A part's export first (the shared suggestions': without the pending ones, `sugg.json.base`).
|
|
251
|
+
const base = !options?.suggestions && part.base?.();
|
|
252
|
+
if (base)
|
|
253
|
+
return base;
|
|
230
254
|
const data = docData();
|
|
231
255
|
const children = childrenIds(null).map(blockJSON);
|
|
232
256
|
return Object.keys(data).length > 0
|
|
@@ -236,32 +260,17 @@ export const docFacade = (Y, layers) => {
|
|
|
236
260
|
// ── facade object ─────────────────────────────────────────────────
|
|
237
261
|
/** A read taking an id first: the id normalizes at ingress. */
|
|
238
262
|
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,
|
|
263
|
+
/**
|
|
264
|
+
* The public operations (`DocumentOperations`), each name once: what
|
|
265
|
+
* an `EdytorDocument` forwards. The facade has them and the internal
|
|
266
|
+
* members below.
|
|
267
|
+
*/
|
|
268
|
+
const api = {
|
|
257
269
|
// reads — every id argument normalizes at ingress
|
|
258
270
|
project: () => project(doc),
|
|
259
271
|
toJSON,
|
|
260
272
|
blockJSON: byRef(blockJSON),
|
|
261
273
|
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
274
|
positionOf: byRef(positionOf),
|
|
266
275
|
pathOf: byRef(pathOf),
|
|
267
276
|
parentOf: byRef((id) => positionOf(id)?.parent ?? null),
|
|
@@ -279,8 +288,6 @@ export const docFacade = (Y, layers) => {
|
|
|
279
288
|
* O(1) per call; live-replicated (remote values read the same).
|
|
280
289
|
*/
|
|
281
290
|
blockAttribution: byRef((id) => blockAttributionOf(doc, id)),
|
|
282
|
-
crdtId: byRef((id) => crdtId(doc, id)),
|
|
283
|
-
resolveBlock: byRef((id) => resolveBlock(doc, id)),
|
|
284
291
|
displayLength: byRef(displayLength),
|
|
285
292
|
contentItems: byRef(contentItems),
|
|
286
293
|
hasBlock: byRef(hasBlock),
|
|
@@ -292,10 +299,6 @@ export const docFacade = (Y, layers) => {
|
|
|
292
299
|
// caret anchors — backing-text-bound selection endpoints
|
|
293
300
|
anchorAt: byRef(anchorAt),
|
|
294
301
|
resolveAnchor,
|
|
295
|
-
followUndo,
|
|
296
|
-
// roles
|
|
297
|
-
/** Re-read the roles after `roleOf` answers differently (roles adopted later). */
|
|
298
|
-
rolesChanged: () => runsView.roles(roles),
|
|
299
302
|
isVoid: byRef(isVoid),
|
|
300
303
|
isIsland: byRef(isIsland),
|
|
301
304
|
isLines: byRef(isLines),
|
|
@@ -331,10 +334,8 @@ export const docFacade = (Y, layers) => {
|
|
|
331
334
|
nestParent: (ids, parent) => nestParent(ids.map(ref), ref(parent)),
|
|
332
335
|
/** Where a block of `kind` at `id`'s place lands, and the containers it leaves (`liftOut`). */
|
|
333
336
|
landingOf: (id, kind, after) => landingOf(ref(id), ref(kind), after),
|
|
334
|
-
defaultChild: byRef(defaultChild),
|
|
335
337
|
// maintained runs (bound to this doc)
|
|
336
338
|
runs: byRef(runsView.runs),
|
|
337
|
-
contentJSON: byRef(runsView.contentJSON),
|
|
338
339
|
// events
|
|
339
340
|
onChange,
|
|
340
341
|
// every op — each returns an {@link OpResult}; `apply(prepare.op(…))`
|
|
@@ -347,10 +348,6 @@ export const docFacade = (Y, layers) => {
|
|
|
347
348
|
// transactions (composed ops already run in one; expose for callers
|
|
348
349
|
// that batch several ops into one undo step / one event)
|
|
349
350
|
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
351
|
// ── model-state version ─────────────────────────────
|
|
355
352
|
/**
|
|
356
353
|
* The index version — bumps on every fold that changed derived
|
|
@@ -359,11 +356,57 @@ export const docFacade = (Y, layers) => {
|
|
|
359
356
|
* post-write state — this is the read-your-writes contract.
|
|
360
357
|
*/
|
|
361
358
|
get version() {
|
|
362
|
-
|
|
359
|
+
// A part's change may show in no index fact (a suggestion's decision).
|
|
360
|
+
return runsView.version() + part.v;
|
|
363
361
|
}
|
|
364
362
|
};
|
|
365
|
-
|
|
363
|
+
const internal = {
|
|
364
|
+
// lifecycle
|
|
365
|
+
init: (opts) => write(() => init(doc, opts)),
|
|
366
|
+
/** Apply the deterministic seed of `value` and the document's `data` — the document's seed decision. */
|
|
367
|
+
seed: (value, data) => write(() => seed(doc, value, defaultType, data)),
|
|
368
|
+
isInitialized: () => isInitialized(doc),
|
|
369
|
+
/** Replicated `meta.v` schema version (the module-level read, bound). */
|
|
370
|
+
schemaVersion: () => schemaVersion(doc),
|
|
371
|
+
/**
|
|
372
|
+
* The schema gate for this doc — throws {@link SchemaMismatchError}
|
|
373
|
+
* on unversioned-content or unsupported-version state. Consumers
|
|
374
|
+
* (`Edytor.sync()`, packed consumers) call it before trusting
|
|
375
|
+
* a synced doc.
|
|
376
|
+
*/
|
|
377
|
+
checkSchema: () => checkSchema(doc),
|
|
378
|
+
assertSchema: () => assertSchema(doc),
|
|
379
|
+
dispose,
|
|
380
|
+
createUndoManager,
|
|
381
|
+
/** @internal What a part built over the document reads and writes (`doc/suggest.ts`). */
|
|
382
|
+
part,
|
|
383
|
+
/** Visible children of `parent` with their ranks, in `(rank, id)` order. */
|
|
384
|
+
childSlots: (parent) => view().kids.get(parent) ?? [],
|
|
385
|
+
slotOf: byRef(slotOf),
|
|
386
|
+
crdtId: byRef((id) => crdtId(doc, id)),
|
|
387
|
+
resolveBlock: byRef((id) => resolveBlock(doc, id)),
|
|
388
|
+
followUndo,
|
|
389
|
+
// roles
|
|
390
|
+
/** Re-read the roles after `roleOf` answers differently (roles adopted later). */
|
|
391
|
+
rolesChanged: (place = true) => {
|
|
392
|
+
kinds = new Map();
|
|
393
|
+
declared = undefined;
|
|
394
|
+
if (place)
|
|
395
|
+
runsView.roles(roles);
|
|
396
|
+
},
|
|
397
|
+
defaultChild: byRef(defaultChild),
|
|
398
|
+
contentJSON: byRef(runsView.contentJSON),
|
|
399
|
+
// escape hatch for the history and debugging — the bound engine layers.
|
|
400
|
+
model: layers.model,
|
|
401
|
+
text: layers.text,
|
|
402
|
+
runsView,
|
|
403
|
+
/** The public members' names (`EdytorDocument` forwards them). */
|
|
404
|
+
api: api
|
|
405
|
+
};
|
|
406
|
+
// The public members joined as they are (the `version` getter stays one).
|
|
407
|
+
return Object.defineProperties(internal, Object.getOwnPropertyDescriptors(api));
|
|
366
408
|
};
|
|
409
|
+
return create;
|
|
367
410
|
};
|
|
368
411
|
/**
|
|
369
412
|
* 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
|
@@ -82,7 +82,7 @@ export type FlowContext = OpsContext & Pick<MoveOps, 'insertBlocks'> & Pick<Dele
|
|
|
82
82
|
* paragraph (`doc.empty.virtual`) place the caret by it.
|
|
83
83
|
*/
|
|
84
84
|
export declare const placedEnd: (roleOf: (kind: string) => {
|
|
85
|
-
|
|
85
|
+
childless: boolean;
|
|
86
86
|
rendersContent: boolean;
|
|
87
87
|
}) => (s: BlockSpec) => DocPosition | undefined;
|
|
88
88
|
/** `insertFlow`, prepared. */
|
package/dist/crdt/flow.js
CHANGED
|
@@ -14,7 +14,7 @@ const lengthOf = (l) => (l.content ?? []).reduce((n, i) => n + (i.kind === 'text
|
|
|
14
14
|
export const placedEnd = (roleOf) => {
|
|
15
15
|
const endOf = (s) => {
|
|
16
16
|
const role = roleOf(s.type);
|
|
17
|
-
if (role.rendersContent && !role.
|
|
17
|
+
if (role.rendersContent && !role.childless)
|
|
18
18
|
return { block: s.id, offset: lengthOf(s) };
|
|
19
19
|
for (const kid of [...(s.children ?? [])].reverse()) {
|
|
20
20
|
const at = endOf(kid);
|
|
@@ -27,15 +27,9 @@ export const placedEnd = (roleOf) => {
|
|
|
27
27
|
};
|
|
28
28
|
/** `insertFlow`, prepared. */
|
|
29
29
|
export const flowOps = (c) => {
|
|
30
|
-
|
|
31
|
-
const roleOf = (kind) => ({
|
|
32
|
-
void: c.roles.childless(kind),
|
|
33
|
-
island: c.roles.island(kind),
|
|
34
|
-
rendersContent: c.roles.rendersContent(kind),
|
|
35
|
-
layout: c.roles.layout(kind)
|
|
36
|
-
});
|
|
30
|
+
const roleOf = c.roles.of;
|
|
37
31
|
/** What a kind is in a table: the table, its row or its cell. */
|
|
38
|
-
const tableKind = (kind) =>
|
|
32
|
+
const tableKind = (kind) => roleOf(kind).table !== undefined
|
|
39
33
|
? 'table'
|
|
40
34
|
: c.isRowKind(kind)
|
|
41
35
|
? 'row'
|
|
@@ -150,7 +144,7 @@ export const flowOps = (c) => {
|
|
|
150
144
|
const apart = (l, under) => {
|
|
151
145
|
const kind = l.type && fit(under, l.type);
|
|
152
146
|
const role = kind ? roleOf(kind) : undefined;
|
|
153
|
-
return !!role && (!role.rendersContent || role.
|
|
147
|
+
return !!role && (!role.rendersContent || role.childless || role.island);
|
|
154
148
|
};
|
|
155
149
|
// At the end of a container's header whose body shows, what follows the caret
|
|
156
150
|
// leads its children and the body stays, as Enter opens a first child
|