edytor 4.0.0 → 6.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (193) 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 +106 -109
  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/funnel.d.ts +1 -1
  29. package/dist/crdt/doc/funnel.js +5 -2
  30. package/dist/crdt/doc/gate.d.ts +1 -1
  31. package/dist/crdt/doc/history.d.ts +6 -0
  32. package/dist/crdt/doc/history.js +79 -59
  33. package/dist/crdt/doc/ops.d.ts +81 -0
  34. package/dist/crdt/doc/ops.js +1898 -0
  35. package/dist/crdt/doc/reads.d.ts +2 -2
  36. package/dist/crdt/doc/reads.js +18 -28
  37. package/dist/crdt/doc/suggest.d.ts +167 -0
  38. package/dist/crdt/doc/suggest.js +579 -0
  39. package/dist/crdt/document.d.ts +10 -1
  40. package/dist/crdt/document.js +19 -11
  41. package/dist/crdt/edytor-doc.d.ts +294 -272
  42. package/dist/crdt/edytor-doc.js +123 -108
  43. package/dist/crdt/engine-api.d.ts +8 -2
  44. package/dist/crdt/engine.d.ts +2 -1
  45. package/dist/crdt/engine.js +3 -1
  46. package/dist/crdt/flow.d.ts +5 -47
  47. package/dist/crdt/flow.js +3 -269
  48. package/dist/crdt/index.d.ts +102 -108
  49. package/dist/crdt/index.js +3 -0
  50. package/dist/crdt/operations.d.ts +13 -4
  51. package/dist/crdt/parts.d.ts +43 -0
  52. package/dist/crdt/parts.js +44 -0
  53. package/dist/crdt/placement/display.d.ts +1 -1
  54. package/dist/crdt/placement/display.js +3 -3
  55. package/dist/crdt/placement/keys.d.ts +5 -0
  56. package/dist/crdt/placement/keys.js +5 -0
  57. package/dist/crdt/placement/resolve.d.ts +1 -1
  58. package/dist/crdt/placement/resolve.js +2 -1
  59. package/dist/crdt/protocol.d.ts +1 -1
  60. package/dist/crdt/protocol.js +1 -1
  61. package/dist/crdt/protocols/auth.d.ts +11 -1
  62. package/dist/crdt/protocols/auth.js +17 -1
  63. package/dist/crdt/protocols/awareness.js +46 -81
  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 +12 -22
  67. package/dist/crdt/providers/index.js +3 -1
  68. package/dist/crdt/providers/indexeddb.d.ts +6 -10
  69. package/dist/crdt/providers/indexeddb.js +10 -16
  70. package/dist/crdt/providers/room.d.ts +11 -0
  71. package/dist/crdt/providers/room.js +26 -12
  72. package/dist/crdt/providers/websocket.d.ts +8 -12
  73. package/dist/crdt/providers/websocket.js +17 -19
  74. package/dist/crdt/purge.d.ts +7 -1
  75. package/dist/crdt/purge.js +32 -2
  76. package/dist/crdt/rangeDelete.d.ts +2 -47
  77. package/dist/crdt/rangeDelete.js +1 -169
  78. package/dist/crdt/restore.d.ts +2 -1
  79. package/dist/crdt/restore.js +9 -0
  80. package/dist/crdt/schema.d.ts +9 -1
  81. package/dist/crdt/schema.js +13 -3
  82. package/dist/crdt/structs.d.ts +2 -0
  83. package/dist/crdt/structs.js +2 -0
  84. package/dist/crdt/text/index/build.d.ts +125 -0
  85. package/dist/crdt/text/index/build.js +2895 -0
  86. package/dist/crdt/text/index/shared.d.ts +2 -6
  87. package/dist/crdt/text/index/shared.js +19 -19
  88. package/dist/crdt/text/model.d.ts +10 -0
  89. package/dist/crdt/text/model.js +10 -4
  90. package/dist/crdt/text/runs.d.ts +43 -42
  91. package/dist/crdt/text/runs.js +2 -165
  92. package/dist/crdt/vendor/yjs/UPSTREAM.md +83 -0
  93. package/dist/crdt/vendor/yjs/dts/index.d.ts +1 -1
  94. package/dist/crdt/vendor/yjs/dts/structs/Item.d.ts +6 -3
  95. package/dist/crdt/vendor/yjs/dts/ynode.d.ts +13 -2
  96. package/dist/crdt/vendor/yjs/src/index.js +1 -1
  97. package/dist/crdt/vendor/yjs/src/structs/Item.js +44 -5
  98. package/dist/crdt/vendor/yjs/src/ynode.js +29 -7
  99. package/dist/edytor.svelte.d.ts +1 -1
  100. package/dist/edytor.svelte.js +100 -75
  101. package/dist/events/beforeInputCommands.d.ts +2 -2
  102. package/dist/events/domTextOffset.d.ts +2 -0
  103. package/dist/events/domTextOffset.js +8 -0
  104. package/dist/events/nativeInteractiveControl.d.ts +11 -1
  105. package/dist/events/nativeInteractiveControl.js +41 -1
  106. package/dist/events/onBeforeInput.js +3 -3
  107. package/dist/events/onFocus.js +9 -11
  108. package/dist/export/forms.d.ts +75 -75
  109. package/dist/index.d.ts +4 -2
  110. package/dist/index.js +1 -1
  111. package/dist/labels.d.ts +8 -0
  112. package/dist/labels.js +6 -1
  113. package/dist/plugins/comments/CommentsController.svelte.d.ts +5 -1
  114. package/dist/plugins/comments/CommentsController.svelte.js +14 -4
  115. package/dist/plugins/find/search.js +2 -2
  116. package/dist/plugins/index.d.ts +1 -0
  117. package/dist/plugins/index.js +1 -0
  118. package/dist/plugins/richtext/RichTextPlugin.svelte +63 -61
  119. package/dist/plugins/richtext/richTextOperations.js +26 -32
  120. package/dist/plugins/suggestions/SuggestionBars.svelte +40 -23
  121. package/dist/plugins/suggestions/SuggestionBars.svelte.d.ts +3 -1
  122. package/dist/plugins/suggestions/SuggestionRuns.svelte +77 -0
  123. package/dist/plugins/suggestions/SuggestionRuns.svelte.d.ts +9 -0
  124. package/dist/plugins/suggestions/shared.svelte.d.ts +58 -0
  125. package/dist/plugins/suggestions/shared.svelte.js +421 -0
  126. package/dist/plugins/suggestions/suggestionsPlugin.d.ts +15 -4
  127. package/dist/selection/domSelection.d.ts +2 -0
  128. package/dist/selection/domSelection.js +6 -2
  129. package/dist/selection/pointer.svelte.js +75 -48
  130. package/dist/selection/replaceSelection.js +2 -6
  131. package/dist/selection/selection.svelte.d.ts +3 -3
  132. package/dist/selection/selection.svelte.js +39 -32
  133. package/dist/selection/selection.utils.d.ts +14 -0
  134. package/dist/selection/selection.utils.js +33 -11
  135. package/dist/session/commands.js +21 -11
  136. package/dist/session/composition.svelte.d.ts +5 -3
  137. package/dist/session/composition.svelte.js +21 -17
  138. package/dist/session/handles.d.ts +4 -17
  139. package/dist/session/handles.js +14 -44
  140. package/dist/session/navigation.js +6 -9
  141. package/dist/session/selection.d.ts +11 -5
  142. package/dist/session/selection.js +14 -48
  143. package/dist/session/suggestions.svelte.d.ts +38 -9
  144. package/dist/session/suggestions.svelte.js +37 -18
  145. package/dist/session/virtual.d.ts +1 -1
  146. package/dist/surface/attributes.d.ts +5 -0
  147. package/dist/surface/attributes.js +2 -2
  148. package/dist/surface/cells.d.ts +2 -26
  149. package/dist/surface/cells.js +2 -33
  150. package/dist/surface/observer.svelte.d.ts +6 -1
  151. package/dist/surface/observer.svelte.js +143 -111
  152. package/dist/surface/pin.svelte.d.ts +9 -9
  153. package/dist/surface/pin.svelte.js +15 -22
  154. package/dist/surface/projector.svelte.js +10 -16
  155. package/dist/text/text.svelte.js +14 -19
  156. package/dist/themes/notion.css +29 -0
  157. package/dist/utils.d.ts +5 -0
  158. package/dist/utils.js +7 -0
  159. package/package.json +3 -1
  160. package/dist/crdt/doc/capability.d.ts +0 -56
  161. package/dist/crdt/doc/capability.js +0 -211
  162. package/dist/crdt/doc/content.d.ts +0 -16
  163. package/dist/crdt/doc/content.js +0 -77
  164. package/dist/crdt/doc/delete.d.ts +0 -15
  165. package/dist/crdt/doc/delete.js +0 -84
  166. package/dist/crdt/doc/layout.d.ts +0 -9
  167. package/dist/crdt/doc/layout.js +0 -178
  168. package/dist/crdt/doc/meta.d.ts +0 -19
  169. package/dist/crdt/doc/meta.js +0 -199
  170. package/dist/crdt/doc/moves.d.ts +0 -21
  171. package/dist/crdt/doc/moves.js +0 -274
  172. package/dist/crdt/doc/split-merge.d.ts +0 -10
  173. package/dist/crdt/doc/split-merge.js +0 -179
  174. package/dist/crdt/doc/steps.d.ts +0 -65
  175. package/dist/crdt/doc/steps.js +0 -311
  176. package/dist/crdt/text/index/cache.d.ts +0 -16
  177. package/dist/crdt/text/index/cache.js +0 -175
  178. package/dist/crdt/text/index/claims.d.ts +0 -18
  179. package/dist/crdt/text/index/claims.js +0 -225
  180. package/dist/crdt/text/index/fold.d.ts +0 -21
  181. package/dist/crdt/text/index/fold.js +0 -656
  182. package/dist/crdt/text/index/layout.d.ts +0 -24
  183. package/dist/crdt/text/index/layout.js +0 -271
  184. package/dist/crdt/text/index/placement.d.ts +0 -47
  185. package/dist/crdt/text/index/placement.js +0 -741
  186. package/dist/crdt/text/index/records.d.ts +0 -13
  187. package/dist/crdt/text/index/records.js +0 -139
  188. package/dist/crdt/text/index/report.d.ts +0 -18
  189. package/dist/crdt/text/index/report.js +0 -337
  190. package/dist/crdt/text/index/state.d.ts +0 -197
  191. package/dist/crdt/text/index/state.js +0 -116
  192. package/dist/crdt/text/index/streams.d.ts +0 -25
  193. package/dist/crdt/text/index/streams.js +0 -248
@@ -28,7 +28,7 @@ export declare const crdt: {
28
28
  Awareness: typeof import("../../index.js").Awareness;
29
29
  doc: {
30
30
  SCHEMA: {
31
- readonly version: 10;
31
+ readonly version: 11;
32
32
  readonly name: "edytor-doc";
33
33
  readonly roots: {
34
34
  readonly registry: "blocks";
@@ -39,7 +39,7 @@ export declare const crdt: {
39
39
  readonly schema: "schema";
40
40
  };
41
41
  };
42
- SCHEMA_VERSION: 10;
42
+ SCHEMA_VERSION: 11;
43
43
  SCHEMA_NAME: "edytor-doc";
44
44
  META_KEY: "meta";
45
45
  init: (doc: E.EngineDoc, opts?: {
@@ -55,48 +55,36 @@ export declare const crdt: {
55
55
  assertSchema: (doc: E.EngineDoc, docName?: string) => void;
56
56
  SchemaMismatchError: typeof E.SchemaMismatchError;
57
57
  create: (doc: E.EngineDoc, config?: import("../../crdt/edytor-doc.js").EdytorDocConfig) => {
58
- prepare: {
59
- insertFlow: (target: import("../../index.js").FlowTarget, flow: import("../../index.js").Flow, view?: import("../../index.js").FlowView) => import("../../index.js").Prepared;
60
- deleteRange: (from: import("../../index.js").DocPosition, to: import("../../index.js").DocPosition, view?: import("../../index.js").RangeView) => import("../../index.js").Prepared;
61
- replaceRange: (from: import("../../index.js").DocPosition, to: import("../../index.js").DocPosition, view?: import("../../index.js").RangeView) => import("../../index.js").Prepared;
62
- insertBlocks: (dest: import("../../index.js").Destination, specs: readonly (import("../../index.js").BlockSpec | import("../../index.js").JSONBlock)[]) => import("../../index.js").Prepared;
63
- moveBlocks: (ids: readonly import("../../index.js").BlockId[], dest: import("../../index.js").Destination) => import("../../index.js").Prepared;
64
- nestBlock: (id: import("../../index.js").BlockId, parent: import("../../index.js").BlockId) => import("../../index.js").Prepared;
65
- unNestBlock: (id: import("../../index.js").BlockId) => import("../../index.js").Prepared;
66
- unNestBlocks: (ids: readonly import("../../index.js").BlockId[]) => import("../../index.js").Prepared;
67
- liftOut: (id: import("../../index.js").BlockId, kind: string, { keep, after }?: {
68
- keep?: boolean;
69
- after?: readonly import("../../index.js").BlockSpec[];
70
- }) => import("../../index.js").Prepared;
71
- placeBeside: (ids: readonly import("../../index.js").BlockId[], target: import("../../index.js").BlockId, side: "left" | "right", kind?: string) => import("../../index.js").Prepared;
72
- wrapInLayout: (ids: readonly import("../../index.js").BlockId[], kind?: string, columns?: number) => import("../../index.js").Prepared;
73
- splitBlock: (id: import("../../index.js").BlockId, offset: number, newId: import("../../index.js").BlockId, tail?: import("../../index.js").SplitTail) => import("../../index.js").Prepared;
74
- mergeBlocks: (fromId: import("../../index.js").BlockId, intoId: import("../../index.js").BlockId) => import("../../index.js").Prepared;
75
- mergeBackward: (id: import("../../index.js").BlockId) => import("../../index.js").Prepared;
76
- mergeForward: (id: import("../../index.js").BlockId) => import("../../index.js").Prepared;
77
- deleteBlock: (id: import("../../index.js").BlockId, opts?: {
78
- keepChildren?: boolean;
79
- }) => import("../../index.js").Prepared;
80
- setBlock: (id: import("../../index.js").BlockId, value: {
81
- type?: string;
82
- data?: Record<string, unknown>;
83
- content?: (import("../../index.js").ContentItem | import("../../index.js").JSONText | import("../../index.js").JSONInlineBlock)[];
84
- children?: (import("../../index.js").BlockSpec | import("../../index.js").JSONBlock)[];
85
- }) => import("../../index.js").Prepared;
86
- setBlockType: (id: import("../../index.js").BlockId, type: string) => import("../../index.js").Prepared;
87
- patchData: (target: import("../../index.js").DataTarget, patches: readonly import("../../index.js").DataPatch[]) => import("../../index.js").Prepared;
88
- duplicateBlock: (id: import("../../index.js").BlockId, freshId?: (oldId: string, kind: "block" | "inline") => string) => import("../../index.js").Prepared;
89
- insertText: (id: import("../../index.js").BlockId, offset: number, text: string, marks?: Record<string, unknown>) => import("../../index.js").Prepared;
90
- deleteText: (id: import("../../index.js").BlockId, offset: number, length: number) => import("../../index.js").Prepared;
91
- formatRange: (id: import("../../index.js").BlockId, offset: number, length: number, marks: Record<string, unknown>) => import("../../index.js").Prepared;
92
- clearMarks: (id: import("../../index.js").BlockId, offset: number, length: number) => import("../../index.js").Prepared;
93
- insertInline: (id: import("../../index.js").BlockId, offset: number, atom: import("../../crdt/doc/content.js").NewInline) => import("../../index.js").Prepared;
94
- removeInline: (id: import("../../index.js").BlockId, inlineId: string) => import("../../index.js").Prepared;
95
- deleteBlocks: (ids: readonly import("../../index.js").BlockId[]) => import("../../index.js").Prepared;
96
- };
97
- apply: (p: import("../../index.js").Prepared) => import("../../index.js").OpResult;
98
- compose: (...parts: import("../../index.js").Prepared[]) => import("../../index.js").Prepared;
99
- transact: <R>(fn: () => R, origin?: unknown) => R;
58
+ init: (opts?: Parameters<(doc: E.EngineDoc, opts?: {
59
+ content?: import("../../index.js").BlockSpec[];
60
+ defaultType?: string;
61
+ }) => void>[1]) => void;
62
+ seed: (value: import("../../index.js").JSONBlock[], data?: import("../../crdt/doc/types.js").JsonObj) => void;
63
+ isInitialized: () => boolean;
64
+ schemaVersion: () => number | undefined;
65
+ checkSchema: () => E.SchemaProblem | null;
66
+ assertSchema: () => void;
67
+ dispose: () => void;
68
+ createUndoManager: (options?: import("../../crdt/doc/history.js").HistoryOptions) => import("../../crdt/doc/history.js").UndoManager;
69
+ part: import("../../crdt/doc/suggest.js").SuggestContext;
70
+ childSlots: (parent: import("../../index.js").BlockId | null) => import("../../crdt/placement/model.js").ChildSlot[];
71
+ slotOf: (id: string) => {
72
+ parent: import("../../index.js").BlockId | null;
73
+ rank: string;
74
+ } | null;
75
+ crdtId: (id: string) => string | null;
76
+ resolveBlock: (id: string) => E.EngineNode | null;
77
+ followUndo: (anchor: import("../../index.js").DocAnchor) => import("../../index.js").DocAnchor;
78
+ rolesChanged: (place?: boolean) => void;
79
+ defaultChild: (id: string | null) => string;
80
+ contentJSON: (id: string) => ({
81
+ text: string;
82
+ marks?: Record<string, unknown>;
83
+ } | {
84
+ id?: string;
85
+ type: string;
86
+ data?: unknown;
87
+ })[];
100
88
  model: {
101
89
  REGISTRY_KEY: string;
102
90
  registryOf: (doc: E.EngineDoc) => E.EngineNode;
@@ -166,19 +154,62 @@ export declare const crdt: {
166
154
  };
167
155
  };
168
156
  runsView: import("../../crdt/text/runs.js").RunView;
157
+ api: object;
158
+ } & {
159
+ prepare: {
160
+ nestBlock: (id: import("../../index.js").BlockId, parent: import("../../index.js").BlockId) => import("../../index.js").Prepared;
161
+ deleteBlocks: (ids: readonly import("../../index.js").BlockId[]) => import("../../index.js").Prepared;
162
+ insertBlocks: (dest: import("../../index.js").Destination, specs: readonly (import("../../index.js").BlockSpec | import("../../index.js").JSONBlock)[]) => import("../../index.js").Prepared;
163
+ moveBlocks: (ids: readonly import("../../index.js").BlockId[], dest: import("../../index.js").Destination) => import("../../index.js").Prepared;
164
+ unNestBlocks: (ids: readonly import("../../index.js").BlockId[]) => import("../../index.js").Prepared;
165
+ unNestBlock: (id: import("../../index.js").BlockId) => import("../../index.js").Prepared;
166
+ liftOut: (id: import("../../index.js").BlockId, kind: string, { keep, after }?: {
167
+ keep?: boolean;
168
+ after?: readonly import("../../index.js").BlockSpec[];
169
+ }) => import("../../index.js").Prepared;
170
+ duplicateBlock: (id: import("../../index.js").BlockId, freshId?: (oldId: string, kind: "block" | "inline") => string) => import("../../index.js").Prepared;
171
+ placeBeside: (ids: readonly import("../../index.js").BlockId[], target: import("../../index.js").BlockId, side: "left" | "right", kind?: string) => import("../../index.js").Prepared;
172
+ wrapInLayout: (ids: readonly import("../../index.js").BlockId[], kind?: string, columns?: number) => import("../../index.js").Prepared;
173
+ splitBlock: (id: import("../../index.js").BlockId, offset: number, newId: import("../../index.js").BlockId, tail?: import("../../index.js").SplitTail) => import("../../index.js").Prepared;
174
+ mergeBlocks: (fromId: import("../../index.js").BlockId, intoId: import("../../index.js").BlockId) => import("../../index.js").Prepared;
175
+ mergeBackward: (id: import("../../index.js").BlockId) => import("../../index.js").Prepared;
176
+ mergeForward: (id: import("../../index.js").BlockId) => import("../../index.js").Prepared;
177
+ deleteBlock: (id: import("../../index.js").BlockId, opts?: {
178
+ keepChildren?: boolean;
179
+ }) => import("../../index.js").Prepared;
180
+ setBlockType: (id: import("../../index.js").BlockId, type: string) => import("../../index.js").Prepared;
181
+ patchData: (target: import("../../index.js").DataTarget, patches: readonly import("../../index.js").DataPatch[]) => import("../../index.js").Prepared;
182
+ setBlock: (id: import("../../index.js").BlockId, value: {
183
+ type?: string;
184
+ data?: Record<string, unknown>;
185
+ content?: (import("../../index.js").ContentItem | import("../../index.js").JSONText | import("../../index.js").JSONInlineBlock)[];
186
+ children?: (import("../../index.js").BlockSpec | import("../../index.js").JSONBlock)[];
187
+ }) => import("../../index.js").Prepared;
188
+ insertText: (id: import("../../index.js").BlockId, offset: number, text: string, marks?: Record<string, unknown>) => import("../../index.js").Prepared;
189
+ deleteText: (id: import("../../index.js").BlockId, offset: number, length: number) => import("../../index.js").Prepared;
190
+ formatRange: (id: import("../../index.js").BlockId, offset: number, length: number, marks: Record<string, unknown>) => import("../../index.js").Prepared;
191
+ clearMarks: (id: import("../../index.js").BlockId, offset: number, length: number) => import("../../index.js").Prepared;
192
+ insertInline: (id: import("../../index.js").BlockId, offset: number, atom: import("../../crdt/doc/ops.js").NewInline) => import("../../index.js").Prepared;
193
+ removeInline: (id: import("../../index.js").BlockId, inlineId: string) => import("../../index.js").Prepared;
194
+ insertFlow: (target: import("../../index.js").FlowTarget, flow: import("../../index.js").Flow, view?: import("../../index.js").FlowView) => import("../../index.js").Prepared;
195
+ deleteRange: (from: import("../../index.js").DocPosition, to: import("../../index.js").DocPosition, view?: import("../../index.js").RangeView) => import("../../index.js").Prepared;
196
+ replaceRange: (from: import("../../index.js").DocPosition, to: import("../../index.js").DocPosition, view?: import("../../index.js").RangeView) => import("../../index.js").Prepared;
197
+ };
198
+ apply: (p: import("../../index.js").Prepared, quiet?: boolean) => import("../../index.js").OpResult;
199
+ compose: (...parts: import("../../index.js").Prepared[]) => import("../../index.js").Prepared;
200
+ transact: <R>(fn: () => R, origin?: unknown) => R;
169
201
  version: number;
170
- insertFlow: (target: import("../../index.js").FlowTarget, flow: import("../../index.js").Flow, view?: import("../../index.js").FlowView | undefined) => import("../../index.js").OpResult;
171
- deleteRange: (from: import("../../index.js").DocPosition, to: import("../../index.js").DocPosition, view?: import("../../index.js").RangeView | undefined) => import("../../index.js").OpResult;
172
- replaceRange: (from: import("../../index.js").DocPosition, to: import("../../index.js").DocPosition, view?: import("../../index.js").RangeView | undefined) => import("../../index.js").OpResult;
173
- insertBlocks: (dest: import("../../index.js").Destination, specs: readonly (import("../../index.js").BlockSpec | import("../../index.js").JSONBlock)[]) => import("../../index.js").OpResult;
174
- moveBlocks: (ids: readonly string[], dest: import("../../index.js").Destination) => import("../../index.js").OpResult;
175
202
  nestBlock: (id: string, parent: string) => import("../../index.js").OpResult;
176
- unNestBlock: (id: string) => import("../../index.js").OpResult;
203
+ deleteBlocks: (ids: readonly string[]) => import("../../index.js").OpResult;
204
+ insertBlocks: (dest: import("../../index.js").Destination, specs: readonly (import("../../index.js").JSONBlock | import("../../index.js").BlockSpec)[]) => import("../../index.js").OpResult;
205
+ moveBlocks: (ids: readonly string[], dest: import("../../index.js").Destination) => import("../../index.js").OpResult;
177
206
  unNestBlocks: (ids: readonly string[]) => import("../../index.js").OpResult;
207
+ unNestBlock: (id: string) => import("../../index.js").OpResult;
178
208
  liftOut: (id: string, kind: string, args_2?: {
179
209
  keep?: boolean;
180
210
  after?: readonly import("../../index.js").BlockSpec[];
181
211
  } | undefined) => import("../../index.js").OpResult;
212
+ duplicateBlock: (id: string, freshId?: ((oldId: string, kind: "block" | "inline") => string) | undefined) => import("../../index.js").OpResult;
182
213
  placeBeside: (ids: readonly string[], target: string, side: "left" | "right", kind?: string | undefined) => import("../../index.js").OpResult;
183
214
  wrapInLayout: (ids: readonly string[], kind?: string | undefined, columns?: number | undefined) => import("../../index.js").OpResult;
184
215
  splitBlock: (id: string, offset: number, newId: string, tail?: import("../../index.js").SplitTail | undefined) => import("../../index.js").OpResult;
@@ -188,42 +219,29 @@ export declare const crdt: {
188
219
  deleteBlock: (id: string, opts?: {
189
220
  keepChildren?: boolean;
190
221
  } | undefined) => import("../../index.js").OpResult;
222
+ setBlockType: (id: string, type: string) => import("../../index.js").OpResult;
223
+ patchData: (target: import("../../index.js").DataTarget, patches: readonly import("../../index.js").DataPatch[]) => import("../../index.js").OpResult;
191
224
  setBlock: (id: string, value: {
192
225
  type?: string;
193
226
  data?: Record<string, unknown>;
194
227
  content?: (import("../../index.js").ContentItem | import("../../index.js").JSONText | import("../../index.js").JSONInlineBlock)[];
195
228
  children?: (import("../../index.js").BlockSpec | import("../../index.js").JSONBlock)[];
196
229
  }) => import("../../index.js").OpResult;
197
- setBlockType: (id: string, type: string) => import("../../index.js").OpResult;
198
- patchData: (target: import("../../index.js").DataTarget, patches: readonly import("../../index.js").DataPatch[]) => import("../../index.js").OpResult;
199
- duplicateBlock: (id: string, freshId?: ((oldId: string, kind: "block" | "inline") => string) | undefined) => import("../../index.js").OpResult;
200
230
  insertText: (id: string, offset: number, text: string, marks?: Record<string, unknown> | undefined) => import("../../index.js").OpResult;
201
231
  deleteText: (id: string, offset: number, length: number) => import("../../index.js").OpResult;
202
232
  formatRange: (id: string, offset: number, length: number, marks: Record<string, unknown>) => import("../../index.js").OpResult;
203
233
  clearMarks: (id: string, offset: number, length: number) => import("../../index.js").OpResult;
204
- insertInline: (id: string, offset: number, atom: import("../../crdt/doc/content.js").NewInline) => import("../../index.js").OpResult;
234
+ insertInline: (id: string, offset: number, atom: import("../../crdt/doc/ops.js").NewInline) => import("../../index.js").OpResult;
205
235
  removeInline: (id: string, inlineId: string) => import("../../index.js").OpResult;
206
- deleteBlocks: (ids: readonly string[]) => import("../../index.js").OpResult;
207
- init: (opts?: Parameters<(doc: E.EngineDoc, opts?: {
208
- content?: import("../../index.js").BlockSpec[];
209
- defaultType?: string;
210
- }) => void>[1]) => void;
211
- seed: (value: import("../../index.js").JSONBlock[], data?: import("../../crdt/doc/types.js").JsonObj) => void;
212
- isInitialized: () => boolean;
213
- schemaVersion: () => number | undefined;
214
- checkSchema: () => E.SchemaProblem | null;
215
- assertSchema: () => void;
216
- dispose: () => void;
217
- createUndoManager: (options?: import("../../crdt/doc/history.js").HistoryOptions) => import("../../crdt/doc/history.js").UndoManager;
236
+ insertFlow: (target: import("../../index.js").FlowTarget, flow: import("../../index.js").Flow, view?: import("../../index.js").FlowView | undefined) => import("../../index.js").OpResult;
237
+ deleteRange: (from: import("../../index.js").DocPosition, to: import("../../index.js").DocPosition, view?: import("../../index.js").RangeView | undefined) => import("../../index.js").OpResult;
238
+ replaceRange: (from: import("../../index.js").DocPosition, to: import("../../index.js").DocPosition, view?: import("../../index.js").RangeView | undefined) => import("../../index.js").OpResult;
218
239
  project: () => import("../../index.js").ProjectedDoc;
219
- toJSON: () => JSONDoc;
240
+ toJSON: (options?: {
241
+ suggestions?: boolean;
242
+ } | undefined) => JSONDoc;
220
243
  blockJSON: (id: string) => import("../../index.js").JSONBlock;
221
244
  childrenIds: (id: string | null) => string[];
222
- childSlots: (parent: import("../../index.js").BlockId | null) => import("../../crdt/placement/model.js").ChildSlot[];
223
- slotOf: (id: string) => {
224
- parent: import("../../index.js").BlockId | null;
225
- rank: string;
226
- } | null;
227
245
  positionOf: (id: string) => import("../../index.js").Destination | null;
228
246
  pathOf: (id: string) => number[] | null;
229
247
  parentOf: (id: string) => string | null;
@@ -241,8 +259,6 @@ export declare const crdt: {
241
259
  ids: (path: readonly string[]) => string[];
242
260
  } | null;
243
261
  blockAttribution: (id: string) => import("../../index.js").BlockAttribution | undefined;
244
- crdtId: (id: string) => string | null;
245
- resolveBlock: (id: string) => E.EngineNode | null;
246
262
  displayLength: (id: string) => number;
247
263
  contentItems: (id: string) => import("../../index.js").ContentItem[];
248
264
  hasBlock: (id: string) => boolean;
@@ -256,8 +272,6 @@ export declare const crdt: {
256
272
  blockId: import("../../index.js").BlockId;
257
273
  offset: number;
258
274
  } | null;
259
- followUndo: (anchor: import("../../index.js").DocAnchor) => import("../../index.js").DocAnchor;
260
- rolesChanged: () => void;
261
275
  isVoid: (id: string) => boolean;
262
276
  isIsland: (id: string) => boolean;
263
277
  isLines: (id: string) => boolean;
@@ -289,20 +303,11 @@ export declare const crdt: {
289
303
  parent: string | null;
290
304
  levels: string[];
291
305
  };
292
- defaultChild: (id: string | null) => string;
293
306
  runs: (id: string) => readonly import("../../index.js").ContentRun[];
294
- contentJSON: (id: string) => ({
295
- text: string;
296
- marks?: Record<string, unknown>;
297
- } | {
298
- id?: string;
299
- type: string;
300
- data?: unknown;
301
- })[];
302
307
  onChange: (cb: (change: import("../../index.js").DocChange) => void) => (() => void);
303
308
  };
304
309
  newDoc: (opts?: ConstructorParameters<E.EngineApi["Doc"]>[0]) => YDoc;
305
- purge: (doc: E.EngineDoc, facade: {
310
+ purge: (doc: E.EngineDoc, facade: Partial<import("../../crdt/doc/suggest.js").SuggestFacade> & {
306
311
  model: import("../../crdt/placement/model.js").PlacementModel;
307
312
  text: import("../../crdt/text/model.js").TextEngine;
308
313
  }, horizon: import("../../crdt/purge.js").Horizon | null) => import("../index.js").PurgeReport;
@@ -402,17 +407,12 @@ export declare const crdt: {
402
407
  loadError: unknown;
403
408
  _storeTimeout: number;
404
409
  _storeTimeoutId: ReturnType<typeof setTimeout> | null;
405
- _storeUpdate: (update: Uint8Array, origin: unknown) => void;
410
+ _unlisten: () => void;
406
411
  awareness: import("../../index.js").Awareness;
407
412
  bcconnected: boolean;
408
413
  disableBc: boolean;
409
414
  _ownsAwareness: boolean;
410
415
  _bcSubscriber: (data: ArrayBuffer | Uint8Array, origin: unknown) => void;
411
- _awarenessUpdateHandler: (updates: {
412
- added: number[];
413
- updated: number[];
414
- removed: number[];
415
- }, origin: unknown) => void;
416
416
  get synced(): boolean;
417
417
  messageHandlers: Record<number, import("../../crdt/providers/room.js").RoomMessageHandler</*elided*/ any>>;
418
418
  readMessage: (buf: Uint8Array, emitSynced: boolean) => E.Encoder;
@@ -420,7 +420,7 @@ export declare const crdt: {
420
420
  connectBc(): void;
421
421
  disconnectBc(): void;
422
422
  destroy(): Promise<void>;
423
- emit<N extends "failed" | "schema-mismatch" | "message-error" | "protocol-mismatch" | "synced" | "load-error">(name: N, args: Parameters<{
423
+ emit<N extends "failed" | "message-error" | "schema-mismatch" | "protocol-mismatch" | "synced" | "load-error">(name: N, args: Parameters<{
424
424
  synced: (provider: /*elided*/ any) => void;
425
425
  'protocol-mismatch': (mismatch: E.ProtocolMismatch, provider: /*elided*/ any) => void;
426
426
  'load-error': (error: unknown, provider: /*elided*/ any) => void;
@@ -429,7 +429,7 @@ export declare const crdt: {
429
429
  failed: (error: unknown, provider: /*elided*/ any) => void;
430
430
  }[N]>): void;
431
431
  _observers: Map<string, Set<any>>;
432
- on<NAME extends "failed" | "schema-mismatch" | "message-error" | "protocol-mismatch" | "synced" | "load-error">(name: NAME, f: {
432
+ on<NAME extends "failed" | "message-error" | "schema-mismatch" | "protocol-mismatch" | "synced" | "load-error">(name: NAME, f: {
433
433
  synced: (provider: /*elided*/ any) => void;
434
434
  'protocol-mismatch': (mismatch: E.ProtocolMismatch, provider: /*elided*/ any) => void;
435
435
  'load-error': (error: unknown, provider: /*elided*/ any) => void;
@@ -444,7 +444,7 @@ export declare const crdt: {
444
444
  'schema-mismatch': (detail: E.SchemaMismatchDetail, provider: /*elided*/ any) => void;
445
445
  failed: (error: unknown, provider: /*elided*/ any) => void;
446
446
  }[NAME];
447
- once<NAME extends "failed" | "schema-mismatch" | "message-error" | "protocol-mismatch" | "synced" | "load-error">(name: NAME, f: {
447
+ once<NAME extends "failed" | "message-error" | "schema-mismatch" | "protocol-mismatch" | "synced" | "load-error">(name: NAME, f: {
448
448
  synced: (provider: /*elided*/ any) => void;
449
449
  'protocol-mismatch': (mismatch: E.ProtocolMismatch, provider: /*elided*/ any) => void;
450
450
  'load-error': (error: unknown, provider: /*elided*/ any) => void;
@@ -452,7 +452,7 @@ export declare const crdt: {
452
452
  'schema-mismatch': (detail: E.SchemaMismatchDetail, provider: /*elided*/ any) => void;
453
453
  failed: (error: unknown, provider: /*elided*/ any) => void;
454
454
  }[NAME]): void;
455
- off<NAME extends "failed" | "schema-mismatch" | "message-error" | "protocol-mismatch" | "synced" | "load-error">(name: NAME, f: {
455
+ off<NAME extends "failed" | "message-error" | "schema-mismatch" | "protocol-mismatch" | "synced" | "load-error">(name: NAME, f: {
456
456
  synced: (provider: /*elided*/ any) => void;
457
457
  'protocol-mismatch': (mismatch: E.ProtocolMismatch, provider: /*elided*/ any) => void;
458
458
  'load-error': (error: unknown, provider: /*elided*/ any) => void;
@@ -513,14 +513,7 @@ export declare const crdt: {
513
513
  _resync: ReturnType<typeof setInterval> | undefined;
514
514
  _connectTimer: ReturnType<typeof setTimeout> | undefined;
515
515
  _checkInterval: ReturnType<typeof setInterval>;
516
- _updateHandler: (update: Uint8Array, origin: unknown, doc?: unknown, transaction?: {
517
- local: boolean;
518
- }) => void;
519
- _awarenessUpdateHandler: (updates: {
520
- added: number[];
521
- updated: number[];
522
- removed: number[];
523
- }, origin: unknown) => void;
516
+ _unlisten: () => void;
524
517
  get url(): string;
525
518
  get unsaved(): number;
526
519
  get saved(): boolean;
@@ -530,11 +523,11 @@ export declare const crdt: {
530
523
  destroy(): void;
531
524
  disconnect(): void;
532
525
  connect(): void;
533
- emit<N extends "refused" | "status" | "failed" | "schema-mismatch" | "message-error" | "protocol-mismatch" | "synced" | "connection-close" | "connection-error" | "saved" | "permission-denied" | "expired" | "unreachable">(name: N, args: Parameters<E.WebsocketProviderEvents[N]>): void;
526
+ emit<N extends "refused" | "status" | "failed" | "message-error" | "schema-mismatch" | "protocol-mismatch" | "synced" | "access" | "connection-close" | "connection-error" | "saved" | "permission-denied" | "expired" | "unreachable">(name: N, args: Parameters<E.WebsocketProviderEvents[N]>): void;
534
527
  _observers: Map<string, Set<any>>;
535
- on<NAME extends "refused" | "status" | "failed" | "schema-mismatch" | "message-error" | "protocol-mismatch" | "synced" | "connection-close" | "connection-error" | "saved" | "permission-denied" | "expired" | "unreachable">(name: NAME, f: E.WebsocketProviderEvents[NAME]): E.WebsocketProviderEvents[NAME];
536
- once<NAME extends "refused" | "status" | "failed" | "schema-mismatch" | "message-error" | "protocol-mismatch" | "synced" | "connection-close" | "connection-error" | "saved" | "permission-denied" | "expired" | "unreachable">(name: NAME, f: E.WebsocketProviderEvents[NAME]): void;
537
- off<NAME extends "refused" | "status" | "failed" | "schema-mismatch" | "message-error" | "protocol-mismatch" | "synced" | "connection-close" | "connection-error" | "saved" | "permission-denied" | "expired" | "unreachable">(name: NAME, f: E.WebsocketProviderEvents[NAME]): void;
528
+ on<NAME extends "refused" | "status" | "failed" | "message-error" | "schema-mismatch" | "protocol-mismatch" | "synced" | "access" | "connection-close" | "connection-error" | "saved" | "permission-denied" | "expired" | "unreachable">(name: NAME, f: E.WebsocketProviderEvents[NAME]): E.WebsocketProviderEvents[NAME];
529
+ once<NAME extends "refused" | "status" | "failed" | "message-error" | "schema-mismatch" | "protocol-mismatch" | "synced" | "access" | "connection-close" | "connection-error" | "saved" | "permission-denied" | "expired" | "unreachable">(name: NAME, f: E.WebsocketProviderEvents[NAME]): void;
530
+ off<NAME extends "refused" | "status" | "failed" | "message-error" | "schema-mismatch" | "protocol-mismatch" | "synced" | "access" | "connection-close" | "connection-error" | "saved" | "permission-denied" | "expired" | "unreachable">(name: NAME, f: E.WebsocketProviderEvents[NAME]): void;
538
531
  };
539
532
  };
540
533
  watchComments: (server: string | null, roomName: string, listener: (message: E.CommentMessage) => void) => (() => void);
@@ -695,6 +688,7 @@ export declare class RoomContext {
695
688
  claims: number;
696
689
  merged: number;
697
690
  released: number;
691
+ suggestions: number;
698
692
  };
699
693
  since: number;
700
694
  };
@@ -726,7 +720,10 @@ export declare class RoomContext {
726
720
  get lookups(): ReturnType<typeof lookups>;
727
721
  /** The digest of the room's block roles a client's advertised one is compared with. */
728
722
  get digest(): Record<string, string>;
729
- /** A facade over `doc` obeying the room's block roles (`semantics`). */
723
+ /**
724
+ * A facade over `doc` obeying the room's block roles (`semantics`), its
725
+ * shared suggestions built: its `toJSON()` leaves the pending ones out.
726
+ */
730
727
  facadeOf(doc: YDoc): EdytorDoc;
731
728
  /**
732
729
  * The facade over the live document. Read while the room is idle, it
@@ -11,6 +11,7 @@ import { Y } from '../../crdt/engine.js';
11
11
  import * as E from '../../crdt/protocol.js';
12
12
  import { CLOSE } from '../../crdt/providers/room.js';
13
13
  import { asEngineDoc } from '../../crdt/structs.js';
14
+ import { suggestionsOf } from '../../crdt/doc/suggest.js';
14
15
  import { defaultSemantics, facadeConfigOf, semanticsDigest } from '../../crdt/semantics.js';
15
16
  import { MAX_REFUSALS, ROOM_ORIGIN, SOCKET_TAG, noTimers } from './shared.js';
16
17
  /** The engine API the room is built on (the Worker-safe CRDT entry). */
@@ -53,7 +54,8 @@ const counters = () => ({
53
54
  records: 0,
54
55
  claims: 0,
55
56
  merged: 0,
56
- released: 0
57
+ released: 0,
58
+ suggestions: 0
57
59
  },
58
60
  since: Date.now()
59
61
  });
@@ -132,9 +134,14 @@ export class RoomContext {
132
134
  get digest() {
133
135
  return (this.#_digest ??= semanticsDigest(this.options.semantics ?? defaultSemantics));
134
136
  }
135
- /** A facade over `doc` obeying the room's block roles (`semantics`). */
137
+ /**
138
+ * A facade over `doc` obeying the room's block roles (`semantics`), its
139
+ * shared suggestions built: its `toJSON()` leaves the pending ones out.
140
+ */
136
141
  facadeOf(doc) {
137
- return crdt.doc.create(asEngineDoc(doc), this.lookups);
142
+ const facade = crdt.doc.create(asEngineDoc(doc), this.lookups);
143
+ suggestionsOf(facade);
144
+ return facade;
138
145
  }
139
146
  /**
140
147
  * The facade over the live document. Read while the room is idle, it
@@ -1,5 +1,10 @@
1
1
  import type { YDoc } from '../../crdt/index.js';
2
2
  import type { Decoded, Struct } from './context.js';
3
+ type Id = {
4
+ client: number;
5
+ clock: number;
6
+ };
7
+ export declare const isId: (value: unknown) => value is Id;
3
8
  /**
4
9
  * The clients of a frame (but `skip`) that write a per-writer block mark
5
10
  * of another writer: a struct whose key is `del.<n>` or `wd.<n>` on a
@@ -39,6 +44,14 @@ export type AttributionWrites = {
39
44
  * it again (`#bindOrphan`).
40
45
  */
41
46
  export declare const attributionWrites: (doc: YDoc, structs: Struct[], skip: Set<number>, user: string, owns: (client: number) => boolean, ownerOf: (client: number) => string | undefined) => AttributionWrites;
47
+ /**
48
+ * The suggestion writers of a frame that bind themselves to `user`: `n`
49
+ * writes a record in the suggestions' root and `c/<n>` naming `user` — a
50
+ * suggestion writer's first frame registers it as the user's
51
+ * (`sugg.writer.binding`). Any other self-bound id stays a replica's,
52
+ * claimed only by its own dial.
53
+ */
54
+ export declare const selfBound: (doc: YDoc, structs: Struct[], user: string) => Set<number>;
42
55
  /**
43
56
  * Of a frame's deletes, those of live attribution entries `user` may not
44
57
  * delete, with their keys: a binding of a replica the user does not own
@@ -48,3 +61,4 @@ export declare const forgedAttributionDeletes: (doc: YDoc, ds: Decoded["ds"], us
48
61
  ids: Decoded["ds"];
49
62
  keys: string[];
50
63
  };
64
+ export {};
@@ -7,7 +7,7 @@
7
7
  * find.
8
8
  */
9
9
  import { Y } from '../../crdt/engine.js';
10
- import { ATTRIBUTION_ROOT, DEL_PREFIX, HORIZON_ROOT, REGISTRY_KEY, WITHDRAW_PREFIX } from '../../crdt/schema.js';
10
+ import { ATTRIBUTION_ROOT, DEL_PREFIX, HORIZON_ROOT, REGISTRY_KEY, SUGGEST_ROOT, WITHDRAW_PREFIX } from '../../crdt/schema.js';
11
11
  import { heldClock, runsOf, storedStruct, structAt } from './updates.js';
12
12
  // ── Per-writer marks ──────────────────────────────────────────
13
13
  /** The writer `n` of a per-writer block mark key (`del.<n>`, `wd.<n>`), or `null`. */
@@ -22,7 +22,7 @@ const markWriter = (key) => {
22
22
  const digits = prefix === null ? '' : key.slice(prefix.length);
23
23
  return /^\d{1,16}$/.test(digits) ? Number(digits) : null;
24
24
  };
25
- const isId = (value) => typeof value === 'object' &&
25
+ export const isId = (value) => typeof value === 'object' &&
26
26
  value !== null &&
27
27
  typeof value.client === 'number' &&
28
28
  typeof value.clock === 'number' &&
@@ -198,6 +198,34 @@ export const attributionWrites = (doc, structs, skip, user, owns, ownerOf) => {
198
198
  }
199
199
  return writes;
200
200
  };
201
+ /**
202
+ * The suggestion writers of a frame that bind themselves to `user`: `n`
203
+ * writes a record in the suggestions' root and `c/<n>` naming `user` — a
204
+ * suggestion writer's first frame registers it as the user's
205
+ * (`sugg.writer.binding`). Any other self-bound id stays a replica's,
206
+ * claimed only by its own dial.
207
+ */
208
+ export const selfBound = (doc, structs, user) => {
209
+ const frame = runsOf(structs);
210
+ const records = new Set();
211
+ const bound = new Set();
212
+ for (const struct of structs) {
213
+ if (!(struct instanceof Y.Item))
214
+ continue;
215
+ const place = placeOf(doc, frame, struct.id);
216
+ if (place?.key == null)
217
+ continue;
218
+ const { parent } = place;
219
+ if (parent === SUGGEST_ROOT || (parent != null && parent === doc.share.get(SUGGEST_ROOT)))
220
+ records.add(struct.id.client);
221
+ if (!isAttribution(doc, parent))
222
+ continue;
223
+ const content = struct.content.getContent();
224
+ if (boundReplica(place.key) === struct.id.client && content[content.length - 1] === user)
225
+ bound.add(struct.id.client);
226
+ }
227
+ return new Set([...bound].filter((client) => records.has(client)));
228
+ };
201
229
  /**
202
230
  * Of a frame's deletes, those of live attribution entries `user` may not
203
231
  * delete, with their keys: a binding of a replica the user does not own
@@ -27,5 +27,9 @@ export declare const updateFrame: (update: Uint8Array) => Uint8Array;
27
27
  export declare const readOnlyFrame: () => Uint8Array;
28
28
  /** The denial of a read-only socket's write: it stays, and still syncs. */
29
29
  export declare const readOnlyDenialFrame: () => Uint8Array;
30
+ /** The denial of what a suggest-only socket may not write (stripped): it stays, and still syncs. */
31
+ export declare const suggestOnlyDenialFrame: () => Uint8Array;
32
+ /** The socket's access, at the join and at a change in place (`write`, `suggest`, `comment`, `read`). */
33
+ export declare const accessFrame: (access: string) => Uint8Array;
30
34
  /** A Step2 of what the room STORED: the engine's pending store (never stored) is left out. */
31
35
  export declare const storedStep2: (doc: YDoc, sv: Uint8Array) => Uint8Array;
@@ -4,7 +4,7 @@
4
4
  * room's.
5
5
  */
6
6
  import * as encoding from 'lib0-v14/encoding';
7
- import { READ_ONLY_DENIAL } from '../../crdt/protocols/auth.js';
7
+ import { READ_ONLY_DENIAL, SUGGEST_ONLY_DENIAL } from '../../crdt/protocols/auth.js';
8
8
  import * as E from '../../crdt/protocol.js';
9
9
  import { sync } from './context.js';
10
10
  import { withoutPending } from './updates.js';
@@ -49,5 +49,9 @@ export const updateFrame = (update) => E.frame(E.messageSync, (e) => sync.writeU
49
49
  export const readOnlyFrame = () => E.frame(E.messageAuth, (e) => E.writeReadOnly(e));
50
50
  /** The denial of a read-only socket's write: it stays, and still syncs. */
51
51
  export const readOnlyDenialFrame = () => E.frame(E.messageAuth, (e) => E.writePermissionDenied(e, READ_ONLY_DENIAL));
52
+ /** The denial of what a suggest-only socket may not write (stripped): it stays, and still syncs. */
53
+ export const suggestOnlyDenialFrame = () => E.frame(E.messageAuth, (e) => E.writePermissionDenied(e, SUGGEST_ONLY_DENIAL));
54
+ /** The socket's access, at the join and at a change in place (`write`, `suggest`, `comment`, `read`). */
55
+ export const accessFrame = (access) => E.frame(E.messageAuth, (e) => E.writeAccess(e, access));
52
56
  /** A Step2 of what the room STORED: the engine's pending store (never stored) is left out. */
53
57
  export const storedStep2 = (doc, sv) => withoutPending(doc, () => E.frame(E.messageSync, (e) => sync.writeSyncStep2(e, doc, sv)));
@@ -125,7 +125,8 @@ export class RoomPurge {
125
125
  'records',
126
126
  'claims',
127
127
  'merged',
128
- 'released'
128
+ 'released',
129
+ 'suggestions'
129
130
  ];
130
131
  // Nothing an ended session deleted was left: no compaction, no run.
131
132
  if (horizon === null && !wrote)
@@ -28,14 +28,16 @@ export declare class ReplicaRegistry {
28
28
  * stripped from its frame (the rest of the frame is applied: never
29
29
  * refused whole). Written: its user's ids, and its own replica (the
30
30
  * dialed or bound one), which claims an unowned id or a fresh one, as
31
- * `bind` would. A socket with no replica claims fresh ids it writes.
31
+ * `bind` would. A socket with no replica claims fresh ids it writes, and
32
+ * any socket a fresh id that binds itself to its user in the frame
33
+ * (`bound`: a suggestion's writer).
32
34
  * Any other id is relayed — another replica's structs, which a restore
33
35
  * from a lagging snapshot may have lost: kept, and left unowned (`''`,
34
36
  * claimable only by its own dial), when the room holds none of that id's
35
37
  * clocks and no user owns it; stripped otherwise (logged `replica`).
36
38
  * Ownership never moves to a relayer.
37
39
  */
38
- attribute({ user, replica }: Attachment, writers: Set<number>, sv: Map<number, number>, orphans: Set<number>): Set<number>;
40
+ attribute({ user, replica }: Attachment, writers: Set<number>, sv: Map<number, number>, orphans: Set<number>, bound?: Set<number>): Set<number>;
39
41
  /**
40
42
  * Bind the sender's replicas whose `c/<n>` a frame set to another actor
41
43
  * to its verified user (`room.attribution.trust`): one room write after the frame's, which
@@ -75,14 +75,16 @@ export class ReplicaRegistry {
75
75
  * stripped from its frame (the rest of the frame is applied: never
76
76
  * refused whole). Written: its user's ids, and its own replica (the
77
77
  * dialed or bound one), which claims an unowned id or a fresh one, as
78
- * `bind` would. A socket with no replica claims fresh ids it writes.
78
+ * `bind` would. A socket with no replica claims fresh ids it writes, and
79
+ * any socket a fresh id that binds itself to its user in the frame
80
+ * (`bound`: a suggestion's writer).
79
81
  * Any other id is relayed — another replica's structs, which a restore
80
82
  * from a lagging snapshot may have lost: kept, and left unowned (`''`,
81
83
  * claimable only by its own dial), when the room holds none of that id's
82
84
  * clocks and no user owns it; stripped otherwise (logged `replica`).
83
85
  * Ownership never moves to a relayer.
84
86
  */
85
- attribute({ user, replica }, writers, sv, orphans) {
87
+ attribute({ user, replica }, writers, sv, orphans, bound = new Set()) {
86
88
  const room = this.room;
87
89
  const claimed = [];
88
90
  const relayed = [];
@@ -93,7 +95,10 @@ export class ReplicaRegistry {
93
95
  continue;
94
96
  const held = (sv.get(client) ?? 0) > 0;
95
97
  const fresh = owner === undefined && !held;
96
- if (client === replica ? fresh || owner === '' : replica === null && fresh) {
98
+ // A fresh id the frame binds to its user by itself (a suggestion's writer) is the user's.
99
+ if (client === replica
100
+ ? fresh || owner === ''
101
+ : (replica === null || bound.has(client)) && fresh) {
97
102
  claimed.push({ replica: client, user });
98
103
  if (owner === '')
99
104
  orphans.add(client);
@@ -0,0 +1,7 @@
1
+ import type { YDoc } from '../../crdt/index.js';
2
+ import type { Decoded } from './context.js';
3
+ /** What a frame of a suggest-only socket may not write: the clients to strip, the deletes to drop. */
4
+ export declare const suggestOnly: (doc: YDoc, { structs, ds }: Decoded, skip: Set<number>, owns: (client: number) => boolean, replica: number | null) => {
5
+ strip: Set<number>;
6
+ deletes: Decoded["ds"];
7
+ };