edytor 0.0.11 → 0.1.0-next.16
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 +77 -197
- package/dist/block/block.svelte.d.ts +156 -69
- package/dist/block/block.svelte.js +324 -355
- package/dist/block/block.utils.d.ts +191 -24
- package/dist/block/block.utils.js +327 -460
- package/dist/block/contentRange.d.ts +4 -0
- package/dist/block/contentRange.js +20 -0
- package/dist/block/inlineBlock.svelte.d.ts +26 -19
- package/dist/block/inlineBlock.svelte.js +91 -39
- package/dist/clipboard/clipboard.d.ts +4 -0
- package/dist/clipboard/clipboard.js +4 -0
- package/dist/clipboard/createClipboardFragment.d.ts +3 -0
- package/dist/clipboard/createClipboardFragment.js +103 -0
- package/dist/clipboard/fragmentData.d.ts +6 -0
- package/dist/clipboard/fragmentData.js +74 -0
- package/dist/clipboard/htmlFlow.d.ts +22 -0
- package/dist/clipboard/htmlFlow.js +167 -0
- package/dist/clipboard/insertClipboardFragment.d.ts +18 -0
- package/dist/clipboard/insertClipboardFragment.js +48 -0
- package/dist/clipboard/serializeClipboardFragment.d.ts +7 -0
- package/dist/clipboard/serializeClipboardFragment.js +53 -0
- package/dist/clipboard/textBlocks.d.ts +23 -0
- package/dist/clipboard/textBlocks.js +103 -0
- package/dist/clipboard/types.d.ts +20 -0
- package/dist/clipboard/types.js +2 -0
- package/dist/cloudflare/DocumentRoom.d.ts +586 -0
- package/dist/cloudflare/DocumentRoom.js +1706 -0
- package/dist/cloudflare/index.d.ts +8 -0
- package/dist/cloudflare/index.js +8 -0
- package/dist/cloudflare/routeDocumentSocket.d.ts +33 -0
- package/dist/cloudflare/routeDocumentSocket.js +51 -0
- package/dist/collaboration/RemoteSelections.svelte +94 -0
- package/dist/collaboration/RemoteSelections.svelte.d.ts +7 -0
- package/dist/collaboration/awarenessSelection.d.ts +127 -0
- package/dist/collaboration/awarenessSelection.js +199 -0
- package/dist/collaboration/documentSync.d.ts +20 -0
- package/dist/collaboration/documentSync.js +13 -0
- package/dist/collaboration/index.d.ts +3 -0
- package/dist/collaboration/index.js +3 -0
- package/dist/collaboration/providers.d.ts +13 -0
- package/dist/collaboration/providers.js +21 -0
- package/dist/collaboration/remoteSelection.d.ts +21 -0
- package/dist/collaboration/remoteSelection.js +159 -0
- package/dist/components/Block.svelte +223 -15
- package/dist/components/Block.svelte.d.ts +4 -2
- package/dist/components/Content.svelte +128 -32
- package/dist/components/Content.svelte.d.ts +6 -2
- package/dist/components/Edytor.svelte +308 -110
- package/dist/components/Edytor.svelte.d.ts +64 -20
- package/dist/components/InlineBlock.svelte +38 -7
- package/dist/components/InlineBlock.svelte.d.ts +5 -2
- package/dist/components/Mark.svelte +29 -13
- package/dist/components/Mark.svelte.d.ts +4 -4
- package/dist/components/Suggestion.svelte +48 -0
- package/dist/components/Suggestion.svelte.d.ts +7 -0
- package/dist/components/SuggestionRanges.svelte +58 -0
- package/dist/components/SuggestionRanges.svelte.d.ts +7 -0
- package/dist/components/Text.svelte +107 -14
- package/dist/components/Text.svelte.d.ts +8 -1
- package/dist/constants.d.ts +0 -2
- package/dist/constants.js +0 -2
- package/dist/crdt/admission.d.ts +141 -0
- package/dist/crdt/admission.js +147 -0
- package/dist/crdt/anchors.d.ts +47 -0
- package/dist/crdt/anchors.js +42 -0
- package/dist/crdt/attribution/attribution.d.ts +169 -0
- package/dist/crdt/attribution/attribution.js +136 -0
- package/dist/crdt/attribution/block.d.ts +200 -0
- package/dist/crdt/attribution/block.js +327 -0
- package/dist/crdt/attribution/index.d.ts +9 -0
- package/dist/crdt/attribution/index.js +9 -0
- package/dist/crdt/data.d.ts +81 -0
- package/dist/crdt/data.js +383 -0
- package/dist/crdt/document.d.ts +590 -0
- package/dist/crdt/document.js +1160 -0
- package/dist/crdt/edytor-doc.d.ts +752 -0
- package/dist/crdt/edytor-doc.js +2382 -0
- package/dist/crdt/engine-api.d.ts +153 -0
- package/dist/crdt/engine.d.ts +37 -0
- package/dist/crdt/engine.js +50 -0
- package/dist/crdt/flow.d.ts +104 -0
- package/dist/crdt/flow.js +229 -0
- package/dist/crdt/index.d.ts +630 -0
- package/dist/crdt/index.js +168 -0
- package/dist/crdt/migration/legacy-schema.d.ts +61 -0
- package/dist/crdt/migration/legacy-schema.js +149 -0
- package/dist/crdt/migration/migrate.d.ts +67 -0
- package/dist/crdt/migration/migrate.js +219 -0
- package/dist/crdt/nodes.d.ts +120 -0
- package/dist/crdt/nodes.js +56 -0
- package/dist/crdt/placement/model.d.ts +383 -0
- package/dist/crdt/placement/model.js +811 -0
- package/dist/crdt/placement/rank.d.ts +57 -0
- package/dist/crdt/placement/rank.js +209 -0
- package/dist/crdt/protocols/auth.d.ts +28 -0
- package/dist/crdt/protocols/auth.js +43 -0
- package/dist/crdt/protocols/awareness.d.ts +87 -0
- package/dist/crdt/protocols/awareness.js +271 -0
- package/dist/crdt/protocols/envelope.d.ts +75 -0
- package/dist/crdt/protocols/envelope.js +89 -0
- package/dist/crdt/protocols/observable.d.ts +19 -0
- package/dist/crdt/protocols/observable.js +26 -0
- package/dist/crdt/protocols/sync.d.ts +82 -0
- package/dist/crdt/protocols/sync.js +288 -0
- package/dist/crdt/providers/container.d.ts +23 -0
- package/dist/crdt/providers/container.js +64 -0
- package/dist/crdt/providers/index.d.ts +282 -0
- package/dist/crdt/providers/index.js +118 -0
- package/dist/crdt/providers/indexeddb.d.ts +196 -0
- package/dist/crdt/providers/indexeddb.js +332 -0
- package/dist/crdt/providers/room.d.ts +193 -0
- package/dist/crdt/providers/room.js +444 -0
- package/dist/crdt/providers/websocket.d.ts +223 -0
- package/dist/crdt/providers/websocket.js +601 -0
- package/dist/crdt/rand.d.ts +22 -0
- package/dist/crdt/rand.js +22 -0
- package/dist/crdt/rangeDelete.d.ts +85 -0
- package/dist/crdt/rangeDelete.js +126 -0
- package/dist/crdt/schema.d.ts +96 -0
- package/dist/crdt/schema.js +79 -0
- package/dist/crdt/semantics.d.ts +81 -0
- package/dist/crdt/semantics.js +57 -0
- package/dist/crdt/structs.d.ts +106 -0
- package/dist/crdt/structs.js +119 -0
- package/dist/crdt/text/deletes.d.ts +23 -0
- package/dist/crdt/text/deletes.js +608 -0
- package/dist/crdt/text/model.d.ts +280 -0
- package/dist/crdt/text/model.js +554 -0
- package/dist/crdt/text/runs.d.ts +212 -0
- package/dist/crdt/text/runs.js +1142 -0
- package/dist/crdt/vendor/yjs/API-NOTES.md +59 -0
- package/dist/crdt/vendor/yjs/LICENSE +23 -0
- package/dist/crdt/vendor/yjs/UPSTREAM.md +653 -0
- package/dist/crdt/vendor/yjs/dts/global.d.ts +52 -0
- package/dist/crdt/vendor/yjs/dts/index.d.ts +25 -0
- package/dist/crdt/vendor/yjs/dts/structs/AbstractStruct.d.ts +38 -0
- package/dist/crdt/vendor/yjs/dts/structs/GC.d.ts +25 -0
- package/dist/crdt/vendor/yjs/dts/structs/Item.d.ts +748 -0
- package/dist/crdt/vendor/yjs/dts/structs/Skip.d.ts +30 -0
- package/dist/crdt/vendor/yjs/dts/utils/BlockSet.d.ts +34 -0
- package/dist/crdt/vendor/yjs/dts/utils/Doc.d.ts +198 -0
- package/dist/crdt/vendor/yjs/dts/utils/EventHandler.d.ts +17 -0
- package/dist/crdt/vendor/yjs/dts/utils/ID.d.ts +20 -0
- package/dist/crdt/vendor/yjs/dts/utils/RangeCursor.d.ts +198 -0
- package/dist/crdt/vendor/yjs/dts/utils/RelativePosition.d.ts +80 -0
- package/dist/crdt/vendor/yjs/dts/utils/StructStore.d.ts +61 -0
- package/dist/crdt/vendor/yjs/dts/utils/Transaction.d.ts +129 -0
- package/dist/crdt/vendor/yjs/dts/utils/UndoManager.d.ts +205 -0
- package/dist/crdt/vendor/yjs/dts/utils/UpdateDecoder.d.ts +170 -0
- package/dist/crdt/vendor/yjs/dts/utils/UpdateEncoder.d.ts +164 -0
- package/dist/crdt/vendor/yjs/dts/utils/YEvent.d.ts +93 -0
- package/dist/crdt/vendor/yjs/dts/utils/content-helper.d.ts +1 -0
- package/dist/crdt/vendor/yjs/dts/utils/encoding-helpers.d.ts +5 -0
- package/dist/crdt/vendor/yjs/dts/utils/encoding.d.ts +26 -0
- package/dist/crdt/vendor/yjs/dts/utils/ids.d.ts +407 -0
- package/dist/crdt/vendor/yjs/dts/utils/isParentOf.d.ts +1 -0
- package/dist/crdt/vendor/yjs/dts/utils/meta.d.ts +25 -0
- package/dist/crdt/vendor/yjs/dts/utils/renderer-helpers.d.ts +98 -0
- package/dist/crdt/vendor/yjs/dts/utils/schemas.d.ts +2 -0
- package/dist/crdt/vendor/yjs/dts/utils/transaction-helpers.d.ts +15 -0
- package/dist/crdt/vendor/yjs/dts/utils/updates.d.ts +70 -0
- package/dist/crdt/vendor/yjs/dts/ynode.d.ts +655 -0
- package/dist/crdt/vendor/yjs/global.d.ts +52 -0
- package/dist/crdt/vendor/yjs/src/index.js +64 -0
- package/dist/crdt/vendor/yjs/src/structs/AbstractStruct.js +64 -0
- package/dist/crdt/vendor/yjs/src/structs/GC.js +75 -0
- package/dist/crdt/vendor/yjs/src/structs/Item.js +1538 -0
- package/dist/crdt/vendor/yjs/src/structs/Skip.js +72 -0
- package/dist/crdt/vendor/yjs/src/utils/BlockSet.js +291 -0
- package/dist/crdt/vendor/yjs/src/utils/Doc.js +255 -0
- package/dist/crdt/vendor/yjs/src/utils/EventHandler.js +75 -0
- package/dist/crdt/vendor/yjs/src/utils/ID.js +59 -0
- package/dist/crdt/vendor/yjs/src/utils/RangeCursor.js +407 -0
- package/dist/crdt/vendor/yjs/src/utils/RelativePosition.js +301 -0
- package/dist/crdt/vendor/yjs/src/utils/StructStore.js +134 -0
- package/dist/crdt/vendor/yjs/src/utils/Transaction.js +458 -0
- package/dist/crdt/vendor/yjs/src/utils/UndoManager.js +554 -0
- package/dist/crdt/vendor/yjs/src/utils/UpdateDecoder.js +284 -0
- package/dist/crdt/vendor/yjs/src/utils/UpdateEncoder.js +323 -0
- package/dist/crdt/vendor/yjs/src/utils/YEvent.js +158 -0
- package/dist/crdt/vendor/yjs/src/utils/content-helper.js +0 -0
- package/dist/crdt/vendor/yjs/src/utils/encoding-helpers.js +110 -0
- package/dist/crdt/vendor/yjs/src/utils/encoding.js +662 -0
- package/dist/crdt/vendor/yjs/src/utils/ids.js +1504 -0
- package/dist/crdt/vendor/yjs/src/utils/isParentOf.js +19 -0
- package/dist/crdt/vendor/yjs/src/utils/meta.js +74 -0
- package/dist/crdt/vendor/yjs/src/utils/renderer-helpers.js +186 -0
- package/dist/crdt/vendor/yjs/src/utils/schemas.js +3 -0
- package/dist/crdt/vendor/yjs/src/utils/transaction-helpers.js +391 -0
- package/dist/crdt/vendor/yjs/src/utils/updates.js +264 -0
- package/dist/crdt/vendor/yjs/src/ynode.js +2897 -0
- package/dist/dnd/pragmatic.d.ts +22 -0
- package/dist/dnd/pragmatic.js +26 -0
- package/dist/edytor.svelte.d.ts +323 -54
- package/dist/edytor.svelte.js +771 -197
- package/dist/edytor.utils.d.ts +49 -2
- package/dist/edytor.utils.js +65 -76
- package/dist/events/beforeInputCommands.d.ts +21 -0
- package/dist/events/beforeInputCommands.js +328 -0
- package/dist/events/beforeInputDeleteCommands.d.ts +3 -0
- package/dist/events/beforeInputDeleteCommands.js +245 -0
- package/dist/events/dataTransferPayload.d.ts +6 -0
- package/dist/events/dataTransferPayload.js +9 -0
- package/dist/events/domTextOffset.d.ts +12 -0
- package/dist/events/domTextOffset.js +52 -0
- package/dist/events/events.utils.d.ts +3 -0
- package/dist/events/events.utils.js +13 -0
- package/dist/events/nativeInteractiveControl.d.ts +31 -0
- package/dist/events/nativeInteractiveControl.js +98 -0
- package/dist/events/onBeforeInput.d.ts +10 -1
- package/dist/events/onBeforeInput.js +449 -330
- package/dist/events/onCopy.d.ts +7 -0
- package/dist/events/onCopy.js +30 -0
- package/dist/events/onCut.d.ts +8 -0
- package/dist/events/onCut.js +13 -0
- package/dist/events/onDrop.d.ts +16 -0
- package/dist/events/onDrop.js +158 -0
- package/dist/events/onFocus.d.ts +4 -0
- package/dist/events/onFocus.js +166 -0
- package/dist/events/onInput.d.ts +20 -0
- package/dist/events/onInput.js +249 -0
- package/dist/events/onKeyDown.js +191 -11
- package/dist/events/onPaste.d.ts +3 -0
- package/dist/events/onPaste.js +108 -0
- package/dist/events/wordBoundary.d.ts +2 -0
- package/dist/events/wordBoundary.js +58 -0
- package/dist/index.d.ts +38 -1
- package/dist/index.js +36 -1
- package/dist/kinds.d.ts +100 -0
- package/dist/kinds.js +198 -0
- package/dist/plugins/arrowMove/arrowMove.d.ts +1 -1
- package/dist/plugins/arrowMove/arrowMove.js +30 -65
- package/dist/plugins/blockHandles/BlockHandle.svelte +152 -0
- package/dist/plugins/blockHandles/BlockHandle.svelte.d.ts +12 -0
- package/dist/plugins/blockHandles/BlockHandleController.svelte.d.ts +208 -0
- package/dist/plugins/blockHandles/BlockHandleController.svelte.js +823 -0
- package/dist/plugins/blockHandles/BlockHandles.svelte +151 -0
- package/dist/plugins/blockHandles/BlockHandles.svelte.d.ts +20 -0
- package/dist/plugins/blockHandles/autoScroll.d.ts +8 -0
- package/dist/plugins/blockHandles/autoScroll.js +25 -0
- package/dist/plugins/blockHandles/blockHandlesPlugin.d.ts +37 -0
- package/dist/plugins/blockHandles/blockHandlesPlugin.js +100 -0
- package/dist/plugins/blockHandles/dragPreview.d.ts +33 -0
- package/dist/plugins/blockHandles/dragPreview.js +228 -0
- package/dist/plugins/blockMenu/BlockMenu.svelte +301 -0
- package/dist/plugins/blockMenu/BlockMenu.svelte.d.ts +9 -0
- package/dist/plugins/blockMenu/BlockMenuController.svelte.d.ts +102 -0
- package/dist/plugins/blockMenu/BlockMenuController.svelte.js +245 -0
- package/dist/plugins/blockMenu/blockMenuPlugin.d.ts +11 -0
- package/dist/plugins/blockMenu/blockMenuPlugin.js +89 -0
- package/dist/plugins/code/CodePlugin.svelte +210 -163
- package/dist/plugins/code/CodePlugin.svelte.d.ts +1 -3
- package/dist/plugins/code/code.css +92 -0
- package/dist/plugins/icons.d.ts +2 -0
- package/dist/plugins/icons.js +31 -0
- package/dist/plugins/image/ImageEmpty.svelte +69 -0
- package/dist/plugins/image/ImageEmpty.svelte.d.ts +8 -0
- package/dist/plugins/image/ImagePlugin.svelte +74 -12
- package/dist/plugins/image/ImagePlugin.svelte.d.ts +15 -0
- package/dist/plugins/image/image.d.ts +2 -0
- package/dist/plugins/image/image.js +7 -0
- package/dist/plugins/index.d.ts +14 -1
- package/dist/plugins/index.js +10 -1
- package/dist/plugins/keepInView.d.ts +4 -0
- package/dist/plugins/keepInView.js +6 -0
- package/dist/plugins/markdownShortcuts.d.ts +3 -0
- package/dist/plugins/markdownShortcuts.js +104 -0
- package/dist/plugins/mention/MentionPlugin.svelte +28 -31
- package/dist/plugins/richtext/RichTextPlugin.svelte +411 -200
- package/dist/plugins/richtext/RichTextPlugin.svelte.d.ts +8 -7
- package/dist/plugins/richtext/richTextOperations.d.ts +53 -0
- package/dist/plugins/richtext/richTextOperations.js +200 -0
- package/dist/plugins/slashMenu/SlashMenu.svelte +297 -0
- package/dist/plugins/slashMenu/SlashMenu.svelte.d.ts +11 -0
- package/dist/plugins/slashMenu/SlashMenuController.svelte.d.ts +56 -0
- package/dist/plugins/slashMenu/SlashMenuController.svelte.js +275 -0
- package/dist/plugins/slashMenu/slashMenuPlugin.d.ts +25 -0
- package/dist/plugins/slashMenu/slashMenuPlugin.js +105 -0
- package/dist/plugins/suggestions/SuggestionBars.svelte +142 -0
- package/dist/plugins/suggestions/SuggestionBars.svelte.d.ts +10 -0
- package/dist/plugins/suggestions/suggestionsPlugin.d.ts +28 -0
- package/dist/plugins/suggestions/suggestionsPlugin.js +53 -0
- package/dist/plugins/toolbar/Toolbar.svelte +341 -0
- package/dist/plugins/toolbar/Toolbar.svelte.d.ts +9 -0
- package/dist/plugins/toolbar/ToolbarController.svelte.d.ts +85 -0
- package/dist/plugins/toolbar/ToolbarController.svelte.js +150 -0
- package/dist/plugins/toolbar/toolbarPlugin.d.ts +16 -0
- package/dist/plugins/toolbar/toolbarPlugin.js +40 -0
- package/dist/plugins.d.ts +249 -40
- package/dist/plugins.js +11 -5
- package/dist/selection/domSelection.d.ts +29 -0
- package/dist/selection/domSelection.js +230 -0
- package/dist/selection/replaceSelection.d.ts +143 -0
- package/dist/selection/replaceSelection.js +316 -0
- package/dist/selection/selection.svelte.d.ts +275 -37
- package/dist/selection/selection.svelte.js +1162 -331
- package/dist/selection/selection.utils.d.ts +35 -4
- package/dist/selection/selection.utils.js +309 -100
- package/dist/selection/visibility.d.ts +88 -0
- package/dist/selection/visibility.js +140 -0
- package/dist/session/attempt.d.ts +190 -0
- package/dist/session/attempt.js +188 -0
- package/dist/session/bindings.d.ts +16 -0
- package/dist/session/bindings.js +262 -0
- package/dist/session/commands.d.ts +158 -0
- package/dist/session/commands.js +601 -0
- package/dist/session/composition.svelte.d.ts +114 -0
- package/dist/session/composition.svelte.js +489 -0
- package/dist/session/editing/text.d.ts +33 -0
- package/dist/session/editing/text.js +36 -0
- package/dist/session/handles.d.ts +63 -0
- package/dist/session/handles.js +123 -0
- package/dist/session/history.d.ts +49 -0
- package/dist/session/history.js +131 -0
- package/dist/session/keymap.d.ts +42 -0
- package/dist/session/keymap.js +144 -0
- package/dist/session/moves.d.ts +32 -0
- package/dist/session/moves.js +116 -0
- package/dist/session/navigation.d.ts +51 -0
- package/dist/session/navigation.js +312 -0
- package/dist/session/props.d.ts +28 -0
- package/dist/session/props.js +162 -0
- package/dist/session/selection.d.ts +126 -0
- package/dist/session/selection.js +227 -0
- package/dist/session/suggestions.svelte.d.ts +125 -0
- package/dist/session/suggestions.svelte.js +329 -0
- package/dist/session/virtual.d.ts +33 -0
- package/dist/session/virtual.js +182 -0
- package/dist/surface/attributes.d.ts +36 -0
- package/dist/surface/attributes.js +143 -0
- package/dist/surface/cells.d.ts +103 -0
- package/dist/surface/cells.js +215 -0
- package/dist/surface/observer.svelte.d.ts +70 -0
- package/dist/surface/observer.svelte.js +969 -0
- package/dist/surface/overlay.d.ts +33 -0
- package/dist/surface/overlay.js +91 -0
- package/dist/surface/pin.svelte.d.ts +56 -0
- package/dist/surface/pin.svelte.js +108 -0
- package/dist/surface/projector.svelte.d.ts +69 -0
- package/dist/surface/projector.svelte.js +486 -0
- package/dist/text/deltas.d.ts +14 -3
- package/dist/text/deltas.js +27 -90
- package/dist/text/text.svelte.d.ts +43 -31
- package/dist/text/text.svelte.js +88 -69
- package/dist/text/text.utils.d.ts +7 -2
- package/dist/text/text.utils.js +121 -97
- package/dist/themes/notion.css +473 -0
- package/dist/utils/diffText.d.ts +15 -0
- package/dist/utils/diffText.js +26 -0
- package/dist/utils/json.d.ts +90 -3
- package/dist/utils/json.js +369 -2
- package/dist/utils.d.ts +3 -1
- package/dist/utils.js +2 -0
- package/package.json +112 -50
- package/dist/block/content.svelte.d.ts +0 -14
- package/dist/block/content.svelte.js +0 -40
- package/dist/components/ReadonlyEditor.svelte +0 -46
- package/dist/components/ReadonlyEditor.svelte.d.ts +0 -4
- package/dist/components/readonlyElements.svelte.d.ts +0 -82
- package/dist/components/readonlyElements.svelte.js +0 -144
- package/dist/dnd.svelte.d.ts +0 -17
- package/dist/dnd.svelte.js +0 -125
- package/dist/hotkeys.d.ts +0 -27
- package/dist/hotkeys.js +0 -282
- package/dist/localProvider.d.ts +0 -82
- package/dist/localProvider.js +0 -267
- package/dist/plugins/code/prism.css +0 -141
- package/dist/utils/jsx.d.ts +0 -25
- package/dist/utils/jsx.js +0 -66
- package/dist/utils/serialize.js +0 -1
- /package/dist/{utils/serialize.d.ts → crdt/engine-api.js} +0 -0
|
@@ -0,0 +1,586 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `DocumentRoom` — the Cloudflare Durable Object that coordinates ONE
|
|
3
|
+
* edytor document (one object per document) over hibernatable
|
|
4
|
+
* WebSockets. Clients are the shipped `WebsocketProvider` /
|
|
5
|
+
* `createWebsocketSync`; the host Worker reaches the room only through
|
|
6
|
+
* {@link routeDocumentSocket}, which authorizes the request and forwards
|
|
7
|
+
* the verified identity in the `X-Edytor-*` headers (and nothing the
|
|
8
|
+
* client sent).
|
|
9
|
+
*
|
|
10
|
+
* Built on the Worker-safe CRDT entry only (`crdt/index.ts` + the vendored
|
|
11
|
+
* engine). Entry point by entry point:
|
|
12
|
+
*
|
|
13
|
+
* - `fetch` (upgrade): read the verified identity, bind the socket's
|
|
14
|
+
* replica to its user (a replica another user owns is accepted, then
|
|
15
|
+
* closed `4409`), `ctx.acceptWebSocket` with the identity in the
|
|
16
|
+
* attachment, then our SyncStep1 (a read-only socket gets the
|
|
17
|
+
* read-only notice instead) and every present peer.
|
|
18
|
+
* - `webSocketMessage`: ADMIT first — the generation word, then the
|
|
19
|
+
* identity: a read-only socket's Step2/Update is refused (permission
|
|
20
|
+
* denied, the socket stays), and new structs under a client id its user
|
|
21
|
+
* does not own are stripped from the frame (a relay of an id the room
|
|
22
|
+
* holds nothing of is kept, unowned) — no attribution spoofing, and the
|
|
23
|
+
* sender's own edits still land. Then the inbound schema refusal
|
|
24
|
+
* (`sync.applyRemote`, which also judges what the engine holds pending:
|
|
25
|
+
* a pending forged stamp the update would release is discarded, never
|
|
26
|
+
* integrated). A refused frame
|
|
27
|
+
* is never applied, stored or relayed. Every sync message is answered
|
|
28
|
+
* with `messageSaved` (the room's state vector, and the deletes of the
|
|
29
|
+
* message it stored), sent after the write (store-before-ack). Presence
|
|
30
|
+
* is relayed through the instance-free codec, only for the socket's own
|
|
31
|
+
* replica. Only bytes that do not decode are refused `malformed`
|
|
32
|
+
* (1008); a storage or engine fault closes the socket 1011 (its
|
|
33
|
+
* provider redials), after rebuilding the document where it may hold
|
|
34
|
+
* what storage does not.
|
|
35
|
+
* - every INTEGRATED update is appended to SQLite as one record split into
|
|
36
|
+
* rows ≤ `maxRowBytes` (2 MB row cap) in one `transactionSync`, then
|
|
37
|
+
* broadcast; after `compactAfter` update records the rows are merged
|
|
38
|
+
* (`mergeUpdates`) into one snapshot record, after the message is
|
|
39
|
+
* acknowledged — never inside the engine's `update` observer, where one
|
|
40
|
+
* throw would silence every later emit. Memory never runs ahead of
|
|
41
|
+
* storage: when an append fails, nothing is relayed or acknowledged, the
|
|
42
|
+
* live doc is rebuilt from the stored rows and the sender's socket is
|
|
43
|
+
* closed (1011) so its provider reconnects and resends.
|
|
44
|
+
* - a delete of an item the room lacks waits in the engine and is stored
|
|
45
|
+
* as a `pending` record (not the entries its frame's waiting rewrites
|
|
46
|
+
* replace: those deletes wait with them, in memory); compaction keeps
|
|
47
|
+
* the pending records apart, and rewrites them as the deletes still
|
|
48
|
+
* waiting; a frame that discards a forged stamp drops them. At most
|
|
49
|
+
* {@link MAX_WAITING_DELETES} ranges wait, stored or in memory: a frame
|
|
50
|
+
* that would pass it has its waiting deletes dropped (refusal `waiting`,
|
|
51
|
+
* left out of the ack), the rest applied. Compaction reclaims the
|
|
52
|
+
* waiting deletes of client ids no user registered and no socket holds;
|
|
53
|
+
* `dropWaitingDeletes()` every one.
|
|
54
|
+
* - a Step2 serves the STORED state: the engine's pending structs (waiting
|
|
55
|
+
* for a dependency, never stored) are not served.
|
|
56
|
+
* - a frame larger than `maxFrameBytes` (32 MiB) goes out as chunks the
|
|
57
|
+
* client applies only when complete (`chunkFrame`).
|
|
58
|
+
* - `webSocketClose`/`webSocketError`: the departure the client may not
|
|
59
|
+
* have announced, read from the attachment (survives hibernation).
|
|
60
|
+
* - constructor: restore from SQLite alone under `blockConcurrencyWhile`
|
|
61
|
+
* (verify the generation record, merge, `admission.admitUpdate`); a
|
|
62
|
+
* container that cannot be restored (another generation, a torn record,
|
|
63
|
+
* a refused `onLoad` payload) refuses every socket (1008); a read of the
|
|
64
|
+
* rows that fails is the storage's fault, retried at the next dial
|
|
65
|
+
* (1011). It never throws out of the constructor (the platform would
|
|
66
|
+
* reset the object on every request).
|
|
67
|
+
*
|
|
68
|
+
* No entry point schedules a timer: each runs under {@link noTimers}
|
|
69
|
+
* (a Durable Object with a pending timer never hibernates). Keepalive is
|
|
70
|
+
* the runtime's: a text `ping` is answered `pong` without waking the
|
|
71
|
+
* object (`ctx.setWebSocketAutoResponse`, installed unless the host set
|
|
72
|
+
* its own pair; `webSocketMessage` answers it otherwise).
|
|
73
|
+
*
|
|
74
|
+
* Extending (subclass it, export the subclass):
|
|
75
|
+
*
|
|
76
|
+
* - `onLoad()` — retrieve: seed a room that stores nothing yet from your
|
|
77
|
+
* own store (JSON, a v14 update, or `{ update, replicas }` from
|
|
78
|
+
* `onSave`). Runs before any socket is served; nothing is stored until
|
|
79
|
+
* it settles.
|
|
80
|
+
* - `onSave(document)` — save: mirror the document to your own store,
|
|
81
|
+
* `saveAfter` ms after the first unsaved change (a Durable Object alarm,
|
|
82
|
+
* so hibernation is unaffected; a throw is retried by the platform).
|
|
83
|
+
* SQLite stays the room's source of truth: acks never wait on `onSave`.
|
|
84
|
+
* - `transact(fn)` — manipulate: edit through the document facade on the
|
|
85
|
+
* server; persisted and broadcast to every socket like a client's edit
|
|
86
|
+
* (one transaction, not a rollback: a throw from `fn` keeps its writes).
|
|
87
|
+
* `read()` returns the document as JSON (both RPC-callable wrappers are
|
|
88
|
+
* yours to define).
|
|
89
|
+
*/
|
|
90
|
+
import { DurableObject } from 'cloudflare:workers';
|
|
91
|
+
import * as E from '../crdt/index.js';
|
|
92
|
+
import type { AwarenessEntry, DocumentSemanticsConfig, EdytorDoc, JSONDoc, YDoc } from '../crdt/index.js';
|
|
93
|
+
/** Under SQLite-backed Durable Objects' 2 MB row cap, with room for the other columns. */
|
|
94
|
+
export declare const DEFAULT_MAX_ROW_BYTES: number;
|
|
95
|
+
/** Update records before the rows are merged into one snapshot. */
|
|
96
|
+
export declare const DEFAULT_COMPACT_AFTER = 500;
|
|
97
|
+
/** ms between the first unsaved change and `onSave`. */
|
|
98
|
+
export declare const DEFAULT_SAVE_AFTER = 2000;
|
|
99
|
+
/**
|
|
100
|
+
* Delete ranges the room keeps waiting for items it does not hold (a
|
|
101
|
+
* relayer's delete of an author's edit a restore lost). Every update the
|
|
102
|
+
* engine applies re-reads them, so they are capped.
|
|
103
|
+
*/
|
|
104
|
+
export declare const MAX_WAITING_DELETES = 1024;
|
|
105
|
+
/** Refusals kept in `refusals` (the newest); `refusalCounts` counts every one. */
|
|
106
|
+
export declare const MAX_REFUSALS = 100;
|
|
107
|
+
/**
|
|
108
|
+
* A client id and the user who owns it (the room's replica registry). An
|
|
109
|
+
* empty `user` marks an id a restore without a registry left unowned: its
|
|
110
|
+
* first authenticated writer claims it.
|
|
111
|
+
*/
|
|
112
|
+
export type ReplicaOwner = {
|
|
113
|
+
replica: number;
|
|
114
|
+
user: string;
|
|
115
|
+
};
|
|
116
|
+
/** The document as `onSave` receives it. */
|
|
117
|
+
export type SavedDocument = {
|
|
118
|
+
/** The document as JSON. */
|
|
119
|
+
value: JSONDoc;
|
|
120
|
+
/** The full v14 state (`onLoad` takes it back). */
|
|
121
|
+
update: Uint8Array;
|
|
122
|
+
/**
|
|
123
|
+
* Who owns each client id, read with `update`. Store it beside `update`
|
|
124
|
+
* and return both from `onLoad`: without it, a restored room cannot
|
|
125
|
+
* tell which user wrote under which id.
|
|
126
|
+
*/
|
|
127
|
+
replicas: ReplicaOwner[];
|
|
128
|
+
};
|
|
129
|
+
/** What `onLoad` may return: JSON, a bare v14 update, or `{ update, replicas }` (a `SavedDocument`). */
|
|
130
|
+
export type LoadedDocument = JSONDoc | Uint8Array | Pick<SavedDocument, 'update' | 'replicas'>;
|
|
131
|
+
/** The transaction origin of the room's own edits (`transact`, `onLoad` seeds). */
|
|
132
|
+
export declare const ROOM_ORIGIN: unique symbol;
|
|
133
|
+
/**
|
|
134
|
+
* Headers carrying the identity `routeDocumentSocket` verified — never the
|
|
135
|
+
* client's. The user id is percent-encoded (`encodeURIComponent`): a header
|
|
136
|
+
* value is trimmed and cannot carry every character, and a user id is any
|
|
137
|
+
* string.
|
|
138
|
+
*/
|
|
139
|
+
export declare const IDENTITY_HEADERS: {
|
|
140
|
+
readonly user: "X-Edytor-User";
|
|
141
|
+
readonly replica: "X-Edytor-Replica";
|
|
142
|
+
readonly access: "X-Edytor-Access";
|
|
143
|
+
};
|
|
144
|
+
/**
|
|
145
|
+
* Optional knobs (strings, as `vars` arrive): row size, outgoing frame
|
|
146
|
+
* limit and compaction threshold. The defaults are the platform limits.
|
|
147
|
+
*/
|
|
148
|
+
export type DocumentRoomEnv = {
|
|
149
|
+
EDYTOR_MAX_ROW_BYTES?: string | number;
|
|
150
|
+
EDYTOR_MAX_FRAME_BYTES?: string | number;
|
|
151
|
+
EDYTOR_COMPACT_AFTER?: string | number;
|
|
152
|
+
EDYTOR_SAVE_AFTER?: string | number;
|
|
153
|
+
};
|
|
154
|
+
/** What a socket is bound to: its verified user, its replica (Yjs client id), its access. */
|
|
155
|
+
export type SocketIdentity = {
|
|
156
|
+
user: string;
|
|
157
|
+
/** `null` until bound — by `authorize`, or by the socket's first presence entry. */
|
|
158
|
+
replica: number | null;
|
|
159
|
+
readOnly: boolean;
|
|
160
|
+
};
|
|
161
|
+
/** A socket's attachment (survives hibernation): its identity and its presence clock. */
|
|
162
|
+
export type Attachment = SocketIdentity & {
|
|
163
|
+
clock: number | null;
|
|
164
|
+
};
|
|
165
|
+
export type Refusal = {
|
|
166
|
+
reason: 'generation' | 'schema' | 'malformed' | 'container' | 'identity' | 'replica' | 'read-only' | 'waiting' | 'storage' | 'internal' | 'orphan' | 'relayed';
|
|
167
|
+
detail: unknown;
|
|
168
|
+
};
|
|
169
|
+
/** `pending`: deletes of items the room does not hold yet (they wait for them). */
|
|
170
|
+
type RowKind = 'generation' | 'update' | 'snapshot' | 'pending';
|
|
171
|
+
/**
|
|
172
|
+
* An upgrade accepted and closed at once, so the client reads `code`: a
|
|
173
|
+
* browser sees an HTTP error at the upgrade only as `1006`, which a
|
|
174
|
+
* provider cannot tell from a network failure. Refuse a dial your Worker
|
|
175
|
+
* turns away itself with it: the provider stops at `1008` or `4xxx`
|
|
176
|
+
* (except `4401`, redialed), and redials after anything else (`CLOSE`,
|
|
177
|
+
* `isRefusal` in `crdt/providers/room.ts`).
|
|
178
|
+
*/
|
|
179
|
+
export declare const closedSocket: (code: number, reason: string) => Response;
|
|
180
|
+
/** Run an entry point with timers forbidden — a pending timer keeps a Durable Object from hibernating. */
|
|
181
|
+
export declare const noTimers: <T>(fn: () => T) => T;
|
|
182
|
+
/** A Yjs client id (a non-negative safe integer), or `null`. */
|
|
183
|
+
export declare const parseReplica: (raw: unknown) => number | null;
|
|
184
|
+
/** An awareness frame carrying `entries` — no `Awareness` instance involved. */
|
|
185
|
+
export declare const presenceFrame: (entries: AwarenessEntry[]) => Uint8Array;
|
|
186
|
+
/** What {@link attachDocument} (and `DocumentRoom`) takes. */
|
|
187
|
+
export type AttachDocumentOptions = {
|
|
188
|
+
/**
|
|
189
|
+
* Retrieve: the document for a room that stores nothing yet. Return
|
|
190
|
+
* JSON, `{ update, replicas }` from `onSave` (a bare `update` restores
|
|
191
|
+
* the content, but not who owns which client id), or nothing for an
|
|
192
|
+
* empty room. Nothing is stored until it settles, so it is asked again
|
|
193
|
+
* at each start (and after a throw, at the next dial) until something
|
|
194
|
+
* is stored. A payload the room refuses (another generation or schema,
|
|
195
|
+
* undecodable bytes, another shape) refuses every socket (1008).
|
|
196
|
+
*/
|
|
197
|
+
onLoad?: () => Promise<LoadedDocument | null | undefined> | LoadedDocument | null | undefined;
|
|
198
|
+
/**
|
|
199
|
+
* Save: mirror the document to your own store, `saveAfter` ms after the
|
|
200
|
+
* first unsaved change, on the object's alarm (a throw is retried by the
|
|
201
|
+
* platform). Without it no alarm is ever set.
|
|
202
|
+
*/
|
|
203
|
+
onSave?: (document: SavedDocument) => Promise<void> | void;
|
|
204
|
+
/** ms between the first unsaved change and `onSave` (default {@link DEFAULT_SAVE_AFTER}). */
|
|
205
|
+
saveAfter?: number;
|
|
206
|
+
/** Update records before the rows are merged into one snapshot (default {@link DEFAULT_COMPACT_AFTER}). */
|
|
207
|
+
compactAfter?: number;
|
|
208
|
+
/** Largest stored row; can only be lowered (default {@link DEFAULT_MAX_ROW_BYTES}). */
|
|
209
|
+
maxRowBytes?: number;
|
|
210
|
+
/** Largest frame sent whole; can only be lowered (default 32 MiB). */
|
|
211
|
+
maxFrameBytes?: number;
|
|
212
|
+
/** Prefix of the document's SQL tables, beside your own (default `'edytor_'`). */
|
|
213
|
+
tablePrefix?: string;
|
|
214
|
+
/**
|
|
215
|
+
* The block roles `transact` edits obey — the document semantics your
|
|
216
|
+
* clients' plugins declare (`defaultType` also names the block an empty
|
|
217
|
+
* room is seeded with). Default
|
|
218
|
+
* {@link E.defaultSemantics} (the bundled rich-text, code and image kinds).
|
|
219
|
+
*/
|
|
220
|
+
semantics?: DocumentSemanticsConfig;
|
|
221
|
+
};
|
|
222
|
+
/** The tag of the document's sockets: other sockets of the object are left to you. */
|
|
223
|
+
export declare const SOCKET_TAG = "edytor";
|
|
224
|
+
/**
|
|
225
|
+
* One edytor document living in a Durable Object's storage: the room
|
|
226
|
+
* logic, independent of the class that hosts it. Create it with
|
|
227
|
+
* {@link attachDocument} (any Durable Object) or extend `DocumentRoom`.
|
|
228
|
+
* The socket handlers ignore sockets without {@link SOCKET_TAG} and
|
|
229
|
+
* return `false` for them.
|
|
230
|
+
*/
|
|
231
|
+
export declare class AttachedDocument {
|
|
232
|
+
readonly ctx: DurableObjectState;
|
|
233
|
+
readonly maxRowBytes: number;
|
|
234
|
+
readonly maxFrameBytes: number;
|
|
235
|
+
readonly compactAfter: number;
|
|
236
|
+
readonly saveAfter: number;
|
|
237
|
+
private live;
|
|
238
|
+
/** Why the stored container was refused (another generation, a torn record, `onLoad`…). */
|
|
239
|
+
failure: Error | null;
|
|
240
|
+
/** Latest presence entry per replica, for join snapshots (memory: refills after a wake). */
|
|
241
|
+
presence: Map<number, E.AwarenessEntry>;
|
|
242
|
+
/** The newest {@link MAX_REFUSALS} refusals since this instance started (diagnostics; memory only). */
|
|
243
|
+
refusals: Refusal[];
|
|
244
|
+
/** Every refusal since this instance started, by reason. */
|
|
245
|
+
refusalCounts: Partial<Record<Refusal['reason'], number>>;
|
|
246
|
+
/** How this instance came to be: a fresh container, or a restore of N stored records. */
|
|
247
|
+
origin: {
|
|
248
|
+
kind: 'fresh';
|
|
249
|
+
} | {
|
|
250
|
+
kind: 'restored';
|
|
251
|
+
records: number;
|
|
252
|
+
};
|
|
253
|
+
private nextRecord;
|
|
254
|
+
private updates;
|
|
255
|
+
/** A failed append: the live doc holds what storage does not, until it is rebuilt. */
|
|
256
|
+
private unstored;
|
|
257
|
+
/** Inside `transact`, its commit included (a nested call is refused but while `fn` runs). */
|
|
258
|
+
private transacting;
|
|
259
|
+
/** Inside `transact`'s `fn`: a nested call joins the enclosing transaction. */
|
|
260
|
+
private running;
|
|
261
|
+
/** Inside a client frame's apply, its events included: the frame's handler settles it. */
|
|
262
|
+
private handling;
|
|
263
|
+
/** The waiting deletes stored as `pending` records (the engine may hold more, in memory). */
|
|
264
|
+
private storedWaiting;
|
|
265
|
+
/** The failure is the storage's (a failed read, `onLoad`'s store down): the next dial starts again. */
|
|
266
|
+
private retryable;
|
|
267
|
+
private readonly sql;
|
|
268
|
+
private _facade;
|
|
269
|
+
private saveScheduled;
|
|
270
|
+
/** Alarms in a row that found the rows unreadable: each re-arms later. */
|
|
271
|
+
private saveRetries;
|
|
272
|
+
private readonly options;
|
|
273
|
+
private readonly rowsTable;
|
|
274
|
+
private readonly replicasTable;
|
|
275
|
+
private _lookups;
|
|
276
|
+
constructor(ctx: DurableObjectState, options?: AttachDocumentOptions);
|
|
277
|
+
/**
|
|
278
|
+
* Restore from storage, or seed from `onLoad`. Never throws: a throw
|
|
279
|
+
* out of `blockConcurrencyWhile` resets the object on every request.
|
|
280
|
+
*/
|
|
281
|
+
private start;
|
|
282
|
+
/** A read of the rows or `onLoad` failed (storage was down): start again. */
|
|
283
|
+
private retryStart;
|
|
284
|
+
private fail;
|
|
285
|
+
/** The room's block roles, read at first use (a subclass's fields exist by then). */
|
|
286
|
+
private get lookups();
|
|
287
|
+
/** A facade over `doc` obeying the room's block roles (`semantics`). */
|
|
288
|
+
private facadeOf;
|
|
289
|
+
/**
|
|
290
|
+
* The live document; `null` when the stored container was refused.
|
|
291
|
+
* Like {@link facade}, reading it first drops a direct write whose
|
|
292
|
+
* append failed (`heal`, only while the room is idle), so the next
|
|
293
|
+
* write through it is stored (HX-12).
|
|
294
|
+
*/
|
|
295
|
+
get doc(): YDoc | null;
|
|
296
|
+
/**
|
|
297
|
+
* The facade over the live document. Read while the room is idle, it
|
|
298
|
+
* first drops a direct write whose append failed (`heal`), so the next
|
|
299
|
+
* write through it is stored (GX-09).
|
|
300
|
+
*/
|
|
301
|
+
get facade(): EdytorDoc;
|
|
302
|
+
/**
|
|
303
|
+
* Inside a room `transact` (its commit included), a client frame's apply
|
|
304
|
+
* or any transaction's events: a write now could not be stored before
|
|
305
|
+
* it returns, and a failed append belongs to what is being handled.
|
|
306
|
+
*/
|
|
307
|
+
private get busy();
|
|
308
|
+
/**
|
|
309
|
+
* Manipulate: run `fn` on the facade in one transaction. The edit is
|
|
310
|
+
* stored, then broadcast to every socket. It is not a rollback, like
|
|
311
|
+
* every client-side `transact`: when `fn` throws, what it wrote before
|
|
312
|
+
* the throw is kept (stored and broadcast) and its error is rethrown —
|
|
313
|
+
* validate before writing, or apply one `facade.prepare.*` plan. When
|
|
314
|
+
* the append fails, the storage error is thrown instead and nothing is
|
|
315
|
+
* kept (the live doc is rebuilt from the stored rows). A call inside
|
|
316
|
+
* `fn` joins the enclosing one. An empty room is first seeded with one
|
|
317
|
+
* empty block, as a client with no `value` would. Called anywhere else
|
|
318
|
+
* inside a transaction or its events — a `facade.onChange` subscriber
|
|
319
|
+
* (of a client's frame or of the room's own `transact`), a
|
|
320
|
+
* `doc.on('afterAllTransactions')` listener during a frame — it throws
|
|
321
|
+
* without writing: the engine would queue the write until that one
|
|
322
|
+
* ends, so it could not be stored before returning (DR-rest-1, HX-04).
|
|
323
|
+
*/
|
|
324
|
+
transact<T>(fn: (facade: EdytorDoc) => T): T;
|
|
325
|
+
/** The document as JSON. */
|
|
326
|
+
read(): JSONDoc;
|
|
327
|
+
/**
|
|
328
|
+
* Runs `onSave` — the object's alarm, `saveAfter` ms after the first
|
|
329
|
+
* unsaved change. While the rows cannot be read (a retryable failure),
|
|
330
|
+
* it starts the room again; if that fails too, the save stays due: the
|
|
331
|
+
* alarm is set again, later at each failure (up to 5 minutes), so the
|
|
332
|
+
* mirror never silently lags what the room stored.
|
|
333
|
+
*/
|
|
334
|
+
alarm(): Promise<void>;
|
|
335
|
+
/** The first unsaved change arms the save alarm; a wake keeps one already armed (`start`). */
|
|
336
|
+
private scheduleSave;
|
|
337
|
+
/**
|
|
338
|
+
* Generation cutover: drop the stored document (both tables) of a room
|
|
339
|
+
* whose storage belongs to another edytor generation, and start again
|
|
340
|
+
* from `onLoad` — reseed it from JSON. Refused for any other room.
|
|
341
|
+
*/
|
|
342
|
+
reset(): Promise<void>;
|
|
343
|
+
/**
|
|
344
|
+
* Seed a fresh room from `onLoad`. Nothing is stored before it settles:
|
|
345
|
+
* a throw or nothing leaves the room fresh, asked again at the next
|
|
346
|
+
* start (after a throw, also at the next dial). The payload is admitted
|
|
347
|
+
* like a stored container, then stored as one snapshot record with its
|
|
348
|
+
* registry, atomically. The deletes it carries of items it lacks (an
|
|
349
|
+
* `onSave` mirror holds the waiting ones) are stored apart, as one
|
|
350
|
+
* `pending` record, as a frame's are: acknowledged by id, reclaimed by
|
|
351
|
+
* compaction.
|
|
352
|
+
*/
|
|
353
|
+
private seed;
|
|
354
|
+
/**
|
|
355
|
+
* Restore the live doc from the stored rows. A read of the rows that
|
|
356
|
+
* fails is the storage's fault: retryable, the next dial loads again
|
|
357
|
+
* (at cold start, at a retry, after a rebuild). A container that reads
|
|
358
|
+
* but cannot be restored (a torn record, another generation, bytes the
|
|
359
|
+
* engine refuses) is refused for good.
|
|
360
|
+
*/
|
|
361
|
+
private load;
|
|
362
|
+
/** Reassembled logical records in write order; a torn record throws. */
|
|
363
|
+
records(): Array<{
|
|
364
|
+
kind: RowKind;
|
|
365
|
+
bytes: Uint8Array<ArrayBuffer>;
|
|
366
|
+
}>;
|
|
367
|
+
/**
|
|
368
|
+
* One logical record split into rows ≤ `maxRowBytes` (callers run it in
|
|
369
|
+
* a transaction). The first record of an empty container brings the
|
|
370
|
+
* generation record with it.
|
|
371
|
+
*/
|
|
372
|
+
private insert;
|
|
373
|
+
/**
|
|
374
|
+
* Compaction: the rows become the generation record + one chunked
|
|
375
|
+
* snapshot, `mergeUpdates` of every stored record, atomically, + one
|
|
376
|
+
* `pending` record of the stored deletes still waiting. A waiting delete
|
|
377
|
+
* of a client id no user registered and no socket holds is reclaimed,
|
|
378
|
+
* in memory too: nothing can deliver its item (a made-up id) — the
|
|
379
|
+
* registrations of ids with waiting deletes are kept. The registry
|
|
380
|
+
* keeps the ids holding content and those bound to an open socket; the
|
|
381
|
+
* others (page loads that never wrote) are dropped, and re-register at
|
|
382
|
+
* their next dial or write. Runs by itself after `compactAfter` update
|
|
383
|
+
* records; callable over RPC (e.g. from the host's own alarm).
|
|
384
|
+
*/
|
|
385
|
+
compact(): {
|
|
386
|
+
rows: number;
|
|
387
|
+
};
|
|
388
|
+
/**
|
|
389
|
+
* Drop every waiting delete, stored or in memory (callable over RPC):
|
|
390
|
+
* the way out when a writer filled {@link MAX_WAITING_DELETES} with
|
|
391
|
+
* deletes of registered ids' items, which compaction keeps. A dropped
|
|
392
|
+
* delete's item shows if it ever arrives — but for an entry a waiting
|
|
393
|
+
* rewrite replaces, which that rewrite deletes should it integrate.
|
|
394
|
+
* Returns how many ranges were dropped.
|
|
395
|
+
*/
|
|
396
|
+
dropWaitingDeletes(): {
|
|
397
|
+
ranges: number;
|
|
398
|
+
};
|
|
399
|
+
/**
|
|
400
|
+
* A fault of the room while it handled `ws`'s frame, never the client's
|
|
401
|
+
* doing (so never a refusal): a failed append (`unstored`) or registry
|
|
402
|
+
* write (`storage`), the engine or a send (`internal`). After a failed
|
|
403
|
+
* append or an engine fault the live doc may hold what storage does
|
|
404
|
+
* not: it is rebuilt from the stored rows alone (as a restart would),
|
|
405
|
+
* so nothing unstored is ever served or acknowledged. The socket is
|
|
406
|
+
* closed 1011: its provider redials, the join rule finds what the room
|
|
407
|
+
* lacks, and the edit is resent and stored.
|
|
408
|
+
*/
|
|
409
|
+
private fault;
|
|
410
|
+
/**
|
|
411
|
+
* Automatic compaction, once the message that made it due is
|
|
412
|
+
* acknowledged. A failure is logged and retried after half the
|
|
413
|
+
* threshold; the edit is already stored and nobody is closed.
|
|
414
|
+
*/
|
|
415
|
+
private compactIfDue;
|
|
416
|
+
/**
|
|
417
|
+
* Drop the live doc for the stored rows (a failed append, an engine
|
|
418
|
+
* fault): `doc` and `facade` are replaced, and subscriptions on the old
|
|
419
|
+
* ones end. A read that fails now is retryable: the next dial loads
|
|
420
|
+
* again. The room's own writes (`waiting`) change nothing the engine
|
|
421
|
+
* holds waiting (updates missing a dependency, deletes kept in memory):
|
|
422
|
+
* that is carried over, not lost as at a restart.
|
|
423
|
+
*/
|
|
424
|
+
private rebuild;
|
|
425
|
+
/**
|
|
426
|
+
* A room-side write outside `transact` (straight through `facade`)
|
|
427
|
+
* whose append failed left the live doc ahead of storage: rebuild it
|
|
428
|
+
* before anything is served, read or acknowledged. Only while the room
|
|
429
|
+
* is idle (not `busy`): from inside a transaction, a frame's apply or
|
|
430
|
+
* their events (a `facade.onChange` subscriber, a
|
|
431
|
+
* `doc.on('afterAllTransactions')` listener), the failure stays for
|
|
432
|
+
* the handler — a frame's faults its sender, `transact` throws it
|
|
433
|
+
* (SW16-room-1, HX-03).
|
|
434
|
+
*/
|
|
435
|
+
private heal;
|
|
436
|
+
/** Run a frame's apply: nothing its listeners do heals it (HX-03). */
|
|
437
|
+
private handle;
|
|
438
|
+
private requireDoc;
|
|
439
|
+
private adopt;
|
|
440
|
+
/** A registry read or write, its SQLite fault tagged (the socket closes 1011, never 1008). */
|
|
441
|
+
private registry;
|
|
442
|
+
/** Who owns `client`: a user, `''` (unowned: its dial claims it), or `undefined` (unregistered). */
|
|
443
|
+
private ownerOf;
|
|
444
|
+
/** Register `owners` in one transaction; an unowned (`''`) row never replaces an owner. */
|
|
445
|
+
private register;
|
|
446
|
+
/**
|
|
447
|
+
* May `user` bind `replica` to a socket (its dial, or its first presence
|
|
448
|
+
* entry)? Its own id; an unregistered id with no content in the room,
|
|
449
|
+
* registered now whatever the socket's access (so a viewer's id cannot be
|
|
450
|
+
* taken before it is granted edit); an unowned id (`''`), which a
|
|
451
|
+
* `writer` claims (logged `orphan`). Not another user's id, nor
|
|
452
|
+
* unregistered history.
|
|
453
|
+
*/
|
|
454
|
+
private bind;
|
|
455
|
+
/**
|
|
456
|
+
* Which new writers of an update a socket may deliver; returns those
|
|
457
|
+
* stripped from its frame (the rest of the frame is applied: never
|
|
458
|
+
* refused whole). Written: its user's ids, and its own replica (the
|
|
459
|
+
* dialed or bound one), which claims an unowned id or a fresh one, as
|
|
460
|
+
* `bind` would. A socket with no replica claims fresh ids it writes.
|
|
461
|
+
* Any other id is relayed — another replica's structs, which a restore
|
|
462
|
+
* from a lagging snapshot may have lost: kept, and left unowned (`''`,
|
|
463
|
+
* claimable only by its own dial), when the room holds none of that id's
|
|
464
|
+
* clocks and no user owns it; stripped otherwise (logged `replica`).
|
|
465
|
+
* Ownership never moves to a relayer.
|
|
466
|
+
*/
|
|
467
|
+
private attribute;
|
|
468
|
+
fetch(request: Request): Promise<Response>;
|
|
469
|
+
/** Is `ws` one of this document's sockets? */
|
|
470
|
+
owns(ws: WebSocket): boolean;
|
|
471
|
+
webSocketMessage(ws: WebSocket, message: string | ArrayBuffer): boolean;
|
|
472
|
+
webSocketClose(ws: WebSocket, code: number, reason: string): boolean;
|
|
473
|
+
webSocketError(ws: WebSocket): boolean;
|
|
474
|
+
/** The departure the client may not have announced — from the attachment, so it works after a wake. */
|
|
475
|
+
private depart;
|
|
476
|
+
private onSync;
|
|
477
|
+
/**
|
|
478
|
+
* A delete of items the room does not hold (a relayer's delete of an
|
|
479
|
+
* author's edit a restore lost) waits in the engine for them: it is
|
|
480
|
+
* stored as it arrives, so it survives eviction and compaction and
|
|
481
|
+
* applies when the author's edit returns. Except the entries the frame's
|
|
482
|
+
* own still-waiting rewrites replace (`stay`): those deletes wait with
|
|
483
|
+
* the rewrites in memory, as the rewrites may never integrate. A frame
|
|
484
|
+
* that released a pending forged stamp discarded every waiting delete
|
|
485
|
+
* (`applyRemote`): the stored ones go too. The deletes the frame applied
|
|
486
|
+
* from the waiting ones go back to its sender, whom the relay of the
|
|
487
|
+
* update skips; they are returned. The cap holds here too: deletes of
|
|
488
|
+
* the frame's own structs that wait for an origin (stored, or kept in
|
|
489
|
+
* memory with its rewrites) pass the check before applying; when the
|
|
490
|
+
* frame's new waiting deletes take the room past
|
|
491
|
+
* {@link MAX_WAITING_DELETES}, they are all dropped (refusal `waiting`,
|
|
492
|
+
* the sender's), unstored and unacknowledged. A replaced entry is
|
|
493
|
+
* deleted by its rewrite anyway, should that integrate.
|
|
494
|
+
*/
|
|
495
|
+
private settleDeletes;
|
|
496
|
+
/**
|
|
497
|
+
* Of `deletes`, those the room stored — applied, or waiting in a
|
|
498
|
+
* `pending` record — and so acknowledges by id: never one it dropped
|
|
499
|
+
* (the waiting cap, a stripped rewrite's replaced entry) or keeps
|
|
500
|
+
* waiting in memory only.
|
|
501
|
+
*/
|
|
502
|
+
private storedDeletes;
|
|
503
|
+
/**
|
|
504
|
+
* Presence through the instance-free codec, for the socket's own replica
|
|
505
|
+
* only (bound by `authorize`, else by its first entry): the newest clock
|
|
506
|
+
* wins, the attachment records the clock, the accepted entry is relayed
|
|
507
|
+
* — to its sender too (a no-op for it), so a lone socket hears from the
|
|
508
|
+
* room at every renewal and is never torn down as silent.
|
|
509
|
+
* Entries for other replicas (a client re-sending what it heard) are dropped.
|
|
510
|
+
*/
|
|
511
|
+
private onPresence;
|
|
512
|
+
/** Log a refusal: the newest {@link MAX_REFUSALS} are kept, every reason is counted. */
|
|
513
|
+
private note;
|
|
514
|
+
/** A refused frame is dropped whole and its socket closed (1008 policy violation). */
|
|
515
|
+
private refuse;
|
|
516
|
+
private close;
|
|
517
|
+
/**
|
|
518
|
+
* No document to serve: a container that cannot be restored is
|
|
519
|
+
* refused for good (1008, the provider stops dialing); a failed read of
|
|
520
|
+
* the rows or an `onLoad` that threw is retried at the next dial (1011,
|
|
521
|
+
* the provider redials).
|
|
522
|
+
*/
|
|
523
|
+
private refuseContainer;
|
|
524
|
+
/** Send one frame — as chunks when it exceeds `maxFrameBytes` (bounded catch-up). */
|
|
525
|
+
private send;
|
|
526
|
+
private broadcast;
|
|
527
|
+
}
|
|
528
|
+
/**
|
|
529
|
+
* Attach an edytor document to any Durable Object (`attachDocument(this,
|
|
530
|
+
* opts)`, in the constructor or a field). Its tables (`edytor_rows`,
|
|
531
|
+
* `edytor_replicas`) live beside yours and its sockets carry
|
|
532
|
+
* {@link SOCKET_TAG}. Each handler your class does not define —
|
|
533
|
+
* `fetch`, `webSocketMessage`, `webSocketClose`, `webSocketError`, and
|
|
534
|
+
* `alarm` when `onSave` is set — is installed on the object; a class that
|
|
535
|
+
* defines one delegates to the returned document's method (which returns
|
|
536
|
+
* `false` for a socket that is not the document's).
|
|
537
|
+
*/
|
|
538
|
+
export declare const attachDocument: (host: DurableObject<any>, options?: AttachDocumentOptions) => AttachedDocument;
|
|
539
|
+
/**
|
|
540
|
+
* The ready-made room: a Durable Object hosting one document, configured
|
|
541
|
+
* by `vars` ({@link DocumentRoomEnv}). Subclass it to override `onLoad` and
|
|
542
|
+
* `onSave`, and add your own RPC methods over `transact`/`read`. Its tables
|
|
543
|
+
* are `rows` and `replicas` (no prefix).
|
|
544
|
+
*/
|
|
545
|
+
export declare class DocumentRoom<Env = DocumentRoomEnv> extends DurableObject<Env> {
|
|
546
|
+
readonly room: AttachedDocument;
|
|
547
|
+
constructor(ctx: DurableObjectState, env: Env);
|
|
548
|
+
/** Retrieve — see {@link AttachDocumentOptions.onLoad}. */
|
|
549
|
+
protected onLoad(): Promise<LoadedDocument | null | undefined>;
|
|
550
|
+
/** Save — see {@link AttachDocumentOptions.onSave}. Not overridden: no alarm is ever set. */
|
|
551
|
+
protected onSave(_document: SavedDocument): Promise<void>;
|
|
552
|
+
/**
|
|
553
|
+
* Block roles — see {@link AttachDocumentOptions.semantics}. Read once,
|
|
554
|
+
* at first use (after construction: it may return a subclass field).
|
|
555
|
+
*/
|
|
556
|
+
protected semantics(): DocumentSemanticsConfig;
|
|
557
|
+
fetch(request: Request): Promise<Response>;
|
|
558
|
+
webSocketMessage(ws: WebSocket, message: string | ArrayBuffer): void;
|
|
559
|
+
webSocketClose(ws: WebSocket, code: number, reason: string): void;
|
|
560
|
+
webSocketError(ws: WebSocket): void;
|
|
561
|
+
/** Runs `onSave`. Call `super.alarm()` if you override it. */
|
|
562
|
+
alarm(): Promise<void>;
|
|
563
|
+
/** Compaction, also over RPC. */
|
|
564
|
+
compact(): {
|
|
565
|
+
rows: number;
|
|
566
|
+
};
|
|
567
|
+
/** Drop the stored waiting deletes, also over RPC — see {@link AttachedDocument.dropWaitingDeletes}. */
|
|
568
|
+
dropWaitingDeletes(): {
|
|
569
|
+
ranges: number;
|
|
570
|
+
};
|
|
571
|
+
/** Generation cutover, also over RPC — see {@link AttachedDocument.reset}. */
|
|
572
|
+
reset(): Promise<void>;
|
|
573
|
+
/** Server-side edit — see {@link AttachedDocument.transact}. */
|
|
574
|
+
transact<T>(fn: (facade: EdytorDoc) => T): T;
|
|
575
|
+
/** The document as JSON. */
|
|
576
|
+
read(): JSONDoc;
|
|
577
|
+
get facade(): EdytorDoc;
|
|
578
|
+
get doc(): YDoc | null;
|
|
579
|
+
get failure(): Error | null;
|
|
580
|
+
get refusals(): Refusal[];
|
|
581
|
+
get refusalCounts(): AttachedDocument['refusalCounts'];
|
|
582
|
+
get presence(): Map<number, AwarenessEntry>;
|
|
583
|
+
get origin(): AttachedDocument['origin'];
|
|
584
|
+
records(): ReturnType<AttachedDocument['records']>;
|
|
585
|
+
}
|
|
586
|
+
export {};
|