edytor 3.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 +23 -12
- package/dist/cloudflare/DocumentRoom.js +10 -6
- 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 +139 -129
- package/dist/cloudflare/room/context.js +11 -4
- 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.d.ts +6 -3
- package/dist/cloudflare/room/purge.js +45 -19
- 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/room/updates.d.ts +3 -4
- package/dist/cloudflare/room/updates.js +6 -8
- 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 +34 -12
- package/dist/crdt/attribution/attribution.js +59 -21
- package/dist/crdt/attribution/block.d.ts +3 -3
- package/dist/crdt/attribution/block.js +7 -8
- package/dist/crdt/attribution/index.d.ts +1 -1
- package/dist/crdt/attribution/index.js +1 -1
- package/dist/crdt/data.d.ts +62 -31
- package/dist/crdt/data.js +211 -103
- package/dist/crdt/doc/capability.js +9 -13
- package/dist/crdt/doc/delete.d.ts +1 -1
- package/dist/crdt/doc/delete.js +13 -30
- package/dist/crdt/doc/funnel.d.ts +1 -1
- package/dist/crdt/doc/funnel.js +34 -26
- package/dist/crdt/doc/gate.d.ts +3 -3
- package/dist/crdt/doc/history.d.ts +31 -9
- package/dist/crdt/doc/history.js +204 -73
- package/dist/crdt/doc/layout.js +16 -27
- package/dist/crdt/doc/meta.js +17 -23
- package/dist/crdt/doc/moves.d.ts +1 -1
- package/dist/crdt/doc/moves.js +52 -32
- package/dist/crdt/doc/reads.d.ts +2 -2
- package/dist/crdt/doc/reads.js +20 -30
- package/dist/crdt/doc/seed.js +2 -2
- package/dist/crdt/doc/split-merge.js +12 -15
- package/dist/crdt/doc/steps.d.ts +25 -13
- package/dist/crdt/doc/steps.js +55 -125
- package/dist/crdt/doc/suggest.d.ts +167 -0
- package/dist/crdt/doc/suggest.js +579 -0
- package/dist/crdt/doc/types.d.ts +21 -9
- package/dist/crdt/document.d.ts +26 -6
- package/dist/crdt/document.js +40 -15
- package/dist/crdt/edytor-doc.d.ts +410 -390
- package/dist/crdt/edytor-doc.js +143 -95
- package/dist/crdt/engine-api.d.ts +39 -1
- package/dist/crdt/engine.d.ts +2 -2
- package/dist/crdt/engine.js +4 -5
- package/dist/crdt/flow.d.ts +2 -2
- package/dist/crdt/flow.js +29 -37
- package/dist/crdt/index.d.ts +134 -127
- package/dist/crdt/index.js +4 -1
- 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 +6 -31
- package/dist/crdt/placement/display.js +41 -146
- package/dist/crdt/placement/keys.d.ts +63 -0
- package/dist/crdt/placement/keys.js +95 -0
- package/dist/crdt/placement/model.d.ts +119 -118
- package/dist/crdt/placement/model.js +242 -142
- package/dist/crdt/placement/resolve.d.ts +123 -35
- package/dist/crdt/placement/resolve.js +188 -153
- package/dist/crdt/placement/slots.d.ts +134 -0
- package/dist/crdt/placement/slots.js +152 -0
- 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/room.d.ts +16 -2
- package/dist/crdt/providers/room.js +64 -17
- package/dist/crdt/providers/websocket.d.ts +6 -4
- package/dist/crdt/providers/websocket.js +14 -7
- package/dist/crdt/purge.d.ts +24 -9
- package/dist/crdt/purge.js +266 -126
- package/dist/crdt/restore.d.ts +4 -3
- package/dist/crdt/restore.js +27 -34
- package/dist/crdt/schema.d.ts +30 -21
- package/dist/crdt/schema.js +39 -23
- package/dist/crdt/storage.d.ts +1 -1
- package/dist/crdt/storage.js +1 -1
- package/dist/crdt/structs.d.ts +17 -15
- package/dist/crdt/structs.js +10 -22
- package/dist/crdt/text/index/cache.js +4 -0
- package/dist/crdt/text/index/claims.js +13 -23
- package/dist/crdt/text/index/fold.d.ts +2 -3
- package/dist/crdt/text/index/fold.js +194 -44
- package/dist/crdt/text/index/layout.d.ts +2 -4
- package/dist/crdt/text/index/layout.js +14 -30
- package/dist/crdt/text/index/placement.d.ts +26 -18
- package/dist/crdt/text/index/placement.js +420 -157
- package/dist/crdt/text/index/records.d.ts +3 -3
- package/dist/crdt/text/index/records.js +24 -31
- package/dist/crdt/text/index/shared.d.ts +11 -3
- package/dist/crdt/text/index/shared.js +29 -17
- package/dist/crdt/text/index/state.d.ts +21 -17
- package/dist/crdt/text/index/state.js +15 -17
- package/dist/crdt/text/index/streams.d.ts +10 -5
- package/dist/crdt/text/index/streams.js +78 -27
- package/dist/crdt/text/items.d.ts +10 -3
- package/dist/crdt/text/items.js +7 -0
- package/dist/crdt/text/model.d.ts +87 -62
- package/dist/crdt/text/model.js +91 -169
- package/dist/crdt/text/ranges.d.ts +1 -1
- package/dist/crdt/text/ranges.js +3 -3
- package/dist/crdt/text/rows.d.ts +13 -7
- package/dist/crdt/text/rows.js +24 -7
- package/dist/crdt/text/runs.d.ts +51 -42
- package/dist/crdt/text/runs.js +24 -7
- package/dist/crdt/text/streams.d.ts +26 -13
- package/dist/crdt/text/streams.js +41 -14
- package/dist/crdt/vendor/yjs/UPSTREAM.md +651 -21
- package/dist/crdt/vendor/yjs/dts/global.d.ts +2 -0
- package/dist/crdt/vendor/yjs/dts/index.d.ts +1 -1
- package/dist/crdt/vendor/yjs/dts/structs/AbstractStruct.d.ts +7 -0
- package/dist/crdt/vendor/yjs/dts/structs/Item.d.ts +197 -10
- package/dist/crdt/vendor/yjs/dts/utils/Doc.d.ts +6 -3
- package/dist/crdt/vendor/yjs/dts/utils/StructStore.d.ts +5 -18
- package/dist/crdt/vendor/yjs/dts/utils/Transaction.d.ts +15 -1
- package/dist/crdt/vendor/yjs/dts/utils/UpdateDecoder.d.ts +14 -6
- package/dist/crdt/vendor/yjs/dts/utils/UpdateEncoder.d.ts +33 -6
- package/dist/crdt/vendor/yjs/dts/utils/ids.d.ts +1 -65
- package/dist/crdt/vendor/yjs/dts/utils/marks.d.ts +6 -1
- package/dist/crdt/vendor/yjs/dts/ynode.d.ts +54 -7
- package/dist/crdt/vendor/yjs/global.d.ts +2 -0
- package/dist/crdt/vendor/yjs/src/index.js +1 -1
- package/dist/crdt/vendor/yjs/src/structs/AbstractStruct.js +10 -0
- package/dist/crdt/vendor/yjs/src/structs/Item.js +649 -51
- package/dist/crdt/vendor/yjs/src/utils/BlockSet.js +18 -9
- package/dist/crdt/vendor/yjs/src/utils/Doc.js +5 -3
- package/dist/crdt/vendor/yjs/src/utils/StructStore.js +5 -0
- package/dist/crdt/vendor/yjs/src/utils/Transaction.js +36 -13
- package/dist/crdt/vendor/yjs/src/utils/UpdateDecoder.js +88 -18
- package/dist/crdt/vendor/yjs/src/utils/UpdateEncoder.js +119 -32
- package/dist/crdt/vendor/yjs/src/utils/encoding.js +13 -1
- package/dist/crdt/vendor/yjs/src/utils/ids.js +7 -7
- package/dist/crdt/vendor/yjs/src/utils/marks.js +193 -8
- package/dist/crdt/vendor/yjs/src/utils/redo.js +1 -1
- package/dist/crdt/vendor/yjs/src/utils/transaction-helpers.js +1 -1
- package/dist/crdt/vendor/yjs/src/utils/updates.js +3 -3
- package/dist/crdt/vendor/yjs/src/ynode.js +199 -12
- package/dist/edytor.svelte.d.ts +1 -1
- package/dist/edytor.svelte.js +103 -75
- package/dist/events/beforeInputCommands.d.ts +2 -2
- package/dist/events/beforeInputCommands.js +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/events/onPageHide.d.ts +3 -0
- package/dist/events/onPageHide.js +16 -0
- package/dist/export/forms.d.ts +50 -50
- 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 +130 -83
- package/dist/surface/pin.svelte.d.ts +9 -9
- package/dist/surface/pin.svelte.js +15 -22
- package/dist/surface/projector.svelte.d.ts +15 -3
- package/dist/surface/projector.svelte.js +67 -22
- package/dist/text/text.svelte.js +14 -19
- package/dist/themes/notion.css +29 -0
- package/package.json +4 -2
- package/dist/crdt/placement/rank.d.ts +0 -87
- package/dist/crdt/placement/rank.js +0 -332
- package/dist/crdt/placement/source.d.ts +0 -43
- package/dist/crdt/placement/source.js +0 -66
- package/dist/crdt/text/delete-index.d.ts +0 -129
- package/dist/crdt/text/delete-index.js +0 -365
- package/dist/crdt/text/deletes.d.ts +0 -76
- package/dist/crdt/text/deletes.js +0 -362
- package/dist/crdt/text/index/anchored.d.ts +0 -17
- package/dist/crdt/text/index/anchored.js +0 -197
package/dist/crdt/restore.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { blockNodeOf,
|
|
1
|
+
import { blockNodeOf, insertSpecsAt, moveBlocksTo, view as modelView } from './placement/model.js';
|
|
2
|
+
import { suggestionsOf } from './doc/suggest.js';
|
|
2
3
|
import { DEL_PREFIX, TYPE, WITHDRAW_PREFIX } from './schema.js';
|
|
3
|
-
import { common, patchWrites,
|
|
4
|
-
import { canonKey } from './text/model.js';
|
|
4
|
+
import { common, patchWrites, writeData } from './data.js';
|
|
5
|
+
import { canonKey, deleteClaims } from './text/model.js';
|
|
5
6
|
import { randOf } from './rand.js';
|
|
6
7
|
import { toBlockSpec } from '../utils/json.js';
|
|
7
8
|
/** `items` one unit each (a character with its marks, or an atom), keyed for comparison. */
|
|
@@ -117,15 +118,8 @@ export const restoreDocument = (doc, facade, json) => {
|
|
|
117
118
|
const { blocks } = modelView(doc);
|
|
118
119
|
for (const rec of blocks.values()) {
|
|
119
120
|
// A deleted holder's claims are void (and stay so): only the others.
|
|
120
|
-
if (rec.deleted
|
|
121
|
-
|
|
122
|
-
// The claims its list stores (an anchor may show one in another block).
|
|
123
|
-
const named = (rec.listClaims ?? rec.claims)
|
|
124
|
-
.filter((claim) => all.has(claim.m))
|
|
125
|
-
.map((c) => c.seqIndex)
|
|
126
|
-
.filter((at) => at >= 0);
|
|
127
|
-
for (const at of named.sort((a, b) => b - a))
|
|
128
|
-
rec.claimsNode.delete(at, 1);
|
|
121
|
+
if (!rec.deleted)
|
|
122
|
+
deleteClaims(doc, rec.claims.filter((claim) => all.has(claim.m)));
|
|
129
123
|
}
|
|
130
124
|
}
|
|
131
125
|
// 2 · Type and data, per leaf, where they differ.
|
|
@@ -135,7 +129,7 @@ export const restoreDocument = (doc, facade, json) => {
|
|
|
135
129
|
continue;
|
|
136
130
|
if (n.getAttr(TYPE) !== spec.type)
|
|
137
131
|
n.setAttr(TYPE, spec.type);
|
|
138
|
-
|
|
132
|
+
writeData(n, patchWrites(n, [{ path: [], value: spec.data ?? {} }], doc.clientID, randOf(doc)) ?? []);
|
|
139
133
|
}
|
|
140
134
|
// 3 · Places, parent by parent in snapshot order (the root first).
|
|
141
135
|
const parents = [[null, specs]];
|
|
@@ -145,36 +139,28 @@ export const restoreDocument = (doc, facade, json) => {
|
|
|
145
139
|
if (list.length === 0)
|
|
146
140
|
continue;
|
|
147
141
|
const slots = facade.childSlots(parent);
|
|
148
|
-
const index = new Map(slots.map((slot, i) => [slot.id, i]));
|
|
149
142
|
// What a longest common run of the two orders keeps stays where it is.
|
|
150
143
|
const kept = new Set(common(slots.map((slot) => slot.id), list.map((spec) => spec.id)).map(([, j]) => j));
|
|
151
|
-
let prev;
|
|
144
|
+
let prev = null;
|
|
152
145
|
list.forEach((spec, i) => {
|
|
153
146
|
if (kept.has(i)) {
|
|
154
|
-
prev =
|
|
147
|
+
prev = spec.id;
|
|
155
148
|
return;
|
|
156
149
|
}
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
break;
|
|
162
|
-
}
|
|
163
|
-
const bounds = [
|
|
164
|
-
...(prev === undefined ? [] : [{ rank: prev }]),
|
|
165
|
-
...(next === undefined ? [] : [{ rank: next }])
|
|
166
|
-
];
|
|
167
|
-
const [rank] = ranksAt(bounds, prev === undefined ? 0 : 1, 1, doc.clientID, randOf(doc));
|
|
150
|
+
const v = modelView(doc);
|
|
151
|
+
// Right after the block before it in the snapshot (the list as it stands, the block itself left out).
|
|
152
|
+
const shown = (v.kids.get(parent) ?? []).map((k) => k.id).filter((id) => id !== spec.id);
|
|
153
|
+
const at = prev === null ? 0 : shown.indexOf(prev) + 1;
|
|
168
154
|
const n = node(spec.id);
|
|
169
155
|
if (n === null) {
|
|
170
|
-
|
|
156
|
+
insertSpecsAt(doc, v, parent, at, [{ ...spec, children: [] }]);
|
|
171
157
|
report.created++;
|
|
172
158
|
}
|
|
173
159
|
else {
|
|
174
|
-
|
|
160
|
+
moveBlocksTo(doc, v, [spec.id], parent, at);
|
|
175
161
|
report.moved++;
|
|
176
162
|
}
|
|
177
|
-
prev =
|
|
163
|
+
prev = spec.id;
|
|
178
164
|
});
|
|
179
165
|
}
|
|
180
166
|
// 4 · Content, where it differs: own claims removed, the stream rewritten.
|
|
@@ -183,10 +169,9 @@ export const restoreDocument = (doc, facade, json) => {
|
|
|
183
169
|
let have = unitsOf(facade.contentItems(id));
|
|
184
170
|
if (have.length === want.length && have.every((u, i) => u.key === want[i].key))
|
|
185
171
|
continue;
|
|
186
|
-
const
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
claims.delete(0, claims.length);
|
|
172
|
+
const claims = modelView(doc).blocks.get(id)?.claims ?? [];
|
|
173
|
+
if (claims.some((c) => c.stamp.c >= 0)) {
|
|
174
|
+
deleteClaims(doc, claims);
|
|
190
175
|
have = unitsOf(facade.contentItems(id));
|
|
191
176
|
}
|
|
192
177
|
rewriteContent(facade, id, have, want);
|
|
@@ -212,5 +197,13 @@ export const restoreDocument = (doc, facade, json) => {
|
|
|
212
197
|
}
|
|
213
198
|
// 6 · The document's data.
|
|
214
199
|
facade.apply(facade.prepare.patchData(null, [{ path: [], value: json.data ?? {} }]));
|
|
200
|
+
// 7 · Pending suggestions are dropped (`sugg.restore`): the version holds
|
|
201
|
+
// none (its document without them), so what the restore left of them —
|
|
202
|
+
// their proposals — is rejected, in the restore's step (its undo brings
|
|
203
|
+
// them back).
|
|
204
|
+
// (Built over the facade, its shared suggestions: `doc/suggest.ts`.)
|
|
205
|
+
const suggest = facade.part && suggestionsOf(facade);
|
|
206
|
+
if (suggest)
|
|
207
|
+
suggest.run(suggest.decide(suggest.changes(), false));
|
|
215
208
|
return report;
|
|
216
209
|
};
|
package/dist/crdt/schema.d.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* facade module.
|
|
6
6
|
*/
|
|
7
7
|
import type { EngineNode } from './engine-api.js';
|
|
8
|
-
/** A replicated value that is a node (a block, its content,
|
|
8
|
+
/** A replicated value that is a node (a block, its content, an atom). */
|
|
9
9
|
export declare const isNodeLike: (v: unknown) => v is EngineNode;
|
|
10
10
|
/** Flat block registry root: blockId → node('block') (`SCHEMA.roots.registry`). */
|
|
11
11
|
export declare const REGISTRY_KEY = "blocks";
|
|
@@ -13,21 +13,19 @@ export declare const REGISTRY_KEY = "blocks";
|
|
|
13
13
|
export declare const META_ROOT_KEY = "meta";
|
|
14
14
|
/** Attribution metadata root (`SCHEMA.roots.attribution`). */
|
|
15
15
|
export declare const ATTRIBUTION_ROOT = "attribution";
|
|
16
|
-
/** The per-block attribution root — `b/<blockId>` records (`SCHEMA.roots.blockAttribution`). */
|
|
17
|
-
export declare const BLOCK_ATTR_ROOT = "blockattr";
|
|
18
16
|
/**
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
* own mark and a redo writes it again.
|
|
17
|
+
* The per-block attribution root — one record per block, keyed by the block's
|
|
18
|
+
* id (`SCHEMA.roots.blockAttribution`): the string table writes the id once
|
|
19
|
+
* for its registry entry and its record (fork patch YP24).
|
|
23
20
|
*/
|
|
24
|
-
export declare const
|
|
21
|
+
export declare const BLOCK_ATTR_ROOT = "blockattr";
|
|
25
22
|
/**
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
23
|
+
* The text hold records (fork patch YP20): a text delete appends one record
|
|
24
|
+
* naming the characters it hides; its writer is the record's engine client.
|
|
25
|
+
* A character shows while no live record holds it. In the history's scope,
|
|
26
|
+
* so an undo deletes the undoer's own record and a redo writes it again.
|
|
29
27
|
*/
|
|
30
|
-
export declare const
|
|
28
|
+
export declare const TEXT_DELETES_ROOT = "textdel";
|
|
31
29
|
/**
|
|
32
30
|
* The document's own data (`crdt/data.ts`): its leaves, as a block's. In the
|
|
33
31
|
* history's scope.
|
|
@@ -41,13 +39,29 @@ export declare const DOC_DATA_ROOT = "docdata";
|
|
|
41
39
|
*/
|
|
42
40
|
export declare const HORIZON_ROOT = "horizon";
|
|
43
41
|
export declare const HORIZON_ATTR = "h";
|
|
42
|
+
/**
|
|
43
|
+
* The ended histories (`hist.release.end`): a list of release records, one
|
|
44
|
+
* item per session whose history ended (its page left for good). A
|
|
45
|
+
* record's engine id names its writer and the clock it ended at: what that
|
|
46
|
+
* writer deleted before it (its delete and withdraw marks, its text hold
|
|
47
|
+
* records) no history can bring back, so the room's purge removes it at
|
|
48
|
+
* its next tick, past the horizon or not. The purge drops a record the
|
|
49
|
+
* horizon covers.
|
|
50
|
+
*/
|
|
51
|
+
export declare const RELEASE_ROOT = "released";
|
|
52
|
+
/**
|
|
53
|
+
* The shared suggestions (`crdt/doc/suggest.ts`): attr `<id>` is one
|
|
54
|
+
* suggestion's record node, written by its writer (a client id bound to its
|
|
55
|
+
* author): its creation time `at`, `via` and `lbl`, and a list of id lists
|
|
56
|
+
* (fork patch YP31: its writer's proposed deletions, anyone else's settled
|
|
57
|
+
* ranges) and proposed operations. In the history's scope.
|
|
58
|
+
*/
|
|
59
|
+
export declare const SUGGEST_ROOT = "suggest";
|
|
44
60
|
/** Named node roles (`SCHEMA.nodes`). */
|
|
45
61
|
export declare const BLOCK_NODE = "block";
|
|
46
62
|
export declare const CONTENT_NODE = "content";
|
|
47
|
-
export declare const CLAIMS_NODE = "claims";
|
|
48
|
-
export declare const AT_NODE = "at";
|
|
49
63
|
export declare const INLINE_NODE = "inline";
|
|
50
|
-
/** Attr keys on a block node (`SCHEMA.blockAttrs`). */
|
|
64
|
+
/** Attr keys on a block node (`SCHEMA.blockAttrs`); `id` is an atom's own (a block's id is its registry key). */
|
|
51
65
|
export declare const ID = "id";
|
|
52
66
|
export declare const TYPE = "type";
|
|
53
67
|
/** A block's or atom's whole data, as documents before 0.1.0-next.6 stored it: no longer read; the room's purge deletes it. */
|
|
@@ -84,14 +98,9 @@ export declare const hasWithdrawMark: (node: {
|
|
|
84
98
|
/** The per-block `lastChangedBy` LWW attr (`SCHEMA.blockAttrs.lastChanged`). */
|
|
85
99
|
export declare const LAST_CHANGED_ATTR = "l";
|
|
86
100
|
export declare const CONTENT = "content";
|
|
87
|
-
/** Ordered merge claims `{m: blockId}`. */
|
|
88
|
-
export declare const CLAIMS = "claims";
|
|
89
|
-
export declare const AT = "at";
|
|
90
|
-
/** `b/<blockId>` record-key prefix on the `blockattr` root. */
|
|
91
|
-
export declare const REC_PREFIX = "b/";
|
|
92
101
|
/** The schema generation stamped on the `meta` root (`v`) and its manifest name (`schema`). */
|
|
93
102
|
export declare const SCHEMA: {
|
|
94
|
-
readonly version:
|
|
103
|
+
readonly version: 11;
|
|
95
104
|
readonly name: "edytor-doc";
|
|
96
105
|
readonly roots: {
|
|
97
106
|
readonly registry: "blocks";
|
package/dist/crdt/schema.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** A replicated value that is a node (a block, its content,
|
|
1
|
+
/** A replicated value that is a node (a block, its content, an atom). */
|
|
2
2
|
export const isNodeLike = (v) => v != null && typeof v.getAttr === 'function';
|
|
3
3
|
/** Flat block registry root: blockId → node('block') (`SCHEMA.roots.registry`). */
|
|
4
4
|
export const REGISTRY_KEY = 'blocks';
|
|
@@ -6,21 +6,19 @@ export const REGISTRY_KEY = 'blocks';
|
|
|
6
6
|
export const META_ROOT_KEY = 'meta';
|
|
7
7
|
/** Attribution metadata root (`SCHEMA.roots.attribution`). */
|
|
8
8
|
export const ATTRIBUTION_ROOT = 'attribution';
|
|
9
|
-
/** The per-block attribution root — `b/<blockId>` records (`SCHEMA.roots.blockAttribution`). */
|
|
10
|
-
export const BLOCK_ATTR_ROOT = 'blockattr';
|
|
11
9
|
/**
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* own mark and a redo writes it again.
|
|
10
|
+
* The per-block attribution root — one record per block, keyed by the block's
|
|
11
|
+
* id (`SCHEMA.roots.blockAttribution`): the string table writes the id once
|
|
12
|
+
* for its registry entry and its record (fork patch YP24).
|
|
16
13
|
*/
|
|
17
|
-
export const
|
|
14
|
+
export const BLOCK_ATTR_ROOT = 'blockattr';
|
|
18
15
|
/**
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
16
|
+
* The text hold records (fork patch YP20): a text delete appends one record
|
|
17
|
+
* naming the characters it hides; its writer is the record's engine client.
|
|
18
|
+
* A character shows while no live record holds it. In the history's scope,
|
|
19
|
+
* so an undo deletes the undoer's own record and a redo writes it again.
|
|
22
20
|
*/
|
|
23
|
-
export const
|
|
21
|
+
export const TEXT_DELETES_ROOT = 'textdel';
|
|
24
22
|
/**
|
|
25
23
|
* The document's own data (`crdt/data.ts`): its leaves, as a block's. In the
|
|
26
24
|
* history's scope.
|
|
@@ -34,13 +32,29 @@ export const DOC_DATA_ROOT = 'docdata';
|
|
|
34
32
|
*/
|
|
35
33
|
export const HORIZON_ROOT = 'horizon';
|
|
36
34
|
export const HORIZON_ATTR = 'h';
|
|
35
|
+
/**
|
|
36
|
+
* The ended histories (`hist.release.end`): a list of release records, one
|
|
37
|
+
* item per session whose history ended (its page left for good). A
|
|
38
|
+
* record's engine id names its writer and the clock it ended at: what that
|
|
39
|
+
* writer deleted before it (its delete and withdraw marks, its text hold
|
|
40
|
+
* records) no history can bring back, so the room's purge removes it at
|
|
41
|
+
* its next tick, past the horizon or not. The purge drops a record the
|
|
42
|
+
* horizon covers.
|
|
43
|
+
*/
|
|
44
|
+
export const RELEASE_ROOT = 'released';
|
|
45
|
+
/**
|
|
46
|
+
* The shared suggestions (`crdt/doc/suggest.ts`): attr `<id>` is one
|
|
47
|
+
* suggestion's record node, written by its writer (a client id bound to its
|
|
48
|
+
* author): its creation time `at`, `via` and `lbl`, and a list of id lists
|
|
49
|
+
* (fork patch YP31: its writer's proposed deletions, anyone else's settled
|
|
50
|
+
* ranges) and proposed operations. In the history's scope.
|
|
51
|
+
*/
|
|
52
|
+
export const SUGGEST_ROOT = 'suggest';
|
|
37
53
|
/** Named node roles (`SCHEMA.nodes`). */
|
|
38
54
|
export const BLOCK_NODE = 'block';
|
|
39
55
|
export const CONTENT_NODE = 'content';
|
|
40
|
-
export const CLAIMS_NODE = 'claims';
|
|
41
|
-
export const AT_NODE = 'at';
|
|
42
56
|
export const INLINE_NODE = 'inline';
|
|
43
|
-
/** Attr keys on a block node (`SCHEMA.blockAttrs`). */
|
|
57
|
+
/** Attr keys on a block node (`SCHEMA.blockAttrs`); `id` is an atom's own (a block's id is its registry key). */
|
|
44
58
|
export const ID = 'id';
|
|
45
59
|
export const TYPE = 'type';
|
|
46
60
|
/** A block's or atom's whole data, as documents before 0.1.0-next.6 stored it: no longer read; the room's purge deletes it. */
|
|
@@ -73,16 +87,18 @@ export const hasWithdrawMark = (node) => [...node.attrKeys()].some((key) => key.
|
|
|
73
87
|
/** The per-block `lastChangedBy` LWW attr (`SCHEMA.blockAttrs.lastChanged`). */
|
|
74
88
|
export const LAST_CHANGED_ATTR = 'l';
|
|
75
89
|
export const CONTENT = 'content';
|
|
76
|
-
/** Ordered merge claims `{m: blockId}`. */
|
|
77
|
-
export const CLAIMS = 'claims';
|
|
78
|
-
export const AT = 'at';
|
|
79
|
-
/** `b/<blockId>` record-key prefix on the `blockattr` root. */
|
|
80
|
-
export const REC_PREFIX = 'b/';
|
|
81
90
|
/** The schema generation stamped on the `meta` root (`v`) and its manifest name (`schema`). */
|
|
82
91
|
export const SCHEMA = {
|
|
83
|
-
//
|
|
84
|
-
// a
|
|
85
|
-
|
|
92
|
+
// 7: a text delete is a hold record (fork patch YP20) on the wire and in
|
|
93
|
+
// storage; 8: a merge claim is an item `{m}` in a backing text (fork patch
|
|
94
|
+
// YP21), a block has no `claims` list; 9: a block's place is its home slot
|
|
95
|
+
// in its parent's sequence and a move is a move record (fork patch YP22),
|
|
96
|
+
// a block has no `at` map and an array item no rank; 10: the update encoding
|
|
97
|
+
// writes each distinct string once (fork patch YP24); 11: a hold record
|
|
98
|
+
// inside a nested node holds nothing (fork patch YP31: a suggestion's
|
|
99
|
+
// proposals and decisions). A container or frame of an earlier generation
|
|
100
|
+
// is refused.
|
|
101
|
+
version: 11,
|
|
86
102
|
name: 'edytor-doc',
|
|
87
103
|
roots: { registry: REGISTRY_KEY, meta: META_ROOT_KEY },
|
|
88
104
|
metaAttrs: { version: 'v', schema: 'schema' }
|
package/dist/crdt/storage.d.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* when that makes them smaller (`CompressionStream`, in every supported
|
|
5
5
|
* browser, Node and Workers). A compressed record starts with gzip's magic
|
|
6
6
|
* `1f 8b`, which no update does (its first byte is the encoder's feature
|
|
7
|
-
* flag, `
|
|
7
|
+
* flag, the encoding: `01`), so a record says itself whether it is compressed.
|
|
8
8
|
* Worker-safe: no timers.
|
|
9
9
|
*/
|
|
10
10
|
/** Whether `bytes` are gzip (its magic `1f 8b`). */
|
package/dist/crdt/storage.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* when that makes them smaller (`CompressionStream`, in every supported
|
|
5
5
|
* browser, Node and Workers). A compressed record starts with gzip's magic
|
|
6
6
|
* `1f 8b`, which no update does (its first byte is the encoder's feature
|
|
7
|
-
* flag, `
|
|
7
|
+
* flag, the encoding: `01`), so a record says itself whether it is compressed.
|
|
8
8
|
* Worker-safe: no timers.
|
|
9
9
|
*/
|
|
10
10
|
/** Whether `bytes` are gzip (its magic `1f 8b`). */
|
package/dist/crdt/structs.d.ts
CHANGED
|
@@ -24,6 +24,16 @@ export type StoreStruct = {
|
|
|
24
24
|
client: number;
|
|
25
25
|
clock: number;
|
|
26
26
|
} | null;
|
|
27
|
+
/** Live hold records naming the item (fork patch YP20): a held item reads as deleted. */
|
|
28
|
+
holds?: number;
|
|
29
|
+
/** Whether the engine deleted it (`deleted` also covers a held or moved item). */
|
|
30
|
+
removed?: boolean;
|
|
31
|
+
/** Removed or held: shown nowhere (fork patch YP22; a moved item shows at its mover). */
|
|
32
|
+
gone?: boolean;
|
|
33
|
+
/** The live move records naming the item (fork patch YP22), `null` at home. */
|
|
34
|
+
movers?: StoreStruct[] | null;
|
|
35
|
+
/** The record that shows the item (the greatest `(priority, client, clock)` of `movers`). */
|
|
36
|
+
mover?: StoreStruct | null;
|
|
27
37
|
};
|
|
28
38
|
/**
|
|
29
39
|
* The engine's IdSet shape (insertSet/deleteSet): per-client range lists —
|
|
@@ -85,8 +95,6 @@ export declare const followRedone: (Y: EngineApi, doc: EngineDoc, id: {
|
|
|
85
95
|
* drops them the same way after a pop.
|
|
86
96
|
*/
|
|
87
97
|
export declare const dropSearchMarkers: (node: unknown) => void;
|
|
88
|
-
/** The clock `client`'s next struct gets in `doc`. */
|
|
89
|
-
export declare const nextClock: (doc: EngineDoc, client: number) => number;
|
|
90
98
|
/**
|
|
91
99
|
* Whether `doc` holds updates it cannot integrate yet (vendor-internal
|
|
92
100
|
* `store.pendingStructs`/`pendingDs`): an out-of-order delivery can apply
|
|
@@ -141,6 +149,11 @@ export type StoreLike = {
|
|
|
141
149
|
};
|
|
142
150
|
/** The doc's struct store (vendor `store`). */
|
|
143
151
|
export declare const storeOf: (doc: EngineDoc | YDoc) => StoreLike;
|
|
152
|
+
/**
|
|
153
|
+
* Whether `doc` holds every id `client:clock … clock+len-1` (none past its
|
|
154
|
+
* clock, none in a gap the engine fills later: vendor `store.skips`).
|
|
155
|
+
*/
|
|
156
|
+
export declare const holdsIds: (doc: EngineDoc, client: number, clock: number, len: number) => boolean;
|
|
144
157
|
/** Whether `doc` collects deleted content at all (vendor `gc`). */
|
|
145
158
|
export declare const collects: (doc: EngineDoc | YDoc) => boolean;
|
|
146
159
|
/** Whether `doc`'s collection filter lets it collect `item` (vendor `gcFilter`). */
|
|
@@ -156,11 +169,6 @@ export declare const keepFromCollection: <I = StoreStruct>(doc: EngineDoc | YDoc
|
|
|
156
169
|
* {@link collects} and {@link collectable}.
|
|
157
170
|
*/
|
|
158
171
|
export declare const collectNow: (item: object, tr: unknown) => void;
|
|
159
|
-
/**
|
|
160
|
-
* Listen to `doc`'s transaction events (vendor `beforeTransaction`,
|
|
161
|
-
* `afterTransaction`), with the caller's view of a transaction.
|
|
162
|
-
*/
|
|
163
|
-
export declare const onTransaction: <T>(doc: EngineDoc | YDoc, event: "beforeTransaction" | "afterTransaction", f: (tr: T) => void) => void;
|
|
164
172
|
/**
|
|
165
173
|
* Whether a transaction changed one of `nodes` or a node under one: its
|
|
166
174
|
* `changed` types and their ancestors (what a deep observer of `nodes`
|
|
@@ -189,8 +197,6 @@ export declare const engineOps: (Y: EngineApi) => {
|
|
|
189
197
|
insertInto: (into: IdSetLike, from: IdSetLike) => void;
|
|
190
198
|
/** Each struct `ids` covers, split at its edges, inside `tr`. */
|
|
191
199
|
iterate: <I = StoreStruct>(tr: unknown, ids: IdSetLike, f: (item: I) => void) => void;
|
|
192
|
-
/** The item starting at `client:clock`, split there, inside `tr`. */
|
|
193
|
-
cleanStart: <I = StoreStruct>(tr: unknown, client: number, clock: number) => I;
|
|
194
200
|
/**
|
|
195
201
|
* Re-create deleted `item` (`redoItem`, fork patch YP18): its copy, or
|
|
196
202
|
* `null` when it cannot come back. `items` are re-created with it (a
|
|
@@ -206,6 +212,8 @@ export declare const engineOps: (Y: EngineApi) => {
|
|
|
206
212
|
merge: (sets: IdSetLike[]) => IdSetOf;
|
|
207
213
|
/** Whether a store struct is an item (not a GC or a Skip). */
|
|
208
214
|
isItem: (struct: unknown) => struct is StoreStruct;
|
|
215
|
+
/** Show again what a suggestion's deletes in `tr` proposed (fork patch YP32). */
|
|
216
|
+
unhide: (tr: unknown) => void;
|
|
209
217
|
/** Whether `item` sits in `node`'s subtree. */
|
|
210
218
|
inside: (node: EngineNode, item: StoreStruct) => boolean;
|
|
211
219
|
/** Keep `item` (and its parents) from collection (`keepItem`). */
|
|
@@ -217,12 +225,6 @@ export declare const engineOps: (Y: EngineApi) => {
|
|
|
217
225
|
/** Listen to a doc event (vendor `on`/`off`), with the caller's view of its arguments. */
|
|
218
226
|
on: (doc: EngineDoc, event: string, f: (...args: never[]) => void) => void;
|
|
219
227
|
off: (doc: EngineDoc, event: string, f: (...args: never[]) => void) => void;
|
|
220
|
-
/**
|
|
221
|
-
* Integrate a new item holding `content` right after `left` (its
|
|
222
|
-
* origin: `left`'s last id) in `parent`, written by `client` at
|
|
223
|
-
* `clock`, inside `tr`.
|
|
224
|
-
*/
|
|
225
|
-
appendAfter: (tr: unknown, left: StoreStruct, parent: EngineNode, client: number, clock: number, content: unknown[]) => void;
|
|
226
228
|
/** Whether `item` is a node value a concurrent write replaced and its doc keeps. */
|
|
227
229
|
isKeptReplaced: (item: unknown) => boolean;
|
|
228
230
|
};
|
package/dist/crdt/structs.js
CHANGED
|
@@ -121,12 +121,6 @@ export const dropSearchMarkers = (node) => {
|
|
|
121
121
|
if (markers)
|
|
122
122
|
markers.length = 0;
|
|
123
123
|
};
|
|
124
|
-
/** The clock `client`'s next struct gets in `doc`. */
|
|
125
|
-
export const nextClock = (doc, client) => {
|
|
126
|
-
const structs = clientsOf(doc).get(client);
|
|
127
|
-
const last = structs?.[structs.length - 1];
|
|
128
|
-
return last === undefined ? 0 : last.id.clock + last.length;
|
|
129
|
-
};
|
|
130
124
|
/**
|
|
131
125
|
* Whether `doc` holds updates it cannot integrate yet (vendor-internal
|
|
132
126
|
* `store.pendingStructs`/`pendingDs`): an out-of-order delivery can apply
|
|
@@ -177,6 +171,14 @@ export const sequenceLength = (node) => node._length;
|
|
|
177
171
|
export const itemOf = (node) => node._item;
|
|
178
172
|
/** The doc's struct store (vendor `store`). */
|
|
179
173
|
export const storeOf = (doc) => doc.store;
|
|
174
|
+
/**
|
|
175
|
+
* Whether `doc` holds every id `client:clock … clock+len-1` (none past its
|
|
176
|
+
* clock, none in a gap the engine fills later: vendor `store.skips`).
|
|
177
|
+
*/
|
|
178
|
+
export const holdsIds = (doc, client, clock, len) => {
|
|
179
|
+
const store = doc;
|
|
180
|
+
return (clock + len <= store.store.getClock(client) && !store.store.skips.intersects(client, clock, len));
|
|
181
|
+
};
|
|
180
182
|
/** Whether `doc` collects deleted content at all (vendor `gc`). */
|
|
181
183
|
export const collects = (doc) => doc.gc;
|
|
182
184
|
/** Whether `doc`'s collection filter lets it collect `item` (vendor `gcFilter`). */
|
|
@@ -196,11 +198,6 @@ export const keepFromCollection = (doc, keep) => {
|
|
|
196
198
|
* {@link collects} and {@link collectable}.
|
|
197
199
|
*/
|
|
198
200
|
export const collectNow = (item, tr) => item.gc(tr, false);
|
|
199
|
-
/**
|
|
200
|
-
* Listen to `doc`'s transaction events (vendor `beforeTransaction`,
|
|
201
|
-
* `afterTransaction`), with the caller's view of a transaction.
|
|
202
|
-
*/
|
|
203
|
-
export const onTransaction = (doc, event, f) => doc.on(event, f);
|
|
204
201
|
/**
|
|
205
202
|
* Whether a transaction changed one of `nodes` or a node under one: its
|
|
206
203
|
* `changed` types and their ancestors (what a deep observer of `nodes`
|
|
@@ -229,8 +226,6 @@ export const engineOps = (Y) => {
|
|
|
229
226
|
insertInto: (into, from) => Y.insertIntoIdSet(into, from),
|
|
230
227
|
/** Each struct `ids` covers, split at its edges, inside `tr`. */
|
|
231
228
|
iterate: (tr, ids, f) => Y.iterateStructsByIdSet(tr, ids, f),
|
|
232
|
-
/** The item starting at `client:clock`, split there, inside `tr`. */
|
|
233
|
-
cleanStart: (tr, client, clock) => Y.getItemCleanStart(tr, Y.createID(client, clock)),
|
|
234
229
|
/**
|
|
235
230
|
* Re-create deleted `item` (`redoItem`, fork patch YP18): its copy, or
|
|
236
231
|
* `null` when it cannot come back. `items` are re-created with it (a
|
|
@@ -243,6 +238,8 @@ export const engineOps = (Y) => {
|
|
|
243
238
|
merge: (sets) => Y.mergeIdSets(sets),
|
|
244
239
|
/** Whether a store struct is an item (not a GC or a Skip). */
|
|
245
240
|
isItem: (struct) => struct instanceof Y.Item,
|
|
241
|
+
/** Show again what a suggestion's deletes in `tr` proposed (fork patch YP32). */
|
|
242
|
+
unhide: (tr) => Y.unhide(tr),
|
|
246
243
|
/** Whether `item` sits in `node`'s subtree. */
|
|
247
244
|
inside: (node, item) => Y.isParentOf(asYNode(node), item),
|
|
248
245
|
/** Keep `item` (and its parents) from collection (`keepItem`). */
|
|
@@ -262,15 +259,6 @@ export const engineOps = (Y) => {
|
|
|
262
259
|
/** Listen to a doc event (vendor `on`/`off`), with the caller's view of its arguments. */
|
|
263
260
|
on: (doc, event, f) => doc.on(event, f),
|
|
264
261
|
off: (doc, event, f) => doc.off(event, f),
|
|
265
|
-
/**
|
|
266
|
-
* Integrate a new item holding `content` right after `left` (its
|
|
267
|
-
* origin: `left`'s last id) in `parent`, written by `client` at
|
|
268
|
-
* `clock`, inside `tr`.
|
|
269
|
-
*/
|
|
270
|
-
appendAfter: (tr, left, parent, client, clock, content) => {
|
|
271
|
-
const item = new Y.Item(Y.createID(client, clock), left, left.lastId, null, null, asYNode(parent), null, new Y.ContentAny(content));
|
|
272
|
-
item.integrate(tr, 0);
|
|
273
|
-
},
|
|
274
262
|
/** Whether `item` is a node value a concurrent write replaced and its doc keeps. */
|
|
275
263
|
isKeptReplaced: (item) => Y.isKeptReplaced(item)
|
|
276
264
|
};
|
|
@@ -32,12 +32,16 @@ export const indexCache = (ix) => {
|
|
|
32
32
|
get foldedStructs() {
|
|
33
33
|
return foldStats.structs;
|
|
34
34
|
},
|
|
35
|
+
get placements() {
|
|
36
|
+
return foldStats.placed;
|
|
37
|
+
},
|
|
35
38
|
reset() {
|
|
36
39
|
debug.recomputes = 0;
|
|
37
40
|
debug.recomputed.clear();
|
|
38
41
|
foldStats.folds = 0;
|
|
39
42
|
foldStats.pairs = 0;
|
|
40
43
|
foldStats.structs = 0;
|
|
44
|
+
foldStats.placed = 0;
|
|
41
45
|
rangeStats.items = 0;
|
|
42
46
|
rangeStats.markers = 0;
|
|
43
47
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { DEAD,
|
|
1
|
+
import { DEAD, cmpStamp } from '../model.js';
|
|
2
2
|
import { addTo, dropFrom } from './shared.js';
|
|
3
3
|
/** The claim graph of one doc's index, over its state. */
|
|
4
4
|
export const indexClaims = (ix) => {
|
|
@@ -16,7 +16,6 @@ export const indexClaims = (ix) => {
|
|
|
16
16
|
const topInv = new Map();
|
|
17
17
|
/** Claimed block → the blocks whose claims list names it (live or not). */
|
|
18
18
|
const claimersOf = new Map();
|
|
19
|
-
let ownersBuilt = false;
|
|
20
19
|
/** The max-stamp claim on `m` held by a live block. */
|
|
21
20
|
const topClaim = (m) => {
|
|
22
21
|
let best;
|
|
@@ -91,32 +90,12 @@ export const indexClaims = (ix) => {
|
|
|
91
90
|
addTo(displaysMap, to, b);
|
|
92
91
|
};
|
|
93
92
|
const ensureOwners = () => {
|
|
94
|
-
if (!ownersBuilt) {
|
|
95
|
-
ownersBuilt = true;
|
|
96
|
-
ownerSeeds.clear();
|
|
97
|
-
const graph = claimGraph(blocks);
|
|
98
|
-
owners.clear();
|
|
99
|
-
for (const [b, o] of graph.owners)
|
|
100
|
-
if (blocks.has(b))
|
|
101
|
-
owners.set(b, o);
|
|
102
|
-
topOf.clear();
|
|
103
|
-
topInv.clear();
|
|
104
|
-
claimersOf.clear();
|
|
105
|
-
for (const [holder, rec] of blocks)
|
|
106
|
-
for (const c of rec.claims)
|
|
107
|
-
addTo(claimersOf, c.m, holder);
|
|
108
|
-
for (const m of claimersOf.keys())
|
|
109
|
-
setTop(m, topClaim(m));
|
|
110
|
-
displaysMap.clear();
|
|
111
|
-
for (const b of blocks.keys())
|
|
112
|
-
setDisplay(b, undefined, owners.get(b));
|
|
113
|
-
return;
|
|
114
|
-
}
|
|
115
93
|
if (ownerSeeds.size === 0)
|
|
116
94
|
return;
|
|
117
95
|
// The tops a seed's claims (now, and those it dropped: noted in `claimersOf` changes) decide.
|
|
118
96
|
const affected = new Set();
|
|
119
97
|
const stack = [];
|
|
98
|
+
const seeds = [...ownerSeeds];
|
|
120
99
|
for (const x of ownerSeeds) {
|
|
121
100
|
stack.push(x);
|
|
122
101
|
for (const m of claimTargets.get(x) ?? [])
|
|
@@ -150,6 +129,17 @@ export const indexClaims = (ix) => {
|
|
|
150
129
|
setDisplay(x, was, now);
|
|
151
130
|
ownerChanged.add(x);
|
|
152
131
|
}
|
|
132
|
+
// A holder whose claims changed re-slots what shows through them: their
|
|
133
|
+
// order among its claims is the key of the blocks shown under it
|
|
134
|
+
// (`claimedRank`) — under its owner when it is itself merged away.
|
|
135
|
+
for (const x of seeds) {
|
|
136
|
+
if (!blocks.has(x))
|
|
137
|
+
continue;
|
|
138
|
+
ownerChanged.add(x);
|
|
139
|
+
const o = owners.get(x);
|
|
140
|
+
if (typeof o === 'string' && o !== x)
|
|
141
|
+
ownerChanged.add(o);
|
|
142
|
+
}
|
|
153
143
|
};
|
|
154
144
|
/** The claims each seed held before its record changed (their tops are re-decided too). */
|
|
155
145
|
const claimTargets = new Map();
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { BlockId } from '../../placement/model.js';
|
|
2
2
|
import type { ContentRun } from '../runs.js';
|
|
3
|
-
import type { IndexAnchored } from './anchored.js';
|
|
4
3
|
import type { IndexCache } from './cache.js';
|
|
5
4
|
import type { IndexClaims } from './claims.js';
|
|
6
5
|
import type { IndexPlacement } from './placement.js';
|
|
@@ -9,7 +8,7 @@ import type { FoldCtx, IndexState, Tx } from './state.js';
|
|
|
9
8
|
import type { IndexStreams } from './streams.js';
|
|
10
9
|
import type { IndexLayout } from './layout.js';
|
|
11
10
|
/** The fold of one doc's index, over every part it folds into. */
|
|
12
|
-
export declare const indexFold: (ix: IndexState & IndexClaims & IndexStreams &
|
|
11
|
+
export declare const indexFold: (ix: IndexState & IndexClaims & IndexStreams & IndexLayout & IndexPlacement & IndexRecords & IndexCache) => {
|
|
13
12
|
runs: (b: BlockId) => readonly ContentRun[];
|
|
14
13
|
settle: (affected: Iterable<BlockId>, ctx: FoldCtx | null) => void;
|
|
15
14
|
syncPending: (tr: Tx | null | undefined) => boolean;
|