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
|
@@ -3,41 +3,42 @@
|
|
|
3
3
|
* ownership the display reads (`ownShim`), and THE shown-kind rule
|
|
4
4
|
* (`typeOf`).
|
|
5
5
|
*
|
|
6
|
-
* A structural change re-decides only what it can change: the
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* (`
|
|
14
|
-
*
|
|
15
|
-
*
|
|
6
|
+
* A structural change re-decides only what it can change: the display
|
|
7
|
+
* edge of the blocks whose slot, record or mover changed (fork patch
|
|
8
|
+
* YP22), and the display slot of every block whose slot walk
|
|
9
|
+
* (`displaySlotOf`) reads one that changed — its stored subtree, through
|
|
10
|
+
* the blocks it displays — patched into the parents' child lists. A
|
|
11
|
+
* block's candidate edges are its live move records, strongest first, then
|
|
12
|
+
* its home slot; it shows at the first that closes no cycle through the
|
|
13
|
+
* accepted edges (`settle`): the later move wins, and the block whose edge
|
|
14
|
+
* is the oldest of a cycle falls back to its next candidate, back where it
|
|
15
|
+
* stood (its previous record, else home; the root's tail only when every
|
|
16
|
+
* candidate closes a cycle), so a cycle resolves locally: no global pass.
|
|
17
|
+
* The first build places every block the same way (their unique acyclic
|
|
18
|
+
* acceptance, whatever the order; the tests' greedy rebuild,
|
|
19
|
+
* `src/tests/oracles/placements.ts`, is what the self-checks compare). A
|
|
20
|
+
* placed block's order key is found from its sequence neighbours
|
|
21
|
+
* (`placement/keys.ts`), never by walking the parent's sequence; a rebuild
|
|
22
|
+
* keys every list once, in its sequence's order. The layout rules re-run
|
|
23
|
+
* only on the layouts a change reaches.
|
|
16
24
|
*/
|
|
17
|
-
import { bySlot, childrenIndex, displaySlotOf, documentOrder
|
|
25
|
+
import { bySlot, childrenIndex, displaySlotOf, documentOrder } from '../../placement/model.js';
|
|
26
|
+
import { denseKey, keyBetween } from '../../placement/keys.js';
|
|
27
|
+
import { NO_SLOT, byTail, candidatesOf, cycleThrough, edgeParentOf, collectSlots, homeOf, registryOwners, ownerOfNode, positionsOfItem, slotOwner, slotsBefore } from '../../placement/resolve.js';
|
|
28
|
+
import { cmpStamp, sameUnit } from '../../placement/slots.js';
|
|
29
|
+
import { Y } from '../../engine.js';
|
|
30
|
+
import { engineOps, firstItem } from '../../structs.js';
|
|
18
31
|
import { DEAD, displayOf } from '../model.js';
|
|
19
|
-
import { addTo, dropFrom } from './shared.js';
|
|
20
32
|
/** Placement maintenance of one doc's index, over its state, claims, streams and layout rules. */
|
|
21
33
|
export const indexPlacement = (ix) => {
|
|
22
|
-
const {
|
|
34
|
+
const { doc, registry, blocks, displaysMap, ownerChanged, placementsMap, following, dirtyLists, leftLists, placementSeeds, stateSeeds, kindsOf, slotsByBlock, rawOrder, edges, fallen, rejected, ensureOwners, ownerOf, top, streamOf, streamsIn, streamAt, role, lineKind, itemKind, rowKind, rowOfTable, declaredRows, cellKind, cellRank, declaredItems, dissolve, redissolve } = ix;
|
|
35
|
+
const kept = engineOps(Y).isKeptReplaced;
|
|
23
36
|
// ── placements and the children index (maintained) ────────────
|
|
24
|
-
/** The blocks of `home`'s text, in text order (segment 0's first). */
|
|
25
|
-
const rowBlocks = (home) => {
|
|
26
|
-
const at = placed.get(home);
|
|
27
|
-
if (at === undefined)
|
|
28
|
-
return [];
|
|
29
|
-
return at.head === null ? at.blocks : [at.head, ...at.blocks];
|
|
30
|
-
};
|
|
31
|
-
const ranker = textRanker(blocks, placementsMap, (b) => streamIx.get(b)?.home, rowBlocks);
|
|
32
|
-
/** Resolved parent → the blocks placed under it. */
|
|
33
|
-
const kidsOf = new Map();
|
|
34
37
|
/** The document holds a layout or an item kind: `kids0` and `kidsMap` differ. */
|
|
35
38
|
let layoutMode = false;
|
|
36
39
|
/** The line kinds the roles declare, and those of the lines islands the document holds. */
|
|
37
40
|
let lineKinds = new Set();
|
|
38
41
|
let orderCache = null;
|
|
39
|
-
/** Some block shows no argmax candidate (a cycle rejected one, or none): passes run whole. */
|
|
40
|
-
let irregular = false;
|
|
41
42
|
let layoutBlocks = 0;
|
|
42
43
|
let itemBlocks = 0;
|
|
43
44
|
/** Tables, rows and cells (`table.*`): their rules run in the layout pass. */
|
|
@@ -58,11 +59,11 @@ export const indexPlacement = (ix) => {
|
|
|
58
59
|
},
|
|
59
60
|
slotRank: (owner, id) => cellRank(owner, id),
|
|
60
61
|
top,
|
|
62
|
+
claimIndex: (holder, m) => blocks.get(holder)?.claims.findIndex((c) => c.m === m) ?? -1,
|
|
61
63
|
streamOf,
|
|
62
64
|
streamsIn,
|
|
63
65
|
streamAt,
|
|
64
|
-
display: (b) => displayOf(b, blocks, ownShim)
|
|
65
|
-
textRank: (id, parent, rank) => ranker.rank(id, parent, rank)
|
|
66
|
+
display: (b) => displayOf(b, blocks, ownShim)
|
|
66
67
|
};
|
|
67
68
|
/** Re-count `id`'s kind facts; a fact the roles never declared forces a full pass. */
|
|
68
69
|
const noteKind = (id) => {
|
|
@@ -108,17 +109,6 @@ export const indexPlacement = (ix) => {
|
|
|
108
109
|
if (layoutMode !== layoutBlocks + itemBlocks + tableBlocks > 0)
|
|
109
110
|
ix.placementFull = true;
|
|
110
111
|
};
|
|
111
|
-
/** The argmax candidate's parent (a registry entry or the root), and its index entry. */
|
|
112
|
-
const argParent = (rec) => rec?.cands[0]?.p;
|
|
113
|
-
const noteCands = (id, before) => {
|
|
114
|
-
const after = argParent(blocks.get(id));
|
|
115
|
-
if (before === after)
|
|
116
|
-
return;
|
|
117
|
-
if (typeof before === 'string')
|
|
118
|
-
dropFrom(byArgParent, before, id);
|
|
119
|
-
if (typeof after === 'string')
|
|
120
|
-
addTo(byArgParent, after, id);
|
|
121
|
-
};
|
|
122
112
|
/** The ownership the layout rules read: none of their decisions applied. */
|
|
123
113
|
const own0 = {
|
|
124
114
|
...ownShim,
|
|
@@ -210,12 +200,12 @@ export const indexPlacement = (ix) => {
|
|
|
210
200
|
if (out.has(x))
|
|
211
201
|
continue;
|
|
212
202
|
out.add(x);
|
|
213
|
-
for (const c of
|
|
214
|
-
stack.push(c);
|
|
203
|
+
for (const c of rawOrder.get(x) ?? [])
|
|
204
|
+
stack.push(c.id);
|
|
215
205
|
for (const d of displaysMap.get(x) ?? [])
|
|
216
206
|
if (d !== x)
|
|
217
|
-
for (const c of
|
|
218
|
-
stack.push(c);
|
|
207
|
+
for (const c of rawOrder.get(d) ?? [])
|
|
208
|
+
stack.push(c.id);
|
|
219
209
|
}
|
|
220
210
|
return out;
|
|
221
211
|
};
|
|
@@ -231,48 +221,282 @@ export const indexPlacement = (ix) => {
|
|
|
231
221
|
else
|
|
232
222
|
following.delete(id);
|
|
233
223
|
};
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
224
|
+
// ── edges, keys and acceptance ─────────────────────────────────
|
|
225
|
+
/**
|
|
226
|
+
* Whether the slot map has been read from the sequences: once, before the
|
|
227
|
+
* first rebuild (a shell settled on the first fold asks for a home), then
|
|
228
|
+
* the fold keeps it and every rebuild fills it again.
|
|
229
|
+
*/
|
|
230
|
+
let slotsRead = false;
|
|
231
|
+
/** What the first read collected, for a rebuild while no sequence changed since (one scan). */
|
|
232
|
+
let collected = null;
|
|
233
|
+
let collectedAt = -1;
|
|
234
|
+
const readSlots = () => {
|
|
235
|
+
slotsRead = true;
|
|
236
|
+
slotsByBlock.clear();
|
|
237
|
+
// Every registry node, its kept incarnations too (the records may not all be built yet).
|
|
238
|
+
collected = collectSlots(doc, registryOwners(registry, kept));
|
|
239
|
+
collectedAt = ix.seqEpoch;
|
|
240
|
+
for (const [b, refs] of collected.slots)
|
|
241
|
+
slotsByBlock.set(b, refs);
|
|
244
242
|
};
|
|
245
|
-
/**
|
|
246
|
-
const
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
243
|
+
/** Put `ref` (`null`: none) where the slot map holds unit `u` of the slots naming id `b`. */
|
|
244
|
+
const putSlot = (b, u, ref) => {
|
|
245
|
+
const list = (slotsByBlock.get(b) ?? []).filter((x) => !sameUnit(x, u));
|
|
246
|
+
if (ref !== null)
|
|
247
|
+
list.push(ref);
|
|
248
|
+
if (list.length === 0)
|
|
249
|
+
slotsByBlock.delete(b);
|
|
250
|
+
else
|
|
251
|
+
slotsByBlock.set(b, list);
|
|
252
|
+
};
|
|
253
|
+
/** `id`'s home slot among the slots naming its registry id (`null`: none). */
|
|
254
|
+
const homeFor = (id) => {
|
|
255
|
+
if (!slotsRead)
|
|
256
|
+
readSlots();
|
|
257
|
+
return homeOf(registry, kept, slotsByBlock, id);
|
|
259
258
|
};
|
|
259
|
+
/**
|
|
260
|
+
* Re-own the home slots of `node`'s sequence after the registry value it
|
|
261
|
+
* stands for changed (a concurrent creation of one id won or lost, its
|
|
262
|
+
* losing incarnation shown or not): each slot's parent is the node's owner
|
|
263
|
+
* now, and its block re-placed; a node that is no block of the document
|
|
264
|
+
* any more holds no slot (as a rebuild reads it).
|
|
265
|
+
*/
|
|
266
|
+
const reslot = (node) => {
|
|
267
|
+
if (!slotsRead)
|
|
268
|
+
return; // the first read collects them as they are
|
|
269
|
+
const owner = ownerOfNode(registry, kept, node);
|
|
270
|
+
for (let it = firstItem(node); it !== null; it = it.right)
|
|
271
|
+
for (const { value, unit, via } of positionsOfItem(doc, it)) {
|
|
272
|
+
if (via !== null)
|
|
273
|
+
continue; // a record's unit is another sequence's slot
|
|
274
|
+
const b = value.b;
|
|
275
|
+
putSlot(b, unit, owner === undefined ? null : { parent: owner, ...unit });
|
|
276
|
+
for (const id of new Set([b, slotOwner(registry, kept, b, unit.c)])) {
|
|
277
|
+
const rec = blocks.get(id);
|
|
278
|
+
if (rec !== undefined)
|
|
279
|
+
rec.home = homeOf(registry, kept, slotsByBlock, id);
|
|
280
|
+
placementSeeds.add(id);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
};
|
|
284
|
+
/** The slot items a rebuild collected (its homes' items, read once), while it places every block. */
|
|
285
|
+
let known = null;
|
|
286
|
+
/** `id`'s candidate edges, read from the engine: its live records, strongest first, then home (`[]`: no slot, or gone). */
|
|
287
|
+
const candidatesFor = (id) => {
|
|
288
|
+
const home = blocks.get(id)?.home ?? homeFor(id);
|
|
289
|
+
return home === null ? [] : candidatesOf(doc, registry, kept, home, known?.get(home));
|
|
290
|
+
};
|
|
291
|
+
/** The owner of the sequence `id`'s slot shows in as the engine stands (its mover's, else home's; `null`: the root). */
|
|
292
|
+
const edgeParent = (id) => {
|
|
293
|
+
const home = blocks.get(id)?.home ?? homeFor(id);
|
|
294
|
+
return home === null ? undefined : edgeParentOf(doc, registry, kept, home);
|
|
295
|
+
};
|
|
296
|
+
/** The raw children of `parent` in order (every block whose edge parent it is), kept sorted by key. */
|
|
297
|
+
const rawList = (parent) => {
|
|
298
|
+
let l = rawOrder.get(parent);
|
|
299
|
+
if (l === undefined)
|
|
300
|
+
rawOrder.set(parent, (l = []));
|
|
301
|
+
return l;
|
|
302
|
+
};
|
|
303
|
+
/** Counts the placement writes: a key's walk that saw one happen under it walks again. */
|
|
304
|
+
let placedEpoch = 0;
|
|
305
|
+
/** Whether a placement is keyed as it is decided: not while a rebuild places every block (it keys them after, in one pass). */
|
|
306
|
+
let keyed = true;
|
|
260
307
|
const setPlacement = (id, pl) => {
|
|
308
|
+
ix.foldStats.placed++;
|
|
309
|
+
placedEpoch++;
|
|
261
310
|
const old = placementsMap.get(id);
|
|
262
|
-
if (old !== undefined)
|
|
263
|
-
|
|
311
|
+
if (keyed && old !== undefined) {
|
|
312
|
+
const l = rawList(old.parent);
|
|
313
|
+
const at = seek(l, { id, rank: old.rank });
|
|
314
|
+
if (l[at]?.id === id)
|
|
315
|
+
l.splice(at, 1);
|
|
316
|
+
if (l.length === 0)
|
|
317
|
+
rawOrder.delete(old.parent);
|
|
318
|
+
}
|
|
264
319
|
if (pl === undefined)
|
|
265
320
|
placementsMap.delete(id);
|
|
266
321
|
else {
|
|
267
322
|
placementsMap.set(id, pl);
|
|
268
|
-
|
|
323
|
+
if (!keyed)
|
|
324
|
+
return;
|
|
325
|
+
const l = rawList(pl.parent);
|
|
326
|
+
const slot = { id, rank: pl.rank };
|
|
327
|
+
l.splice(seek(l, slot), 0, slot);
|
|
328
|
+
}
|
|
329
|
+
};
|
|
330
|
+
/**
|
|
331
|
+
* The key `id` takes under `edge.parent`: between the key of the nearest
|
|
332
|
+
* block shown where it stands before `id`'s place in the sequence (placed
|
|
333
|
+
* first when it is a pending seed; walked past when it shows elsewhere)
|
|
334
|
+
* and the next key of that list. Placing a pending neighbour can drop a
|
|
335
|
+
* block the walk already passed back into that stretch (a cycle's
|
|
336
|
+
* fallback, back where it stood): a walk under which a placement changed
|
|
337
|
+
* walks again, so the key it returns reads one state.
|
|
338
|
+
*/
|
|
339
|
+
const keyFor = (id, edge, place) => {
|
|
340
|
+
for (;;) {
|
|
341
|
+
const before = placedEpoch;
|
|
342
|
+
const lrank = leftKey(id, edge, place);
|
|
343
|
+
if (placedEpoch !== before)
|
|
344
|
+
continue;
|
|
345
|
+
const list = rawOrder.get(edge.parent) ?? [];
|
|
346
|
+
const i = lrank === undefined ? 0 : seek(list, { id: '', rank: lrank }) + 1;
|
|
347
|
+
return keyBetween(lrank, list[i]?.rank);
|
|
348
|
+
}
|
|
349
|
+
};
|
|
350
|
+
/** The key of the nearest block shown before `id`'s place at `edge`, under its parent (`undefined`: none). */
|
|
351
|
+
const leftKey = (id, edge, place) => {
|
|
352
|
+
const home = blocks.get(id)?.home ?? homeFor(id);
|
|
353
|
+
for (const e of slotsBefore(doc, edge, home)) {
|
|
354
|
+
const b = slotOwner(registry, kept, e.value.b, e.unit.c);
|
|
355
|
+
// `id` itself (its place before this one) keys nothing.
|
|
356
|
+
if (b === id)
|
|
357
|
+
continue;
|
|
358
|
+
// A slot that is not its block's home (a second creation of one id) places nothing.
|
|
359
|
+
const h = blocks.get(b)?.home ?? homeFor(b);
|
|
360
|
+
if (h === null || !sameUnit(h, e.unit))
|
|
361
|
+
continue;
|
|
362
|
+
place(b);
|
|
363
|
+
const pl = placementsMap.get(b);
|
|
364
|
+
const shows = edges.get(b);
|
|
365
|
+
if (pl !== undefined &&
|
|
366
|
+
pl.parent === edge.parent &&
|
|
367
|
+
!rejected.has(b) &&
|
|
368
|
+
shows != null &&
|
|
369
|
+
shows.via === e.via)
|
|
370
|
+
return pl.rank;
|
|
371
|
+
}
|
|
372
|
+
return undefined;
|
|
373
|
+
};
|
|
374
|
+
/** The key of `id` at the root's tail, among the rejected by stamp then id, after the last top-level block. */
|
|
375
|
+
const tailKey = (id, stamp) => {
|
|
376
|
+
const tail = [...rejected]
|
|
377
|
+
.filter((x) => x !== id)
|
|
378
|
+
.map((x) => ({ id: x, stamp: edges.get(x)?.stamp ?? NO_SLOT }))
|
|
379
|
+
.sort(byTail);
|
|
380
|
+
const list = rawOrder.get(null) ?? [];
|
|
381
|
+
const me = { id, stamp };
|
|
382
|
+
let at = 0;
|
|
383
|
+
while (at < tail.length && byTail(tail[at], me) < 0)
|
|
384
|
+
at++;
|
|
385
|
+
const prev = at > 0
|
|
386
|
+
? placementsMap.get(tail[at - 1].id)?.rank
|
|
387
|
+
: list[list.length - tail.length - 1]?.rank;
|
|
388
|
+
const next = at < tail.length ? placementsMap.get(tail[at].id)?.rank : undefined;
|
|
389
|
+
return keyBetween(prev, next);
|
|
390
|
+
};
|
|
391
|
+
/** Show `id` at the root's tail: every edge closes a cycle, or none. */
|
|
392
|
+
const reject = (id, edge) => {
|
|
393
|
+
edges.set(id, edge);
|
|
394
|
+
if (placementsMap.has(id))
|
|
395
|
+
setPlacement(id, undefined);
|
|
396
|
+
fallen.delete(id);
|
|
397
|
+
rejected.add(id);
|
|
398
|
+
const rank = keyed ? tailKey(id, edge?.stamp ?? NO_SLOT) : '';
|
|
399
|
+
setPlacement(id, { parent: null, rank });
|
|
400
|
+
};
|
|
401
|
+
/** The same display edge: the same sequence, the same record, the same stamp. */
|
|
402
|
+
const sameEdge = (a, b) => a.parent === b.parent && a.via === b.via && cmpStamp(a.stamp, b.stamp) === 0;
|
|
403
|
+
/** Whether `edge` (of `id`) is a place `id` may take now: a live parent, and no cycle it would be the oldest edge of. */
|
|
404
|
+
const admits = (id, edge) => {
|
|
405
|
+
const parent = edge.parent;
|
|
406
|
+
if (parent === undefined || (parent !== null && !blocks.has(parent)))
|
|
407
|
+
return { ok: false, drop: null };
|
|
408
|
+
const cycle = cycleThrough(placementsMap, ownerOf, id, parent);
|
|
409
|
+
if (cycle === null)
|
|
410
|
+
return { ok: true, drop: null };
|
|
411
|
+
let [min, minStamp] = [id, edge.stamp];
|
|
412
|
+
for (const m of cycle) {
|
|
413
|
+
const e = m === id ? edge : edges.get(m);
|
|
414
|
+
if (m !== id && e && cmpStamp(e.stamp, minStamp) < 0)
|
|
415
|
+
[min, minStamp] = [m, e.stamp];
|
|
416
|
+
}
|
|
417
|
+
return min === id ? { ok: false, drop: null } : { ok: true, drop: min };
|
|
418
|
+
};
|
|
419
|
+
/**
|
|
420
|
+
* Place `id` at its strongest candidate edge from `from` on that closes no
|
|
421
|
+
* cycle it would be the oldest edge of (the later move wins). When the
|
|
422
|
+
* edge closes a cycle through an older edge, that edge's block is dropped
|
|
423
|
+
* to its next candidate (back where it stood before that move), and so on
|
|
424
|
+
* down its records to home; a block every candidate of which fails shows
|
|
425
|
+
* at the root's tail. `place` places a pending neighbour first. Returns
|
|
426
|
+
* the blocks whose placement changed.
|
|
427
|
+
*/
|
|
428
|
+
const settle = (id, place, from = 0) => {
|
|
429
|
+
const changed = [id];
|
|
430
|
+
const cands = candidatesFor(id);
|
|
431
|
+
for (let n = from; n < cands.length; n++) {
|
|
432
|
+
const edge = cands[n];
|
|
433
|
+
// The key first: its walk places the pending neighbours, so the cycle
|
|
434
|
+
// check reads them placed (a neighbour placed after it could close a
|
|
435
|
+
// cycle through `id` that no check saw).
|
|
436
|
+
const rank = keyed ? keyFor(id, edge, place) : '';
|
|
437
|
+
const { ok, drop } = admits(id, edge);
|
|
438
|
+
if (!ok)
|
|
439
|
+
continue;
|
|
440
|
+
edges.set(id, edge);
|
|
441
|
+
rejected.delete(id);
|
|
442
|
+
if (n > 0)
|
|
443
|
+
fallen.add(id);
|
|
444
|
+
else
|
|
445
|
+
fallen.delete(id);
|
|
446
|
+
if (placementsMap.has(id))
|
|
447
|
+
setPlacement(id, undefined);
|
|
448
|
+
setPlacement(id, { parent: edge.parent, rank });
|
|
449
|
+
if (drop !== null) {
|
|
450
|
+
const now = edges.get(drop);
|
|
451
|
+
const at = now ? candidatesFor(drop).findIndex((c) => sameEdge(c, now)) : -1;
|
|
452
|
+
changed.push(...settle(drop, () => { }, at + 1));
|
|
453
|
+
}
|
|
454
|
+
return changed;
|
|
455
|
+
}
|
|
456
|
+
reject(id, cands[0] ?? null);
|
|
457
|
+
return changed;
|
|
458
|
+
};
|
|
459
|
+
/** Whether a candidate stronger than `id`'s accepted edge would take it now. */
|
|
460
|
+
const canRise = (id) => {
|
|
461
|
+
const cands = candidatesFor(id);
|
|
462
|
+
const now = edges.get(id);
|
|
463
|
+
const at = rejected.has(id) || !now ? cands.length : cands.findIndex((c) => sameEdge(c, now));
|
|
464
|
+
for (let n = 0; n < (at < 0 ? cands.length : at); n++)
|
|
465
|
+
if (admits(id, cands[n]).ok)
|
|
466
|
+
return true;
|
|
467
|
+
return false;
|
|
468
|
+
};
|
|
469
|
+
/**
|
|
470
|
+
* Try every block below its strongest edge again (a changed edge may have
|
|
471
|
+
* broken its cycle, or made another the one to drop): those that rise join
|
|
472
|
+
* `moved`.
|
|
473
|
+
*/
|
|
474
|
+
const retryFallen = (moved) => {
|
|
475
|
+
for (let round = 0; round < fallen.size + rejected.size + 2; round++) {
|
|
476
|
+
let changed = false;
|
|
477
|
+
const below = [...rejected, ...fallen]
|
|
478
|
+
.map((x) => ({ id: x, stamp: candidatesFor(x)[0]?.stamp ?? NO_SLOT }))
|
|
479
|
+
.sort((a, b) => -byTail(a, b));
|
|
480
|
+
for (const { id } of below) {
|
|
481
|
+
if (!canRise(id))
|
|
482
|
+
continue;
|
|
483
|
+
for (const x of settle(id, () => { }))
|
|
484
|
+
moved.add(x);
|
|
485
|
+
changed = true;
|
|
486
|
+
}
|
|
487
|
+
if (!changed)
|
|
488
|
+
break;
|
|
269
489
|
}
|
|
270
490
|
};
|
|
271
|
-
/**
|
|
491
|
+
/**
|
|
492
|
+
* Everything rebuilt from the sequences (the first build, roles): every
|
|
493
|
+
* block placed as an edit places one (`settle`, then `retryFallen`) —
|
|
494
|
+
* the one acyclic acceptance, whatever the order the blocks come in —
|
|
495
|
+
* then keyed in one pass over each sequence's places (dense keys in its
|
|
496
|
+
* order), the root's tail after the last top-level block.
|
|
497
|
+
*/
|
|
272
498
|
const rebuildPlacements = () => {
|
|
273
499
|
ix.placementFull = false;
|
|
274
|
-
ranker.forget();
|
|
275
|
-
regroup.clear();
|
|
276
500
|
placementSeeds.clear();
|
|
277
501
|
stateSeeds.clear();
|
|
278
502
|
ownerChanged.clear();
|
|
@@ -299,32 +523,60 @@ export const indexPlacement = (ix) => {
|
|
|
299
523
|
for (const line of lineCounts.keys())
|
|
300
524
|
lineKinds.add(line);
|
|
301
525
|
ix.placementFull = false;
|
|
302
|
-
|
|
526
|
+
// The first read's slots while no sequence changed since (one scan).
|
|
527
|
+
const { slots, items, places } = collected !== null && collectedAt === ix.seqEpoch
|
|
528
|
+
? collected
|
|
529
|
+
: collectSlots(doc, blocks.values());
|
|
530
|
+
collected = null;
|
|
531
|
+
slotsByBlock.clear();
|
|
532
|
+
for (const [b, refs] of slots)
|
|
533
|
+
slotsByBlock.set(b, refs);
|
|
534
|
+
slotsRead = true;
|
|
303
535
|
placementsMap.clear();
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
536
|
+
edges.clear();
|
|
537
|
+
rawOrder.clear();
|
|
538
|
+
fallen.clear();
|
|
539
|
+
rejected.clear();
|
|
540
|
+
[keyed, known] = [false, items];
|
|
541
|
+
for (const id of blocks.keys())
|
|
542
|
+
settle(id, () => { });
|
|
543
|
+
if (fallen.size + rejected.size > 0)
|
|
544
|
+
retryFallen(new Set());
|
|
545
|
+
[keyed, known] = [true, null];
|
|
546
|
+
// The lists in key order: a block where its edge shows it, in its sequence's order.
|
|
547
|
+
for (const [owner, list] of places)
|
|
548
|
+
for (const e of list) {
|
|
549
|
+
const b = slotOwner(registry, kept, e.value.b, e.unit.c);
|
|
550
|
+
const pl = placementsMap.get(b);
|
|
551
|
+
const h = blocks.get(b)?.home;
|
|
552
|
+
if (pl?.parent !== owner || rejected.has(b) || !h || !sameUnit(h, e.unit))
|
|
553
|
+
continue;
|
|
554
|
+
if (edges.get(b)?.via !== e.via)
|
|
555
|
+
continue;
|
|
556
|
+
const l = rawList(owner);
|
|
557
|
+
pl.rank = denseKey(l.length);
|
|
558
|
+
l.push({ id: b, rank: pl.rank });
|
|
559
|
+
}
|
|
560
|
+
// The root's tail, keyed as an edit keys a rejected block, in its order.
|
|
561
|
+
const tail = [...rejected].map((x) => ({ id: x, stamp: edges.get(x)?.stamp ?? NO_SLOT }));
|
|
562
|
+
rejected.clear();
|
|
563
|
+
for (const { id } of tail.sort(byTail))
|
|
564
|
+
reject(id, edges.get(id) ?? null);
|
|
312
565
|
layoutMode = layoutBlocks + itemBlocks + tableBlocks > 0;
|
|
313
566
|
ix.dissolved = new Set();
|
|
314
|
-
const index = (
|
|
567
|
+
const index = (map) => {
|
|
315
568
|
const at = new Map();
|
|
316
569
|
for (const [parent, list] of map)
|
|
317
570
|
for (const { id, rank, reset } of list)
|
|
318
571
|
at.set(id, reset === undefined ? { parent, rank } : { parent, rank, reset });
|
|
319
|
-
void own;
|
|
320
572
|
return at;
|
|
321
573
|
};
|
|
322
574
|
ix.kids0 = childrenIndex(placementsMap, own0);
|
|
323
|
-
ix.slots0 = index(
|
|
575
|
+
ix.slots0 = index(ix.kids0);
|
|
324
576
|
if (layoutMode) {
|
|
325
577
|
ix.dissolved = dissolve(ix.kids0);
|
|
326
578
|
ix.kidsMap = childrenIndex(placementsMap, ownShim);
|
|
327
|
-
ix.slots = index(
|
|
579
|
+
ix.slots = index(ix.kidsMap);
|
|
328
580
|
}
|
|
329
581
|
else
|
|
330
582
|
[ix.kidsMap, ix.slots] = [ix.kids0, ix.slots0];
|
|
@@ -337,48 +589,61 @@ export const indexPlacement = (ix) => {
|
|
|
337
589
|
};
|
|
338
590
|
const ensurePlacements = () => {
|
|
339
591
|
ensureOwners();
|
|
340
|
-
if (ix.placementFull
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
return;
|
|
344
|
-
}
|
|
345
|
-
if (placementSeeds.size + stateSeeds.size + ownerChanged.size + regroup.size === 0)
|
|
592
|
+
if (ix.placementFull)
|
|
593
|
+
return rebuildPlacements();
|
|
594
|
+
if (placementSeeds.size + stateSeeds.size + ownerChanged.size === 0)
|
|
346
595
|
return;
|
|
347
596
|
const moved = new Set();
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
597
|
+
const seeds = new Set(placementSeeds);
|
|
598
|
+
const done = new Set();
|
|
599
|
+
/** Place one seed (its left neighbour first, when it is a seed too). */
|
|
600
|
+
const place = (id) => {
|
|
601
|
+
if (done.has(id) || !seeds.has(id))
|
|
602
|
+
return;
|
|
603
|
+
done.add(id);
|
|
604
|
+
if (!blocks.has(id)) {
|
|
605
|
+
if (placementsMap.has(id)) {
|
|
606
|
+
setPlacement(id, undefined);
|
|
607
|
+
edges.delete(id);
|
|
608
|
+
fallen.delete(id);
|
|
609
|
+
rejected.delete(id);
|
|
610
|
+
moved.add(id);
|
|
611
|
+
}
|
|
612
|
+
return;
|
|
613
|
+
}
|
|
614
|
+
const top = candidatesFor(id)[0] ?? null;
|
|
615
|
+
const old = edges.get(id);
|
|
616
|
+
// The same edge, placed at its strongest: its key still orders it (its neighbours' keys are theirs).
|
|
617
|
+
if (top !== null &&
|
|
618
|
+
old &&
|
|
619
|
+
!rejected.has(id) &&
|
|
620
|
+
!fallen.has(id) &&
|
|
621
|
+
placementsMap.has(id) &&
|
|
622
|
+
sameEdge(top, old))
|
|
623
|
+
return;
|
|
624
|
+
for (const x of settle(id, place))
|
|
625
|
+
moved.add(x);
|
|
626
|
+
};
|
|
627
|
+
for (const id of [...seeds])
|
|
628
|
+
place(id);
|
|
629
|
+
// A changed claim owner can close a cycle through a display edge that did not change.
|
|
366
630
|
for (const o of ownerChanged)
|
|
367
|
-
for (const c of
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
631
|
+
for (const c of [...(rawOrder.get(o) ?? [])]) {
|
|
632
|
+
const edge = edges.get(c.id);
|
|
633
|
+
if (!edge || rejected.has(c.id) || edge.parent === undefined)
|
|
634
|
+
continue;
|
|
635
|
+
if (cycleThrough(placementsMap, ownerOf, c.id, edge.parent) !== null)
|
|
636
|
+
for (const x of settle(c.id, () => { }))
|
|
637
|
+
moved.add(x);
|
|
638
|
+
}
|
|
639
|
+
if (rejected.size + fallen.size > 0 && (moved.size > 0 || ownerChanged.size > 0))
|
|
640
|
+
retryFallen(moved);
|
|
641
|
+
const seeds2 = new Set([...moved, ...stateSeeds, ...ownerChanged]);
|
|
377
642
|
const kinds = [...stateSeeds];
|
|
378
643
|
placementSeeds.clear();
|
|
379
644
|
stateSeeds.clear();
|
|
380
645
|
ownerChanged.clear();
|
|
381
|
-
const affected = reach(
|
|
646
|
+
const affected = reach(seeds2);
|
|
382
647
|
let touched = affected;
|
|
383
648
|
const changed = patch(ix.kids0, ix.slots0, own0, affected);
|
|
384
649
|
let any = changed.size > 0;
|
|
@@ -395,6 +660,21 @@ export const indexPlacement = (ix) => {
|
|
|
395
660
|
ix.kidsVersion++;
|
|
396
661
|
}
|
|
397
662
|
};
|
|
663
|
+
/**
|
|
664
|
+
* A plain block (the document's default kind) directly in a container
|
|
665
|
+
* whose item is a kind of its own that renders content (a list) shows
|
|
666
|
+
* as that item — the read-time side of the facade's `fitted`: a race
|
|
667
|
+
* (a peer's lift of an item another peer's outdent moves, a concurrent
|
|
668
|
+
* undo of a retype) or an explicit write never shows a bare paragraph
|
|
669
|
+
* in a list. Anywhere else it shows `plain`.
|
|
670
|
+
*/
|
|
671
|
+
const itemOf = (under, plain) => {
|
|
672
|
+
const parent = typeOf(under);
|
|
673
|
+
if (!ix.roles.container(parent))
|
|
674
|
+
return plain;
|
|
675
|
+
const item = ix.roles.defaultChild(parent);
|
|
676
|
+
return ix.roles.rendersContent(item) ? item : plain;
|
|
677
|
+
};
|
|
398
678
|
/**
|
|
399
679
|
* The kind `id` displays as — THE shown-kind rule, read from its slot
|
|
400
680
|
* and the role table. A block directly in an island declared `lines`
|
|
@@ -411,21 +691,6 @@ export const indexPlacement = (ix) => {
|
|
|
411
691
|
* (`itemOf`). Any other shows its stored kind (a retype shows). Read from the stored kinds
|
|
412
692
|
* at call time: a retype rebuilds no placement.
|
|
413
693
|
*/
|
|
414
|
-
/**
|
|
415
|
-
* A plain block (the document's default kind) directly in a container
|
|
416
|
-
* whose item is a kind of its own that renders content (a list) shows
|
|
417
|
-
* as that item — the read-time side of the facade's `fitted`: a race
|
|
418
|
-
* (a peer's lift of an item another peer's outdent moves, a concurrent
|
|
419
|
-
* undo of a retype) or an explicit write never shows a bare paragraph
|
|
420
|
-
* in a list. Anywhere else it shows `plain`.
|
|
421
|
-
*/
|
|
422
|
-
const itemOf = (under, plain) => {
|
|
423
|
-
const parent = typeOf(under);
|
|
424
|
-
if (!ix.roles.container(parent))
|
|
425
|
-
return plain;
|
|
426
|
-
const item = ix.roles.defaultChild(parent);
|
|
427
|
-
return ix.roles.rendersContent(item) ? item : plain;
|
|
428
|
-
};
|
|
429
694
|
const typeOf = (id) => {
|
|
430
695
|
const stored = blocks.get(id)?.type ?? 'unknown';
|
|
431
696
|
const slot = ix.slots.get(id);
|
|
@@ -461,14 +726,15 @@ export const indexPlacement = (ix) => {
|
|
|
461
726
|
/** The document order, cached until a child list changes. */
|
|
462
727
|
const order = () => (orderCache ??= documentOrder(ix.kidsMap));
|
|
463
728
|
return {
|
|
464
|
-
ranker,
|
|
465
729
|
ownShim,
|
|
466
730
|
own0,
|
|
467
731
|
noteKind,
|
|
468
|
-
|
|
469
|
-
|
|
732
|
+
homeFor,
|
|
733
|
+
putSlot,
|
|
734
|
+
edgeParent,
|
|
470
735
|
noteFollowing,
|
|
471
736
|
ensurePlacements,
|
|
737
|
+
reslot,
|
|
472
738
|
typeOf,
|
|
473
739
|
order
|
|
474
740
|
};
|