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.
- package/README.md +2 -2
- package/dist/block/block.svelte.js +6 -21
- package/dist/block/inlineBlock.svelte.js +4 -6
- package/dist/clipboard/moveText.js +6 -8
- package/dist/cloudflare/DocumentRoom.d.ts +10 -3
- package/dist/cloudflare/index.d.ts +1 -1
- package/dist/cloudflare/room/access.d.ts +8 -3
- package/dist/cloudflare/room/access.js +44 -20
- package/dist/cloudflare/room/admission.js +28 -5
- package/dist/cloudflare/room/comments.js +28 -1
- package/dist/cloudflare/room/context.d.ts +106 -109
- package/dist/cloudflare/room/context.js +10 -3
- package/dist/cloudflare/room/forged.d.ts +14 -0
- package/dist/cloudflare/room/forged.js +30 -2
- package/dist/cloudflare/room/frames.d.ts +4 -0
- package/dist/cloudflare/room/frames.js +5 -1
- package/dist/cloudflare/room/purge.js +2 -1
- package/dist/cloudflare/room/replicas.d.ts +4 -2
- package/dist/cloudflare/room/replicas.js +8 -3
- package/dist/cloudflare/room/suggest.d.ts +7 -0
- package/dist/cloudflare/room/suggest.js +143 -0
- package/dist/cloudflare/routeDocumentSocket.d.ts +10 -1
- package/dist/cloudflare/routeDocumentSocket.js +5 -3
- package/dist/components/Content.svelte +9 -1
- package/dist/crdt/anchors.js +3 -2
- package/dist/crdt/attribution/attribution.d.ts +3 -0
- package/dist/crdt/attribution/attribution.js +3 -3
- package/dist/crdt/doc/funnel.d.ts +1 -1
- package/dist/crdt/doc/funnel.js +5 -2
- package/dist/crdt/doc/gate.d.ts +1 -1
- package/dist/crdt/doc/history.d.ts +6 -0
- package/dist/crdt/doc/history.js +79 -59
- package/dist/crdt/doc/ops.d.ts +81 -0
- package/dist/crdt/doc/ops.js +1898 -0
- package/dist/crdt/doc/reads.d.ts +2 -2
- package/dist/crdt/doc/reads.js +18 -28
- package/dist/crdt/doc/suggest.d.ts +167 -0
- package/dist/crdt/doc/suggest.js +579 -0
- package/dist/crdt/document.d.ts +10 -1
- package/dist/crdt/document.js +19 -11
- package/dist/crdt/edytor-doc.d.ts +294 -272
- package/dist/crdt/edytor-doc.js +123 -108
- package/dist/crdt/engine-api.d.ts +8 -2
- package/dist/crdt/engine.d.ts +2 -1
- package/dist/crdt/engine.js +3 -1
- package/dist/crdt/flow.d.ts +5 -47
- package/dist/crdt/flow.js +3 -269
- package/dist/crdt/index.d.ts +102 -108
- package/dist/crdt/index.js +3 -0
- package/dist/crdt/operations.d.ts +13 -4
- package/dist/crdt/parts.d.ts +43 -0
- package/dist/crdt/parts.js +44 -0
- package/dist/crdt/placement/display.d.ts +1 -1
- package/dist/crdt/placement/display.js +3 -3
- package/dist/crdt/placement/keys.d.ts +5 -0
- package/dist/crdt/placement/keys.js +5 -0
- package/dist/crdt/placement/resolve.d.ts +1 -1
- package/dist/crdt/placement/resolve.js +2 -1
- package/dist/crdt/protocol.d.ts +1 -1
- package/dist/crdt/protocol.js +1 -1
- package/dist/crdt/protocols/auth.d.ts +11 -1
- package/dist/crdt/protocols/auth.js +17 -1
- package/dist/crdt/protocols/awareness.js +46 -81
- package/dist/crdt/protocols/comments.d.ts +16 -1
- package/dist/crdt/protocols/comments.js +9 -1
- package/dist/crdt/providers/index.d.ts +12 -22
- package/dist/crdt/providers/index.js +3 -1
- package/dist/crdt/providers/indexeddb.d.ts +6 -10
- package/dist/crdt/providers/indexeddb.js +10 -16
- package/dist/crdt/providers/room.d.ts +11 -0
- package/dist/crdt/providers/room.js +26 -12
- package/dist/crdt/providers/websocket.d.ts +8 -12
- package/dist/crdt/providers/websocket.js +17 -19
- package/dist/crdt/purge.d.ts +7 -1
- package/dist/crdt/purge.js +32 -2
- package/dist/crdt/rangeDelete.d.ts +2 -47
- package/dist/crdt/rangeDelete.js +1 -169
- package/dist/crdt/restore.d.ts +2 -1
- package/dist/crdt/restore.js +9 -0
- package/dist/crdt/schema.d.ts +9 -1
- package/dist/crdt/schema.js +13 -3
- package/dist/crdt/structs.d.ts +2 -0
- package/dist/crdt/structs.js +2 -0
- package/dist/crdt/text/index/build.d.ts +125 -0
- package/dist/crdt/text/index/build.js +2895 -0
- package/dist/crdt/text/index/shared.d.ts +2 -6
- package/dist/crdt/text/index/shared.js +19 -19
- package/dist/crdt/text/model.d.ts +10 -0
- package/dist/crdt/text/model.js +10 -4
- package/dist/crdt/text/runs.d.ts +43 -42
- package/dist/crdt/text/runs.js +2 -165
- package/dist/crdt/vendor/yjs/UPSTREAM.md +83 -0
- package/dist/crdt/vendor/yjs/dts/index.d.ts +1 -1
- package/dist/crdt/vendor/yjs/dts/structs/Item.d.ts +6 -3
- package/dist/crdt/vendor/yjs/dts/ynode.d.ts +13 -2
- package/dist/crdt/vendor/yjs/src/index.js +1 -1
- package/dist/crdt/vendor/yjs/src/structs/Item.js +44 -5
- package/dist/crdt/vendor/yjs/src/ynode.js +29 -7
- package/dist/edytor.svelte.d.ts +1 -1
- package/dist/edytor.svelte.js +100 -75
- package/dist/events/beforeInputCommands.d.ts +2 -2
- package/dist/events/domTextOffset.d.ts +2 -0
- package/dist/events/domTextOffset.js +8 -0
- package/dist/events/nativeInteractiveControl.d.ts +11 -1
- package/dist/events/nativeInteractiveControl.js +41 -1
- package/dist/events/onBeforeInput.js +3 -3
- package/dist/events/onFocus.js +9 -11
- package/dist/export/forms.d.ts +75 -75
- package/dist/index.d.ts +4 -2
- package/dist/index.js +1 -1
- package/dist/labels.d.ts +8 -0
- package/dist/labels.js +6 -1
- package/dist/plugins/comments/CommentsController.svelte.d.ts +5 -1
- package/dist/plugins/comments/CommentsController.svelte.js +14 -4
- package/dist/plugins/find/search.js +2 -2
- package/dist/plugins/index.d.ts +1 -0
- package/dist/plugins/index.js +1 -0
- package/dist/plugins/richtext/RichTextPlugin.svelte +63 -61
- package/dist/plugins/richtext/richTextOperations.js +26 -32
- package/dist/plugins/suggestions/SuggestionBars.svelte +40 -23
- package/dist/plugins/suggestions/SuggestionBars.svelte.d.ts +3 -1
- package/dist/plugins/suggestions/SuggestionRuns.svelte +77 -0
- package/dist/plugins/suggestions/SuggestionRuns.svelte.d.ts +9 -0
- package/dist/plugins/suggestions/shared.svelte.d.ts +58 -0
- package/dist/plugins/suggestions/shared.svelte.js +421 -0
- package/dist/plugins/suggestions/suggestionsPlugin.d.ts +15 -4
- package/dist/selection/domSelection.d.ts +2 -0
- package/dist/selection/domSelection.js +6 -2
- package/dist/selection/pointer.svelte.js +75 -48
- package/dist/selection/replaceSelection.js +2 -6
- package/dist/selection/selection.svelte.d.ts +3 -3
- package/dist/selection/selection.svelte.js +39 -32
- package/dist/selection/selection.utils.d.ts +14 -0
- package/dist/selection/selection.utils.js +33 -11
- package/dist/session/commands.js +21 -11
- package/dist/session/composition.svelte.d.ts +5 -3
- package/dist/session/composition.svelte.js +21 -17
- package/dist/session/handles.d.ts +4 -17
- package/dist/session/handles.js +14 -44
- package/dist/session/navigation.js +6 -9
- package/dist/session/selection.d.ts +11 -5
- package/dist/session/selection.js +14 -48
- package/dist/session/suggestions.svelte.d.ts +38 -9
- package/dist/session/suggestions.svelte.js +37 -18
- package/dist/session/virtual.d.ts +1 -1
- package/dist/surface/attributes.d.ts +5 -0
- package/dist/surface/attributes.js +2 -2
- package/dist/surface/cells.d.ts +2 -26
- package/dist/surface/cells.js +2 -33
- package/dist/surface/observer.svelte.d.ts +6 -1
- package/dist/surface/observer.svelte.js +143 -111
- package/dist/surface/pin.svelte.d.ts +9 -9
- package/dist/surface/pin.svelte.js +15 -22
- package/dist/surface/projector.svelte.js +10 -16
- package/dist/text/text.svelte.js +14 -19
- package/dist/themes/notion.css +29 -0
- package/dist/utils.d.ts +5 -0
- package/dist/utils.js +7 -0
- package/package.json +3 -1
- package/dist/crdt/doc/capability.d.ts +0 -56
- package/dist/crdt/doc/capability.js +0 -211
- package/dist/crdt/doc/content.d.ts +0 -16
- package/dist/crdt/doc/content.js +0 -77
- package/dist/crdt/doc/delete.d.ts +0 -15
- package/dist/crdt/doc/delete.js +0 -84
- package/dist/crdt/doc/layout.d.ts +0 -9
- package/dist/crdt/doc/layout.js +0 -178
- package/dist/crdt/doc/meta.d.ts +0 -19
- package/dist/crdt/doc/meta.js +0 -199
- package/dist/crdt/doc/moves.d.ts +0 -21
- package/dist/crdt/doc/moves.js +0 -274
- package/dist/crdt/doc/split-merge.d.ts +0 -10
- package/dist/crdt/doc/split-merge.js +0 -179
- package/dist/crdt/doc/steps.d.ts +0 -65
- package/dist/crdt/doc/steps.js +0 -311
- package/dist/crdt/text/index/cache.d.ts +0 -16
- package/dist/crdt/text/index/cache.js +0 -175
- package/dist/crdt/text/index/claims.d.ts +0 -18
- package/dist/crdt/text/index/claims.js +0 -225
- package/dist/crdt/text/index/fold.d.ts +0 -21
- package/dist/crdt/text/index/fold.js +0 -656
- package/dist/crdt/text/index/layout.d.ts +0 -24
- package/dist/crdt/text/index/layout.js +0 -271
- package/dist/crdt/text/index/placement.d.ts +0 -47
- package/dist/crdt/text/index/placement.js +0 -741
- package/dist/crdt/text/index/records.d.ts +0 -13
- package/dist/crdt/text/index/records.js +0 -139
- package/dist/crdt/text/index/report.d.ts +0 -18
- package/dist/crdt/text/index/report.js +0 -337
- package/dist/crdt/text/index/state.d.ts +0 -197
- package/dist/crdt/text/index/state.js +0 -116
- package/dist/crdt/text/index/streams.d.ts +0 -25
- 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:
|
|
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:
|
|
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
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
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
|
-
|
|
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/
|
|
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
|
-
|
|
207
|
-
|
|
208
|
-
|
|
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: (
|
|
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
|
-
|
|
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" | "
|
|
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" | "
|
|
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" | "
|
|
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" | "
|
|
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
|
-
|
|
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" | "
|
|
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" | "
|
|
536
|
-
once<NAME extends "refused" | "status" | "failed" | "
|
|
537
|
-
off<NAME extends "refused" | "status" | "failed" | "
|
|
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
|
-
/**
|
|
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
|
-
/**
|
|
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
|
-
|
|
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)));
|
|
@@ -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
|
-
|
|
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
|
+
};
|