kritzel-stencil 0.0.157 → 0.0.159
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/dist/cjs/app-globals-V2Kpy_OQ.js +8 -0
- package/dist/cjs/app-globals-V2Kpy_OQ.js.map +1 -0
- package/dist/cjs/default-text-tool.config-BySzvIox.js +31267 -0
- package/dist/cjs/default-text-tool.config-BySzvIox.js.map +1 -0
- package/dist/cjs/index-Cj__YTlG.js +1650 -0
- package/dist/cjs/index-Cj__YTlG.js.map +1 -0
- package/dist/cjs/index.cjs.js +1465 -0
- package/dist/cjs/index.cjs.js.map +1 -0
- package/dist/cjs/kritzel-brush-style.cjs.entry.js +32 -0
- package/dist/cjs/kritzel-brush-style.entry.cjs.js.map +1 -0
- package/dist/cjs/kritzel-color_22.cjs.entry.js +20957 -0
- package/dist/cjs/loader.cjs.js +14 -0
- package/dist/cjs/loader.cjs.js.map +1 -0
- package/dist/cjs/stencil.cjs.js +26 -0
- package/dist/cjs/stencil.cjs.js.map +1 -0
- package/dist/collection/classes/core/core.class.js +470 -0
- package/dist/collection/classes/core/core.class.js.map +1 -0
- package/dist/collection/classes/core/reviver.class.js +71 -0
- package/dist/collection/classes/core/reviver.class.js.map +1 -0
- package/dist/collection/classes/core/store.class.js +72 -0
- package/dist/collection/classes/core/store.class.js.map +1 -0
- package/dist/collection/classes/core/viewport.class.js +190 -0
- package/dist/collection/classes/core/viewport.class.js.map +1 -0
- package/dist/collection/classes/core/workspace.class.js +41 -0
- package/dist/collection/classes/core/workspace.class.js.map +1 -0
- package/dist/collection/classes/handlers/base.handler.js +8 -0
- package/dist/collection/classes/handlers/base.handler.js.map +1 -0
- package/dist/collection/classes/handlers/context-menu.handler.js +62 -0
- package/dist/collection/classes/handlers/context-menu.handler.js.map +1 -0
- package/dist/collection/classes/handlers/hover.handler.js +19 -0
- package/dist/collection/classes/handlers/hover.handler.js.map +1 -0
- package/dist/collection/classes/handlers/key.handler.js +58 -0
- package/dist/collection/classes/handlers/key.handler.js.map +1 -0
- package/dist/collection/classes/handlers/move.handler.js +149 -0
- package/dist/collection/classes/handlers/move.handler.js.map +1 -0
- package/dist/collection/classes/handlers/resize.handler.js +184 -0
- package/dist/collection/classes/handlers/resize.handler.js.map +1 -0
- package/dist/collection/classes/handlers/rotation.handler.js +116 -0
- package/dist/collection/classes/handlers/rotation.handler.js.map +1 -0
- package/dist/collection/classes/handlers/selection.handler.js +246 -0
- package/dist/collection/classes/handlers/selection.handler.js.map +1 -0
- package/dist/collection/classes/objects/base-object.class.js +232 -0
- package/dist/collection/classes/objects/base-object.class.js.map +1 -0
- package/dist/collection/classes/objects/custom-element.class.js +62 -0
- package/dist/collection/classes/objects/custom-element.class.js.map +1 -0
- package/dist/collection/classes/objects/image.class.js +56 -0
- package/dist/collection/classes/objects/image.class.js.map +1 -0
- package/dist/collection/classes/objects/path.class.js +284 -0
- package/dist/collection/classes/objects/path.class.js.map +1 -0
- package/dist/collection/classes/objects/selection-box.class.js +19 -0
- package/dist/collection/classes/objects/selection-box.class.js.map +1 -0
- package/dist/collection/classes/objects/selection-group.class.js +226 -0
- package/dist/collection/classes/objects/selection-group.class.js.map +1 -0
- package/dist/collection/classes/objects/text.class.js +261 -0
- package/dist/collection/classes/objects/text.class.js.map +1 -0
- package/dist/collection/classes/providers/broadcast-sync-provider.class.js +93 -0
- package/dist/collection/classes/providers/broadcast-sync-provider.class.js.map +1 -0
- package/dist/collection/classes/providers/hocuspocus-sync-provider.class.js +232 -0
- package/dist/collection/classes/providers/hocuspocus-sync-provider.class.js.map +1 -0
- package/dist/collection/classes/providers/indexeddb-sync-provider.class.js +35 -0
- package/dist/collection/classes/providers/indexeddb-sync-provider.class.js.map +1 -0
- package/dist/collection/classes/providers/websocket-sync-provider.class.js +89 -0
- package/dist/collection/classes/providers/websocket-sync-provider.class.js.map +1 -0
- package/dist/{stencil/icon-registry.class-BtT8riKh.js → collection/classes/registries/icon-registry.class.js} +2 -6
- package/dist/collection/classes/registries/icon-registry.class.js.map +1 -0
- package/dist/collection/classes/registries/tool.registry.js +18 -0
- package/dist/collection/classes/registries/tool.registry.js.map +1 -0
- package/dist/collection/classes/structures/app-state-map.structure.js +189 -0
- package/dist/collection/classes/structures/app-state-map.structure.js.map +1 -0
- package/dist/collection/classes/structures/object-map.structure.js +328 -0
- package/dist/collection/classes/structures/object-map.structure.js.map +1 -0
- package/dist/collection/classes/structures/quadtree.structure.js +113 -0
- package/dist/collection/classes/structures/quadtree.structure.js.map +1 -0
- package/dist/collection/classes/tools/base-tool.class.js +38 -0
- package/dist/collection/classes/tools/base-tool.class.js.map +1 -0
- package/dist/collection/classes/tools/brush-tool.class.js +133 -0
- package/dist/collection/classes/tools/brush-tool.class.js.map +1 -0
- package/dist/collection/classes/tools/eraser-tool.class.js +85 -0
- package/dist/collection/classes/tools/eraser-tool.class.js.map +1 -0
- package/dist/collection/classes/tools/image-tool.class.js +83 -0
- package/dist/collection/classes/tools/image-tool.class.js.map +1 -0
- package/dist/collection/classes/tools/selection-tool.class.js +164 -0
- package/dist/collection/classes/tools/selection-tool.class.js.map +1 -0
- package/dist/collection/classes/tools/text-tool.class.js +108 -0
- package/dist/collection/classes/tools/text-tool.class.js.map +1 -0
- package/dist/collection/collection-manifest.json +34 -0
- package/dist/collection/components/core/kritzel-cursor-trail/kritzel-cursor-trail.css +10 -0
- package/dist/collection/components/core/kritzel-cursor-trail/kritzel-cursor-trail.js +153 -0
- package/dist/collection/components/core/kritzel-cursor-trail/kritzel-cursor-trail.js.map +1 -0
- package/dist/collection/components/core/kritzel-editor/kritzel-editor.css +34 -0
- package/dist/collection/components/core/kritzel-editor/kritzel-editor.js +928 -0
- package/dist/collection/components/core/kritzel-editor/kritzel-editor.js.map +1 -0
- package/dist/collection/components/core/kritzel-engine/kritzel-engine.css +73 -0
- package/dist/collection/components/core/kritzel-engine/kritzel-engine.js +1613 -0
- package/dist/collection/components/core/kritzel-engine/kritzel-engine.js.map +1 -0
- package/dist/collection/components/shared/kritzel-brush-style/kritzel-brush-style.css +44 -0
- package/dist/collection/components/shared/kritzel-brush-style/kritzel-brush-style.js +98 -0
- package/dist/collection/components/shared/kritzel-brush-style/kritzel-brush-style.js.map +1 -0
- package/dist/collection/components/shared/kritzel-color/kritzel-color.css +21 -0
- package/dist/collection/components/shared/kritzel-color/kritzel-color.js +107 -0
- package/dist/collection/components/shared/kritzel-color/kritzel-color.js.map +1 -0
- package/dist/collection/components/shared/kritzel-color-palette/kritzel-color-palette.css +46 -0
- package/dist/collection/components/shared/kritzel-color-palette/kritzel-color-palette.js +145 -0
- package/dist/collection/components/shared/kritzel-color-palette/kritzel-color-palette.js.map +1 -0
- package/dist/collection/components/shared/kritzel-dropdown/kritzel-dropdown.css +53 -0
- package/dist/collection/components/shared/kritzel-dropdown/kritzel-dropdown.js +218 -0
- package/dist/collection/components/shared/kritzel-dropdown/kritzel-dropdown.js.map +1 -0
- package/dist/collection/components/shared/kritzel-font/kritzel-font.css +10 -0
- package/dist/collection/components/shared/kritzel-font/kritzel-font.js +90 -0
- package/dist/collection/components/shared/kritzel-font/kritzel-font.js.map +1 -0
- package/dist/collection/components/shared/kritzel-font-family/kritzel-font-family.css +48 -0
- package/dist/collection/components/shared/kritzel-font-family/kritzel-font-family.js +114 -0
- package/dist/collection/components/shared/kritzel-font-family/kritzel-font-family.js.map +1 -0
- package/dist/collection/components/shared/kritzel-font-size/kritzel-font-size.css +30 -0
- package/dist/collection/components/shared/kritzel-font-size/kritzel-font-size.js +110 -0
- package/dist/collection/components/shared/kritzel-font-size/kritzel-font-size.js.map +1 -0
- package/dist/collection/components/shared/kritzel-icon/kritzel-icon.css +18 -0
- package/dist/collection/components/shared/kritzel-icon/kritzel-icon.js +94 -0
- package/dist/collection/components/shared/kritzel-icon/kritzel-icon.js.map +1 -0
- package/dist/collection/components/shared/kritzel-menu/kritzel-menu.css +27 -0
- package/dist/collection/components/shared/kritzel-menu/kritzel-menu.js +291 -0
- package/dist/collection/components/shared/kritzel-menu/kritzel-menu.js.map +1 -0
- package/dist/collection/components/shared/kritzel-menu-item/kritzel-menu-item.css +145 -0
- package/dist/collection/components/shared/kritzel-menu-item/kritzel-menu-item.js +280 -0
- package/dist/collection/components/shared/kritzel-menu-item/kritzel-menu-item.js.map +1 -0
- package/dist/collection/components/shared/kritzel-portal/kritzel-portal.js +310 -0
- package/dist/collection/components/shared/kritzel-portal/kritzel-portal.js.map +1 -0
- package/dist/collection/components/shared/kritzel-split-button/kritzel-split-button.css +78 -0
- package/dist/collection/components/shared/kritzel-split-button/kritzel-split-button.js +406 -0
- package/dist/collection/components/shared/kritzel-split-button/kritzel-split-button.js.map +1 -0
- package/dist/collection/components/shared/kritzel-stroke-size/kritzel-stroke-size.css +28 -0
- package/dist/collection/components/shared/kritzel-stroke-size/kritzel-stroke-size.js +89 -0
- package/dist/collection/components/shared/kritzel-stroke-size/kritzel-stroke-size.js.map +1 -0
- package/dist/collection/components/shared/kritzel-tooltip/kritzel-tooltip.css +17 -0
- package/dist/collection/components/shared/kritzel-tooltip/kritzel-tooltip.js +251 -0
- package/dist/collection/components/shared/kritzel-tooltip/kritzel-tooltip.js.map +1 -0
- package/dist/collection/components/ui/kritzel-context-menu/kritzel-context-menu.css +55 -0
- package/dist/collection/components/ui/kritzel-context-menu/kritzel-context-menu.js +172 -0
- package/dist/collection/components/ui/kritzel-context-menu/kritzel-context-menu.js.map +1 -0
- package/dist/collection/components/ui/kritzel-control-brush-config/kritzel-control-brush-config.css +19 -0
- package/dist/collection/components/ui/kritzel-control-brush-config/kritzel-control-brush-config.js +135 -0
- package/dist/collection/components/ui/kritzel-control-brush-config/kritzel-control-brush-config.js.map +1 -0
- package/dist/collection/components/ui/kritzel-control-text-config/kritzel-control-text-config.css +19 -0
- package/dist/collection/components/ui/kritzel-control-text-config/kritzel-control-text-config.js +115 -0
- package/dist/collection/components/ui/kritzel-control-text-config/kritzel-control-text-config.js.map +1 -0
- package/dist/collection/components/ui/kritzel-controls/kritzel-controls.css +127 -0
- package/dist/collection/components/ui/kritzel-controls/kritzel-controls.js +312 -0
- package/dist/collection/components/ui/kritzel-controls/kritzel-controls.js.map +1 -0
- package/dist/collection/components/ui/kritzel-utility-panel/kritzel-utility-panel.css +44 -0
- package/dist/collection/components/ui/kritzel-utility-panel/kritzel-utility-panel.js +111 -0
- package/dist/collection/components/ui/kritzel-utility-panel/kritzel-utility-panel.js.map +1 -0
- package/dist/collection/components/ui/kritzel-workspace-manager/kritzel-workspace-manager.css +5 -0
- package/dist/collection/components/ui/kritzel-workspace-manager/kritzel-workspace-manager.js +255 -0
- package/dist/collection/components/ui/kritzel-workspace-manager/kritzel-workspace-manager.js.map +1 -0
- package/dist/collection/configs/default-brush-tool.config.js +60 -0
- package/dist/collection/configs/default-brush-tool.config.js.map +1 -0
- package/dist/collection/configs/default-engine-config.js +53 -0
- package/dist/collection/configs/default-engine-config.js.map +1 -0
- package/dist/collection/configs/default-sync.config.js +10 -0
- package/dist/collection/configs/default-sync.config.js.map +1 -0
- package/dist/collection/configs/default-text-tool.config.js +32 -0
- package/dist/collection/configs/default-text-tool.config.js.map +1 -0
- package/dist/collection/constants/core.constants.js +2 -0
- package/dist/collection/constants/core.constants.js.map +1 -0
- package/dist/collection/constants/engine.constants.js +3 -0
- package/dist/collection/constants/engine.constants.js.map +1 -0
- package/dist/collection/enums/event-button.enum.js +7 -0
- package/dist/collection/enums/event-button.enum.js.map +1 -0
- package/dist/collection/enums/handle-type.enum.js +8 -0
- package/dist/collection/enums/handle-type.enum.js.map +1 -0
- package/dist/collection/helpers/class.helper.js +6 -0
- package/dist/collection/helpers/class.helper.js.map +1 -0
- package/dist/collection/helpers/devices.helper.js +26 -0
- package/dist/collection/helpers/devices.helper.js.map +1 -0
- package/dist/collection/helpers/event.helper.js +51 -0
- package/dist/collection/helpers/event.helper.js.map +1 -0
- package/dist/collection/helpers/geometry.helper.js +53 -0
- package/dist/collection/helpers/geometry.helper.js.map +1 -0
- package/dist/collection/helpers/html.helper.js +64 -0
- package/dist/{stencil/html.helper-C6qB08BS.js.map → collection/helpers/html.helper.js.map} +1 -1
- package/dist/collection/helpers/keyboard.helper.js +49 -0
- package/dist/collection/helpers/keyboard.helper.js.map +1 -0
- package/dist/collection/helpers/math.helper.js +6 -0
- package/dist/collection/helpers/math.helper.js.map +1 -0
- package/dist/collection/helpers/object.helper.js +12 -0
- package/dist/collection/helpers/object.helper.js.map +1 -0
- package/dist/collection/index.js +30 -0
- package/dist/collection/index.js.map +1 -0
- package/dist/collection/interfaces/bounding-box.interface.js +2 -0
- package/dist/collection/interfaces/bounding-box.interface.js.map +1 -0
- package/dist/collection/interfaces/clonable.interface.js +2 -0
- package/dist/collection/interfaces/clonable.interface.js.map +1 -0
- package/dist/collection/interfaces/context-menu-item.interface.js +2 -0
- package/dist/collection/interfaces/context-menu-item.interface.js.map +1 -0
- package/dist/collection/interfaces/debug-info.interface.js +2 -0
- package/dist/collection/interfaces/debug-info.interface.js.map +1 -0
- package/dist/collection/interfaces/engine-state.interface.js +2 -0
- package/dist/collection/interfaces/engine-state.interface.js.map +1 -0
- package/dist/collection/interfaces/menu-item.interface.js +2 -0
- package/dist/collection/interfaces/menu-item.interface.js.map +1 -0
- package/dist/collection/interfaces/object.interface.js +2 -0
- package/dist/collection/interfaces/object.interface.js.map +1 -0
- package/dist/collection/interfaces/path-options.interface.js +2 -0
- package/dist/collection/interfaces/path-options.interface.js.map +1 -0
- package/dist/collection/interfaces/point.interface.js +2 -0
- package/dist/collection/interfaces/point.interface.js.map +1 -0
- package/dist/collection/interfaces/polygon.interface.js +2 -0
- package/dist/collection/interfaces/polygon.interface.js.map +1 -0
- package/dist/collection/interfaces/selection-state.interface.js +2 -0
- package/dist/collection/interfaces/selection-state.interface.js.map +1 -0
- package/dist/collection/interfaces/serializable.interface.js +2 -0
- package/dist/collection/interfaces/serializable.interface.js.map +1 -0
- package/dist/collection/interfaces/shortcut.interface.js +2 -0
- package/dist/collection/interfaces/shortcut.interface.js.map +1 -0
- package/dist/collection/interfaces/sync-config.interface.js +2 -0
- package/dist/collection/interfaces/sync-config.interface.js.map +1 -0
- package/dist/collection/interfaces/sync-provider.interface.js +2 -0
- package/dist/collection/interfaces/sync-provider.interface.js.map +1 -0
- package/dist/collection/interfaces/tool.interface.js +2 -0
- package/dist/collection/interfaces/tool.interface.js.map +1 -0
- package/dist/collection/interfaces/toolbar-control.interface.js +2 -0
- package/dist/collection/interfaces/toolbar-control.interface.js.map +1 -0
- package/dist/collection/interfaces/undo-state.interface.js +2 -0
- package/dist/collection/interfaces/undo-state.interface.js.map +1 -0
- package/dist/collection/types/deep-readonly.type.js +2 -0
- package/dist/collection/types/deep-readonly.type.js.map +1 -0
- package/dist/collection/types/state.types.js +2 -0
- package/dist/collection/types/state.types.js.map +1 -0
- package/dist/components/index.js +1477 -0
- package/dist/components/index.js.map +1 -0
- package/dist/components/kritzel-brush-style.js +67 -0
- package/dist/components/kritzel-brush-style.js.map +1 -0
- package/dist/components/kritzel-color-palette.js +9 -0
- package/dist/components/kritzel-color-palette.js.map +1 -0
- package/dist/components/kritzel-color.js +9 -0
- package/dist/components/kritzel-color.js.map +1 -0
- package/dist/components/kritzel-context-menu.js +9 -0
- package/dist/components/kritzel-context-menu.js.map +1 -0
- package/dist/components/kritzel-control-brush-config.js +9 -0
- package/dist/components/kritzel-control-brush-config.js.map +1 -0
- package/dist/components/kritzel-control-text-config.js +9 -0
- package/dist/components/kritzel-control-text-config.js.map +1 -0
- package/dist/components/kritzel-controls.js +9 -0
- package/dist/components/kritzel-controls.js.map +1 -0
- package/dist/components/kritzel-cursor-trail.js +9 -0
- package/dist/components/kritzel-cursor-trail.js.map +1 -0
- package/dist/components/kritzel-dropdown.js +9 -0
- package/dist/components/kritzel-dropdown.js.map +1 -0
- package/dist/components/kritzel-editor.js +516 -0
- package/dist/components/kritzel-editor.js.map +1 -0
- package/dist/components/kritzel-engine.js +9 -0
- package/dist/components/kritzel-engine.js.map +1 -0
- package/dist/components/kritzel-font-family.js +9 -0
- package/dist/components/kritzel-font-family.js.map +1 -0
- package/dist/components/kritzel-font-size.js +9 -0
- package/dist/components/kritzel-font-size.js.map +1 -0
- package/dist/components/kritzel-font.js +9 -0
- package/dist/components/kritzel-font.js.map +1 -0
- package/dist/components/kritzel-icon.js +9 -0
- package/dist/components/kritzel-icon.js.map +1 -0
- package/dist/components/kritzel-menu-item.js +9 -0
- package/dist/components/kritzel-menu-item.js.map +1 -0
- package/dist/components/kritzel-menu.js +9 -0
- package/dist/components/kritzel-menu.js.map +1 -0
- package/dist/components/kritzel-portal.js +9 -0
- package/dist/components/kritzel-portal.js.map +1 -0
- package/dist/components/kritzel-split-button.js +9 -0
- package/dist/components/kritzel-split-button.js.map +1 -0
- package/dist/components/kritzel-stroke-size.js +9 -0
- package/dist/components/kritzel-stroke-size.js.map +1 -0
- package/dist/components/kritzel-tooltip.js +9 -0
- package/dist/components/kritzel-tooltip.js.map +1 -0
- package/dist/components/kritzel-utility-panel.js +9 -0
- package/dist/components/kritzel-utility-panel.js.map +1 -0
- package/dist/components/kritzel-workspace-manager.js +9 -0
- package/dist/components/kritzel-workspace-manager.js.map +1 -0
- package/dist/{stencil/kritzel-controls.entry.js → components/p-1lIHoOlH.js} +115 -17
- package/dist/components/p-1lIHoOlH.js.map +1 -0
- package/dist/{stencil/object.helper-B0kd2rUI.js → components/p-B0kd2rUI.js} +2 -2
- package/dist/components/p-B0kd2rUI.js.map +1 -0
- package/dist/components/p-B4kxkVe-.js +55 -0
- package/dist/components/p-B4kxkVe-.js.map +1 -0
- package/dist/components/p-BAplhrRJ.js +35593 -0
- package/dist/components/p-BAplhrRJ.js.map +1 -0
- package/dist/components/p-BQg4YML7.js +106 -0
- package/dist/components/p-BQg4YML7.js.map +1 -0
- package/dist/{stencil/kritzel-font-family.entry.js → components/p-BgznZoBH.js} +37 -9
- package/dist/components/p-BgznZoBH.js.map +1 -0
- package/dist/components/p-Bhtn9qay.js +98 -0
- package/dist/components/p-Bhtn9qay.js.map +1 -0
- package/dist/{stencil/kritzel-context-menu-GdU9xEKC.js → components/p-C2sWlNsJ.js} +41 -12
- package/dist/components/p-C2sWlNsJ.js.map +1 -0
- package/dist/{stencil/html.helper-C6qB08BS.js → components/p-C6qB08BS.js} +2 -2
- package/dist/components/p-C6qB08BS.js.map +1 -0
- package/dist/{stencil/text-tool.class-C0GbC5zQ.js → components/p-CBYBurdY.js} +25 -729
- package/dist/components/p-CBYBurdY.js.map +1 -0
- package/dist/{stencil/kritzel-dropdown.entry.js → components/p-CIXPLjCu.js} +39 -9
- package/dist/components/p-CIXPLjCu.js.map +1 -0
- package/dist/{stencil/kritzel-workspace-manager.entry.js → components/p-CK6no3mi.js} +68 -13
- package/dist/components/p-CK6no3mi.js.map +1 -0
- package/dist/{stencil/kritzel-cursor-trail.entry.js → components/p-CLt3HMl6.js} +33 -10
- package/dist/components/p-CLt3HMl6.js.map +1 -0
- package/dist/{stencil/kritzel-tooltip.entry.js → components/p-CTP479Lf.js} +39 -11
- package/dist/components/p-CTP479Lf.js.map +1 -0
- package/dist/{stencil/kritzel-menu-item.entry.js → components/p-CsA9M6me.js} +174 -16
- package/dist/components/p-CsA9M6me.js.map +1 -0
- package/dist/components/p-CwkUrTy1.js +1367 -0
- package/dist/components/p-CwkUrTy1.js.map +1 -0
- package/dist/{stencil/kritzel-color-palette.entry.js → components/p-D1uj4A4F.js} +39 -9
- package/dist/components/p-D1uj4A4F.js.map +1 -0
- package/dist/{stencil/kritzel-color.entry.js → components/p-D4yvhd1d.js} +30 -8
- package/dist/components/p-D4yvhd1d.js.map +1 -0
- package/dist/{stencil/kritzel-portal.entry.js → components/p-D5Wq4x4r.js} +37 -11
- package/dist/components/p-D5Wq4x4r.js.map +1 -0
- package/dist/{stencil/event-button.enum-D8W6LE-c.js → components/p-D8W6LE-c.js} +2 -2
- package/dist/components/p-D8W6LE-c.js.map +1 -0
- package/dist/{stencil/kritzel-utility-panel.entry.js → components/p-DAfkuR8U.js} +38 -11
- package/dist/components/p-DAfkuR8U.js.map +1 -0
- package/dist/components/p-DDmSxM5f.js +57 -0
- package/dist/{stencil/kritzel-font-size.entry.esm.js.map → components/p-DDmSxM5f.js.map} +1 -1
- package/dist/components/p-Ddh40W3x.js +103 -0
- package/dist/components/p-Ddh40W3x.js.map +1 -0
- package/dist/{stencil/kritzel-split-button.entry.js → components/p-TdCTkEu0.js} +72 -18
- package/dist/components/p-TdCTkEu0.js.map +1 -0
- package/dist/{stencil/devices.helper-l10It7Nm.js → components/p-l10It7Nm.js} +2 -2
- package/dist/components/p-l10It7Nm.js.map +1 -0
- package/dist/{stencil/workspace.class-n789Y3S-.js → components/p-n789Y3S-.js} +2 -2
- package/dist/components/p-n789Y3S-.js.map +1 -0
- package/dist/components/p-uuRJU2R1.js +46 -0
- package/dist/components/p-uuRJU2R1.js.map +1 -0
- package/dist/esm/app-globals-DQuL1Twl.js +6 -0
- package/dist/esm/app-globals-DQuL1Twl.js.map +1 -0
- package/dist/esm/default-text-tool.config-2YFQA3SF.js +31208 -0
- package/dist/esm/default-text-tool.config-2YFQA3SF.js.map +1 -0
- package/dist/esm/index-SGde3HXB.js +1623 -0
- package/dist/esm/index-SGde3HXB.js.map +1 -0
- package/dist/esm/index.js +1449 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/{stencil → esm}/kritzel-brush-style.entry.js +3 -3
- package/dist/esm/kritzel-brush-style.entry.js.map +1 -0
- package/dist/{stencil/kritzel-engine.entry.js → esm/kritzel-color_22.entry.js} +1806 -90
- package/dist/esm/loader.js +12 -0
- package/dist/esm/loader.js.map +1 -0
- package/dist/esm/stencil.js +22 -0
- package/dist/esm/stencil.js.map +1 -0
- package/dist/index.cjs.js +1 -0
- package/dist/index.js +1 -0
- package/dist/stencil/index.esm.js +2 -18
- package/dist/stencil/index.esm.js.map +1 -1
- package/dist/stencil/loader.esm.js.map +1 -1
- package/dist/stencil/p-2YFQA3SF.js +2 -0
- package/dist/stencil/p-2YFQA3SF.js.map +1 -0
- package/dist/stencil/p-2e85a4af.entry.js +10 -0
- package/dist/stencil/p-2e85a4af.entry.js.map +1 -0
- package/dist/stencil/p-DQuL1Twl.js +2 -0
- package/dist/stencil/p-DQuL1Twl.js.map +1 -0
- package/dist/stencil/p-SGde3HXB.js +3 -0
- package/dist/stencil/p-SGde3HXB.js.map +1 -0
- package/dist/stencil/p-d702c5af.entry.js +2 -0
- package/dist/stencil/p-d702c5af.entry.js.map +1 -0
- package/dist/stencil/stencil.esm.js +2 -48
- package/dist/stencil/stencil.esm.js.map +1 -1
- package/dist/types/components/core/kritzel-engine/kritzel-engine.d.ts +0 -1
- package/package.json +1 -1
- package/dist/stencil/default-text-tool.config-DKpRP4XR.js +0 -1441
- package/dist/stencil/default-text-tool.config-DKpRP4XR.js.map +0 -1
- package/dist/stencil/devices.helper-l10It7Nm.js.map +0 -1
- package/dist/stencil/engine.constants-DsjjAmnl.js +0 -7
- package/dist/stencil/engine.constants-DsjjAmnl.js.map +0 -1
- package/dist/stencil/event-button.enum-D8W6LE-c.js.map +0 -1
- package/dist/stencil/icon-registry.class-BtT8riKh.js.map +0 -1
- package/dist/stencil/index-DniO_INI.js +0 -4395
- package/dist/stencil/index-DniO_INI.js.map +0 -1
- package/dist/stencil/kritzel-color-palette.entry.esm.js.map +0 -1
- package/dist/stencil/kritzel-color.entry.esm.js.map +0 -1
- package/dist/stencil/kritzel-context-menu-BYgOEy-i.js +0 -66
- package/dist/stencil/kritzel-context-menu-BYgOEy-i.js.map +0 -1
- package/dist/stencil/kritzel-context-menu-GdU9xEKC.js.map +0 -1
- package/dist/stencil/kritzel-context-menu.entry.esm.js.map +0 -1
- package/dist/stencil/kritzel-context-menu.entry.js +0 -3
- package/dist/stencil/kritzel-control-brush-config.entry.esm.js.map +0 -1
- package/dist/stencil/kritzel-control-brush-config.entry.js +0 -54
- package/dist/stencil/kritzel-control-text-config.entry.esm.js.map +0 -1
- package/dist/stencil/kritzel-control-text-config.entry.js +0 -42
- package/dist/stencil/kritzel-controls.entry.esm.js.map +0 -1
- package/dist/stencil/kritzel-cursor-trail.entry.esm.js.map +0 -1
- package/dist/stencil/kritzel-dropdown.entry.esm.js.map +0 -1
- package/dist/stencil/kritzel-editor.entry.esm.js.map +0 -1
- package/dist/stencil/kritzel-editor.entry.js +0 -248
- package/dist/stencil/kritzel-engine.entry.esm.js.map +0 -1
- package/dist/stencil/kritzel-font-family.entry.esm.js.map +0 -1
- package/dist/stencil/kritzel-font-size.entry.js +0 -28
- package/dist/stencil/kritzel-font.entry.esm.js.map +0 -1
- package/dist/stencil/kritzel-font.entry.js +0 -23
- package/dist/stencil/kritzel-icon.entry.esm.js.map +0 -1
- package/dist/stencil/kritzel-icon.entry.js +0 -29
- package/dist/stencil/kritzel-menu-item.entry.esm.js.map +0 -1
- package/dist/stencil/kritzel-menu.entry.esm.js.map +0 -1
- package/dist/stencil/kritzel-menu.entry.js +0 -72
- package/dist/stencil/kritzel-portal.entry.esm.js.map +0 -1
- package/dist/stencil/kritzel-split-button.entry.esm.js.map +0 -1
- package/dist/stencil/kritzel-stroke-size.entry.esm.js.map +0 -1
- package/dist/stencil/kritzel-stroke-size.entry.js +0 -27
- package/dist/stencil/kritzel-tooltip.entry.esm.js.map +0 -1
- package/dist/stencil/kritzel-utility-panel.entry.esm.js.map +0 -1
- package/dist/stencil/kritzel-workspace-manager.entry.esm.js.map +0 -1
- package/dist/stencil/object.helper-B0kd2rUI.js.map +0 -1
- package/dist/stencil/sync-config.interface-lKfyG1EN.js +0 -19839
- package/dist/stencil/sync-config.interface-lKfyG1EN.js.map +0 -1
- package/dist/stencil/text-tool.class-C0GbC5zQ.js.map +0 -1
- package/dist/stencil/workspace.class-n789Y3S-.js.map +0 -1
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import * as Y from "yjs";
|
|
2
|
+
import { KritzelWorkspace } from "../core/workspace.class";
|
|
3
|
+
import { DEFAULT_SYNC_CONFIG } from "../../configs/default-sync.config";
|
|
4
|
+
export class KritzelAppStateMap {
|
|
5
|
+
map;
|
|
6
|
+
_ydoc = null;
|
|
7
|
+
_workspacesMap = null;
|
|
8
|
+
_providers = [];
|
|
9
|
+
_core = null;
|
|
10
|
+
_isReady = false;
|
|
11
|
+
_onRemoteChangeCallback = null;
|
|
12
|
+
get isReady() {
|
|
13
|
+
return this._isReady;
|
|
14
|
+
}
|
|
15
|
+
constructor() {
|
|
16
|
+
this.map = new Map();
|
|
17
|
+
}
|
|
18
|
+
onRemoteChange(callback) {
|
|
19
|
+
this._onRemoteChangeCallback = callback;
|
|
20
|
+
}
|
|
21
|
+
async initialize(core, config) {
|
|
22
|
+
this._core = core;
|
|
23
|
+
// Create a dedicated Y.Doc for app state (workspaces)
|
|
24
|
+
this._ydoc = new Y.Doc();
|
|
25
|
+
this._workspacesMap = this._ydoc.getMap('workspaces');
|
|
26
|
+
const docName = 'kritzel-app-state';
|
|
27
|
+
const finalConfig = config ?? DEFAULT_SYNC_CONFIG;
|
|
28
|
+
// Instantiate providers from configuration
|
|
29
|
+
for (const providerConfig of finalConfig.providers) {
|
|
30
|
+
let provider;
|
|
31
|
+
// Check if it's a class constructor or a factory
|
|
32
|
+
if (typeof providerConfig === 'function') {
|
|
33
|
+
// It's a class constructor
|
|
34
|
+
provider = new providerConfig(docName, this._ydoc);
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
// It's a factory with a create method
|
|
38
|
+
provider = providerConfig.create(docName, this._ydoc);
|
|
39
|
+
}
|
|
40
|
+
this._providers.push(provider);
|
|
41
|
+
}
|
|
42
|
+
// Observe changes to workspaces and sync with application state
|
|
43
|
+
this._workspacesMap.observe(event => {
|
|
44
|
+
this.handleWorkspacesChange(event);
|
|
45
|
+
});
|
|
46
|
+
// Connect all providers in parallel
|
|
47
|
+
await Promise.all(this._providers.map(p => p.connect()));
|
|
48
|
+
this._isReady = true;
|
|
49
|
+
// Load workspaces from Yjs
|
|
50
|
+
this.loadFromYjs();
|
|
51
|
+
}
|
|
52
|
+
handleWorkspacesChange(event) {
|
|
53
|
+
// Skip Map updates for local changes (already done), but still trigger re-render
|
|
54
|
+
if (event.transaction.origin === 'local') {
|
|
55
|
+
this._core?.rerender();
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
const changedKeys = Array.from(event.keysChanged);
|
|
59
|
+
const workspacesToUpdate = [];
|
|
60
|
+
const workspacesToDelete = [];
|
|
61
|
+
changedKeys.forEach(key => {
|
|
62
|
+
const change = event.changes.keys.get(key);
|
|
63
|
+
if (change && change.action === 'delete') {
|
|
64
|
+
workspacesToDelete.push(key);
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
const serialized = this._workspacesMap.get(key);
|
|
68
|
+
if (serialized) {
|
|
69
|
+
const workspace = this.reviveWorkspace(serialized);
|
|
70
|
+
workspacesToUpdate.push(workspace);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
// Delete workspaces from local map
|
|
75
|
+
workspacesToDelete.forEach(workspaceId => {
|
|
76
|
+
this.map.delete(workspaceId);
|
|
77
|
+
});
|
|
78
|
+
// Update or insert workspaces
|
|
79
|
+
workspacesToUpdate.forEach(workspace => {
|
|
80
|
+
this.map.set(workspace.id, workspace);
|
|
81
|
+
});
|
|
82
|
+
// Update the store's workspace list to reflect remote changes
|
|
83
|
+
if (this._core?.store) {
|
|
84
|
+
this._core.store.state.workspaces = this.allWorkspaces();
|
|
85
|
+
}
|
|
86
|
+
// Notify about remote changes
|
|
87
|
+
if (this._onRemoteChangeCallback) {
|
|
88
|
+
this._onRemoteChangeCallback();
|
|
89
|
+
}
|
|
90
|
+
this._core?.rerender();
|
|
91
|
+
}
|
|
92
|
+
reviveWorkspace(serialized) {
|
|
93
|
+
const workspace = new KritzelWorkspace(serialized.id, serialized.name, serialized.viewport);
|
|
94
|
+
workspace._core = this._core;
|
|
95
|
+
workspace.createdAt = new Date(serialized.createdAt);
|
|
96
|
+
workspace.updatedAt = new Date(serialized.updatedAt);
|
|
97
|
+
return workspace;
|
|
98
|
+
}
|
|
99
|
+
transaction(callback) {
|
|
100
|
+
if (this._ydoc) {
|
|
101
|
+
this._ydoc.transact(callback, 'local');
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
loadFromYjs() {
|
|
105
|
+
if (!this._workspacesMap) {
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
this.map.clear();
|
|
109
|
+
this._workspacesMap.forEach((serialized, key) => {
|
|
110
|
+
const workspace = this.reviveWorkspace(serialized);
|
|
111
|
+
this.map.set(key, workspace);
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
reset() {
|
|
115
|
+
this.map.clear();
|
|
116
|
+
this._ydoc.transact(() => {
|
|
117
|
+
this._workspacesMap.clear();
|
|
118
|
+
}, 'local');
|
|
119
|
+
}
|
|
120
|
+
insert(workspace) {
|
|
121
|
+
if (!workspace.id) {
|
|
122
|
+
return false;
|
|
123
|
+
}
|
|
124
|
+
this.map.set(workspace.id, workspace);
|
|
125
|
+
if (this._workspacesMap) {
|
|
126
|
+
const serialized = workspace.serialize();
|
|
127
|
+
this._ydoc.transact(() => {
|
|
128
|
+
this._workspacesMap.set(workspace.id, serialized);
|
|
129
|
+
}, 'local');
|
|
130
|
+
}
|
|
131
|
+
return true;
|
|
132
|
+
}
|
|
133
|
+
update(workspace) {
|
|
134
|
+
if (!workspace.id || !this.map.has(workspace.id)) {
|
|
135
|
+
return false;
|
|
136
|
+
}
|
|
137
|
+
this.map.set(workspace.id, workspace);
|
|
138
|
+
if (this._workspacesMap) {
|
|
139
|
+
const serialized = workspace.serialize();
|
|
140
|
+
this._ydoc.transact(() => {
|
|
141
|
+
this._workspacesMap.set(workspace.id, serialized);
|
|
142
|
+
}, 'local');
|
|
143
|
+
}
|
|
144
|
+
return true;
|
|
145
|
+
}
|
|
146
|
+
remove(predicate) {
|
|
147
|
+
const workspaceToRemove = Array.from(this.map.values()).find(predicate);
|
|
148
|
+
if (!workspaceToRemove) {
|
|
149
|
+
return false;
|
|
150
|
+
}
|
|
151
|
+
this.map.delete(workspaceToRemove.id);
|
|
152
|
+
if (this._workspacesMap) {
|
|
153
|
+
this._ydoc.transact(() => {
|
|
154
|
+
this._workspacesMap.delete(workspaceToRemove.id);
|
|
155
|
+
}, 'local');
|
|
156
|
+
}
|
|
157
|
+
return true;
|
|
158
|
+
}
|
|
159
|
+
get(id) {
|
|
160
|
+
return this.map.get(id);
|
|
161
|
+
}
|
|
162
|
+
allWorkspaces() {
|
|
163
|
+
return Array.from(this.map.values());
|
|
164
|
+
}
|
|
165
|
+
filter(predicate) {
|
|
166
|
+
return Array.from(this.map.values()).filter(predicate);
|
|
167
|
+
}
|
|
168
|
+
find(predicate) {
|
|
169
|
+
return Array.from(this.map.values()).find(predicate);
|
|
170
|
+
}
|
|
171
|
+
has(id) {
|
|
172
|
+
return this.map.has(id);
|
|
173
|
+
}
|
|
174
|
+
destroy() {
|
|
175
|
+
// Disconnect all providers
|
|
176
|
+
this._providers.forEach(p => p.disconnect());
|
|
177
|
+
this._providers = [];
|
|
178
|
+
// Clear maps
|
|
179
|
+
this.map.clear();
|
|
180
|
+
this._workspacesMap = null;
|
|
181
|
+
// Destroy Y.Doc
|
|
182
|
+
if (this._ydoc) {
|
|
183
|
+
this._ydoc.destroy();
|
|
184
|
+
this._ydoc = null;
|
|
185
|
+
}
|
|
186
|
+
this._isReady = false;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
//# sourceMappingURL=app-state-map.structure.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app-state-map.structure.js","sourceRoot":"","sources":["../../../src/classes/structures/app-state-map.structure.ts"],"names":[],"mappings":"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","sourcesContent":["import * as Y from 'yjs';\r\nimport { KritzelWorkspace } from '../core/workspace.class';\r\nimport { KritzelCore } from '../core/core.class';\r\nimport { ISyncProvider } from '../../interfaces/sync-provider.interface';\r\nimport { KritzelSyncConfig } from '../../interfaces/sync-config.interface';\r\nimport { DEFAULT_SYNC_CONFIG } from '../../configs/default-sync.config';\r\n\r\nexport class KritzelAppStateMap {\r\n private map: Map<string, KritzelWorkspace>;\r\n private _ydoc: Y.Doc | null = null;\r\n private _workspacesMap: Y.Map<any> | null = null;\r\n private _providers: ISyncProvider[] = [];\r\n private _core: KritzelCore | null = null;\r\n private _isReady: boolean = false;\r\n private _onRemoteChangeCallback: (() => void) | null = null;\r\n\r\n get isReady(): boolean {\r\n return this._isReady;\r\n }\r\n\r\n constructor() {\r\n this.map = new Map<string, KritzelWorkspace>();\r\n }\r\n\r\n onRemoteChange(callback: () => void): void {\r\n this._onRemoteChangeCallback = callback;\r\n }\r\n\r\n async initialize(core: KritzelCore, config?: KritzelSyncConfig): Promise<void> {\r\n this._core = core;\r\n\r\n // Create a dedicated Y.Doc for app state (workspaces)\r\n this._ydoc = new Y.Doc();\r\n this._workspacesMap = this._ydoc.getMap('workspaces');\r\n\r\n const docName = 'kritzel-app-state';\r\n const finalConfig = config ?? DEFAULT_SYNC_CONFIG;\r\n\r\n // Instantiate providers from configuration\r\n for (const providerConfig of finalConfig.providers) {\r\n let provider: ISyncProvider;\r\n\r\n // Check if it's a class constructor or a factory\r\n if (typeof providerConfig === 'function') {\r\n // It's a class constructor\r\n provider = new providerConfig(docName, this._ydoc);\r\n } else {\r\n // It's a factory with a create method\r\n provider = providerConfig.create(docName, this._ydoc);\r\n }\r\n\r\n this._providers.push(provider);\r\n }\r\n\r\n // Observe changes to workspaces and sync with application state\r\n this._workspacesMap.observe(event => {\r\n this.handleWorkspacesChange(event);\r\n });\r\n\r\n // Connect all providers in parallel\r\n await Promise.all(this._providers.map(p => p.connect()));\r\n this._isReady = true;\r\n\r\n // Load workspaces from Yjs\r\n this.loadFromYjs();\r\n }\r\n\r\n private handleWorkspacesChange(event: Y.YMapEvent<any>): void {\r\n // Skip Map updates for local changes (already done), but still trigger re-render\r\n if (event.transaction.origin === 'local') {\r\n this._core?.rerender();\r\n return;\r\n }\r\n\r\n const changedKeys = Array.from(event.keysChanged);\r\n const workspacesToUpdate = [];\r\n const workspacesToDelete = [];\r\n\r\n changedKeys.forEach(key => {\r\n const change = event.changes.keys.get(key);\r\n\r\n if (change && change.action === 'delete') {\r\n workspacesToDelete.push(key);\r\n } else {\r\n const serialized = this._workspacesMap.get(key);\r\n if (serialized) {\r\n const workspace = this.reviveWorkspace(serialized);\r\n workspacesToUpdate.push(workspace);\r\n }\r\n }\r\n });\r\n\r\n // Delete workspaces from local map\r\n workspacesToDelete.forEach(workspaceId => {\r\n this.map.delete(workspaceId);\r\n });\r\n\r\n // Update or insert workspaces\r\n workspacesToUpdate.forEach(workspace => {\r\n this.map.set(workspace.id, workspace);\r\n });\r\n\r\n // Update the store's workspace list to reflect remote changes\r\n if (this._core?.store) {\r\n this._core.store.state.workspaces = this.allWorkspaces();\r\n }\r\n\r\n // Notify about remote changes\r\n if (this._onRemoteChangeCallback) {\r\n this._onRemoteChangeCallback();\r\n }\r\n\r\n this._core?.rerender();\r\n }\r\n\r\n private reviveWorkspace(serialized: any): KritzelWorkspace {\r\n const workspace = new KritzelWorkspace(\r\n serialized.id,\r\n serialized.name,\r\n serialized.viewport\r\n );\r\n workspace._core = this._core;\r\n workspace.createdAt = new Date(serialized.createdAt);\r\n workspace.updatedAt = new Date(serialized.updatedAt);\r\n return workspace;\r\n }\r\n\r\n transaction(callback: () => void): void {\r\n if (this._ydoc) {\r\n this._ydoc.transact(callback, 'local');\r\n }\r\n }\r\n\r\n loadFromYjs(): void {\r\n if (!this._workspacesMap) {\r\n return;\r\n }\r\n\r\n this.map.clear();\r\n this._workspacesMap.forEach((serialized, key) => {\r\n const workspace = this.reviveWorkspace(serialized);\r\n this.map.set(key, workspace);\r\n });\r\n }\r\n\r\n reset(): void {\r\n this.map.clear();\r\n this._ydoc.transact(() => {\r\n this._workspacesMap.clear();\r\n }, 'local');\r\n }\r\n\r\n insert(workspace: KritzelWorkspace): boolean {\r\n if (!workspace.id) {\r\n return false;\r\n }\r\n this.map.set(workspace.id, workspace);\r\n\r\n if (this._workspacesMap) {\r\n const serialized = workspace.serialize();\r\n this._ydoc.transact(() => {\r\n this._workspacesMap.set(workspace.id, serialized);\r\n }, 'local');\r\n }\r\n\r\n return true;\r\n }\r\n\r\n update(workspace: KritzelWorkspace): boolean {\r\n if (!workspace.id || !this.map.has(workspace.id)) {\r\n return false;\r\n }\r\n\r\n this.map.set(workspace.id, workspace);\r\n\r\n if (this._workspacesMap) {\r\n const serialized = workspace.serialize();\r\n this._ydoc.transact(() => {\r\n this._workspacesMap.set(workspace.id, serialized);\r\n }, 'local');\r\n }\r\n\r\n return true;\r\n }\r\n\r\n remove(predicate: (workspace: KritzelWorkspace) => boolean): boolean {\r\n const workspaceToRemove = Array.from(this.map.values()).find(predicate);\r\n\r\n if (!workspaceToRemove) {\r\n return false;\r\n }\r\n\r\n this.map.delete(workspaceToRemove.id);\r\n\r\n if (this._workspacesMap) {\r\n this._ydoc.transact(() => {\r\n this._workspacesMap.delete(workspaceToRemove.id);\r\n }, 'local');\r\n }\r\n\r\n return true;\r\n }\r\n\r\n get(id: string): KritzelWorkspace | undefined {\r\n return this.map.get(id);\r\n }\r\n\r\n allWorkspaces(): KritzelWorkspace[] {\r\n return Array.from(this.map.values());\r\n }\r\n\r\n filter(predicate: (workspace: KritzelWorkspace) => boolean): KritzelWorkspace[] {\r\n return Array.from(this.map.values()).filter(predicate);\r\n }\r\n\r\n find(predicate: (workspace: KritzelWorkspace) => boolean): KritzelWorkspace | undefined {\r\n return Array.from(this.map.values()).find(predicate);\r\n }\r\n\r\n has(id: string): boolean {\r\n return this.map.has(id);\r\n }\r\n\r\n destroy(): void {\r\n // Disconnect all providers\r\n this._providers.forEach(p => p.disconnect());\r\n this._providers = [];\r\n\r\n // Clear maps\r\n this.map.clear();\r\n this._workspacesMap = null;\r\n\r\n // Destroy Y.Doc\r\n if (this._ydoc) {\r\n this._ydoc.destroy();\r\n this._ydoc = null;\r\n }\r\n\r\n this._isReady = false;\r\n }\r\n}\r\n"]}
|
|
@@ -0,0 +1,328 @@
|
|
|
1
|
+
import * as Y from "yjs";
|
|
2
|
+
import { KritzelReviver } from "../core/reviver.class";
|
|
3
|
+
import { KritzelSelectionBox } from "../objects/selection-box.class";
|
|
4
|
+
import { KritzelSelectionGroup } from "../objects/selection-group.class";
|
|
5
|
+
import { DEFAULT_SYNC_CONFIG } from "../../configs/default-sync.config";
|
|
6
|
+
import { KritzelQuadtree } from "./quadtree.structure";
|
|
7
|
+
export class KritzelObjectMap {
|
|
8
|
+
quadtree;
|
|
9
|
+
_ydoc = null;
|
|
10
|
+
_objectsMap = null;
|
|
11
|
+
_providers = [];
|
|
12
|
+
_undoManager = null;
|
|
13
|
+
_reviver = null;
|
|
14
|
+
_core = null;
|
|
15
|
+
_workspaceId = null;
|
|
16
|
+
_isReady = false;
|
|
17
|
+
_temporaryItemsCount = 0;
|
|
18
|
+
get isReady() {
|
|
19
|
+
return this._isReady;
|
|
20
|
+
}
|
|
21
|
+
get undoManager() {
|
|
22
|
+
return this._undoManager;
|
|
23
|
+
}
|
|
24
|
+
get workspaceId() {
|
|
25
|
+
return this._workspaceId;
|
|
26
|
+
}
|
|
27
|
+
get undoState() {
|
|
28
|
+
return {
|
|
29
|
+
canUndo: this._undoManager ? this._undoManager.canUndo() : false,
|
|
30
|
+
canRedo: this._undoManager ? this._undoManager.canRedo() : false,
|
|
31
|
+
undoStackSize: this._undoManager ? this._undoManager.undoStack.length : 0,
|
|
32
|
+
redoStackSize: this._undoManager ? this._undoManager.redoStack.length : 0,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
constructor() {
|
|
36
|
+
this.quadtree = new KritzelQuadtree({
|
|
37
|
+
x: -Infinity,
|
|
38
|
+
y: -Infinity,
|
|
39
|
+
z: 0,
|
|
40
|
+
width: Infinity,
|
|
41
|
+
height: Infinity,
|
|
42
|
+
}, 8);
|
|
43
|
+
}
|
|
44
|
+
async initialize(core, workspaceId, config) {
|
|
45
|
+
this._core = core;
|
|
46
|
+
this._workspaceId = workspaceId;
|
|
47
|
+
this._reviver = new KritzelReviver(core);
|
|
48
|
+
// Create a dedicated Y.Doc for this workspace
|
|
49
|
+
this._ydoc = new Y.Doc();
|
|
50
|
+
this._objectsMap = this._ydoc.getMap('objects');
|
|
51
|
+
const docName = `kritzel-workspace-${workspaceId}`;
|
|
52
|
+
const finalConfig = config ?? DEFAULT_SYNC_CONFIG;
|
|
53
|
+
// Instantiate providers from configuration
|
|
54
|
+
for (const providerConfig of finalConfig.providers) {
|
|
55
|
+
let provider;
|
|
56
|
+
// Check if it's a class constructor or a factory
|
|
57
|
+
if (typeof providerConfig === 'function') {
|
|
58
|
+
// It's a class constructor
|
|
59
|
+
provider = new providerConfig(docName, this._ydoc);
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
// It's a factory with a create method
|
|
63
|
+
provider = providerConfig.create(docName, this._ydoc);
|
|
64
|
+
}
|
|
65
|
+
this._providers.push(provider);
|
|
66
|
+
}
|
|
67
|
+
// Set up undo/redo manager for this workspace
|
|
68
|
+
this._undoManager = new Y.UndoManager([this._objectsMap], {
|
|
69
|
+
captureTimeout: 200,
|
|
70
|
+
trackedOrigins: new Set(['local', 'temporary']),
|
|
71
|
+
ignoreRemoteMapChanges: true,
|
|
72
|
+
});
|
|
73
|
+
this._undoManager.on('stack-item-added', event => {
|
|
74
|
+
if (event.type === 'undo') {
|
|
75
|
+
// Track if this was a temporary item
|
|
76
|
+
if (event.origin === 'temporary') {
|
|
77
|
+
this._temporaryItemsCount++;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
this._undoManager.on('stack-item-popped', event => {
|
|
82
|
+
if (event.type === 'undo') {
|
|
83
|
+
// Reduce temporary count when items are undone
|
|
84
|
+
if (event.origin === 'temporary' && this._temporaryItemsCount > 0) {
|
|
85
|
+
this._temporaryItemsCount--;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
// Observe changes to objects and sync with application state
|
|
90
|
+
this._objectsMap.observe(event => {
|
|
91
|
+
this.handleObjectsChange(event);
|
|
92
|
+
});
|
|
93
|
+
// Connect all providers in parallel
|
|
94
|
+
await Promise.all(this._providers.map(p => p.connect()));
|
|
95
|
+
this._isReady = true;
|
|
96
|
+
// Load objects from Yjs
|
|
97
|
+
this.loadFromYjs();
|
|
98
|
+
}
|
|
99
|
+
handleObjectsChange(event) {
|
|
100
|
+
// Skip Map updates for local changes (already done), but still trigger re-render
|
|
101
|
+
// 'temporary' is also a local change that shouldn't be re-deserialized
|
|
102
|
+
if (event.transaction.origin === 'local' || event.transaction.origin === 'temporary') {
|
|
103
|
+
this._core?.rerender();
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
const changedKeys = Array.from(event.keysChanged);
|
|
107
|
+
const objectsToUpdate = [];
|
|
108
|
+
const selectionGroupsToUpdate = [];
|
|
109
|
+
const objectsToDelete = [];
|
|
110
|
+
changedKeys.forEach(key => {
|
|
111
|
+
const change = event.changes.keys.get(key);
|
|
112
|
+
if (change && change.action === 'delete') {
|
|
113
|
+
objectsToDelete.push(key);
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
const serialized = this._objectsMap.get(key);
|
|
117
|
+
if (serialized) {
|
|
118
|
+
const object = this._reviver.revive(serialized);
|
|
119
|
+
// Separate SelectionGroups to process them after regular objects
|
|
120
|
+
if (object instanceof KritzelSelectionGroup) {
|
|
121
|
+
selectionGroupsToUpdate.push(object);
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
objectsToUpdate.push(object);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
// Delete objects from local map
|
|
130
|
+
objectsToDelete.forEach(objectId => {
|
|
131
|
+
this.quadtree.remove(o => o.id === objectId);
|
|
132
|
+
});
|
|
133
|
+
// First, update or insert regular objects
|
|
134
|
+
objectsToUpdate.forEach(object => {
|
|
135
|
+
const existed = this.quadtree.filter(o => o.id === object.id).length > 0;
|
|
136
|
+
if (existed) {
|
|
137
|
+
this.quadtree.update(object);
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
this.quadtree.insert(object);
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
// Then, update or insert SelectionGroups
|
|
144
|
+
selectionGroupsToUpdate.forEach(object => {
|
|
145
|
+
const existed = this.quadtree.filter(o => o.id === object.id).length > 0;
|
|
146
|
+
if (existed) {
|
|
147
|
+
this.quadtree.update(object);
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
this.quadtree.insert(object);
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
this._core?.rerender();
|
|
154
|
+
}
|
|
155
|
+
transaction(callback) {
|
|
156
|
+
if (this._ydoc) {
|
|
157
|
+
this._ydoc.transact(callback, 'local');
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
loadFromYjs() {
|
|
161
|
+
if (!this._objectsMap || !this._reviver) {
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
this.quadtree.reset();
|
|
165
|
+
this._objectsMap.forEach(serialized => {
|
|
166
|
+
const object = this._reviver.revive(serialized);
|
|
167
|
+
this.quadtree.insert(object);
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
reset() {
|
|
171
|
+
this.quadtree.reset();
|
|
172
|
+
this._ydoc.transact(() => {
|
|
173
|
+
this._objectsMap.clear();
|
|
174
|
+
}, 'local');
|
|
175
|
+
}
|
|
176
|
+
insert(object) {
|
|
177
|
+
if (!object.id) {
|
|
178
|
+
return false;
|
|
179
|
+
}
|
|
180
|
+
this.quadtree.insert(object);
|
|
181
|
+
if (this._objectsMap && this.isPersistable(object)) {
|
|
182
|
+
const serialized = object.serialize();
|
|
183
|
+
this._ydoc.transact(() => {
|
|
184
|
+
this._objectsMap.set(object.id, serialized);
|
|
185
|
+
}, 'local');
|
|
186
|
+
}
|
|
187
|
+
return true;
|
|
188
|
+
}
|
|
189
|
+
update(object, options = {}) {
|
|
190
|
+
if (!object.id) {
|
|
191
|
+
return false;
|
|
192
|
+
}
|
|
193
|
+
const existed = this.quadtree.filter(o => o.id === object.id).length > 0;
|
|
194
|
+
if (!existed) {
|
|
195
|
+
return false;
|
|
196
|
+
}
|
|
197
|
+
this.quadtree.update(object);
|
|
198
|
+
if (this._objectsMap && this.isPersistable(object)) {
|
|
199
|
+
const serialized = object.serialize();
|
|
200
|
+
const origin = options.temporary ? 'temporary' : 'local';
|
|
201
|
+
this._ydoc.transact(() => {
|
|
202
|
+
this._objectsMap.set(object.id, serialized);
|
|
203
|
+
}, origin);
|
|
204
|
+
}
|
|
205
|
+
return true;
|
|
206
|
+
}
|
|
207
|
+
remove(predicate) {
|
|
208
|
+
const objectsToRemove = this.quadtree.filter(predicate);
|
|
209
|
+
for (const object of objectsToRemove) {
|
|
210
|
+
this.quadtree.remove(o => o.id === object.id);
|
|
211
|
+
if (this._objectsMap && this.isPersistable(object)) {
|
|
212
|
+
this._ydoc.transact(() => {
|
|
213
|
+
this._objectsMap.delete(object.id);
|
|
214
|
+
}, 'local');
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
filter(predicate) {
|
|
219
|
+
return this.quadtree.filter(predicate);
|
|
220
|
+
}
|
|
221
|
+
allObjects() {
|
|
222
|
+
return this.quadtree.allObjects();
|
|
223
|
+
}
|
|
224
|
+
query(range) {
|
|
225
|
+
return this.quadtree.query(range);
|
|
226
|
+
}
|
|
227
|
+
isPersistable(object) {
|
|
228
|
+
if (object instanceof KritzelSelectionBox) {
|
|
229
|
+
return false;
|
|
230
|
+
}
|
|
231
|
+
return true;
|
|
232
|
+
}
|
|
233
|
+
undo() {
|
|
234
|
+
if (this._undoManager && this._undoManager.canUndo()) {
|
|
235
|
+
this._undoManager.undo();
|
|
236
|
+
this._core.engine.emitObjectsChange();
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
redo() {
|
|
240
|
+
if (this._undoManager && this._undoManager.canRedo()) {
|
|
241
|
+
this._undoManager.redo();
|
|
242
|
+
this._core.engine.emitObjectsChange();
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
canUndo() {
|
|
246
|
+
return this._undoManager ? this._undoManager.canUndo() : false;
|
|
247
|
+
}
|
|
248
|
+
canRedo() {
|
|
249
|
+
return this._undoManager ? this._undoManager.canRedo() : false;
|
|
250
|
+
}
|
|
251
|
+
clearHistory() {
|
|
252
|
+
if (this._undoManager) {
|
|
253
|
+
this._undoManager.clear();
|
|
254
|
+
this._temporaryItemsCount = 0;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Consolidates all temporary items in the undo stack into a single undo item.
|
|
259
|
+
* Call this when you want to merge multiple temporary changes (e.g., keystrokes) into one.
|
|
260
|
+
*/
|
|
261
|
+
consolidateTemporaryItems() {
|
|
262
|
+
if (!this._undoManager || this._temporaryItemsCount === 0) {
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
// Get current stack length
|
|
266
|
+
const stackLength = this._undoManager.undoStack.length;
|
|
267
|
+
if (stackLength === 0) {
|
|
268
|
+
this._temporaryItemsCount = 0;
|
|
269
|
+
return;
|
|
270
|
+
}
|
|
271
|
+
// Stop tracking temporarily
|
|
272
|
+
this._undoManager.stopCapturing();
|
|
273
|
+
// The temporary items should be at the end of the stack
|
|
274
|
+
// We'll need to undo them all, then redo as a single transaction
|
|
275
|
+
const itemsToConsolidate = Math.min(this._temporaryItemsCount, stackLength);
|
|
276
|
+
if (itemsToConsolidate > 1) {
|
|
277
|
+
// Store the current state before undoing
|
|
278
|
+
const undoneItems = [];
|
|
279
|
+
// Undo all temporary items
|
|
280
|
+
for (let i = 0; i < itemsToConsolidate; i++) {
|
|
281
|
+
if (this._undoManager.canUndo()) {
|
|
282
|
+
undoneItems.push(this._undoManager.undoStack[this._undoManager.undoStack.length - 1]);
|
|
283
|
+
this._undoManager.undo();
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
// Now redo them all as a single 'local' transaction
|
|
287
|
+
// This will consolidate them into one undo item
|
|
288
|
+
this._ydoc.transact(() => {
|
|
289
|
+
for (let i = itemsToConsolidate - 1; i >= 0; i--) {
|
|
290
|
+
if (this._undoManager.canRedo()) {
|
|
291
|
+
this._undoManager.redo();
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
}, 'local');
|
|
295
|
+
}
|
|
296
|
+
else if (itemsToConsolidate === 1) {
|
|
297
|
+
// If only one temporary item, just change its origin to 'local'
|
|
298
|
+
// This is implicit - next transaction will be separate
|
|
299
|
+
}
|
|
300
|
+
this._temporaryItemsCount = 0;
|
|
301
|
+
}
|
|
302
|
+
/**
|
|
303
|
+
* Removes all temporary items from the undo stack without consolidating them.
|
|
304
|
+
* Use this to discard temporary changes completely.
|
|
305
|
+
*/
|
|
306
|
+
clearTemporaryItems() {
|
|
307
|
+
if (!this._undoManager || this._temporaryItemsCount === 0) {
|
|
308
|
+
return;
|
|
309
|
+
}
|
|
310
|
+
const stackLength = this._undoManager.undoStack.length;
|
|
311
|
+
const itemsToRemove = Math.min(this._temporaryItemsCount, stackLength);
|
|
312
|
+
// Remove items from the end of the stack
|
|
313
|
+
for (let i = 0; i < itemsToRemove; i++) {
|
|
314
|
+
if (this._undoManager.undoStack.length > 0) {
|
|
315
|
+
this._undoManager.undoStack.pop();
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
this._temporaryItemsCount = 0;
|
|
319
|
+
}
|
|
320
|
+
destroy() {
|
|
321
|
+
this._providers.forEach(p => p.destroy());
|
|
322
|
+
this._providers = [];
|
|
323
|
+
if (this._ydoc) {
|
|
324
|
+
this._ydoc.destroy();
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
//# sourceMappingURL=object-map.structure.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"object-map.structure.js","sourceRoot":"","sources":["../../../src/classes/structures/object-map.structure.ts"],"names":[],"mappings":"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","sourcesContent":["import * as Y from 'yjs';\r\nimport { KritzelReviver } from '../core/reviver.class';\r\nimport { KritzelBaseObject } from '../objects/base-object.class';\r\nimport { KritzelSelectionBox } from '../objects/selection-box.class';\r\nimport { KritzelSelectionGroup } from '../objects/selection-group.class';\r\nimport { KritzelCore } from '../core/core.class';\r\nimport { ISyncProvider } from '../../interfaces/sync-provider.interface';\r\nimport { KritzelSyncConfig } from '../../interfaces/sync-config.interface';\r\nimport { DEFAULT_SYNC_CONFIG } from '../../configs/default-sync.config';\r\nimport { KritzelUndoState } from '../..';\r\nimport { KritzelQuadtree } from './quadtree.structure';\r\n\r\nexport class KritzelObjectMap<T extends KritzelBaseObject<any>> {\r\n private quadtree: KritzelQuadtree<T>;\r\n private _ydoc: Y.Doc | null = null;\r\n private _objectsMap: Y.Map<any> | null = null;\r\n private _providers: ISyncProvider[] = [];\r\n private _undoManager: Y.UndoManager | null = null;\r\n private _reviver: KritzelReviver | null = null;\r\n private _core: KritzelCore | null = null;\r\n private _workspaceId: string | null = null;\r\n private _isReady: boolean = false;\r\n private _temporaryItemsCount: number = 0;\r\n\r\n get isReady(): boolean {\r\n return this._isReady;\r\n }\r\n\r\n get undoManager(): Y.UndoManager | null {\r\n return this._undoManager;\r\n }\r\n\r\n get workspaceId(): string | null {\r\n return this._workspaceId;\r\n }\r\n\r\n get undoState() : KritzelUndoState {\r\n return {\r\n canUndo: this._undoManager ? this._undoManager.canUndo() : false,\r\n canRedo: this._undoManager ? this._undoManager.canRedo() : false,\r\n undoStackSize: this._undoManager ? this._undoManager.undoStack.length : 0,\r\n redoStackSize: this._undoManager ? this._undoManager.redoStack.length : 0,\r\n };\r\n }\r\n\r\n constructor() {\r\n this.quadtree = new KritzelQuadtree<T>(\r\n {\r\n x: -Infinity,\r\n y: -Infinity,\r\n z: 0,\r\n width: Infinity,\r\n height: Infinity,\r\n },\r\n 8\r\n );\r\n }\r\n\r\n async initialize(core: KritzelCore, workspaceId: string, config?: KritzelSyncConfig): Promise<void> {\r\n this._core = core;\r\n this._workspaceId = workspaceId;\r\n this._reviver = new KritzelReviver(core);\r\n\r\n // Create a dedicated Y.Doc for this workspace\r\n this._ydoc = new Y.Doc();\r\n this._objectsMap = this._ydoc.getMap('objects');\r\n\r\n const docName = `kritzel-workspace-${workspaceId}`;\r\n const finalConfig = config ?? DEFAULT_SYNC_CONFIG;\r\n\r\n // Instantiate providers from configuration\r\n for (const providerConfig of finalConfig.providers) {\r\n let provider: ISyncProvider;\r\n\r\n // Check if it's a class constructor or a factory\r\n if (typeof providerConfig === 'function') {\r\n // It's a class constructor\r\n provider = new providerConfig(docName, this._ydoc);\r\n } else {\r\n // It's a factory with a create method\r\n provider = providerConfig.create(docName, this._ydoc);\r\n }\r\n\r\n this._providers.push(provider);\r\n }\r\n\r\n // Set up undo/redo manager for this workspace\r\n this._undoManager = new Y.UndoManager([this._objectsMap], {\r\n captureTimeout: 200,\r\n trackedOrigins: new Set(['local', 'temporary']),\r\n ignoreRemoteMapChanges: true,\r\n });\r\n\r\n this._undoManager.on('stack-item-added', event => {\r\n if (event.type === 'undo') {\r\n // Track if this was a temporary item\r\n if (event.origin === 'temporary') {\r\n this._temporaryItemsCount++;\r\n }\r\n }\r\n });\r\n\r\n this._undoManager.on('stack-item-popped', event => {\r\n if (event.type === 'undo') {\r\n // Reduce temporary count when items are undone\r\n if (event.origin === 'temporary' && this._temporaryItemsCount > 0) {\r\n this._temporaryItemsCount--;\r\n }\r\n }\r\n });\r\n\r\n // Observe changes to objects and sync with application state\r\n this._objectsMap.observe(event => {\r\n this.handleObjectsChange(event);\r\n });\r\n\r\n // Connect all providers in parallel\r\n await Promise.all(this._providers.map(p => p.connect()));\r\n this._isReady = true;\r\n\r\n // Load objects from Yjs\r\n this.loadFromYjs();\r\n }\r\n\r\n private handleObjectsChange(event: Y.YMapEvent<any>): void {\r\n // Skip Map updates for local changes (already done), but still trigger re-render\r\n // 'temporary' is also a local change that shouldn't be re-deserialized\r\n if (event.transaction.origin === 'local' || event.transaction.origin === 'temporary') {\r\n this._core?.rerender();\r\n return;\r\n }\r\n\r\n const changedKeys = Array.from(event.keysChanged);\r\n const objectsToUpdate = [];\r\n const selectionGroupsToUpdate = [];\r\n const objectsToDelete = [];\r\n\r\n changedKeys.forEach(key => {\r\n const change = event.changes.keys.get(key);\r\n\r\n if (change && change.action === 'delete') {\r\n objectsToDelete.push(key);\r\n } else {\r\n const serialized = this._objectsMap.get(key);\r\n if (serialized) {\r\n const object = this._reviver.revive(serialized);\r\n\r\n // Separate SelectionGroups to process them after regular objects\r\n if (object instanceof KritzelSelectionGroup) {\r\n selectionGroupsToUpdate.push(object);\r\n } else {\r\n objectsToUpdate.push(object);\r\n }\r\n }\r\n }\r\n });\r\n\r\n // Delete objects from local map\r\n objectsToDelete.forEach(objectId => {\r\n this.quadtree.remove(o => o.id === objectId);\r\n });\r\n\r\n // First, update or insert regular objects\r\n objectsToUpdate.forEach(object => {\r\n const existed = this.quadtree.filter(o => o.id === object.id).length > 0;\r\n if (existed) {\r\n this.quadtree.update(object);\r\n } else {\r\n this.quadtree.insert(object);\r\n }\r\n });\r\n\r\n // Then, update or insert SelectionGroups\r\n selectionGroupsToUpdate.forEach(object => {\r\n const existed = this.quadtree.filter(o => o.id === object.id).length > 0;\r\n if (existed) {\r\n this.quadtree.update(object);\r\n } else {\r\n this.quadtree.insert(object);\r\n }\r\n });\r\n\r\n this._core?.rerender();\r\n }\r\n transaction(callback: () => void): void {\r\n if (this._ydoc) {\r\n this._ydoc.transact(callback, 'local');\r\n }\r\n }\r\n\r\n loadFromYjs(): void {\r\n if (!this._objectsMap || !this._reviver) {\r\n return;\r\n }\r\n\r\n this.quadtree.reset();\r\n this._objectsMap.forEach(serialized => {\r\n const object = this._reviver.revive<T>(serialized);\r\n this.quadtree.insert(object);\r\n });\r\n }\r\n\r\n reset(): void {\r\n this.quadtree.reset();\r\n this._ydoc.transact(() => {\r\n this._objectsMap.clear();\r\n }, 'local');\r\n }\r\n\r\n insert(object: T): boolean {\r\n if (!object.id) {\r\n return false;\r\n }\r\n this.quadtree.insert(object);\r\n\r\n if (this._objectsMap && this.isPersistable(object)) {\r\n const serialized = object.serialize();\r\n this._ydoc.transact(() => {\r\n this._objectsMap.set(object.id, serialized);\r\n }, 'local');\r\n }\r\n\r\n return true;\r\n }\r\n\r\n update(object: T, options: { temporary?: boolean } = {}): boolean {\r\n if (!object.id) {\r\n return false;\r\n }\r\n const existed = this.quadtree.filter(o => o.id === object.id).length > 0;\r\n if (!existed) {\r\n return false;\r\n }\r\n this.quadtree.update(object);\r\n\r\n if (this._objectsMap && this.isPersistable(object)) {\r\n const serialized = object.serialize();\r\n\r\n const origin = options.temporary ? 'temporary' : 'local';\r\n\r\n this._ydoc.transact(() => {\r\n this._objectsMap.set(object.id, serialized);\r\n }, origin);\r\n }\r\n\r\n return true;\r\n }\r\n\r\n remove(predicate: (object: T) => boolean): void {\r\n const objectsToRemove = this.quadtree.filter(predicate);\r\n for (const object of objectsToRemove) {\r\n this.quadtree.remove(o => o.id === object.id);\r\n\r\n if (this._objectsMap && this.isPersistable(object)) {\r\n this._ydoc.transact(() => {\r\n this._objectsMap.delete(object.id);\r\n }, 'local');\r\n }\r\n }\r\n }\r\n\r\n filter(predicate: (object: T) => boolean): T[] {\r\n return this.quadtree.filter(predicate);\r\n }\r\n\r\n allObjects(): T[] {\r\n return this.quadtree.allObjects();\r\n }\r\n\r\n query(range: { x: number; y: number; z: number; width: number; height: number; depth?: number }): T[] {\r\n return this.quadtree.query(range);\r\n }\r\n\r\n private isPersistable(object: T): boolean {\r\n if (object instanceof KritzelSelectionBox) {\r\n return false;\r\n }\r\n\r\n return true;\r\n }\r\n\r\n undo(): void {\r\n if (this._undoManager && this._undoManager.canUndo()) {\r\n this._undoManager.undo();\r\n this._core.engine.emitObjectsChange();\r\n }\r\n }\r\n\r\n redo(): void {\r\n if (this._undoManager && this._undoManager.canRedo()) {\r\n this._undoManager.redo();\r\n this._core.engine.emitObjectsChange();\r\n }\r\n }\r\n\r\n canUndo(): boolean {\r\n return this._undoManager ? this._undoManager.canUndo() : false;\r\n }\r\n\r\n canRedo(): boolean {\r\n return this._undoManager ? this._undoManager.canRedo() : false;\r\n }\r\n\r\n clearHistory(): void {\r\n if (this._undoManager) {\r\n this._undoManager.clear();\r\n this._temporaryItemsCount = 0;\r\n }\r\n }\r\n\r\n /**\r\n * Consolidates all temporary items in the undo stack into a single undo item.\r\n * Call this when you want to merge multiple temporary changes (e.g., keystrokes) into one.\r\n */\r\n consolidateTemporaryItems(): void {\r\n if (!this._undoManager || this._temporaryItemsCount === 0) {\r\n return;\r\n }\r\n\r\n // Get current stack length\r\n const stackLength = this._undoManager.undoStack.length;\r\n \r\n if (stackLength === 0) {\r\n this._temporaryItemsCount = 0;\r\n return;\r\n }\r\n\r\n // Stop tracking temporarily\r\n this._undoManager.stopCapturing();\r\n \r\n // The temporary items should be at the end of the stack\r\n // We'll need to undo them all, then redo as a single transaction\r\n const itemsToConsolidate = Math.min(this._temporaryItemsCount, stackLength);\r\n \r\n if (itemsToConsolidate > 1) {\r\n // Store the current state before undoing\r\n const undoneItems: any[] = [];\r\n \r\n // Undo all temporary items\r\n for (let i = 0; i < itemsToConsolidate; i++) {\r\n if (this._undoManager.canUndo()) {\r\n undoneItems.push(this._undoManager.undoStack[this._undoManager.undoStack.length - 1]);\r\n this._undoManager.undo();\r\n }\r\n }\r\n \r\n // Now redo them all as a single 'local' transaction\r\n // This will consolidate them into one undo item\r\n this._ydoc.transact(() => {\r\n for (let i = itemsToConsolidate - 1; i >= 0; i--) {\r\n if (this._undoManager.canRedo()) {\r\n this._undoManager.redo();\r\n }\r\n }\r\n }, 'local');\r\n } else if (itemsToConsolidate === 1) {\r\n // If only one temporary item, just change its origin to 'local'\r\n // This is implicit - next transaction will be separate\r\n }\r\n \r\n this._temporaryItemsCount = 0;\r\n }\r\n\r\n /**\r\n * Removes all temporary items from the undo stack without consolidating them.\r\n * Use this to discard temporary changes completely.\r\n */\r\n clearTemporaryItems(): void {\r\n if (!this._undoManager || this._temporaryItemsCount === 0) {\r\n return;\r\n }\r\n\r\n const stackLength = this._undoManager.undoStack.length;\r\n const itemsToRemove = Math.min(this._temporaryItemsCount, stackLength);\r\n \r\n // Remove items from the end of the stack\r\n for (let i = 0; i < itemsToRemove; i++) {\r\n if (this._undoManager.undoStack.length > 0) {\r\n this._undoManager.undoStack.pop();\r\n }\r\n }\r\n \r\n this._temporaryItemsCount = 0;\r\n }\r\n\r\n destroy(): void {\r\n this._providers.forEach(p => p.destroy());\r\n this._providers = [];\r\n\r\n if (this._ydoc) {\r\n this._ydoc.destroy();\r\n }\r\n }\r\n}\r\n"]}
|