edytor 3.0.0 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/cloudflare/DocumentRoom.d.ts +13 -9
- package/dist/cloudflare/DocumentRoom.js +10 -6
- package/dist/cloudflare/room/context.d.ts +27 -26
- package/dist/cloudflare/room/context.js +2 -2
- package/dist/cloudflare/room/purge.d.ts +6 -3
- package/dist/cloudflare/room/purge.js +44 -19
- package/dist/cloudflare/room/updates.d.ts +3 -4
- package/dist/cloudflare/room/updates.js +6 -8
- package/dist/crdt/attribution/attribution.d.ts +31 -12
- package/dist/crdt/attribution/attribution.js +56 -18
- 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/delete.d.ts +1 -1
- package/dist/crdt/doc/delete.js +13 -30
- package/dist/crdt/doc/funnel.js +29 -24
- package/dist/crdt/doc/gate.d.ts +3 -3
- package/dist/crdt/doc/history.d.ts +25 -9
- package/dist/crdt/doc/history.js +150 -40
- package/dist/crdt/doc/layout.js +11 -22
- package/dist/crdt/doc/meta.js +12 -17
- package/dist/crdt/doc/moves.d.ts +1 -1
- package/dist/crdt/doc/moves.js +52 -32
- package/dist/crdt/doc/reads.js +2 -2
- 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 +52 -122
- package/dist/crdt/doc/types.d.ts +21 -9
- package/dist/crdt/document.d.ts +16 -5
- package/dist/crdt/document.js +21 -4
- package/dist/crdt/edytor-doc.d.ts +62 -64
- package/dist/crdt/edytor-doc.js +18 -13
- package/dist/crdt/engine-api.d.ts +33 -1
- package/dist/crdt/engine.d.ts +0 -1
- package/dist/crdt/engine.js +1 -4
- package/dist/crdt/flow.d.ts +1 -1
- package/dist/crdt/flow.js +25 -27
- package/dist/crdt/index.d.ts +26 -25
- package/dist/crdt/index.js +1 -1
- package/dist/crdt/placement/display.d.ts +5 -30
- package/dist/crdt/placement/display.js +39 -144
- package/dist/crdt/placement/keys.d.ts +58 -0
- package/dist/crdt/placement/keys.js +90 -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 +187 -153
- package/dist/crdt/placement/slots.d.ts +134 -0
- package/dist/crdt/placement/slots.js +152 -0
- package/dist/crdt/providers/room.d.ts +16 -2
- package/dist/crdt/providers/room.js +64 -17
- package/dist/crdt/providers/websocket.js +5 -3
- package/dist/crdt/purge.d.ts +17 -8
- package/dist/crdt/purge.js +236 -126
- package/dist/crdt/restore.d.ts +2 -2
- package/dist/crdt/restore.js +18 -34
- package/dist/crdt/schema.d.ts +22 -21
- package/dist/crdt/schema.js +29 -23
- package/dist/crdt/storage.d.ts +1 -1
- package/dist/crdt/storage.js +1 -1
- package/dist/crdt/structs.d.ts +15 -15
- package/dist/crdt/structs.js +8 -22
- package/dist/crdt/text/index/cache.js +4 -0
- package/dist/crdt/text/index/claims.js +12 -0
- 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.js +5 -8
- package/dist/crdt/text/index/placement.d.ts +26 -18
- package/dist/crdt/text/index/placement.js +404 -138
- 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 +12 -3
- 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 +77 -62
- package/dist/crdt/text/model.js +84 -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 +17 -12
- 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 +568 -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 +194 -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 +43 -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 +610 -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 +177 -12
- package/dist/edytor.svelte.js +4 -1
- package/dist/events/beforeInputCommands.js +2 -2
- package/dist/events/onPageHide.d.ts +3 -0
- package/dist/events/onPageHide.js +16 -0
- package/dist/export/forms.d.ts +25 -25
- package/dist/surface/observer.svelte.js +2 -2
- package/dist/surface/projector.svelte.d.ts +15 -3
- package/dist/surface/projector.svelte.js +59 -8
- package/package.json +2 -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/text/rows.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The maintained form of one backing text's boundary table — the
|
|
3
|
-
* index's row: the text's live boundary items in text order and
|
|
4
|
-
* units between them, held in a Fenwick tree so an edit that writes or
|
|
3
|
+
* index's row: the text's live boundary and claim items in text order and
|
|
4
|
+
* the live units between them, held in a Fenwick tree so an edit that writes or
|
|
5
5
|
* removes no boundary moves every later boundary in O(log B) instead of a
|
|
6
|
-
* rescan.
|
|
6
|
+
* rescan. (A claim item is a bound like a boundary that never delimits: below,
|
|
7
|
+
* "boundary" names both.)
|
|
7
8
|
*
|
|
8
9
|
* `h[j]` is the units before boundary `j` since the one before it, plus
|
|
9
10
|
* boundary `j` itself (`h[B]`: the units after the last boundary), so the
|
|
@@ -21,11 +22,11 @@
|
|
|
21
22
|
* segment `k > 0` is the stream of the block its opening cut names.
|
|
22
23
|
*/
|
|
23
24
|
import type { EngineNode } from '../engine-api.js';
|
|
24
|
-
import { type BlockId, type Bound, type Stream, type TextRow } from './model.js';
|
|
25
|
+
import { type BlockId, type Bound, type Claim, type Stream, type TextRow } from './model.js';
|
|
25
26
|
export type LiveRow = {
|
|
26
27
|
home: BlockId;
|
|
27
28
|
text: EngineNode;
|
|
28
|
-
/** The live boundaries in text order (`at` is NOT maintained: read {@link boundAt}). */
|
|
29
|
+
/** The live boundaries and claim items in text order (`at` is NOT maintained: read {@link boundAt}). */
|
|
29
30
|
bounds: readonly Bound[];
|
|
30
31
|
/** Fenwick tree over `h` (1-based, size `bounds.length + 1`). */
|
|
31
32
|
tree: Float64Array;
|
|
@@ -35,6 +36,8 @@ export type LiveRow = {
|
|
|
35
36
|
keyIndex: Map<string, number>;
|
|
36
37
|
/** Indexes into `bounds` of the delimiting boundaries, ascending ({@link placeRow}). */
|
|
37
38
|
cuts: number[];
|
|
39
|
+
/** The block each cut opens the stream of (`null`: a removed block's, nobody's). */
|
|
40
|
+
heads: (BlockId | null)[];
|
|
38
41
|
/** The block of segment 0 (`null`: the home is delimited elsewhere). */
|
|
39
42
|
head: BlockId | null;
|
|
40
43
|
};
|
|
@@ -82,11 +85,14 @@ export declare const segmentAt: (row: LiveRow, x: number) => number;
|
|
|
82
85
|
export declare const segmentOfCut: (row: LiveRow, cut: string | null) => number;
|
|
83
86
|
/** The block of segment `k` (`null`: nobody's). */
|
|
84
87
|
export declare const headOf: (row: LiveRow, k: number) => BlockId | null;
|
|
88
|
+
/** The claims of segment `k`: its claim items, in text order. */
|
|
89
|
+
export declare const segmentClaims: (row: LiveRow, k: number) => Claim[];
|
|
85
90
|
/** Segment `k` as a {@link Stream} of `block`. */
|
|
86
91
|
export declare const streamOfSegment: (row: LiveRow, k: number, block: BlockId) => Stream;
|
|
87
92
|
/**
|
|
88
93
|
* Set the row's segments from the delimiting boundaries (`delim`): the
|
|
89
94
|
* home's head (unless delimited elsewhere), then one per cut — the same
|
|
90
|
-
* streams `placeText` returns for the row's scan
|
|
95
|
+
* streams `placeText` returns for the row's scan (a cut of a block `nobody`
|
|
96
|
+
* names opens nobody's stretch).
|
|
91
97
|
*/
|
|
92
|
-
export declare const placeRow: (row: LiveRow, delim: ReadonlyMap<BlockId, string
|
|
98
|
+
export declare const placeRow: (row: LiveRow, delim: ReadonlyMap<BlockId, string>, nobody: (s: BlockId) => boolean) => void;
|
package/dist/crdt/text/rows.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { isRowMark } from './model.js';
|
|
2
2
|
const add = (row, i, d) => {
|
|
3
3
|
const t = row.tree;
|
|
4
4
|
for (let x = i + 1; x < t.length; x += x & -x)
|
|
@@ -61,6 +61,7 @@ export const rowOf = (scan) => {
|
|
|
61
61
|
key: scan.key,
|
|
62
62
|
keyIndex,
|
|
63
63
|
cuts: [],
|
|
64
|
+
heads: [],
|
|
64
65
|
head: scan.home
|
|
65
66
|
};
|
|
66
67
|
};
|
|
@@ -76,7 +77,7 @@ const boundIn = (row, it, first) => {
|
|
|
76
77
|
return -1;
|
|
77
78
|
for (let n = 0; n < it.length; n++) {
|
|
78
79
|
const k = first ? n : it.length - 1 - n;
|
|
79
|
-
if (!
|
|
80
|
+
if (!isRowMark(arr[k]))
|
|
80
81
|
continue;
|
|
81
82
|
return row.keyIndex.get(`${it.id.client}:${it.id.clock + k}`) ?? -2;
|
|
82
83
|
}
|
|
@@ -153,7 +154,18 @@ export const segmentOfCut = (row, cut) => {
|
|
|
153
154
|
return row.cuts[k] === j ? k + 1 : -1;
|
|
154
155
|
};
|
|
155
156
|
/** The block of segment `k` (`null`: nobody's). */
|
|
156
|
-
export const headOf = (row, k) => k === 0 ? row.head : row.
|
|
157
|
+
export const headOf = (row, k) => k === 0 ? row.head : row.heads[k - 1];
|
|
158
|
+
/** The claims of segment `k`: its claim items, in text order. */
|
|
159
|
+
export const segmentClaims = (row, k) => {
|
|
160
|
+
const out = [];
|
|
161
|
+
const hi = k < row.cuts.length ? row.cuts[k] : row.bounds.length;
|
|
162
|
+
for (let j = k === 0 ? 0 : row.cuts[k - 1] + 1; j < hi; j++) {
|
|
163
|
+
const b = row.bounds[j];
|
|
164
|
+
if (b.m !== undefined)
|
|
165
|
+
out.push({ m: b.m, stamp: b.stamp });
|
|
166
|
+
}
|
|
167
|
+
return out;
|
|
168
|
+
};
|
|
157
169
|
/** Segment `k` as a {@link Stream} of `block`. */
|
|
158
170
|
export const streamOfSegment = (row, k, block) => {
|
|
159
171
|
const lo = k === 0 ? -1 : row.cuts[k - 1];
|
|
@@ -168,15 +180,20 @@ export const streamOfSegment = (row, k, block) => {
|
|
|
168
180
|
/**
|
|
169
181
|
* Set the row's segments from the delimiting boundaries (`delim`): the
|
|
170
182
|
* home's head (unless delimited elsewhere), then one per cut — the same
|
|
171
|
-
* streams `placeText` returns for the row's scan
|
|
183
|
+
* streams `placeText` returns for the row's scan (a cut of a block `nobody`
|
|
184
|
+
* names opens nobody's stretch).
|
|
172
185
|
*/
|
|
173
|
-
export const placeRow = (row, delim) => {
|
|
186
|
+
export const placeRow = (row, delim, nobody) => {
|
|
174
187
|
const cuts = [];
|
|
188
|
+
const heads = [];
|
|
175
189
|
for (let j = 0; j < row.bounds.length; j++) {
|
|
176
190
|
const b = row.bounds[j];
|
|
177
|
-
if (delim.get(b.s)
|
|
178
|
-
|
|
191
|
+
if (b.m !== undefined || delim.get(b.s) !== b.key)
|
|
192
|
+
continue;
|
|
193
|
+
cuts.push(j);
|
|
194
|
+
heads.push(nobody(b.s) ? null : b.s);
|
|
179
195
|
}
|
|
180
196
|
row.cuts = cuts;
|
|
197
|
+
row.heads = heads;
|
|
181
198
|
row.head = delim.has(row.home) ? null : row.home;
|
|
182
199
|
};
|
package/dist/crdt/text/runs.d.ts
CHANGED
|
@@ -18,9 +18,9 @@
|
|
|
18
18
|
* The fold (see `docs/crdt-v14-richtext-adr.md` for the run contract):
|
|
19
19
|
*
|
|
20
20
|
* - One classifier maps a changed `(type, parentSub)` pair to the block and
|
|
21
|
-
* the facet it entered through (`content`, `
|
|
22
|
-
*
|
|
23
|
-
*
|
|
21
|
+
* the facet it entered through (`content`, `at`, `n`, a delete mark,
|
|
22
|
+
* `type`/`data`, or the registry entry itself); one routine folds a set of
|
|
23
|
+
* such pairs into the indexes.
|
|
24
24
|
* - A transaction is folded ONCE at commit, from `transaction.changed`.
|
|
25
25
|
* - A read first folds the PENDING part of every transaction whose writes
|
|
26
26
|
* are in the document and whose commit fold has not run: the open one, and
|
|
@@ -29,12 +29,12 @@
|
|
|
29
29
|
* fold (the watermark is those sets' lengths). The commit fold takes only
|
|
30
30
|
* what no read folded.
|
|
31
31
|
* - Each backing text has a maintained row (`text/rows.ts`): its
|
|
32
|
-
* boundaries and the live units between them. An edit
|
|
33
|
-
* removes
|
|
34
|
-
* (found by walking the item list to the nearest boundary), never a
|
|
35
|
-
* rescan; a boundary written or removed rescans that text,
|
|
36
|
-
* delimiters of the blocks its boundaries name,
|
|
37
|
-
* rows those cut. Every cached block records which texts its display
|
|
32
|
+
* boundaries and claim items and the live units between them. An edit
|
|
33
|
+
* that writes or removes neither moves the row by its units in the gap it
|
|
34
|
+
* lies in (found by walking the item list to the nearest boundary), never a
|
|
35
|
+
* rescan; a boundary or claim item written or removed rescans that text,
|
|
36
|
+
* re-decides the delimiters of the blocks its boundaries name, re-places
|
|
37
|
+
* only the rows those cut, and re-reads the claims of their blocks. Every cached block records which texts its display
|
|
38
38
|
* walked and which blocks it walked or read a claim on (a skipped claim
|
|
39
39
|
* included); an edit invalidates the display owner of the stream it lies
|
|
40
40
|
* in, a placement the blocks whose stream's delimiting boundaries changed
|
|
@@ -55,8 +55,8 @@
|
|
|
55
55
|
*
|
|
56
56
|
* The index is built from parts under `index/`, each over the shared state
|
|
57
57
|
* (`index/state.ts`) and the parts before it: the claim graph
|
|
58
|
-
* (`claims.ts`), the stream table (`streams.ts`),
|
|
59
|
-
*
|
|
58
|
+
* (`claims.ts`), the stream table and each block's claims (`streams.ts`),
|
|
59
|
+
* the layout rules (`layout.ts`), placements and the
|
|
60
60
|
* children index (`placement.ts`), block records (`records.ts`), the run
|
|
61
61
|
* cache (`cache.ts`), the fold (`fold.ts`), the change report
|
|
62
62
|
* (`report.ts`); the self-checks a test lane installs are `indexChecks`. This module declares the
|
|
@@ -64,7 +64,7 @@
|
|
|
64
64
|
*/
|
|
65
65
|
import type { EngineApi, EngineDoc } from '../engine-api.js';
|
|
66
66
|
import type { BlockId, ContentItem, ModelView, ProjectedBlock } from '../placement/model.js';
|
|
67
|
-
export { CONTENT_ATTR, ENTRY_FACET, indexChecks } from './index/shared.js';
|
|
67
|
+
export { CONTENT_ATTR, ENTRY_FACET, SEQ_FACET, indexChecks } from './index/shared.js';
|
|
68
68
|
/**
|
|
69
69
|
* One visible run of a block — the maintained form of `ContentItem`.
|
|
70
70
|
* `marks`/`data` are interned: equal payloads share one frozen instance,
|
|
@@ -139,6 +139,8 @@ export type RunViewDebug = {
|
|
|
139
139
|
* last `reset()`: each struct once, whatever the number of reads.
|
|
140
140
|
*/
|
|
141
141
|
readonly foldedStructs: number;
|
|
142
|
+
/** Blocks whose placement the index decided since last `reset()` (a global pass decides every one). */
|
|
143
|
+
readonly placements: number;
|
|
142
144
|
reset: () => void;
|
|
143
145
|
};
|
|
144
146
|
/**
|
|
@@ -201,9 +203,12 @@ export type RunView = {
|
|
|
201
203
|
* Track the folds from now on (the write funnel's frame): `end()` folds
|
|
202
204
|
* what is pending and returns the facets every fold since `track()` saw
|
|
203
205
|
* per block, and whether the transaction wrote anything meanwhile.
|
|
206
|
+
* `quiet(write)` runs a write whose facets are not the frame's (it counts
|
|
207
|
+
* as written).
|
|
204
208
|
*/
|
|
205
209
|
track: () => {
|
|
206
210
|
end: () => Folded;
|
|
211
|
+
quiet: (write: () => void) => void;
|
|
207
212
|
};
|
|
208
213
|
/**
|
|
209
214
|
* Subscribe to the change report — one per commit that changed the
|
package/dist/crdt/text/runs.js
CHANGED
|
@@ -3,14 +3,13 @@ import { cloneJsonSafe } from '../../utils/json.js';
|
|
|
3
3
|
import { indexState } from './index/state.js';
|
|
4
4
|
import { indexClaims } from './index/claims.js';
|
|
5
5
|
import { indexStreams } from './index/streams.js';
|
|
6
|
-
import { indexAnchored } from './index/anchored.js';
|
|
7
6
|
import { indexLayout } from './index/layout.js';
|
|
8
7
|
import { indexPlacement } from './index/placement.js';
|
|
9
8
|
import { indexRecords } from './index/records.js';
|
|
10
9
|
import { indexCache } from './index/cache.js';
|
|
11
10
|
import { indexFold } from './index/fold.js';
|
|
12
11
|
import { indexReporter } from './index/report.js';
|
|
13
|
-
export { CONTENT_ATTR, ENTRY_FACET, indexChecks } from './index/shared.js';
|
|
12
|
+
export { CONTENT_ATTR, ENTRY_FACET, SEQ_FACET, indexChecks } from './index/shared.js';
|
|
14
13
|
/** One index per engine doc, shared by every binding (the doc's lifetime). */
|
|
15
14
|
const indexes = new WeakMap();
|
|
16
15
|
/** The doc's index — built on first use, torn down when the doc is destroyed. */
|
|
@@ -27,14 +26,13 @@ const buildView = (doc) => {
|
|
|
27
26
|
const ix0 = indexState(doc);
|
|
28
27
|
const ix1 = Object.assign(ix0, indexClaims(ix0));
|
|
29
28
|
const ix2 = Object.assign(ix1, indexStreams(ix1));
|
|
30
|
-
const
|
|
31
|
-
const ix4 = Object.assign(ix3, indexLayout(ix3));
|
|
29
|
+
const ix4 = Object.assign(ix2, indexLayout(ix2));
|
|
32
30
|
const ix5 = Object.assign(ix4, indexPlacement(ix4));
|
|
33
31
|
const ix6 = Object.assign(ix5, indexRecords(ix5));
|
|
34
32
|
const ix7 = Object.assign(ix6, indexCache(ix6));
|
|
35
33
|
const ix8 = Object.assign(ix7, indexFold(ix7));
|
|
36
34
|
const ix = Object.assign(ix8, indexReporter(ix8));
|
|
37
|
-
const { registry, blocks, rows, homeOfText, shells, placementsMap, frames, displays, ownShim, ensurePlacements, typeOf, order, rebuildTable, scanRow,
|
|
35
|
+
const { registry, blocks, rows, homeOfText, shells, placementsMap, frames, displays, ownShim, ensurePlacements, typeOf, order, rebuildTable, scanRow, applyReclaims, updateBlockRec, syncIncarnations, intern, debug, runs, settle, syncPending, syncAll, openTx, onCommit, committed, itemsOf, projectBlock, publish, onUpdate, onReport, hasSubscribers } = ix;
|
|
38
36
|
const ctx = {
|
|
39
37
|
blocks,
|
|
40
38
|
own: ownShim,
|
|
@@ -53,7 +51,11 @@ const buildView = (doc) => {
|
|
|
53
51
|
// The publication boundary shares THIS interner, so a payload
|
|
54
52
|
// emitted by `project()`/`contentItems()` is `===` the runs' one.
|
|
55
53
|
intern,
|
|
56
|
-
displays
|
|
54
|
+
displays,
|
|
55
|
+
accepted: (id) => {
|
|
56
|
+
ensurePlacements();
|
|
57
|
+
return ix.rejected.has(id) ? null : (ix.edges.get(id) ?? null);
|
|
58
|
+
}
|
|
57
59
|
};
|
|
58
60
|
// ── initial scan: index every existing block ────────────────────
|
|
59
61
|
registry.forEachAttr((v, id) => {
|
|
@@ -69,7 +71,7 @@ const buildView = (doc) => {
|
|
|
69
71
|
}
|
|
70
72
|
});
|
|
71
73
|
rebuildTable(new Set());
|
|
72
|
-
|
|
74
|
+
applyReclaims(null);
|
|
73
75
|
settle(shells, null);
|
|
74
76
|
// Every commit folds once, before the document's `afterTransaction` listeners.
|
|
75
77
|
doc.on('commit', onCommit);
|
|
@@ -141,6 +143,21 @@ const buildView = (doc) => {
|
|
|
141
143
|
syncAll();
|
|
142
144
|
frames.delete(f);
|
|
143
145
|
return f;
|
|
146
|
+
},
|
|
147
|
+
quiet: (write) => {
|
|
148
|
+
syncAll();
|
|
149
|
+
const g = { touched: new Map(), wrote: false };
|
|
150
|
+
frames.delete(f);
|
|
151
|
+
frames.add(g);
|
|
152
|
+
try {
|
|
153
|
+
write();
|
|
154
|
+
syncAll();
|
|
155
|
+
}
|
|
156
|
+
finally {
|
|
157
|
+
frames.delete(g);
|
|
158
|
+
frames.add(f);
|
|
159
|
+
f.wrote ||= g.wrote;
|
|
160
|
+
}
|
|
144
161
|
}
|
|
145
162
|
};
|
|
146
163
|
},
|
|
@@ -1,27 +1,40 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The stream table, pure: a backing text's boundaries, each
|
|
3
|
-
* delimiting boundary, a text's streams, and a block's display as
|
|
4
|
-
* of streams (its stream, then each
|
|
2
|
+
* The stream table, pure: a backing text's boundaries and claim items, each
|
|
3
|
+
* block's delimiting boundary, a text's streams, and a block's display as
|
|
4
|
+
* pieces of streams (its stream, then each claim's display).
|
|
5
5
|
*/
|
|
6
6
|
import type { EngineNode } from '../engine-api.js';
|
|
7
|
-
import type { BlockId, Ownership, Seg, Stream, TextBlockRec, TextRow } from './model.js';
|
|
8
|
-
/** Scan `text` (live space) for its boundary items. */
|
|
7
|
+
import type { BlockId, Claim, Ownership, Seg, Stream, TextBlockRec, TextRow } from './model.js';
|
|
8
|
+
/** Scan `text` (live space) for its boundary and claim items. */
|
|
9
9
|
export declare const scanText: (home: BlockId, text: EngineNode) => TextRow;
|
|
10
10
|
export declare const byId: (a: string, b: string) => number;
|
|
11
|
-
/**
|
|
12
|
-
|
|
11
|
+
/**
|
|
12
|
+
* Whether `s` names a removed block of `registry` (`room.purge.what`): its
|
|
13
|
+
* entry was deleted — only the purge deletes one — and holds no value. The
|
|
14
|
+
* purge removes a block that streams in another block's text alone, and its
|
|
15
|
+
* boundary keeps delimiting the stream it emptied, which nobody shows.
|
|
16
|
+
*/
|
|
17
|
+
export declare const removedKeys: (registry: EngineNode) => (s: BlockId) => boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Each block's delimiting boundary: the lowest-id live boundary whose nonce
|
|
20
|
+
* matches its record; for a removed block (`removed`, no record), the
|
|
21
|
+
* lowest-id live boundary naming it.
|
|
22
|
+
*/
|
|
23
|
+
export declare const delimiters: (blocks: ReadonlyMap<BlockId, Pick<TextBlockRec, "n">>, rows: Iterable<TextRow>, removed?: (s: BlockId) => boolean) => Map<BlockId, string>;
|
|
13
24
|
/**
|
|
14
25
|
* The streams of one text, in text order: the home's head (unless delimited
|
|
15
26
|
* elsewhere), then one per delimiting boundary — one sweep over the
|
|
16
|
-
* boundaries (each non-delimiting one
|
|
17
|
-
* sits in).
|
|
27
|
+
* boundaries (each non-delimiting one, and each claim item, is an inert unit
|
|
28
|
+
* of the stream it sits in). A boundary of a block `nobody` names (a
|
|
29
|
+
* removed one) opens a stretch that is no block's stream.
|
|
18
30
|
*/
|
|
19
|
-
export declare const placeText: (row: TextRow, delim: ReadonlyMap<BlockId, string
|
|
20
|
-
/**
|
|
31
|
+
export declare const placeText: (row: TextRow, delim: ReadonlyMap<BlockId, string>, nobody?: (s: BlockId) => boolean) => Stream[];
|
|
32
|
+
/** The claims of stream `s` of `row`: its claim items, in text order. */
|
|
33
|
+
export declare const claimsIn: (row: TextRow, s: Stream) => Claim[];
|
|
34
|
+
/** A stream's content pieces: the range minus its inert units (at least one piece). */
|
|
21
35
|
export declare const pieces: (s: Stream) => [number, number][];
|
|
22
36
|
/**
|
|
23
|
-
* `display(b)`: `b`'s stream, then each
|
|
24
|
-
* order. `track(x, home)` reports every walked block and the home of its
|
|
37
|
+
* `display(b)`: `b`'s stream, then each claim's display, in claim order. `track(x, home)` reports every walked block and the home of its
|
|
25
38
|
* stream (the index's dependency capture). `null` when `b` is hidden, unless
|
|
26
39
|
* `hidden` asks for the pieces a hidden block would show (an anchor minted in
|
|
27
40
|
* a merged-away or deleted block binds its items all the same).
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import { isIncarnationId } from '../incarnations.js';
|
|
2
|
+
import { attrItems } from '../structs.js';
|
|
3
|
+
import { isBoundary, isClaimItem, nodeStart } from './items.js';
|
|
4
|
+
/** Scan `text` (live space) for its boundary and claim items. */
|
|
3
5
|
export const scanText = (home, text) => {
|
|
4
6
|
const bounds = [];
|
|
5
7
|
let at = 0;
|
|
@@ -10,8 +12,11 @@ export const scanText = (home, text) => {
|
|
|
10
12
|
if (arr !== undefined) {
|
|
11
13
|
for (let j = 0; j < it.length; j++) {
|
|
12
14
|
const v = arr[j];
|
|
15
|
+
const [c, k] = [it.id.client, it.id.clock + j];
|
|
13
16
|
if (isBoundary(v))
|
|
14
|
-
bounds.push({ s: v.s, n: v.n, at: at + j, key: `${
|
|
17
|
+
bounds.push({ s: v.s, n: v.n, at: at + j, key: `${c}:${k}` });
|
|
18
|
+
else if (isClaimItem(v))
|
|
19
|
+
bounds.push({ m: v.m, stamp: { c, k }, at: at + j, key: `${c}:${k}` });
|
|
15
20
|
}
|
|
16
21
|
}
|
|
17
22
|
at += it.length;
|
|
@@ -23,12 +28,26 @@ export const byId = (a, b) => {
|
|
|
23
28
|
const [bc, bk] = b.split(':').map(Number);
|
|
24
29
|
return ac - bc || ak - bk;
|
|
25
30
|
};
|
|
26
|
-
/**
|
|
27
|
-
|
|
31
|
+
/**
|
|
32
|
+
* Whether `s` names a removed block of `registry` (`room.purge.what`): its
|
|
33
|
+
* entry was deleted — only the purge deletes one — and holds no value. The
|
|
34
|
+
* purge removes a block that streams in another block's text alone, and its
|
|
35
|
+
* boundary keeps delimiting the stream it emptied, which nobody shows.
|
|
36
|
+
*/
|
|
37
|
+
export const removedKeys = (registry) => (s) => attrItems(registry).get(s)?.deleted === true && !isIncarnationId(s);
|
|
38
|
+
/**
|
|
39
|
+
* Each block's delimiting boundary: the lowest-id live boundary whose nonce
|
|
40
|
+
* matches its record; for a removed block (`removed`, no record), the
|
|
41
|
+
* lowest-id live boundary naming it.
|
|
42
|
+
*/
|
|
43
|
+
export const delimiters = (blocks, rows, removed = () => false) => {
|
|
28
44
|
const out = new Map();
|
|
29
45
|
for (const row of rows) {
|
|
30
46
|
for (const b of row.bounds) {
|
|
31
|
-
if (
|
|
47
|
+
if (b.m !== undefined)
|
|
48
|
+
continue;
|
|
49
|
+
const rec = blocks.get(b.s);
|
|
50
|
+
if (rec === undefined ? !removed(b.s) : rec.n !== b.n)
|
|
32
51
|
continue;
|
|
33
52
|
const cur = out.get(b.s);
|
|
34
53
|
if (cur === undefined || byId(b.key, cur) < 0)
|
|
@@ -40,10 +59,11 @@ export const delimiters = (blocks, rows) => {
|
|
|
40
59
|
/**
|
|
41
60
|
* The streams of one text, in text order: the home's head (unless delimited
|
|
42
61
|
* elsewhere), then one per delimiting boundary — one sweep over the
|
|
43
|
-
* boundaries (each non-delimiting one
|
|
44
|
-
* sits in).
|
|
62
|
+
* boundaries (each non-delimiting one, and each claim item, is an inert unit
|
|
63
|
+
* of the stream it sits in). A boundary of a block `nobody` names (a
|
|
64
|
+
* removed one) opens a stretch that is no block's stream.
|
|
45
65
|
*/
|
|
46
|
-
export const placeText = (row, delim) => {
|
|
66
|
+
export const placeText = (row, delim, nobody = () => false) => {
|
|
47
67
|
const out = [];
|
|
48
68
|
let block = delim.has(row.home) ? null : row.home;
|
|
49
69
|
let start = 0;
|
|
@@ -53,17 +73,25 @@ export const placeText = (row, delim) => {
|
|
|
53
73
|
out.push({ block, home: row.home, text: row.text, start, end, inert });
|
|
54
74
|
};
|
|
55
75
|
for (const b of row.bounds) {
|
|
56
|
-
if (delim.get(b.s) !== b.key) {
|
|
76
|
+
if (b.m !== undefined || delim.get(b.s) !== b.key) {
|
|
57
77
|
inert.push(b.at);
|
|
58
78
|
continue;
|
|
59
79
|
}
|
|
60
80
|
close(b.at);
|
|
61
|
-
[block, start, inert] = [b.s, b.at + 1, []];
|
|
81
|
+
[block, start, inert] = [nobody(b.s) ? null : b.s, b.at + 1, []];
|
|
62
82
|
}
|
|
63
83
|
close(row.len);
|
|
64
84
|
return out;
|
|
65
85
|
};
|
|
66
|
-
/**
|
|
86
|
+
/** The claims of stream `s` of `row`: its claim items, in text order. */
|
|
87
|
+
export const claimsIn = (row, s) => {
|
|
88
|
+
const out = [];
|
|
89
|
+
for (const b of row.bounds)
|
|
90
|
+
if (b.m !== undefined && b.at >= s.start && b.at < s.end)
|
|
91
|
+
out.push({ m: b.m, stamp: b.stamp });
|
|
92
|
+
return out;
|
|
93
|
+
};
|
|
94
|
+
/** A stream's content pieces: the range minus its inert units (at least one piece). */
|
|
67
95
|
export const pieces = (s) => {
|
|
68
96
|
const out = [];
|
|
69
97
|
let a = s.start;
|
|
@@ -75,8 +103,7 @@ export const pieces = (s) => {
|
|
|
75
103
|
return out;
|
|
76
104
|
};
|
|
77
105
|
/**
|
|
78
|
-
* `display(b)`: `b`'s stream, then each
|
|
79
|
-
* order. `track(x, home)` reports every walked block and the home of its
|
|
106
|
+
* `display(b)`: `b`'s stream, then each claim's display, in claim order. `track(x, home)` reports every walked block and the home of its
|
|
80
107
|
* stream (the index's dependency capture). `null` when `b` is hidden, unless
|
|
81
108
|
* `hidden` asks for the pieces a hidden block would show (an anchor minted in
|
|
82
109
|
* a merged-away or deleted block binds its items all the same).
|