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.
Files changed (147) hide show
  1. package/README.md +2 -2
  2. package/dist/block/block.svelte.js +6 -21
  3. package/dist/block/inlineBlock.svelte.js +4 -6
  4. package/dist/clipboard/moveText.js +6 -8
  5. package/dist/cloudflare/DocumentRoom.d.ts +10 -3
  6. package/dist/cloudflare/index.d.ts +1 -1
  7. package/dist/cloudflare/room/access.d.ts +8 -3
  8. package/dist/cloudflare/room/access.js +44 -20
  9. package/dist/cloudflare/room/admission.js +28 -5
  10. package/dist/cloudflare/room/comments.js +28 -1
  11. package/dist/cloudflare/room/context.d.ts +115 -106
  12. package/dist/cloudflare/room/context.js +10 -3
  13. package/dist/cloudflare/room/forged.d.ts +14 -0
  14. package/dist/cloudflare/room/forged.js +30 -2
  15. package/dist/cloudflare/room/frames.d.ts +4 -0
  16. package/dist/cloudflare/room/frames.js +5 -1
  17. package/dist/cloudflare/room/purge.js +2 -1
  18. package/dist/cloudflare/room/replicas.d.ts +4 -2
  19. package/dist/cloudflare/room/replicas.js +8 -3
  20. package/dist/cloudflare/room/suggest.d.ts +7 -0
  21. package/dist/cloudflare/room/suggest.js +143 -0
  22. package/dist/cloudflare/routeDocumentSocket.d.ts +10 -1
  23. package/dist/cloudflare/routeDocumentSocket.js +5 -3
  24. package/dist/components/Content.svelte +9 -1
  25. package/dist/crdt/anchors.js +3 -2
  26. package/dist/crdt/attribution/attribution.d.ts +3 -0
  27. package/dist/crdt/attribution/attribution.js +3 -3
  28. package/dist/crdt/doc/capability.js +9 -13
  29. package/dist/crdt/doc/funnel.d.ts +1 -1
  30. package/dist/crdt/doc/funnel.js +5 -2
  31. package/dist/crdt/doc/gate.d.ts +1 -1
  32. package/dist/crdt/doc/history.d.ts +6 -0
  33. package/dist/crdt/doc/history.js +77 -56
  34. package/dist/crdt/doc/layout.js +5 -5
  35. package/dist/crdt/doc/meta.js +6 -7
  36. package/dist/crdt/doc/reads.d.ts +2 -2
  37. package/dist/crdt/doc/reads.js +18 -28
  38. package/dist/crdt/doc/steps.js +4 -4
  39. package/dist/crdt/doc/suggest.d.ts +167 -0
  40. package/dist/crdt/doc/suggest.js +579 -0
  41. package/dist/crdt/document.d.ts +10 -1
  42. package/dist/crdt/document.js +19 -11
  43. package/dist/crdt/edytor-doc.d.ts +355 -333
  44. package/dist/crdt/edytor-doc.js +125 -82
  45. package/dist/crdt/engine-api.d.ts +8 -2
  46. package/dist/crdt/engine.d.ts +2 -1
  47. package/dist/crdt/engine.js +3 -1
  48. package/dist/crdt/flow.d.ts +1 -1
  49. package/dist/crdt/flow.js +4 -10
  50. package/dist/crdt/index.d.ts +111 -105
  51. package/dist/crdt/index.js +3 -0
  52. package/dist/crdt/operations.d.ts +12 -3
  53. package/dist/crdt/parts.d.ts +43 -0
  54. package/dist/crdt/parts.js +44 -0
  55. package/dist/crdt/placement/display.d.ts +1 -1
  56. package/dist/crdt/placement/display.js +3 -3
  57. package/dist/crdt/placement/keys.d.ts +5 -0
  58. package/dist/crdt/placement/keys.js +5 -0
  59. package/dist/crdt/placement/resolve.js +2 -1
  60. package/dist/crdt/protocol.d.ts +1 -1
  61. package/dist/crdt/protocol.js +1 -1
  62. package/dist/crdt/protocols/auth.d.ts +11 -1
  63. package/dist/crdt/protocols/auth.js +17 -1
  64. package/dist/crdt/protocols/comments.d.ts +16 -1
  65. package/dist/crdt/protocols/comments.js +9 -1
  66. package/dist/crdt/providers/index.d.ts +6 -4
  67. package/dist/crdt/providers/index.js +3 -1
  68. package/dist/crdt/providers/websocket.d.ts +6 -4
  69. package/dist/crdt/providers/websocket.js +9 -4
  70. package/dist/crdt/purge.d.ts +7 -1
  71. package/dist/crdt/purge.js +32 -2
  72. package/dist/crdt/restore.d.ts +2 -1
  73. package/dist/crdt/restore.js +9 -0
  74. package/dist/crdt/schema.d.ts +9 -1
  75. package/dist/crdt/schema.js +13 -3
  76. package/dist/crdt/structs.d.ts +2 -0
  77. package/dist/crdt/structs.js +2 -0
  78. package/dist/crdt/text/index/claims.js +1 -23
  79. package/dist/crdt/text/index/layout.d.ts +2 -4
  80. package/dist/crdt/text/index/layout.js +9 -22
  81. package/dist/crdt/text/index/placement.js +21 -24
  82. package/dist/crdt/text/index/shared.js +17 -14
  83. package/dist/crdt/text/model.d.ts +10 -0
  84. package/dist/crdt/text/model.js +8 -1
  85. package/dist/crdt/text/runs.d.ts +34 -30
  86. package/dist/crdt/vendor/yjs/UPSTREAM.md +83 -0
  87. package/dist/crdt/vendor/yjs/dts/index.d.ts +1 -1
  88. package/dist/crdt/vendor/yjs/dts/structs/Item.d.ts +6 -3
  89. package/dist/crdt/vendor/yjs/dts/ynode.d.ts +13 -2
  90. package/dist/crdt/vendor/yjs/src/index.js +1 -1
  91. package/dist/crdt/vendor/yjs/src/structs/Item.js +44 -5
  92. package/dist/crdt/vendor/yjs/src/ynode.js +29 -7
  93. package/dist/edytor.svelte.d.ts +1 -1
  94. package/dist/edytor.svelte.js +100 -75
  95. package/dist/events/beforeInputCommands.d.ts +2 -2
  96. package/dist/events/nativeInteractiveControl.d.ts +11 -1
  97. package/dist/events/nativeInteractiveControl.js +41 -1
  98. package/dist/events/onBeforeInput.js +3 -3
  99. package/dist/events/onFocus.js +9 -11
  100. package/dist/export/forms.d.ts +25 -25
  101. package/dist/index.d.ts +4 -2
  102. package/dist/index.js +1 -1
  103. package/dist/labels.d.ts +8 -0
  104. package/dist/labels.js +6 -1
  105. package/dist/plugins/comments/CommentsController.svelte.d.ts +5 -1
  106. package/dist/plugins/comments/CommentsController.svelte.js +14 -4
  107. package/dist/plugins/find/search.js +2 -2
  108. package/dist/plugins/index.d.ts +1 -0
  109. package/dist/plugins/index.js +1 -0
  110. package/dist/plugins/suggestions/SuggestionBars.svelte +40 -23
  111. package/dist/plugins/suggestions/SuggestionBars.svelte.d.ts +3 -1
  112. package/dist/plugins/suggestions/SuggestionRuns.svelte +77 -0
  113. package/dist/plugins/suggestions/SuggestionRuns.svelte.d.ts +9 -0
  114. package/dist/plugins/suggestions/shared.svelte.d.ts +58 -0
  115. package/dist/plugins/suggestions/shared.svelte.js +421 -0
  116. package/dist/plugins/suggestions/suggestionsPlugin.d.ts +15 -4
  117. package/dist/selection/domSelection.d.ts +2 -0
  118. package/dist/selection/domSelection.js +6 -2
  119. package/dist/selection/pointer.svelte.js +75 -48
  120. package/dist/selection/replaceSelection.js +2 -6
  121. package/dist/selection/selection.svelte.d.ts +3 -3
  122. package/dist/selection/selection.svelte.js +39 -32
  123. package/dist/selection/selection.utils.d.ts +14 -0
  124. package/dist/selection/selection.utils.js +28 -3
  125. package/dist/session/commands.js +21 -11
  126. package/dist/session/composition.svelte.d.ts +5 -3
  127. package/dist/session/composition.svelte.js +21 -17
  128. package/dist/session/handles.d.ts +4 -17
  129. package/dist/session/handles.js +11 -37
  130. package/dist/session/navigation.js +6 -9
  131. package/dist/session/selection.d.ts +11 -5
  132. package/dist/session/selection.js +14 -48
  133. package/dist/session/suggestions.svelte.d.ts +38 -9
  134. package/dist/session/suggestions.svelte.js +37 -18
  135. package/dist/session/virtual.d.ts +1 -1
  136. package/dist/surface/attributes.d.ts +5 -0
  137. package/dist/surface/attributes.js +2 -2
  138. package/dist/surface/cells.d.ts +2 -26
  139. package/dist/surface/cells.js +2 -33
  140. package/dist/surface/observer.svelte.d.ts +6 -1
  141. package/dist/surface/observer.svelte.js +128 -81
  142. package/dist/surface/pin.svelte.d.ts +9 -9
  143. package/dist/surface/pin.svelte.js +15 -22
  144. package/dist/surface/projector.svelte.js +8 -14
  145. package/dist/text/text.svelte.js +14 -19
  146. package/dist/themes/notion.css +29 -0
  147. package/package.json +3 -1
@@ -1,6 +1,6 @@
1
1
  import type { EngineApi, EngineDoc, EngineNode } from '../engine-api.js';
2
2
  import { type BlockId, type ContentItem, type Destination, type ModelView } from '../placement/model.js';
3
- import type { DisplayRoles, RunView } from '../text/runs.js';
3
+ import type { DisplayRoles, KindRole, RunView } from '../text/runs.js';
4
4
  import { type DataPatch } from '../data.js';
5
5
  import { type JSONBlock } from '../../utils/json.js';
6
6
  import type { BlockRole, DataTarget, JsonObj, OrderPolicy } from './types.js';
@@ -40,7 +40,7 @@ export declare const docReads: (c: DocBase) => {
40
40
  parent: BlockId | null;
41
41
  rank: string;
42
42
  } | null;
43
- is: (id: BlockId, role: (type: string) => boolean) => boolean;
43
+ kindOf: (id: BlockId) => KindRole | undefined;
44
44
  isVoid: (id: BlockId) => boolean;
45
45
  isIsland: (id: BlockId) => boolean;
46
46
  isLines: (id: BlockId) => boolean;
@@ -121,15 +121,15 @@ export const docReads = (c) => {
121
121
  return slot.parent === DEAD ? pl : slot;
122
122
  };
123
123
  // ── roles (island/void) ───────────────────────────────────────────
124
- /** The role table's answer for `id`'s shown kind (`false` without one). */
125
- const is = (id, role) => {
124
+ /** The role of `id`'s shown kind (`undefined` without one). */
125
+ const kindOf = (id) => {
126
126
  const t = blockTypeOf(id);
127
- return t !== undefined && role(t);
127
+ return t === undefined ? undefined : roles.of(t);
128
128
  };
129
- const isVoid = (id) => is(id, roles.childless);
130
- const isIsland = (id) => is(id, roles.island);
129
+ const isVoid = (id) => kindOf(id)?.childless === true;
130
+ const isIsland = (id) => kindOf(id)?.island === true;
131
131
  /** An island that holds only lines (a code block: its role says `lines`). */
132
- const isLines = (id) => is(id, (type) => roles.line(type) !== undefined);
132
+ const isLines = (id) => kindOf(id)?.line !== undefined;
133
133
  /** Nearest island-typed display ancestor of `id`, or null. */
134
134
  const islandOf = (id, v = view()) => ancestorsOf(id, v).find((a) => isIsland(a)) ?? null;
135
135
  /** True iff `id` sits strictly inside an island subtree. */
@@ -139,45 +139,35 @@ export const docReads = (c) => {
139
139
  const parent = positionOf(id)?.parent;
140
140
  return parent != null && isLines(parent);
141
141
  };
142
- /** The child kind `role` gives `id`'s kind: a layout's item kind, a table's row kind. */
143
- const childKindOf = (role) => (id) => {
144
- const type = blockTypeOf(id);
145
- return type === undefined ? undefined : roles[role](type);
146
- };
147
- /** `id` is of its parent's `kindOf` kind, directly in it (a column, a row). */
148
- const childOf = (kindOf) => (id) => {
142
+ /** `id` is of its parent's `kind` kind, directly in it (a column, a row, a cell). */
143
+ const childOf = (kind) => (id) => {
149
144
  const parent = positionOf(id)?.parent;
150
- return parent != null && blockTypeOf(id) === kindOf(parent);
145
+ const k = parent == null ? undefined : kindOf(parent);
146
+ return parent != null && blockTypeOf(id) === (k && kind(k));
151
147
  };
152
148
  /** The item kind of `id` when it is a layout (its role says `layout`): its default child. */
153
- const itemKindOf = childKindOf('layout');
149
+ const itemKindOf = (id) => kindOf(id)?.layout;
154
150
  /** `id` is a layout (`layout.*`). */
155
151
  const isLayout = (id) => itemKindOf(id) !== undefined;
156
152
  /** `id` is a layout item: of its layout's item kind, directly in it (a column). */
157
- const isLayoutItem = childOf(itemKindOf);
153
+ const isLayoutItem = childOf((k) => k.layout);
158
154
  /** `id` is a layout or holds one in its shown subtree (`layout.nest`). */
159
155
  const holdsLayout = (id) => isLayout(id) || childrenIds(id).some(holdsLayout);
160
156
  /** `id` is a layout item or sits inside one. */
161
157
  const insideItem = (id, v) => [id, ...ancestorsOf(id, v)].some(isLayoutItem);
162
158
  // ── tables (`table.*`) ────────────────────────────────────────────
163
- /** The row kind of `id` when it is a table (its role says `table`): its default child. */
164
- const rowKindOf = childKindOf('table');
165
159
  /** `id` is a table (`table.*`). */
166
- const isTable = (id) => rowKindOf(id) !== undefined;
160
+ const isTable = (id) => kindOf(id)?.table !== undefined;
167
161
  /** `type` is a row kind of a table kind the roles declare (`tableRow`). */
168
- const isRowKind = (type) => type !== undefined && [...roles.tableKinds()].some((t) => roles.table(t) === type);
162
+ const isRowKind = (type) => type !== undefined && roles.declared().rows.has(type);
169
163
  /** `type` is a cell kind: the default child of a row kind (`tableCell`). */
170
- const isCellKind = (type) => type !== undefined &&
171
- [...roles.tableKinds()].some((t) => {
172
- const row = roles.table(t);
173
- return row !== undefined && roles.defaultChild(row) === type;
174
- });
164
+ const isCellKind = (type) => type !== undefined && roles.declared().cells.has(type);
175
165
  /** `id` is a table's row: of its table's row kind, directly in it. */
176
- const isTableRow = childOf(rowKindOf);
166
+ const isTableRow = childOf((k) => k.table);
177
167
  /** `id` is a table's cell: of its row's cell kind, directly in a row of a table. */
178
168
  const isTableCell = (id) => {
179
169
  const row = positionOf(id)?.parent;
180
- return (row != null && isTableRow(row) && blockTypeOf(id) === roles.defaultChild(blockTypeOf(row)));
170
+ return row != null && isTableRow(row) && blockTypeOf(id) === kindOf(row).child;
181
171
  };
182
172
  /** The table `id` is, or whose row or cell it is; `null` for any other block. */
183
173
  const tableOf = (id) => {
@@ -317,7 +307,7 @@ export const docReads = (c) => {
317
307
  pathOf,
318
308
  ancestorsOf,
319
309
  slotOf,
320
- is,
310
+ kindOf,
321
311
  isVoid,
322
312
  isIsland,
323
313
  isLines,
@@ -21,7 +21,7 @@ import { REFUSED, effectOf } from './plan.js';
21
21
  export const PART = { head: 0, kept: 1, with: 2, self: 3, after: 4 };
22
22
  /** The step writers of one facade. */
23
23
  export const planSteps = (c) => {
24
- const { doc, runsView, roles, rendersContentOf, view, blockTypeOf, childrenIds, positionOf, ancestorsOf, is, isIsland, itemKindOf, isLayout, displayLength, contentItems, live, isContainer, fitted, emptiable, defaultChild } = c;
24
+ const { doc, runsView, roles, view, blockTypeOf, childrenIds, positionOf, ancestorsOf, isLines, isIsland, itemKindOf, isLayout, displayLength, contentItems, live, isContainer, fitted, emptiable, defaultChild } = c;
25
25
  // ── prepared ops ─────────────────────────────────────────────
26
26
  // Every op is `prepare` (pure: `refused`, or a plan of named steps plus
27
27
  // its effect summary, against the current version) then `apply(plan)`;
@@ -114,9 +114,9 @@ export const planSteps = (c) => {
114
114
  * default kind, any other child keeps its kind (as `typeOf`).
115
115
  */
116
116
  const leavingIsland = (island, kind, to) => {
117
- if (rendersContentOf(to) || (kind !== undefined && !rendersContentOf(kind)))
117
+ if (roles.of(to).rendersContent || (kind !== undefined && !roles.of(kind).rendersContent))
118
118
  return to;
119
- return is(island, (type) => roles.line(type) !== undefined) ? defaultChild(null) : kind;
119
+ return isLines(island) ? defaultChild(null) : kind;
120
120
  };
121
121
  const settledKind = (from, kid, parent) => {
122
122
  let kind = blockTypeOf(kid);
@@ -129,7 +129,7 @@ export const planSteps = (c) => {
129
129
  // column's default child is the document's: it holds no items of its own.
130
130
  const outer = kind !== defaultChild(null) &&
131
131
  within.some((a) => isContainer(a) && defaultChild(a) === kind);
132
- if (!outer && rendersContentOf(to))
132
+ if (!outer && roles.of(to).rendersContent)
133
133
  kind = to;
134
134
  }
135
135
  return fitted(parent, kind);
@@ -0,0 +1,167 @@
1
+ /**
2
+ * Shared suggestions (`docs/archive/shared-suggestions/design.md`, the
3
+ * `sugg.*` rows of `docs/editor-delete-contract.md`): a suggestion lives in
4
+ * the document, so every replica, the room and a reload see it.
5
+ *
6
+ * - A suggestion is a record node under the root `suggest`, written by its
7
+ * **writer**: a client id minted for a suggesting session, bound to its
8
+ * author with its first write like any replica. The record's own item
9
+ * opens the writer's clocks it owns, up to the writer's next record; its
10
+ * creation is in no history step, so no undo or redo moves them.
11
+ * - **An insertion** is the writer's own text and blocks: a shown unit or
12
+ * block of the writer, in the record's clocks, not settled, is pending.
13
+ * - **A deletion** writes nothing to the text: the writer's id list (fork
14
+ * patch YP31, a hold record that holds nothing inside a nested node) in
15
+ * the record names the units; a shown one, not settled, is pending. A
16
+ * block deletion is the same id list naming the block's node.
17
+ * - Nothing else is suggested: a move, a merge, a retype, a data change or
18
+ * a format is refused (written directly on its author's own pending
19
+ * block).
20
+ * - **A decision** writes only what changes, one engine call over the
21
+ * change's ids (`YNode#hold`): the text that goes is the reviewer's hold
22
+ * (fork patch YP20, the root records list), the text that stays a settled
23
+ * id list written by the reviewer into the record (its client is the
24
+ * decider).
25
+ *
26
+ * What is pending is a function of the replicated state (items, records,
27
+ * settled ranges), so replicas converge in any delivery order. It is read
28
+ * again after any write, from the blocks the records' writers and
29
+ * proposals are in: a document with no suggestion pays nothing.
30
+ *
31
+ * The part is built over a document by {@link suggestionsOf} (the shared
32
+ * suggestions plugin, the room, a bare document on a server): once built,
33
+ * the document's `toJSON()` leaves its pending suggestions out. A document
34
+ * no one built it over reads its suggestions' content as plain content.
35
+ */
36
+ import type { EngineDoc } from '../engine-api.js';
37
+ import { type BlockId } from '../placement/model.js';
38
+ import type { DocAnchor, EdytorDocConfig, OpResult, Prepared } from './types.js';
39
+ import type { DocBase, DocReads } from './reads.js';
40
+ import type { JSONDoc } from '../../utils/json.js';
41
+ import type { EdytorDocument } from '../document.js';
42
+ /** One change of a suggestion, as a reviewer sees it. */
43
+ export type SuggestedChange = {
44
+ /** The suggestion it is part of (its record's id). */
45
+ readonly suggestion: string;
46
+ /**
47
+ * `insert`: a run of text it inserts; `delete`: a run it proposes to
48
+ * delete; `block`: a block it inserts, its text with it; `split`: the
49
+ * block its split makes; `remove`: a block it proposes to delete.
50
+ */
51
+ readonly kind: 'insert' | 'delete' | 'block' | 'split' | 'remove';
52
+ /** The block it is in or about. */
53
+ readonly block: BlockId;
54
+ /** Its run, in the block's display offsets (a block's: the whole block). */
55
+ readonly offset: number;
56
+ readonly length: number;
57
+ readonly text: string;
58
+ };
59
+ /** A suggestion the document holds. */
60
+ export type SuggestionRecord = {
61
+ readonly id: string;
62
+ /** Its author (its writer's actor), `undefined` until the binding arrives. */
63
+ readonly by: string | undefined;
64
+ /** The agent that wrote it for its author (`'ai'`), when one did. */
65
+ readonly via: string | undefined;
66
+ readonly label: string | undefined;
67
+ /** When it was opened (ms since the epoch). */
68
+ readonly at: number;
69
+ };
70
+ /**
71
+ * One part of a decision: an id list written into suggestion `into`'s
72
+ * record (settled: it stays) or, `into` null, the decider's hold of the
73
+ * text that goes (fork patch YP20, the root records list): one engine
74
+ * call either way (`YNode#hold`); or a document operation's calls (their
75
+ * arguments read when it runs).
76
+ */
77
+ export type DecisionPart = {
78
+ into: string | null;
79
+ ids: number[];
80
+ blocks?: BlockId[];
81
+ } | {
82
+ op: string;
83
+ calls: () => unknown[][];
84
+ };
85
+ /** What the part reads of its document beyond the facade: the facade's `part` (`edytor-doc.ts`). */
86
+ export type SuggestContext = DocBase & DocReads & {
87
+ config: EdytorDocConfig;
88
+ /** A facade over another doc, with `config`. */
89
+ create: (doc: EngineDoc, config: EdytorDocConfig) => SuggestFacade;
90
+ /** Its changes no index fact shows: counted in the facade's `version`. */
91
+ v: number;
92
+ /** The export `toJSON()` gives unless asked for the suggestions. */
93
+ base: (() => JSONDoc | undefined) | undefined;
94
+ };
95
+ /** The facade the part is built over: its `part`, and the operations it writes through. */
96
+ export type SuggestFacade = {
97
+ part: SuggestContext;
98
+ toJSON: (options?: {
99
+ suggestions?: boolean;
100
+ }) => JSONDoc;
101
+ dispose: () => void;
102
+ apply: (p: Prepared, quiet?: boolean) => OpResult;
103
+ transact: <R>(fn: () => R) => R;
104
+ anchorAt: (id: BlockId, offset: number, affinity?: 'left' | 'right') => DocAnchor | null;
105
+ resolveAnchor: (anchor: DocAnchor) => {
106
+ blockId: BlockId;
107
+ offset: number;
108
+ } | null;
109
+ /** Its operations by name (`f[op](…args)`). */
110
+ [op: string]: unknown;
111
+ };
112
+ /**
113
+ * The shared suggestions of the document `facade` is over, built once:
114
+ * from then on, its `toJSON()` leaves the pending ones out (`sugg.json.base`).
115
+ */
116
+ export declare const suggestionsOf: (facade: SuggestFacade) => DocSuggest;
117
+ /**
118
+ * Build the shared suggestions over `document`, a document read without a
119
+ * view (on a server, in a worker): its `toJSON()` leaves the pending ones
120
+ * out from then on, as a view's with the shared suggestions plugin does. A
121
+ * document no one built them over reads their content as plain content.
122
+ */
123
+ export declare const adoptSharedSuggestions: (document: EdytorDocument) => void;
124
+ /** The document's shared suggestions ({@link suggestionsOf}), built over facade `f`. */
125
+ declare const docSuggest: (f: SuggestFacade) => {
126
+ /** A fresh writer this replica writes suggestions under. */
127
+ writer: () => number;
128
+ /** The writers this replica minted (a history tags their steps, `StackItem.writer`). */
129
+ writers: Set<number>;
130
+ open: (options?: {
131
+ id?: string;
132
+ writer?: number;
133
+ via?: string;
134
+ label?: string;
135
+ at?: number;
136
+ }) => string;
137
+ apply: (id: string | null, p: Prepared, w?: number) => {
138
+ result: OpResult;
139
+ id?: string;
140
+ at?: {
141
+ block: BlockId;
142
+ offset: number;
143
+ };
144
+ };
145
+ decide: (changes: readonly SuggestedChange[], accept: boolean) => DecisionPart[];
146
+ run: (parts: readonly DecisionPart[], exec?: (op: string, args: unknown[]) => unknown, w?: number) => void;
147
+ /** The suggestions the document holds, oldest first. */
148
+ records: () => SuggestionRecord[];
149
+ /** Whether the document holds any suggestion record. */
150
+ any: () => boolean;
151
+ /** Every pending change, in document order. */
152
+ changes: () => SuggestedChange[];
153
+ /** The pending changes of block `b` (`[]`: none). */
154
+ at: (b: BlockId) => readonly SuggestedChange[];
155
+ /** Bumped by every change of the records. */
156
+ version: () => number;
157
+ /** Be told of every change of the records. Returns the unsubscribe. */
158
+ onChange: (f: () => void) => () => undefined;
159
+ /** @internal The work done (blocks read, units walked): the scaling rows count it. */
160
+ debug: {
161
+ computes: number;
162
+ units: number;
163
+ };
164
+ dispose: () => void;
165
+ };
166
+ export type DocSuggest = ReturnType<typeof docSuggest>;
167
+ export {};