edytor 2.0.0 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +19 -4
- package/dist/block/block.svelte.js +2 -4
- package/dist/clipboard/htmlFlow.d.ts +20 -7
- package/dist/clipboard/htmlFlow.js +23 -15
- package/dist/clipboard/serializeClipboardFragment.d.ts +37 -4
- package/dist/clipboard/serializeClipboardFragment.js +6 -4
- package/dist/clipboard/textBlocks.d.ts +8 -0
- package/dist/clipboard/textBlocks.js +6 -2
- package/dist/cloudflare/DocumentRoom.d.ts +13 -9
- package/dist/cloudflare/DocumentRoom.js +10 -6
- package/dist/cloudflare/room/admission.js +3 -3
- package/dist/cloudflare/room/context.d.ts +28 -27
- package/dist/cloudflare/room/context.js +2 -2
- package/dist/cloudflare/room/purge.d.ts +6 -3
- package/dist/cloudflare/room/purge.js +44 -19
- package/dist/cloudflare/room/updates.d.ts +3 -4
- package/dist/cloudflare/room/updates.js +6 -8
- package/dist/cloudflare/routeDocumentSocket.d.ts +17 -0
- package/dist/cloudflare/routeDocumentSocket.js +53 -0
- package/dist/collaboration/comments/client.d.ts +1 -1
- package/dist/collaboration/comments/client.js +1 -1
- package/dist/collaboration/remoteSelection.js +3 -3
- package/dist/components/Edytor.svelte +2 -10
- package/dist/components/Edytor.svelte.d.ts +1 -3
- package/dist/crdt/admission.d.ts +5 -10
- package/dist/crdt/admission.js +5 -11
- package/dist/crdt/attribution/attribution.d.ts +31 -12
- package/dist/crdt/attribution/attribution.js +56 -18
- package/dist/crdt/attribution/block.d.ts +3 -3
- package/dist/crdt/attribution/block.js +7 -8
- package/dist/crdt/attribution/index.d.ts +1 -1
- package/dist/crdt/attribution/index.js +1 -1
- package/dist/crdt/data.d.ts +62 -31
- package/dist/crdt/data.js +211 -103
- package/dist/crdt/doc/delete.d.ts +1 -1
- package/dist/crdt/doc/delete.js +13 -30
- package/dist/crdt/doc/funnel.d.ts +7 -6
- package/dist/crdt/doc/funnel.js +39 -33
- package/dist/crdt/doc/gate.d.ts +3 -20
- package/dist/crdt/doc/gate.js +2 -41
- package/dist/crdt/doc/history.d.ts +25 -9
- package/dist/crdt/doc/history.js +152 -42
- package/dist/crdt/doc/layout.js +11 -22
- package/dist/crdt/doc/meta.js +12 -17
- package/dist/crdt/doc/moves.d.ts +1 -1
- package/dist/crdt/doc/moves.js +52 -32
- package/dist/crdt/doc/reads.js +2 -2
- package/dist/crdt/doc/seed.js +2 -2
- package/dist/crdt/doc/split-merge.js +12 -15
- package/dist/crdt/doc/steps.d.ts +25 -13
- package/dist/crdt/doc/steps.js +52 -122
- package/dist/crdt/doc/types.d.ts +21 -9
- package/dist/crdt/document.d.ts +21 -19
- package/dist/crdt/document.js +26 -23
- package/dist/crdt/edytor-doc.d.ts +66 -68
- package/dist/crdt/edytor-doc.js +21 -20
- package/dist/crdt/engine-api.d.ts +33 -1
- package/dist/crdt/engine.d.ts +0 -1
- package/dist/crdt/engine.js +1 -4
- package/dist/crdt/flow.d.ts +1 -1
- package/dist/crdt/flow.js +25 -27
- package/dist/crdt/index.d.ts +29 -28
- package/dist/crdt/index.js +3 -3
- package/dist/crdt/placement/display.d.ts +5 -30
- package/dist/crdt/placement/display.js +39 -144
- package/dist/crdt/placement/keys.d.ts +58 -0
- package/dist/crdt/placement/keys.js +90 -0
- package/dist/crdt/placement/model.d.ts +119 -118
- package/dist/crdt/placement/model.js +242 -142
- package/dist/crdt/placement/resolve.d.ts +123 -35
- package/dist/crdt/placement/resolve.js +187 -153
- package/dist/crdt/placement/slots.d.ts +134 -0
- package/dist/crdt/placement/slots.js +152 -0
- package/dist/crdt/protocol.d.ts +2 -2
- package/dist/crdt/protocol.js +2 -2
- package/dist/crdt/providers/index.d.ts +1 -1
- package/dist/crdt/providers/room.d.ts +26 -11
- package/dist/crdt/providers/room.js +77 -27
- package/dist/crdt/providers/websocket.d.ts +1 -1
- package/dist/crdt/providers/websocket.js +33 -32
- package/dist/crdt/purge.d.ts +17 -8
- package/dist/crdt/purge.js +236 -126
- package/dist/crdt/restore.d.ts +2 -2
- package/dist/crdt/restore.js +18 -34
- package/dist/crdt/schema.d.ts +22 -21
- package/dist/crdt/schema.js +29 -23
- package/dist/crdt/semantics.js +3 -1
- package/dist/crdt/storage.d.ts +1 -1
- package/dist/crdt/storage.js +1 -1
- package/dist/crdt/structs.d.ts +15 -15
- package/dist/crdt/structs.js +8 -22
- package/dist/crdt/text/index/cache.js +4 -0
- package/dist/crdt/text/index/claims.js +12 -0
- package/dist/crdt/text/index/fold.d.ts +2 -3
- package/dist/crdt/text/index/fold.js +194 -44
- package/dist/crdt/text/index/layout.js +5 -8
- package/dist/crdt/text/index/placement.d.ts +26 -18
- package/dist/crdt/text/index/placement.js +404 -138
- package/dist/crdt/text/index/records.d.ts +3 -3
- package/dist/crdt/text/index/records.js +24 -31
- package/dist/crdt/text/index/shared.d.ts +11 -3
- package/dist/crdt/text/index/shared.js +12 -3
- package/dist/crdt/text/index/state.d.ts +21 -17
- package/dist/crdt/text/index/state.js +15 -17
- package/dist/crdt/text/index/streams.d.ts +10 -5
- package/dist/crdt/text/index/streams.js +78 -27
- package/dist/crdt/text/items.d.ts +10 -3
- package/dist/crdt/text/items.js +7 -0
- package/dist/crdt/text/model.d.ts +77 -62
- package/dist/crdt/text/model.js +84 -169
- package/dist/crdt/text/ranges.d.ts +1 -1
- package/dist/crdt/text/ranges.js +3 -3
- package/dist/crdt/text/rows.d.ts +13 -7
- package/dist/crdt/text/rows.js +24 -7
- package/dist/crdt/text/runs.d.ts +17 -12
- package/dist/crdt/text/runs.js +24 -7
- package/dist/crdt/text/streams.d.ts +26 -13
- package/dist/crdt/text/streams.js +41 -14
- package/dist/crdt/vendor/yjs/UPSTREAM.md +568 -21
- package/dist/crdt/vendor/yjs/dts/global.d.ts +2 -0
- package/dist/crdt/vendor/yjs/dts/index.d.ts +1 -1
- package/dist/crdt/vendor/yjs/dts/structs/AbstractStruct.d.ts +7 -0
- package/dist/crdt/vendor/yjs/dts/structs/Item.d.ts +194 -10
- package/dist/crdt/vendor/yjs/dts/utils/Doc.d.ts +6 -3
- package/dist/crdt/vendor/yjs/dts/utils/StructStore.d.ts +5 -18
- package/dist/crdt/vendor/yjs/dts/utils/Transaction.d.ts +15 -1
- package/dist/crdt/vendor/yjs/dts/utils/UpdateDecoder.d.ts +14 -6
- package/dist/crdt/vendor/yjs/dts/utils/UpdateEncoder.d.ts +33 -6
- package/dist/crdt/vendor/yjs/dts/utils/ids.d.ts +1 -65
- package/dist/crdt/vendor/yjs/dts/utils/marks.d.ts +6 -1
- package/dist/crdt/vendor/yjs/dts/ynode.d.ts +43 -7
- package/dist/crdt/vendor/yjs/global.d.ts +2 -0
- package/dist/crdt/vendor/yjs/src/index.js +1 -1
- package/dist/crdt/vendor/yjs/src/structs/AbstractStruct.js +10 -0
- package/dist/crdt/vendor/yjs/src/structs/Item.js +610 -51
- package/dist/crdt/vendor/yjs/src/utils/BlockSet.js +18 -9
- package/dist/crdt/vendor/yjs/src/utils/Doc.js +5 -3
- package/dist/crdt/vendor/yjs/src/utils/StructStore.js +5 -0
- package/dist/crdt/vendor/yjs/src/utils/Transaction.js +36 -13
- package/dist/crdt/vendor/yjs/src/utils/UpdateDecoder.js +88 -18
- package/dist/crdt/vendor/yjs/src/utils/UpdateEncoder.js +119 -32
- package/dist/crdt/vendor/yjs/src/utils/encoding.js +13 -1
- package/dist/crdt/vendor/yjs/src/utils/ids.js +7 -7
- package/dist/crdt/vendor/yjs/src/utils/marks.js +193 -8
- package/dist/crdt/vendor/yjs/src/utils/redo.js +1 -1
- package/dist/crdt/vendor/yjs/src/utils/transaction-helpers.js +1 -1
- package/dist/crdt/vendor/yjs/src/utils/updates.js +3 -3
- package/dist/crdt/vendor/yjs/src/ynode.js +177 -12
- package/dist/dnd/autoScroll.d.ts +15 -7
- package/dist/dnd/autoScroll.js +10 -15
- package/dist/dnd/dropIndicator.js +2 -5
- package/dist/dnd/external.d.ts +6 -0
- package/dist/dnd/external.js +17 -0
- package/dist/dnd/geometry.d.ts +2 -0
- package/dist/dnd/geometry.js +3 -4
- package/dist/dnd/placement.d.ts +1 -1
- package/dist/dnd/pragmatic.d.ts +3 -1
- package/dist/dnd/pragmatic.js +12 -2
- package/dist/dnd/vendor/pragmatic/UPSTREAM.md +51 -18
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/adapter/drop-target-for-external.d.ts +4 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/adapter/drop-target-for-external.js +6 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/adapter/element-adapter.d.ts +0 -2
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/adapter/element-adapter.js +4 -22
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/adapter/external-adapter-types.d.ts +26 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/adapter/external-adapter.d.ts +30 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/adapter/external-adapter.js +203 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/adapter/get-available-items.js +13 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/adapter/get-available-types.js +9 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/adapter/is-an-available-type.js +19 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/adapter/monitor-for-external.d.ts +4 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/adapter/monitor-for-external.js +6 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/honey-pot-fix/make-honey-pot-fix.js +4 -16
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/internal-types.d.ts +1 -8
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/make-adapter/make-drop-target.js +5 -6
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/make-adapter/make-monitor.js +2 -3
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/public-utils/element/custom-native-drag-preview/set-custom-native-drag-preview.d.ts +1 -1
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/public-utils/element/custom-native-drag-preview/set-custom-native-drag-preview.js +6 -24
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/public-utils/external/contains-files.d.ts +2 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/public-utils/external/contains-files.js +5 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/public-utils/external/get-files.d.ts +3 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/public-utils/external/get-files.js +12 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/public-utils/external/native-types.d.ts +12 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/util/changing-window/is-entering-window-in-safari.js +10 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/util/changing-window/is-entering-window.js +55 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop-auto-scroll/entry-point/external.d.ts +4 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop-auto-scroll/entry-point/external.js +8 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop-auto-scroll/internal-types.d.ts +0 -4
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop-auto-scroll/over-element/get-scroll-by.js +16 -72
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop-auto-scroll/over-element/try-scroll.js +1 -9
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop-auto-scroll/shared/configuration.js +4 -29
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop-auto-scroll/shared/get-scroll-change.js +2 -3
- package/dist/edytor.svelte.d.ts +2 -5
- package/dist/edytor.svelte.js +21 -32
- package/dist/events/beforeInputCommands.js +2 -2
- package/dist/events/onBeforeInput.js +1 -1
- package/dist/events/onDrop.d.ts +0 -6
- package/dist/events/onDrop.js +10 -23
- package/dist/events/onInput.d.ts +0 -12
- package/dist/events/onInput.js +1 -67
- package/dist/events/onPageHide.d.ts +3 -0
- package/dist/events/onPageHide.js +16 -0
- package/dist/export/forms.d.ts +627 -0
- package/dist/export/forms.js +749 -0
- package/dist/export/index.d.ts +170 -0
- package/dist/export/index.js +161 -0
- package/dist/export/markdown.d.ts +41 -0
- package/dist/export/markdown.js +585 -0
- package/dist/export/markdownWriter.d.ts +9 -0
- package/dist/export/markdownWriter.js +133 -0
- package/dist/export/mdx.d.ts +15 -0
- package/dist/export/mdx.js +33 -0
- package/dist/index.d.ts +3 -3
- package/dist/index.js +1 -1
- package/dist/kinds.js +1 -1
- package/dist/plugins/anchored.svelte.d.ts +21 -25
- package/dist/plugins/anchored.svelte.js +23 -39
- package/dist/plugins/blockHandles/BlockHandleController.svelte.js +24 -32
- package/dist/plugins/blockHandles/dragPreview.d.ts +26 -7
- package/dist/plugins/blockHandles/dragPreview.js +33 -0
- package/dist/plugins/blockMenu/BlockMenuController.svelte.d.ts +5 -0
- package/dist/plugins/blockMenu/BlockMenuController.svelte.js +7 -2
- package/dist/plugins/blockMenu/blockMenuPlugin.js +5 -50
- package/dist/plugins/chrome.d.ts +27 -5
- package/dist/plugins/chrome.js +24 -9
- package/dist/plugins/code/CodePlugin.svelte +12 -9
- package/dist/plugins/code/header.svelte.js +7 -11
- package/dist/plugins/code/languageMenu.svelte.d.ts +5 -2
- package/dist/plugins/code/languageMenu.svelte.js +13 -20
- package/dist/plugins/columns/ColumnsPlugin.svelte +7 -20
- package/dist/plugins/columns/resize.svelte.d.ts +2 -3
- package/dist/plugins/columns/resize.svelte.js +2 -5
- package/dist/plugins/comments/CommentsController.svelte.d.ts +6 -0
- package/dist/plugins/comments/CommentsController.svelte.js +20 -0
- package/dist/plugins/equation/EquationPlugin.svelte +12 -22
- package/dist/plugins/equation/equation.svelte.d.ts +7 -15
- package/dist/plugins/equation/equation.svelte.js +13 -50
- package/dist/plugins/equation/tex.d.ts +17 -0
- package/dist/plugins/equation/tex.js +42 -0
- package/dist/plugins/fileDrop.d.ts +38 -23
- package/dist/plugins/fileDrop.js +82 -76
- package/dist/plugins/find/FindController.svelte.d.ts +5 -0
- package/dist/plugins/find/FindController.svelte.js +14 -14
- package/dist/plugins/find/findPlugin.js +1 -15
- package/dist/plugins/image/ImageChrome.svelte +8 -2
- package/dist/plugins/image/ImagePlugin.svelte +15 -52
- package/dist/plugins/image/controls.svelte.js +16 -2
- package/dist/plugins/image/toolbar.svelte.d.ts +5 -4
- package/dist/plugins/image/toolbar.svelte.js +21 -31
- package/dist/plugins/index.d.ts +1 -1
- package/dist/plugins/list.svelte.d.ts +9 -0
- package/dist/plugins/list.svelte.js +18 -0
- package/dist/plugins/marquee/marqueePlugin.js +0 -4
- package/dist/plugins/media/AudioPlugin.svelte +1 -1
- package/dist/plugins/media/BookmarkPlugin.svelte +6 -97
- package/dist/plugins/media/EmbedPlugin.svelte +5 -90
- package/dist/plugins/media/EmptySlot.svelte +36 -20
- package/dist/plugins/media/EmptySlot.svelte.d.ts +6 -15
- package/dist/plugins/media/FilePlugin.svelte +1 -19
- package/dist/plugins/media/MediaEmpty.svelte +2 -55
- package/dist/plugins/media/MediaEmpty.svelte.d.ts +18 -14
- package/dist/plugins/media/SourceBlock.svelte +142 -52
- package/dist/plugins/media/SourceBlock.svelte.d.ts +10 -4
- package/dist/plugins/media/VideoPlugin.svelte +1 -1
- package/dist/plugins/media/empty.svelte.js +2 -7
- package/dist/plugins/media/media.d.ts +2 -63
- package/dist/plugins/media/media.js +1 -194
- package/dist/plugins/media/sources.d.ts +60 -0
- package/dist/plugins/media/sources.js +165 -0
- package/dist/plugins/media/urlPaste.svelte.d.ts +2 -1
- package/dist/plugins/media/urlPaste.svelte.js +12 -21
- package/dist/plugins/mention/MentionPlugin.svelte +8 -35
- package/dist/plugins/page/PagePlugin.svelte +2 -9
- package/dist/plugins/page/page.js +1 -1
- package/dist/plugins/pageLink/PageLinkPlugin.svelte +6 -13
- package/dist/plugins/richtext/RichTextPlugin.svelte +85 -197
- package/dist/plugins/richtext/body.js +1 -1
- package/dist/plugins/richtext/calloutIcons.svelte.d.ts +2 -2
- package/dist/plugins/richtext/calloutIcons.svelte.js +5 -7
- package/dist/plugins/richtext/richTextOperations.d.ts +1 -19
- package/dist/plugins/richtext/richTextOperations.js +3 -49
- package/dist/plugins/slashMenu/SlashMenuController.svelte.d.ts +2 -0
- package/dist/plugins/slashMenu/SlashMenuController.svelte.js +7 -0
- package/dist/plugins/slashMenu/slashMenuPlugin.js +5 -14
- package/dist/plugins/table/TableChrome.svelte +2 -3
- package/dist/plugins/table/TablePlugin.svelte +20 -54
- package/dist/plugins/table/chrome.svelte.d.ts +5 -2
- package/dist/plugins/table/chrome.svelte.js +30 -54
- package/dist/plugins/table/table.js +3 -3
- package/dist/plugins/toc/TocPlugin.svelte +2 -4
- package/dist/plugins/toolbar/ToolbarController.svelte.d.ts +7 -0
- package/dist/plugins/toolbar/ToolbarController.svelte.js +20 -13
- package/dist/plugins/toolbar/toolbarPlugin.js +19 -53
- package/dist/plugins/triggers/TriggerController.svelte.d.ts +7 -2
- package/dist/plugins/triggers/TriggerController.svelte.js +11 -4
- package/dist/plugins/triggers/place.js +1 -2
- package/dist/plugins/triggers/triggers.d.ts +6 -1
- package/dist/plugins/triggers/triggers.js +12 -13
- package/dist/plugins/uploads.svelte.d.ts +5 -2
- package/dist/plugins/uploads.svelte.js +25 -15
- package/dist/plugins.d.ts +26 -0
- package/dist/plugins.js +0 -24
- package/dist/selection/replaceSelection.js +2 -2
- package/dist/selection/selection.svelte.d.ts +4 -10
- package/dist/selection/selection.svelte.js +7 -11
- package/dist/session/bindings.js +1 -1
- package/dist/session/commands.d.ts +7 -11
- package/dist/session/commands.js +13 -19
- package/dist/session/inputRules.js +1 -1
- package/dist/session/navigation.js +1 -1
- package/dist/session/suggestions.svelte.d.ts +0 -11
- package/dist/session/suggestions.svelte.js +15 -3
- package/dist/session/uploads.d.ts +8 -8
- package/dist/surface/lines.js +1 -3
- package/dist/surface/observer.svelte.d.ts +17 -1
- package/dist/surface/observer.svelte.js +74 -19
- package/dist/surface/overlay.d.ts +0 -14
- package/dist/surface/overlay.js +0 -25
- package/dist/surface/projector.svelte.d.ts +15 -3
- package/dist/surface/projector.svelte.js +60 -9
- package/dist/text/text.svelte.js +3 -13
- package/dist/utils/sanitize.d.ts +38 -0
- package/dist/utils/sanitize.js +82 -0
- package/dist/utils.d.ts +2 -0
- package/dist/utils.js +5 -0
- package/package.json +19 -2
- package/dist/crdt/placement/rank.d.ts +0 -87
- package/dist/crdt/placement/rank.js +0 -332
- package/dist/crdt/placement/source.d.ts +0 -43
- package/dist/crdt/placement/source.js +0 -66
- package/dist/crdt/text/delete-index.d.ts +0 -129
- package/dist/crdt/text/delete-index.js +0 -365
- package/dist/crdt/text/deletes.d.ts +0 -76
- package/dist/crdt/text/deletes.js +0 -362
- package/dist/crdt/text/index/anchored.d.ts +0 -17
- package/dist/crdt/text/index/anchored.js +0 -197
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/util/max-z-index.js +0 -3
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/util/supports-popover.js +0 -16
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop-auto-scroll/shared/is-axis-allowed.js +0 -3
- package/dist/plugins/code/LanguageMenu.svelte +0 -25
- package/dist/plugins/code/LanguageMenu.svelte.d.ts +0 -9
- package/dist/plugins/equation/EquationEditor.svelte +0 -27
- package/dist/plugins/equation/EquationEditor.svelte.d.ts +0 -9
- package/dist/plugins/image/ImageToolbarHost.svelte +0 -37
- package/dist/plugins/image/ImageToolbarHost.svelte.d.ts +0 -9
- package/dist/plugins/richtext/CalloutIconPicker.svelte +0 -26
- package/dist/plugins/richtext/CalloutIconPicker.svelte.d.ts +0 -9
package/dist/crdt/admission.d.ts
CHANGED
|
@@ -4,14 +4,12 @@
|
|
|
4
4
|
* Every way content enters an {@link EdytorDocument} crosses the same
|
|
5
5
|
* gate here, in the same order, with the same refusal semantics:
|
|
6
6
|
*
|
|
7
|
-
* 1. **`
|
|
8
|
-
* ({@link UnsupportedDocError} `'foreign'`)?
|
|
9
|
-
* 2. **`assertSchema`** — does the committed schema manifest allow
|
|
7
|
+
* 1. **`assertSchema`** — does the committed schema manifest allow
|
|
10
8
|
* this build to own the doc ({@link SchemaMismatchError}:
|
|
11
9
|
* `'unversioned'` content with no version stamp, `'unsupported'`
|
|
12
10
|
* version this build cannot speak, `'foreign'` manifest naming
|
|
13
11
|
* another schema)?
|
|
14
|
-
*
|
|
12
|
+
* 2. **Verdict** — `'fresh'` (registry empty — seeding is legal) or
|
|
15
13
|
* `'initialized'` (supported schema content present — assert and
|
|
16
14
|
* adopt, never seed).
|
|
17
15
|
*
|
|
@@ -59,10 +57,10 @@
|
|
|
59
57
|
* readiness transition, and a pending document never writes or
|
|
60
58
|
* broadcasts a bootstrap block.
|
|
61
59
|
*/
|
|
62
|
-
import { assertSchema,
|
|
60
|
+
import { assertSchema, checkSchema, isInitialized, registryEmpty, schemaVersion, SchemaMismatchError } from './edytor-doc.js';
|
|
63
61
|
import type { SchemaProblem } from './edytor-doc.js';
|
|
64
62
|
import type { EngineApi, EngineDoc, YDoc } from './engine-api.js';
|
|
65
|
-
export { assertSchema,
|
|
63
|
+
export { assertSchema, checkSchema, isInitialized, registryEmpty, schemaVersion, SchemaMismatchError };
|
|
66
64
|
export type { SchemaProblem };
|
|
67
65
|
/**
|
|
68
66
|
* What an admitted doc carries — the `sync()` readiness decision:
|
|
@@ -83,7 +81,7 @@ export type AdmissionResult = {
|
|
|
83
81
|
verdict: AdmissionVerdict;
|
|
84
82
|
} | {
|
|
85
83
|
admitted: false;
|
|
86
|
-
error:
|
|
84
|
+
error: SchemaMismatchError;
|
|
87
85
|
};
|
|
88
86
|
/**
|
|
89
87
|
* Raised when a candidate update cannot even be decoded or integrated —
|
|
@@ -102,9 +100,6 @@ export declare class UndecodableUpdateError extends Error {
|
|
|
102
100
|
* The document-level admission gate — runs the ordered checks and throws
|
|
103
101
|
* the typed refusal:
|
|
104
102
|
*
|
|
105
|
-
* - {@link UnsupportedDocError} `'foreign'` — not a v14 engine doc
|
|
106
|
-
* (foreign roots/engines may still attach *content* later; this is
|
|
107
|
-
* about doc shape);
|
|
108
103
|
* - {@link SchemaMismatchError} `'unversioned' | 'unsupported' |
|
|
109
104
|
* 'foreign'` — a schema claim this build cannot own.
|
|
110
105
|
*
|
package/dist/crdt/admission.js
CHANGED
|
@@ -4,14 +4,12 @@
|
|
|
4
4
|
* Every way content enters an {@link EdytorDocument} crosses the same
|
|
5
5
|
* gate here, in the same order, with the same refusal semantics:
|
|
6
6
|
*
|
|
7
|
-
* 1. **`
|
|
8
|
-
* ({@link UnsupportedDocError} `'foreign'`)?
|
|
9
|
-
* 2. **`assertSchema`** — does the committed schema manifest allow
|
|
7
|
+
* 1. **`assertSchema`** — does the committed schema manifest allow
|
|
10
8
|
* this build to own the doc ({@link SchemaMismatchError}:
|
|
11
9
|
* `'unversioned'` content with no version stamp, `'unsupported'`
|
|
12
10
|
* version this build cannot speak, `'foreign'` manifest naming
|
|
13
11
|
* another schema)?
|
|
14
|
-
*
|
|
12
|
+
* 2. **Verdict** — `'fresh'` (registry empty — seeding is legal) or
|
|
15
13
|
* `'initialized'` (supported schema content present — assert and
|
|
16
14
|
* adopt, never seed).
|
|
17
15
|
*
|
|
@@ -59,11 +57,11 @@
|
|
|
59
57
|
* readiness transition, and a pending document never writes or
|
|
60
58
|
* broadcasts a bootstrap block.
|
|
61
59
|
*/
|
|
62
|
-
import { assertSchema,
|
|
60
|
+
import { assertSchema, checkSchema, isInitialized, registryEmpty, schemaVersion, SchemaMismatchError } from './edytor-doc.js';
|
|
63
61
|
import { asEngineDoc } from './structs.js';
|
|
64
62
|
import { keepingReplaced } from './incarnations.js';
|
|
65
63
|
// ── shared gate vocabulary (one doorway for document + transport layers) ──
|
|
66
|
-
export { assertSchema,
|
|
64
|
+
export { assertSchema, checkSchema, isInitialized, registryEmpty, schemaVersion, SchemaMismatchError };
|
|
67
65
|
/**
|
|
68
66
|
* Raised when a candidate update cannot even be decoded or integrated —
|
|
69
67
|
* refused before the schema question is ever asked. Distinct from the
|
|
@@ -86,9 +84,6 @@ export class UndecodableUpdateError extends Error {
|
|
|
86
84
|
* The document-level admission gate — runs the ordered checks and throws
|
|
87
85
|
* the typed refusal:
|
|
88
86
|
*
|
|
89
|
-
* - {@link UnsupportedDocError} `'foreign'` — not a v14 engine doc
|
|
90
|
-
* (foreign roots/engines may still attach *content* later; this is
|
|
91
|
-
* about doc shape);
|
|
92
87
|
* - {@link SchemaMismatchError} `'unversioned' | 'unsupported' |
|
|
93
88
|
* 'foreign'` — a schema claim this build cannot own.
|
|
94
89
|
*
|
|
@@ -98,7 +93,6 @@ export class UndecodableUpdateError extends Error {
|
|
|
98
93
|
* readiness decision.
|
|
99
94
|
*/
|
|
100
95
|
export const assertAdmission = (doc, docName = 'document') => {
|
|
101
|
-
assertUsableDoc(doc);
|
|
102
96
|
assertSchema(doc, docName);
|
|
103
97
|
return isInitialized(doc) ? 'initialized' : 'fresh';
|
|
104
98
|
};
|
|
@@ -112,7 +106,7 @@ export const inspectAdmission = (doc, docName = 'document') => {
|
|
|
112
106
|
return { admitted: true, verdict: assertAdmission(doc, docName) };
|
|
113
107
|
}
|
|
114
108
|
catch (error) {
|
|
115
|
-
if (error instanceof
|
|
109
|
+
if (error instanceof SchemaMismatchError) {
|
|
116
110
|
return { admitted: false, error };
|
|
117
111
|
}
|
|
118
112
|
throw error;
|
|
@@ -17,10 +17,13 @@
|
|
|
17
17
|
* `u/<actorId>` → profile `{name?, color?}` — one record per
|
|
18
18
|
* stable application actor, referenced by id.
|
|
19
19
|
*
|
|
20
|
-
* Published
|
|
21
|
-
* transaction
|
|
22
|
-
*
|
|
23
|
-
*
|
|
20
|
+
* Published with the replica's first write: inside the first local
|
|
21
|
+
* transaction that writes under its client id (the engine's
|
|
22
|
+
* `beforeCommit`, fork patch YP30), so a replica that only reads writes
|
|
23
|
+
* nothing, and every struct it writes travels with its binding. Readable
|
|
24
|
+
* through `actors`/`actorOf`. These records also travel inside `encode()`
|
|
25
|
+
* output, so `loadDocument` restores the dictionary without
|
|
26
|
+
* republishing.
|
|
24
27
|
*
|
|
25
28
|
* LEGACY RECORDS — documents saved by early builds carry `a/` per-edit
|
|
26
29
|
* records under the same root. They are plain replicated state, preserved
|
|
@@ -35,9 +38,10 @@ import { type BlockAttribution } from './block.js';
|
|
|
35
38
|
/** Reserved replicated root for all attribution metadata (`SCHEMA.roots.attribution`). */
|
|
36
39
|
export { ATTRIBUTION_ROOT };
|
|
37
40
|
/**
|
|
38
|
-
* Origin of
|
|
39
|
-
*
|
|
40
|
-
* out of undo capture; tooling classifies
|
|
41
|
+
* Origin of the profile writes this module performs on its own
|
|
42
|
+
* (`setProfile`; the binding joins the transaction of the replica's first
|
|
43
|
+
* write, whatever its origin). Kept out of undo capture; tooling classifies
|
|
44
|
+
* it as bookkeeping.
|
|
41
45
|
*/
|
|
42
46
|
export declare const ATTRIBUTION_ORIGIN: unique symbol;
|
|
43
47
|
/** The stable application-level author identity (mirrors `DocumentActor`). */
|
|
@@ -57,14 +61,23 @@ export type ActorProfile = {
|
|
|
57
61
|
* records identically and stay correct as old replicas append records.
|
|
58
62
|
*/
|
|
59
63
|
export type DocumentAttribution = {
|
|
60
|
-
/**
|
|
64
|
+
/**
|
|
65
|
+
* actorId → profile — the replicated actor dictionary (`u/` records): the
|
|
66
|
+
* actors whose replicas wrote, each published with its replica's first
|
|
67
|
+
* write (or `setProfile`).
|
|
68
|
+
*/
|
|
61
69
|
readonly actors: ReadonlyMap<string, ActorProfile>;
|
|
62
|
-
/**
|
|
70
|
+
/**
|
|
71
|
+
* Resolve an item's inserting replica (clientID) to an actor id (`c/`
|
|
72
|
+
* records). A replica's binding is written with its first write, so every
|
|
73
|
+
* client id that wrote a struct resolves; one that never wrote does not.
|
|
74
|
+
*/
|
|
63
75
|
actorOf(client: number): string | undefined;
|
|
64
76
|
/**
|
|
65
|
-
* Re-publish the local actor's profile record (`u/<actorId>` — LWW)
|
|
66
|
-
*
|
|
67
|
-
*
|
|
77
|
+
* Re-publish the local actor's profile record (`u/<actorId>` — LWW), a
|
|
78
|
+
* write of this replica (its binding goes with it, as with any first
|
|
79
|
+
* write). Attribution is never relabeled: historical records keep the
|
|
80
|
+
* stable actor id; only the resolvable profile changes.
|
|
68
81
|
*/
|
|
69
82
|
setProfile(profile: ActorProfile): void;
|
|
70
83
|
/**
|
|
@@ -94,6 +107,12 @@ export type AttributionController = {
|
|
|
94
107
|
type AttachOptions = {
|
|
95
108
|
actor: AttributionActor;
|
|
96
109
|
};
|
|
110
|
+
/**
|
|
111
|
+
* The actor `doc`'s own replica writes for: its binding (`c/<clientID>`),
|
|
112
|
+
* else, before its first write, the actor its attribution controller was
|
|
113
|
+
* attached with (`undefined`: a raw doc). The provider's `saved` reads it.
|
|
114
|
+
*/
|
|
115
|
+
export declare const writerOf: (doc: EngineDoc) => string | undefined;
|
|
97
116
|
/** The display profile of `actor`: its name and color, those it has. */
|
|
98
117
|
export declare const profileOf: (actor: AttributionActor) => ActorProfile;
|
|
99
118
|
/**
|
|
@@ -3,13 +3,28 @@ import { blockAttributionOf } from './block.js';
|
|
|
3
3
|
/** Reserved replicated root for all attribution metadata (`SCHEMA.roots.attribution`). */
|
|
4
4
|
export { ATTRIBUTION_ROOT };
|
|
5
5
|
/**
|
|
6
|
-
* Origin of
|
|
7
|
-
*
|
|
8
|
-
* out of undo capture; tooling classifies
|
|
6
|
+
* Origin of the profile writes this module performs on its own
|
|
7
|
+
* (`setProfile`; the binding joins the transaction of the replica's first
|
|
8
|
+
* write, whatever its origin). Kept out of undo capture; tooling classifies
|
|
9
|
+
* it as bookkeeping.
|
|
9
10
|
*/
|
|
10
11
|
export const ATTRIBUTION_ORIGIN = Symbol('edytor.attribution');
|
|
11
12
|
const ACTOR_PREFIX = 'u/'; // actorId → profile records
|
|
12
13
|
const CLIENT_PREFIX = 'c/'; // replica clientID → actorId records
|
|
14
|
+
/** The actor each attached document's replica writes for (its attribution controller's). */
|
|
15
|
+
const localActors = new WeakMap();
|
|
16
|
+
/**
|
|
17
|
+
* The actor `doc`'s own replica writes for: its binding (`c/<clientID>`),
|
|
18
|
+
* else, before its first write, the actor its attribution controller was
|
|
19
|
+
* attached with (`undefined`: a raw doc). The provider's `saved` reads it.
|
|
20
|
+
*/
|
|
21
|
+
export const writerOf = (doc) => {
|
|
22
|
+
// A raw doc without the root gets none (reading would create it).
|
|
23
|
+
const bound = doc.share?.has(ATTRIBUTION_ROOT)
|
|
24
|
+
? doc.get(ATTRIBUTION_ROOT).getAttr(`${CLIENT_PREFIX}${doc.clientID}`)
|
|
25
|
+
: undefined;
|
|
26
|
+
return typeof bound === 'string' && bound.length > 0 ? bound : localActors.get(doc);
|
|
27
|
+
};
|
|
13
28
|
const sanitizeProfile = (value) => {
|
|
14
29
|
const v = (value ?? undefined);
|
|
15
30
|
const out = {};
|
|
@@ -32,14 +47,45 @@ export const profileOf = (actor) => ({
|
|
|
32
47
|
*/
|
|
33
48
|
export const bindAttribution = (_Y) => {
|
|
34
49
|
/**
|
|
35
|
-
* Attach the actor dictionary to `doc
|
|
36
|
-
* `c/`+`u/` records
|
|
37
|
-
*
|
|
50
|
+
* Attach the actor dictionary to `doc` and return the read-through view.
|
|
51
|
+
* This replica's `c/`+`u/` records are written with its first write
|
|
52
|
+
* (`bind`, below), never at attach: a replica that only reads leaves the
|
|
53
|
+
* document as it found it.
|
|
38
54
|
*/
|
|
39
55
|
const attach = (doc, opts) => {
|
|
40
56
|
const actor = opts.actor;
|
|
41
57
|
const root = doc.get(ATTRIBUTION_ROOT);
|
|
42
58
|
let destroyed = false;
|
|
59
|
+
/** The client id this replica's binding was written for (`null`: none yet). */
|
|
60
|
+
let bound = null;
|
|
61
|
+
/**
|
|
62
|
+
* The binding, inside the transaction of the replica's first write
|
|
63
|
+
* under its client id (and again for a new client id, fork patch
|
|
64
|
+
* YP15): `c/<clientID>`, and `u/<actorId>` when the stored profile
|
|
65
|
+
* differs (it is not rewritten at every reload). A binding the
|
|
66
|
+
* document already holds for the id (an attached doc, the room's
|
|
67
|
+
* rebinding) stands.
|
|
68
|
+
*/
|
|
69
|
+
const bind = (transaction) => {
|
|
70
|
+
const tr = transaction;
|
|
71
|
+
const client = doc.clientID;
|
|
72
|
+
if (destroyed || bound === client || !tr.local || !tr.insertSet.clients.has(client))
|
|
73
|
+
return;
|
|
74
|
+
bound = client;
|
|
75
|
+
if (root.getAttr(`${CLIENT_PREFIX}${client}`) !== undefined)
|
|
76
|
+
return;
|
|
77
|
+
root.setAttr(`${CLIENT_PREFIX}${client}`, actor.id);
|
|
78
|
+
// A profile this transaction wrote (`setProfile`) stands.
|
|
79
|
+
const key = `${ACTOR_PREFIX}${actor.id}`;
|
|
80
|
+
if (tr.changed.get(root)?.has(key))
|
|
81
|
+
return;
|
|
82
|
+
const next = profileOf(actor);
|
|
83
|
+
const stored = sanitizeProfile(root.getAttr(key));
|
|
84
|
+
if (stored.name !== next.name || stored.color !== next.color)
|
|
85
|
+
root.setAttr(key, next);
|
|
86
|
+
};
|
|
87
|
+
doc.on('beforeCommit', bind);
|
|
88
|
+
localActors.set(doc, actor.id);
|
|
43
89
|
const setProfile = (profile) => {
|
|
44
90
|
if (destroyed)
|
|
45
91
|
return;
|
|
@@ -47,17 +93,6 @@ export const bindAttribution = (_Y) => {
|
|
|
47
93
|
root.setAttr(`${ACTOR_PREFIX}${actor.id}`, sanitizeProfile(profile));
|
|
48
94
|
}, ATTRIBUTION_ORIGIN);
|
|
49
95
|
};
|
|
50
|
-
doc.transact(() => {
|
|
51
|
-
root.setAttr(`${CLIENT_PREFIX}${doc.clientID}`, actor.id);
|
|
52
|
-
// `u/` is rewritten only when the stored profile actually differs —
|
|
53
|
-
// `c/<clientID>` is always fresh per attach (new clientID) but the
|
|
54
|
-
// profile item + tombstone shouldn't regrow on every reload.
|
|
55
|
-
const next = profileOf(actor);
|
|
56
|
-
const stored = sanitizeProfile(root.getAttr(`${ACTOR_PREFIX}${actor.id}`));
|
|
57
|
-
if (stored.name !== next.name || stored.color !== next.color) {
|
|
58
|
-
root.setAttr(`${ACTOR_PREFIX}${actor.id}`, next);
|
|
59
|
-
}
|
|
60
|
-
}, ATTRIBUTION_ORIGIN);
|
|
61
96
|
const view = {
|
|
62
97
|
get actors() {
|
|
63
98
|
const out = new Map();
|
|
@@ -73,7 +108,7 @@ export const bindAttribution = (_Y) => {
|
|
|
73
108
|
return typeof value === 'string' && value.length > 0 ? value : undefined;
|
|
74
109
|
},
|
|
75
110
|
setProfile,
|
|
76
|
-
//
|
|
111
|
+
// block records live on the `blockattr` root and `l` on
|
|
77
112
|
// the block node — plain replicated reads, no observer needed.
|
|
78
113
|
block: (blockId) => blockAttributionOf(doc, blockId)
|
|
79
114
|
};
|
|
@@ -82,6 +117,9 @@ export const bindAttribution = (_Y) => {
|
|
|
82
117
|
setProfile,
|
|
83
118
|
destroy: () => {
|
|
84
119
|
destroyed = true;
|
|
120
|
+
doc.off('beforeCommit', bind);
|
|
121
|
+
if (localActors.get(doc) === actor.id)
|
|
122
|
+
localActors.delete(doc);
|
|
85
123
|
}
|
|
86
124
|
};
|
|
87
125
|
};
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* One block gets one small replicated record plus one block-node attr:
|
|
5
5
|
*
|
|
6
|
-
* -
|
|
6
|
+
* - `<blockId>` → nested node on the `blockattr` root
|
|
7
7
|
* (`SCHEMA.roots.blockAttribution`) carrying `c` (createdBy actorId)
|
|
8
8
|
* and `k/<actorId>` → true contributor membership.
|
|
9
9
|
* - `l` (lastChangedBy) lives on the block node itself —
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
* again after its creation was undone, or concurrently by two peers), and a
|
|
28
28
|
* delayed remote write always addresses the incarnation its author saw.
|
|
29
29
|
* Every block node carries the replicated nonce `n` of its incarnation;
|
|
30
|
-
* every
|
|
30
|
+
* every record is stamped (`i`) with the nonce it belongs
|
|
31
31
|
* to, and `ensureRecord` swaps in a FRESH record whenever the live node's
|
|
32
32
|
* nonce doesn't match — a late write to a dead incarnation lands on an
|
|
33
33
|
* orphaned record the recreated block never reads. An undo/redo copy of the
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
* - Semantic no-ops (same-value type/data, empty ranges, pure moves)
|
|
49
49
|
* are suppressed by the CALLERS: ops stamp only after a real write.
|
|
50
50
|
*
|
|
51
|
-
* Known residual:
|
|
51
|
+
* Known residual: record nodes are LWW map entries — concurrent FIRST
|
|
52
52
|
* touches of a record-less block (foreign/migrated docs may lack records)
|
|
53
53
|
* can lose one contributor add. Convergent; heals on the next touch.
|
|
54
54
|
*
|
|
@@ -1,17 +1,16 @@
|
|
|
1
1
|
import { REGISTRY_KEY } from '../placement/model.js';
|
|
2
|
-
import { BLOCK_ATTR_ROOT, isNodeLike, LAST_CHANGED_ATTR, NONCE
|
|
2
|
+
import { BLOCK_ATTR_ROOT, isNodeLike, LAST_CHANGED_ATTR, NONCE } from '../schema.js';
|
|
3
3
|
import { attrItems, newNode as makeNode } from '../structs.js';
|
|
4
|
-
// `BLOCK_ATTR_ROOT`/`LAST_CHANGED_ATTR
|
|
4
|
+
// `BLOCK_ATTR_ROOT`/`LAST_CHANGED_ATTR` live in the shared
|
|
5
5
|
// `../schema.js` leaf — re-exported so existing import sites stay.
|
|
6
6
|
export { BLOCK_ATTR_ROOT, LAST_CHANGED_ATTR };
|
|
7
7
|
const REC_NODE = 'brec';
|
|
8
8
|
const CREATED_KEY = 'c';
|
|
9
9
|
const CONTRIBUTOR_PREFIX = 'k/';
|
|
10
|
-
/** Incarnation stamp on a
|
|
10
|
+
/** Incarnation stamp on a record: the nonce `n` of the node it belongs to. */
|
|
11
11
|
const INCARNATION_KEY = 'i';
|
|
12
|
-
const recKey = (id) => `${REC_PREFIX}${id}`;
|
|
13
12
|
const recordOf = (doc, id) => {
|
|
14
|
-
const v = doc.get(BLOCK_ATTR_ROOT).getAttr(
|
|
13
|
+
const v = doc.get(BLOCK_ATTR_ROOT).getAttr(id);
|
|
15
14
|
return isNodeLike(v) ? v : null;
|
|
16
15
|
};
|
|
17
16
|
const blockNodeOf = (doc, id) => {
|
|
@@ -19,7 +18,7 @@ const blockNodeOf = (doc, id) => {
|
|
|
19
18
|
return isNodeLike(v) ? v : null;
|
|
20
19
|
};
|
|
21
20
|
/**
|
|
22
|
-
* Reads resolve whatever record node the
|
|
21
|
+
* Reads resolve whatever record node the block's attr currently elects.
|
|
23
22
|
* Isolation is enforced on the WRITE side — `ensureRecord` swaps a fresh
|
|
24
23
|
* record in when the attr winner's incarnation stamp doesn't match the live
|
|
25
24
|
* block node's nonce — and the attr winner is already convergent.
|
|
@@ -74,7 +73,7 @@ export const blockAttributionOf = (doc, id) => {
|
|
|
74
73
|
export const bindBlockAttribution = (Y) => {
|
|
75
74
|
const newNode = (name) => makeNode(Y, name);
|
|
76
75
|
/**
|
|
77
|
-
* Get-or-create the
|
|
76
|
+
* Get-or-create the record for `node`'s incarnation (its nonce).
|
|
78
77
|
* A record stamped for another incarnation is dead state — a fresh record
|
|
79
78
|
* replaces it as the attr winner (the orphan stays readable only as the
|
|
80
79
|
* last-incarnation fallback). `node` defaults to the id's current registry
|
|
@@ -87,7 +86,7 @@ export const bindBlockAttribution = (Y) => {
|
|
|
87
86
|
return existing;
|
|
88
87
|
}
|
|
89
88
|
const rec = newNode(REC_NODE);
|
|
90
|
-
doc.get(BLOCK_ATTR_ROOT).setAttr(
|
|
89
|
+
doc.get(BLOCK_ATTR_ROOT).setAttr(id, rec);
|
|
91
90
|
if (n !== undefined)
|
|
92
91
|
rec.setAttr(INCARNATION_KEY, n);
|
|
93
92
|
return rec;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Public surface of the attribution service. `block.ts` holds the
|
|
3
|
-
* compact per-block records (`
|
|
3
|
+
* compact per-block records (`blockattr` `<blockId>` + the block-node `l` attr)
|
|
4
4
|
* written inside the owning facade op's transaction. `attribution.ts`
|
|
5
5
|
* holds the actor dictionary (`u/`/`c/`) plus inert reads over
|
|
6
6
|
* pre-existing `a/` per-edit records written by retired builds.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Public surface of the attribution service. `block.ts` holds the
|
|
3
|
-
* compact per-block records (`
|
|
3
|
+
* compact per-block records (`blockattr` `<blockId>` + the block-node `l` attr)
|
|
4
4
|
* written inside the owning facade op's transaction. `attribution.ts`
|
|
5
5
|
* holds the actor dictionary (`u/`/`c/`) plus inert reads over
|
|
6
6
|
* pre-existing `a/` per-edit records written by retired builds.
|
package/dist/crdt/data.d.ts
CHANGED
|
@@ -5,27 +5,30 @@
|
|
|
5
5
|
* leaf's path as an RFC 6901 pointer without its leading `/` (`~` → `~0`,
|
|
6
6
|
* `/` → `~1`). A leaf is a primitive, `null` or an empty container (`{}`,
|
|
7
7
|
* `[]`), so an emptied one persists. An array is its `[]` leaf plus its
|
|
8
|
-
* items
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
8
|
+
* items: item `id` keeps its value under the segment `~id` (a primitive at
|
|
9
|
+
* it, an object's or array's leaves under it), and its existence and place
|
|
10
|
+
* are its SLOT `{ p, i }` in the owner's one order sequence — the node's
|
|
11
|
+
* list part (`placement/slots.ts`, fork patch YP22): an item lives while a
|
|
12
|
+
* live slot of its id does (the first live slot of an id counts: two peers
|
|
13
|
+
* adopting one array write two), the order is the sequence's, and a move is
|
|
14
|
+
* a move record there. `~` and a letter is no escape, so no key reads as an
|
|
15
|
+
* item. Each leaf is a map entry, so different keys and different items
|
|
16
|
+
* merge and one key is last writer wins; a delete removes the item's slots
|
|
17
|
+
* and leaves, so a concurrent edit inside it or move of it leaves orphans
|
|
18
|
+
* the read skips. A path names an item by index or by id, so a held item
|
|
19
|
+
* is reached wherever peers moved it; an id that names no live item
|
|
20
|
+
* refuses the patch, so nothing is written under a dead item. A key
|
|
21
|
+
* starting with `~` is `~0…` in a path (`keySegment`).
|
|
20
22
|
*
|
|
21
23
|
* Read rule: the leaves are read as a tree; a path with live items is an
|
|
22
|
-
* array (
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
24
|
+
* array (in slot order), one with keys an object (it beats a primitive leaf
|
|
25
|
+
* at the same path: Ada sets `a = 1` while Bob sets `a.b = 2`), else its
|
|
26
|
+
* leaf. A leaf holding an object or an array (an atomic path's,
|
|
27
|
+
* `data.atomic`, or an array 0.1.0-next.6 wrote) reads as its keys or as
|
|
28
|
+
* items with ids derived from the array (as any array assigned where no
|
|
29
|
+
* item is), so two replicas writing into it write the same items; a patch
|
|
30
|
+
* opens it only along its path, and the first write through it gives every
|
|
31
|
+
* item its slot.
|
|
29
32
|
*/
|
|
30
33
|
import type { EngineNode } from './engine-api.js';
|
|
31
34
|
type JsonObj = Record<string, unknown>;
|
|
@@ -43,6 +46,28 @@ export type DataPatch = {
|
|
|
43
46
|
};
|
|
44
47
|
/** An attr write a patch plans: the key and its value, `undefined` to delete it. */
|
|
45
48
|
export type LeafWrite = readonly [key: string, value: unknown];
|
|
49
|
+
/**
|
|
50
|
+
* A sequence write a patch plans (`placement/slots.ts`): new items' slots
|
|
51
|
+
* after item `after` (`null`: first) of the array at `path`, a move of items
|
|
52
|
+
* there, or the removal of items' slots.
|
|
53
|
+
*/
|
|
54
|
+
export type SlotWrite = {
|
|
55
|
+
seq: 'insert';
|
|
56
|
+
path: string;
|
|
57
|
+
after: string | null;
|
|
58
|
+
ids: string[];
|
|
59
|
+
} | {
|
|
60
|
+
seq: 'move';
|
|
61
|
+
path: string;
|
|
62
|
+
after: string | null;
|
|
63
|
+
ids: string[];
|
|
64
|
+
} | {
|
|
65
|
+
seq: 'remove';
|
|
66
|
+
path: string;
|
|
67
|
+
ids: string[];
|
|
68
|
+
};
|
|
69
|
+
/** One write a data patch plans. */
|
|
70
|
+
export type DataWrite = LeafWrite | SlotWrite;
|
|
46
71
|
export declare const isObject: (v: unknown) => v is JsonObj;
|
|
47
72
|
/**
|
|
48
73
|
* Key `k` as a patch path segment: a leading `~` as `~0` (RFC 6901), so a
|
|
@@ -62,8 +87,8 @@ export declare const segmentKey: (s: string) => string;
|
|
|
62
87
|
* `arrange` pairs those items by position.
|
|
63
88
|
*/
|
|
64
89
|
export declare const common: (a: readonly string[], b: readonly string[]) => [number, number][];
|
|
65
|
-
/** A new node's data, as leaves. */
|
|
66
|
-
export declare const
|
|
90
|
+
/** A new node's data, as the writes that give it (its leaves and its arrays' slots). */
|
|
91
|
+
export declare const dataWrites: (data: unknown) => DataWrite[];
|
|
67
92
|
/** A path of the data as a leaf key (`d/` and its pointer). */
|
|
68
93
|
export declare const leafKey: (path: readonly string[]) => string;
|
|
69
94
|
/** `node`'s data (`undefined` when it has none). */
|
|
@@ -76,7 +101,7 @@ export declare const itemIds: (node: EngineNode, path: readonly string[]) => str
|
|
|
76
101
|
/**
|
|
77
102
|
* `node`'s data as it reads once `patches` are applied (nothing written),
|
|
78
103
|
* with the ids of the array items at a path (`itemIds`): an item a patch
|
|
79
|
-
* makes has no
|
|
104
|
+
* makes has no slot yet (`''`), so a later patch names it by index.
|
|
80
105
|
* `null` when a patch fits no value.
|
|
81
106
|
*/
|
|
82
107
|
export declare const previewData: (node: EngineNode | undefined, patches: readonly DataPatch[]) => {
|
|
@@ -86,14 +111,20 @@ export declare const previewData: (node: EngineNode | undefined, patches: readon
|
|
|
86
111
|
/** `data` with `patches` applied in order, as a fresh value (a root patch replaces it); `null` when one fits no value. */
|
|
87
112
|
export declare const applyPatch: (data: JsonObj, patches: readonly DataPatch[]) => JsonObj | null;
|
|
88
113
|
/**
|
|
89
|
-
* The
|
|
90
|
-
* items get ids from `rand
|
|
91
|
-
*
|
|
92
|
-
*
|
|
93
|
-
*
|
|
94
|
-
* An unchanged value
|
|
114
|
+
* The writes that give `node` the data `patches` make of its own (new
|
|
115
|
+
* items get ids from `rand`), or `null` when a patch fits no value there:
|
|
116
|
+
* only the leaves of the keys and items a patch touches change, so a
|
|
117
|
+
* concurrent edit of another key or item is kept, and only the slots of
|
|
118
|
+
* the items it makes, moves or removes. An atomic path is written as one
|
|
119
|
+
* leaf and the leaves and slots under it are dropped. An unchanged value
|
|
120
|
+
* writes nothing.
|
|
121
|
+
*/
|
|
122
|
+
export declare const patchWrites: (node: EngineNode, patches: readonly DataPatch[], client?: number, rand?: () => number, atomic?: readonly string[]) => DataWrite[] | null;
|
|
123
|
+
/**
|
|
124
|
+
* Write `writes` on `node`: its attrs, and its arrays' slots in its one
|
|
125
|
+
* sequence (`placement/slots.ts`). On a detached node (a block or atom being
|
|
126
|
+
* created) the slots are appended in order; on an integrated one each write
|
|
127
|
+
* goes after the item it names, read from the sequence as it stands.
|
|
95
128
|
*/
|
|
96
|
-
export declare const
|
|
97
|
-
/** Write `writes` on `node` (a detached one too: a block or atom being created). */
|
|
98
|
-
export declare const writeLeaves: (node: EngineNode, writes: Iterable<LeafWrite>) => void;
|
|
129
|
+
export declare const writeData: (node: EngineNode, writes: Iterable<DataWrite>) => void;
|
|
99
130
|
export {};
|