kritzel-stencil 0.0.143 → 0.0.145
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/{index-Cg50mv2K.js → default-text-tool.config-D2dP2xyB.js} +15947 -1100
- package/dist/cjs/default-text-tool.config-D2dP2xyB.js.map +1 -0
- package/dist/cjs/{index-DcTwXs_q.js → index-Cj__YTlG.js} +9 -11
- package/dist/cjs/index-Cj__YTlG.js.map +1 -0
- package/dist/cjs/index.cjs.js +1369 -12
- package/dist/cjs/index.cjs.js.map +1 -1
- package/dist/cjs/kritzel-brush-style.cjs.entry.js +1 -1
- package/dist/cjs/kritzel-color_22.cjs.entry.js +771 -720
- package/dist/cjs/loader.cjs.js +2 -2
- package/dist/cjs/stencil.cjs.js +3 -3
- package/dist/cjs/stencil.cjs.js.map +1 -1
- package/dist/collection/classes/core/core.class.js +263 -211
- package/dist/collection/classes/core/core.class.js.map +1 -1
- package/dist/collection/classes/core/store.class.js +21 -3
- package/dist/collection/classes/core/store.class.js.map +1 -1
- package/dist/collection/classes/core/viewport.class.js +8 -3
- package/dist/collection/classes/core/viewport.class.js.map +1 -1
- package/dist/collection/classes/core/workspace.class.js +2 -3
- package/dist/collection/classes/core/workspace.class.js.map +1 -1
- package/dist/collection/classes/handlers/context-menu.handler.js +11 -14
- package/dist/collection/classes/handlers/context-menu.handler.js.map +1 -1
- package/dist/collection/classes/handlers/key.handler.js +13 -13
- package/dist/collection/classes/handlers/key.handler.js.map +1 -1
- package/dist/collection/classes/handlers/move.handler.js +18 -10
- package/dist/collection/classes/handlers/move.handler.js.map +1 -1
- package/dist/collection/classes/handlers/resize.handler.js +20 -17
- package/dist/collection/classes/handlers/resize.handler.js.map +1 -1
- package/dist/collection/classes/handlers/rotation.handler.js +26 -23
- package/dist/collection/classes/handlers/rotation.handler.js.map +1 -1
- package/dist/collection/classes/handlers/selection.handler.js +32 -30
- package/dist/collection/classes/handlers/selection.handler.js.map +1 -1
- package/dist/collection/classes/objects/base-object.class.js +6 -15
- package/dist/collection/classes/objects/base-object.class.js.map +1 -1
- package/dist/collection/classes/objects/custom-element.class.js +2 -0
- package/dist/collection/classes/objects/custom-element.class.js.map +1 -1
- package/dist/collection/classes/objects/image.class.js +2 -0
- package/dist/collection/classes/objects/image.class.js.map +1 -1
- package/dist/collection/classes/objects/path.class.js +4 -0
- package/dist/collection/classes/objects/path.class.js.map +1 -1
- package/dist/collection/classes/objects/selection-box.class.js +3 -4
- package/dist/collection/classes/objects/selection-box.class.js.map +1 -1
- package/dist/collection/classes/objects/selection-group.class.js +109 -49
- package/dist/collection/classes/objects/selection-group.class.js.map +1 -1
- package/dist/collection/classes/objects/text.class.js +36 -42
- package/dist/collection/classes/objects/text.class.js.map +1 -1
- 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/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 +260 -1
- package/dist/collection/classes/structures/object-map.structure.js.map +1 -1
- package/dist/collection/classes/tools/brush-tool.class.js +48 -37
- package/dist/collection/classes/tools/brush-tool.class.js.map +1 -1
- package/dist/collection/classes/tools/eraser-tool.class.js +10 -12
- package/dist/collection/classes/tools/eraser-tool.class.js.map +1 -1
- package/dist/collection/classes/tools/image-tool.class.js +2 -10
- package/dist/collection/classes/tools/image-tool.class.js.map +1 -1
- package/dist/collection/classes/tools/selection-tool.class.js +11 -8
- package/dist/collection/classes/tools/selection-tool.class.js.map +1 -1
- package/dist/collection/classes/tools/text-tool.class.js +12 -18
- package/dist/collection/classes/tools/text-tool.class.js.map +1 -1
- package/dist/collection/collection-manifest.json +1 -1
- package/dist/collection/components/core/kritzel-cursor-trail/kritzel-cursor-trail.js +1 -1
- package/dist/collection/components/core/kritzel-editor/kritzel-editor.js +36 -1
- package/dist/collection/components/core/kritzel-editor/kritzel-editor.js.map +1 -1
- package/dist/collection/components/core/kritzel-engine/kritzel-engine.js +61 -35
- package/dist/collection/components/core/kritzel-engine/kritzel-engine.js.map +1 -1
- package/dist/collection/components/shared/kritzel-color/kritzel-color.js +2 -2
- package/dist/collection/components/shared/kritzel-color-palette/kritzel-color-palette.js +1 -1
- package/dist/collection/components/shared/kritzel-font/kritzel-font.js +1 -1
- package/dist/collection/components/shared/kritzel-font-family/kritzel-font-family.js +1 -1
- package/dist/collection/components/shared/kritzel-font-size/kritzel-font-size.js +1 -1
- package/dist/collection/components/shared/kritzel-menu/kritzel-menu.js +1 -1
- package/dist/collection/components/shared/kritzel-menu-item/kritzel-menu-item.js +2 -2
- package/dist/collection/components/shared/kritzel-portal/kritzel-portal.js +1 -1
- package/dist/collection/components/shared/kritzel-split-button/kritzel-split-button.js +1 -1
- package/dist/collection/components/shared/kritzel-stroke-size/kritzel-stroke-size.js +1 -1
- package/dist/collection/components/shared/kritzel-tooltip/kritzel-tooltip.js +4 -4
- package/dist/collection/components/ui/kritzel-context-menu/kritzel-context-menu.js +1 -1
- package/dist/collection/components/ui/kritzel-control-brush-config/kritzel-control-brush-config.js +2 -2
- package/dist/collection/components/ui/kritzel-control-text-config/kritzel-control-text-config.js +2 -2
- package/dist/collection/components/ui/kritzel-controls/kritzel-controls.js +3 -3
- package/dist/collection/components/ui/kritzel-utility-panel/kritzel-utility-panel.js +1 -1
- package/dist/collection/configs/{default-engine-state.js → default-engine-config.js} +2 -8
- package/dist/collection/configs/default-engine-config.js.map +1 -0
- package/dist/collection/configs/default-sync.config.js +12 -0
- package/dist/collection/configs/default-sync.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/index.js +8 -1
- package/dist/collection/index.js.map +1 -1
- package/dist/collection/interfaces/debug-info.interface.js.map +1 -1
- package/dist/collection/interfaces/engine-state.interface.js.map +1 -1
- package/dist/collection/interfaces/object.interface.js.map +1 -1
- package/dist/collection/interfaces/selection-state.interface.js.map +1 -1
- 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/components/index.js +1361 -4
- package/dist/components/index.js.map +1 -1
- package/dist/components/kritzel-brush-style.js +4 -4
- package/dist/components/kritzel-color-palette.js +1 -1
- package/dist/components/kritzel-color.js +1 -1
- package/dist/components/kritzel-context-menu.js +1 -1
- package/dist/components/kritzel-control-brush-config.js +1 -1
- package/dist/components/kritzel-control-text-config.js +1 -1
- package/dist/components/kritzel-controls.js +1 -1
- package/dist/components/kritzel-cursor-trail.js +1 -1
- package/dist/components/kritzel-dropdown.js +1 -1
- package/dist/components/kritzel-editor.js +39 -27
- package/dist/components/kritzel-editor.js.map +1 -1
- package/dist/components/kritzel-engine.js +1 -1
- package/dist/components/kritzel-font-family.js +1 -1
- package/dist/components/kritzel-font-size.js +1 -1
- package/dist/components/kritzel-font.js +1 -1
- package/dist/components/kritzel-icon.js +1 -1
- package/dist/components/kritzel-menu-item.js +1 -1
- package/dist/components/kritzel-menu.js +1 -1
- package/dist/components/kritzel-portal.js +1 -1
- package/dist/components/kritzel-split-button.js +1 -1
- package/dist/components/kritzel-stroke-size.js +1 -1
- package/dist/components/kritzel-tooltip.js +1 -1
- package/dist/components/kritzel-utility-panel.js +1 -1
- package/dist/components/kritzel-workspace-manager.js +1 -1
- package/dist/components/{p-C_hSH2nN.js → p-8iFF5GHL.js} +6 -6
- package/dist/components/{p-C_hSH2nN.js.map → p-8iFF5GHL.js.map} +1 -1
- package/dist/components/{p-BycHaC-9.js → p-BCrMfH5n.js} +6 -6
- package/dist/components/{p-BycHaC-9.js.map → p-BCrMfH5n.js.map} +1 -1
- package/dist/components/{p-D_RcVGj0.js → p-BHDOht0m.js} +6 -6
- package/dist/components/{p-D_RcVGj0.js.map → p-BHDOht0m.js.map} +1 -1
- package/dist/components/{p-DqsgZIHC.js → p-BHT7_POQ.js} +6 -6
- package/dist/components/{p-DqsgZIHC.js.map → p-BHT7_POQ.js.map} +1 -1
- package/dist/components/{p-DzyZA2GT.js → p-BQ5cdSqE.js} +11 -11
- package/dist/components/{p-DzyZA2GT.js.map → p-BQ5cdSqE.js.map} +1 -1
- package/dist/components/{p-Co5lU_7h.js → p-BaHZYvfq.js} +13 -13
- package/dist/components/{p-Co5lU_7h.js.map → p-BaHZYvfq.js.map} +1 -1
- package/dist/components/{p-BJbN3vca.js → p-BctNMdxr.js} +8 -8
- package/dist/components/{p-BJbN3vca.js.map → p-BctNMdxr.js.map} +1 -1
- package/dist/components/{p-BAw249L9.js → p-BgRGxOIE.js} +20 -20
- package/dist/components/{p-BAw249L9.js.map → p-BgRGxOIE.js.map} +1 -1
- package/dist/components/{p-D27d2rKT.js → p-Bhtn9qay.js} +5 -5
- package/dist/components/{p-D27d2rKT.js.map → p-Bhtn9qay.js.map} +1 -1
- package/dist/components/{p-CEn1WeG3.js → p-Bit0z7Yg.js} +9 -9
- package/dist/components/{p-CEn1WeG3.js.map → p-Bit0z7Yg.js.map} +1 -1
- package/dist/components/{p-CGb-8cK4.js → p-BlI4vzRZ.js} +5 -5
- package/dist/components/{p-CGb-8cK4.js.map → p-BlI4vzRZ.js.map} +1 -1
- package/dist/components/p-ByRC-aCs.js +18262 -0
- package/dist/components/p-ByRC-aCs.js.map +1 -0
- package/dist/components/{p-fiFoOjv0.js → p-C3_LIgzd.js} +10 -10
- package/dist/components/{p-fiFoOjv0.js.map → p-C3_LIgzd.js.map} +1 -1
- package/dist/components/{p-DPxzgBs0.js → p-CIXPLjCu.js} +4 -4
- package/dist/components/{p-DPxzgBs0.js.map → p-CIXPLjCu.js.map} +1 -1
- package/dist/components/{p-CoFmi-t6.js → p-COGwCbe1.js} +116 -188
- package/dist/components/p-COGwCbe1.js.map +1 -0
- package/dist/components/{p-dcR2uxM3.js → p-CURq0twf.js} +6 -6
- package/dist/components/{p-dcR2uxM3.js.map → p-CURq0twf.js.map} +1 -1
- package/dist/components/{p-C9hrbrUN.js → p-CwkUrTy1.js} +5 -7
- package/dist/{cjs/index-DcTwXs_q.js.map → components/p-CwkUrTy1.js.map} +1 -1
- package/dist/components/{p-ByAzDzS5.js → p-D13ydJjo.js} +5 -5
- package/dist/components/{p-ByAzDzS5.js.map → p-D13ydJjo.js.map} +1 -1
- package/dist/components/{p-BFNwskCY.js → p-Dbp5YJIa.js} +5 -5
- package/dist/components/{p-BFNwskCY.js.map → p-Dbp5YJIa.js.map} +1 -1
- package/dist/components/{p-BEKicPnH.js → p-Dcf7tVJW.js} +5 -5
- package/dist/components/{p-BEKicPnH.js.map → p-Dcf7tVJW.js.map} +1 -1
- package/dist/components/{p-CieOx1XL.js → p-EBtkRix7.js} +8 -8
- package/dist/components/{p-CieOx1XL.js.map → p-EBtkRix7.js.map} +1 -1
- package/dist/components/{p-gCHmJzc2.js → p-NXPGXBZ2.js} +6 -6
- package/dist/components/{p-gCHmJzc2.js.map → p-NXPGXBZ2.js.map} +1 -1
- package/dist/components/{p-YqK8ch2R.js → p-n789Y3S-.js} +4 -5
- package/dist/components/p-n789Y3S-.js.map +1 -0
- package/dist/esm/{index-Bj5QIJYQ.js → default-text-tool.config-CsZAW1Cu.js} +15908 -1092
- package/dist/esm/default-text-tool.config-CsZAW1Cu.js.map +1 -0
- package/dist/esm/{index-Cw77zP6g.js → index-SGde3HXB.js} +9 -11
- package/dist/esm/index-SGde3HXB.js.map +1 -0
- package/dist/esm/index.js +1358 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/kritzel-brush-style.entry.js +1 -1
- package/dist/esm/kritzel-color_22.entry.js +736 -685
- package/dist/esm/loader.js +3 -3
- package/dist/esm/stencil.js +4 -4
- package/dist/esm/stencil.js.map +1 -1
- package/dist/stencil/index.esm.js +1 -1
- package/dist/stencil/index.esm.js.map +1 -1
- package/dist/stencil/p-27adbf9d.entry.js +2 -0
- package/dist/stencil/p-27adbf9d.entry.js.map +1 -0
- package/dist/stencil/p-CsZAW1Cu.js +2 -0
- package/dist/stencil/p-CsZAW1Cu.js.map +1 -0
- package/dist/stencil/{p-Cw77zP6g.js → p-SGde3HXB.js} +2 -2
- package/dist/stencil/p-SGde3HXB.js.map +1 -0
- package/dist/stencil/{p-8b831c94.entry.js → p-d702c5af.entry.js} +2 -2
- package/dist/stencil/stencil.esm.js +1 -1
- package/dist/stencil/stencil.esm.js.map +1 -1
- package/dist/types/classes/core/core.class.d.ts +34 -21
- package/dist/types/classes/core/store.class.d.ts +8 -0
- package/dist/types/classes/objects/base-object.class.d.ts +1 -5
- package/dist/types/classes/objects/path.class.d.ts +1 -0
- package/dist/types/classes/objects/selection-box.class.d.ts +2 -3
- package/dist/types/classes/objects/selection-group.class.d.ts +24 -5
- package/dist/types/classes/objects/text.class.d.ts +0 -3
- package/dist/types/classes/providers/broadcast-sync-provider.class.d.ts +18 -0
- package/dist/types/classes/providers/hocuspocus-sync-provider.class.d.ts +120 -0
- package/dist/types/classes/providers/indexeddb-sync-provider.class.d.ts +22 -0
- package/dist/types/classes/providers/websocket-sync-provider.class.d.ts +52 -0
- package/dist/types/classes/structures/app-state-map.structure.d.ts +30 -0
- package/dist/types/classes/structures/object-map.structure.d.ts +39 -1
- package/dist/types/components/core/kritzel-editor/kritzel-editor.d.ts +3 -0
- package/dist/types/components/core/kritzel-engine/kritzel-engine.d.ts +2 -0
- package/dist/types/components.d.ts +6 -0
- package/dist/types/configs/{default-engine-state.d.ts → default-engine-config.d.ts} +1 -1
- package/dist/types/configs/default-sync.config.d.ts +5 -0
- package/dist/types/constants/core.constants.d.ts +0 -0
- package/dist/types/index.d.ts +8 -1
- package/dist/types/interfaces/debug-info.interface.d.ts +0 -1
- package/dist/types/interfaces/engine-state.interface.d.ts +1 -10
- package/dist/types/interfaces/object.interface.d.ts +1 -1
- package/dist/types/interfaces/selection-state.interface.d.ts +0 -4
- package/dist/types/interfaces/sync-config.interface.d.ts +22 -0
- package/dist/types/interfaces/sync-provider.interface.d.ts +29 -0
- package/dist/types/stencil-public-runtime.d.ts +1 -1
- package/package.json +6 -2
- package/dist/cjs/index-Cg50mv2K.js.map +0 -1
- package/dist/collection/classes/commands/add-object.command.js +0 -18
- package/dist/collection/classes/commands/add-object.command.js.map +0 -1
- package/dist/collection/classes/commands/add-selection-group.command.js +0 -24
- package/dist/collection/classes/commands/add-selection-group.command.js.map +0 -1
- package/dist/collection/classes/commands/base.command.js +0 -19
- package/dist/collection/classes/commands/base.command.js.map +0 -1
- package/dist/collection/classes/commands/batch.command.js +0 -15
- package/dist/collection/classes/commands/batch.command.js.map +0 -1
- package/dist/collection/classes/commands/move-selection-group.command.js +0 -44
- package/dist/collection/classes/commands/move-selection-group.command.js.map +0 -1
- package/dist/collection/classes/commands/remove-object.command.js +0 -18
- package/dist/collection/classes/commands/remove-object.command.js.map +0 -1
- package/dist/collection/classes/commands/remove-selection-group.command.js +0 -19
- package/dist/collection/classes/commands/remove-selection-group.command.js.map +0 -1
- package/dist/collection/classes/commands/resize-selection-group.command.js +0 -29
- package/dist/collection/classes/commands/resize-selection-group.command.js.map +0 -1
- package/dist/collection/classes/commands/rotate-selection-group.command.js +0 -29
- package/dist/collection/classes/commands/rotate-selection-group.command.js.map +0 -1
- package/dist/collection/classes/commands/update-object.command.js +0 -38
- package/dist/collection/classes/commands/update-object.command.js.map +0 -1
- package/dist/collection/classes/commands/update-viewport.command.js +0 -25
- package/dist/collection/classes/commands/update-viewport.command.js.map +0 -1
- package/dist/collection/classes/core/command-manager.class.js +0 -51
- package/dist/collection/classes/core/command-manager.class.js.map +0 -1
- package/dist/collection/classes/core/database.class.js +0 -236
- package/dist/collection/classes/core/database.class.js.map +0 -1
- package/dist/collection/classes/core/history.class.js +0 -51
- package/dist/collection/classes/core/history.class.js.map +0 -1
- package/dist/collection/classes/structures/circular-buffer.structure.js +0 -48
- package/dist/collection/classes/structures/circular-buffer.structure.js.map +0 -1
- package/dist/collection/configs/default-engine-state.js.map +0 -1
- package/dist/collection/interfaces/command.interface.js +0 -2
- package/dist/collection/interfaces/command.interface.js.map +0 -1
- package/dist/components/p-C9hrbrUN.js.map +0 -1
- package/dist/components/p-CoFmi-t6.js.map +0 -1
- package/dist/components/p-EO13AYoE.js +0 -3331
- package/dist/components/p-EO13AYoE.js.map +0 -1
- package/dist/components/p-YqK8ch2R.js.map +0 -1
- package/dist/esm/index-Bj5QIJYQ.js.map +0 -1
- package/dist/esm/index-Cw77zP6g.js.map +0 -1
- package/dist/stencil/p-Bj5QIJYQ.js +0 -2
- package/dist/stencil/p-Bj5QIJYQ.js.map +0 -1
- package/dist/stencil/p-Cw77zP6g.js.map +0 -1
- package/dist/stencil/p-b4185842.entry.js +0 -2
- package/dist/stencil/p-b4185842.entry.js.map +0 -1
- package/dist/types/classes/commands/add-object.command.d.ts +0 -9
- package/dist/types/classes/commands/add-selection-group.command.d.ts +0 -10
- package/dist/types/classes/commands/base.command.d.ts +0 -11
- package/dist/types/classes/commands/batch.command.d.ts +0 -8
- package/dist/types/classes/commands/move-selection-group.command.d.ts +0 -13
- package/dist/types/classes/commands/remove-object.command.d.ts +0 -9
- package/dist/types/classes/commands/remove-selection-group.command.d.ts +0 -8
- package/dist/types/classes/commands/resize-selection-group.command.d.ts +0 -20
- package/dist/types/classes/commands/rotate-selection-group.command.d.ts +0 -10
- package/dist/types/classes/commands/update-object.command.d.ts +0 -11
- package/dist/types/classes/commands/update-viewport.command.d.ts +0 -21
- package/dist/types/classes/core/command-manager.class.d.ts +0 -16
- package/dist/types/classes/core/database.class.d.ts +0 -29
- package/dist/types/classes/core/history.class.d.ts +0 -12
- package/dist/types/classes/structures/circular-buffer.structure.d.ts +0 -13
- package/dist/types/interfaces/command.interface.d.ts +0 -6
- /package/dist/stencil/{p-8b831c94.entry.js.map → p-d702c5af.entry.js.map} +0 -0
|
@@ -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"]}
|
|
@@ -1,29 +1,189 @@
|
|
|
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";
|
|
1
6
|
export class KritzelObjectMap {
|
|
2
7
|
map;
|
|
8
|
+
_ydoc = null;
|
|
9
|
+
_objectsMap = null;
|
|
10
|
+
_providers = [];
|
|
11
|
+
_undoManager = null;
|
|
12
|
+
_reviver = null;
|
|
13
|
+
_core = null;
|
|
14
|
+
_workspaceId = null;
|
|
15
|
+
_isReady = false;
|
|
16
|
+
_temporaryItemsCount = 0;
|
|
17
|
+
get isReady() {
|
|
18
|
+
return this._isReady;
|
|
19
|
+
}
|
|
20
|
+
get undoManager() {
|
|
21
|
+
return this._undoManager;
|
|
22
|
+
}
|
|
23
|
+
get workspaceId() {
|
|
24
|
+
return this._workspaceId;
|
|
25
|
+
}
|
|
3
26
|
constructor() {
|
|
4
27
|
this.map = new Map();
|
|
5
28
|
}
|
|
29
|
+
async initialize(core, workspaceId, config) {
|
|
30
|
+
this._core = core;
|
|
31
|
+
this._workspaceId = workspaceId;
|
|
32
|
+
this._reviver = new KritzelReviver(core);
|
|
33
|
+
// Create a dedicated Y.Doc for this workspace
|
|
34
|
+
this._ydoc = new Y.Doc();
|
|
35
|
+
this._objectsMap = this._ydoc.getMap('objects');
|
|
36
|
+
const docName = `kritzel-workspace-${workspaceId}`;
|
|
37
|
+
const finalConfig = config ?? DEFAULT_SYNC_CONFIG;
|
|
38
|
+
// Instantiate providers from configuration
|
|
39
|
+
for (const providerConfig of finalConfig.providers) {
|
|
40
|
+
let provider;
|
|
41
|
+
// Check if it's a class constructor or a factory
|
|
42
|
+
if (typeof providerConfig === 'function') {
|
|
43
|
+
// It's a class constructor
|
|
44
|
+
provider = new providerConfig(docName, this._ydoc);
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
// It's a factory with a create method
|
|
48
|
+
provider = providerConfig.create(docName, this._ydoc);
|
|
49
|
+
}
|
|
50
|
+
this._providers.push(provider);
|
|
51
|
+
}
|
|
52
|
+
// Set up undo/redo manager for this workspace
|
|
53
|
+
this._undoManager = new Y.UndoManager([this._objectsMap], {
|
|
54
|
+
captureTimeout: 200,
|
|
55
|
+
trackedOrigins: new Set(['local', 'temporary']),
|
|
56
|
+
ignoreRemoteMapChanges: true,
|
|
57
|
+
});
|
|
58
|
+
this._undoManager.on('stack-item-added', event => {
|
|
59
|
+
if (event.type === 'undo') {
|
|
60
|
+
// Track if this was a temporary item
|
|
61
|
+
if (event.origin === 'temporary') {
|
|
62
|
+
this._temporaryItemsCount++;
|
|
63
|
+
}
|
|
64
|
+
console.log('Undo performed for workspace', workspaceId, this._undoManager.undoStack.length, this._undoManager.redoStack.length);
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
this._undoManager.on('stack-item-popped', event => {
|
|
68
|
+
if (event.type === 'undo') {
|
|
69
|
+
// Reduce temporary count when items are undone
|
|
70
|
+
if (event.origin === 'temporary' && this._temporaryItemsCount > 0) {
|
|
71
|
+
this._temporaryItemsCount--;
|
|
72
|
+
}
|
|
73
|
+
console.log('Redo performed for workspace', workspaceId, this._undoManager.undoStack.length, this._undoManager.redoStack.length);
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
// Observe changes to objects and sync with application state
|
|
77
|
+
this._objectsMap.observe(event => {
|
|
78
|
+
this.handleObjectsChange(event);
|
|
79
|
+
});
|
|
80
|
+
// Connect all providers in parallel
|
|
81
|
+
await Promise.all(this._providers.map(p => p.connect()));
|
|
82
|
+
this._isReady = true;
|
|
83
|
+
// Load objects from Yjs
|
|
84
|
+
this.loadFromYjs();
|
|
85
|
+
}
|
|
86
|
+
handleObjectsChange(event) {
|
|
87
|
+
// Skip Map updates for local changes (already done), but still trigger re-render
|
|
88
|
+
// 'temporary' is also a local change that shouldn't be re-deserialized
|
|
89
|
+
if (event.transaction.origin === 'local' || event.transaction.origin === 'temporary') {
|
|
90
|
+
this._core?.rerender();
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
const changedKeys = Array.from(event.keysChanged);
|
|
94
|
+
const objectsToUpdate = [];
|
|
95
|
+
const selectionGroupsToUpdate = [];
|
|
96
|
+
const objectsToDelete = [];
|
|
97
|
+
changedKeys.forEach(key => {
|
|
98
|
+
const change = event.changes.keys.get(key);
|
|
99
|
+
if (change && change.action === 'delete') {
|
|
100
|
+
objectsToDelete.push(key);
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
const serialized = this._objectsMap.get(key);
|
|
104
|
+
if (serialized) {
|
|
105
|
+
const object = this._reviver.revive(serialized);
|
|
106
|
+
// Separate SelectionGroups to process them after regular objects
|
|
107
|
+
if (object instanceof KritzelSelectionGroup) {
|
|
108
|
+
selectionGroupsToUpdate.push(object);
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
objectsToUpdate.push(object);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
// Delete objects from local map
|
|
117
|
+
objectsToDelete.forEach(objectId => {
|
|
118
|
+
this.map.delete(objectId);
|
|
119
|
+
});
|
|
120
|
+
// First, update or insert regular objects
|
|
121
|
+
objectsToUpdate.forEach(object => {
|
|
122
|
+
this.map.set(object.id, object);
|
|
123
|
+
});
|
|
124
|
+
// Then, update or insert SelectionGroups
|
|
125
|
+
selectionGroupsToUpdate.forEach(object => {
|
|
126
|
+
this.map.set(object.id, object);
|
|
127
|
+
});
|
|
128
|
+
this._core?.rerender();
|
|
129
|
+
}
|
|
130
|
+
transaction(callback) {
|
|
131
|
+
if (this._ydoc) {
|
|
132
|
+
this._ydoc.transact(callback, 'local');
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
loadFromYjs() {
|
|
136
|
+
if (!this._objectsMap || !this._reviver) {
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
this.map.clear();
|
|
140
|
+
this._objectsMap.forEach((serialized, key) => {
|
|
141
|
+
const object = this._reviver.revive(serialized);
|
|
142
|
+
this.map.set(key, object);
|
|
143
|
+
});
|
|
144
|
+
}
|
|
6
145
|
reset() {
|
|
7
146
|
this.map.clear();
|
|
147
|
+
this._ydoc.transact(() => {
|
|
148
|
+
this._objectsMap.clear();
|
|
149
|
+
}, 'local');
|
|
8
150
|
}
|
|
9
151
|
insert(object) {
|
|
10
152
|
if (!object.id) {
|
|
11
153
|
return false;
|
|
12
154
|
}
|
|
13
155
|
this.map.set(object.id, object);
|
|
156
|
+
if (this._objectsMap && this.isPersistable(object)) {
|
|
157
|
+
const serialized = object.serialize();
|
|
158
|
+
this._ydoc.transact(() => {
|
|
159
|
+
this._objectsMap.set(object.id, serialized);
|
|
160
|
+
}, 'local');
|
|
161
|
+
}
|
|
14
162
|
return true;
|
|
15
163
|
}
|
|
16
|
-
update(object) {
|
|
164
|
+
update(object, options = {}) {
|
|
17
165
|
if (!object.id || !this.map.has(object.id)) {
|
|
18
166
|
return false;
|
|
19
167
|
}
|
|
20
168
|
this.map.set(object.id, object);
|
|
169
|
+
if (this._objectsMap && this.isPersistable(object)) {
|
|
170
|
+
const serialized = object.serialize();
|
|
171
|
+
const origin = options.temporary ? 'temporary' : 'local';
|
|
172
|
+
this._ydoc.transact(() => {
|
|
173
|
+
this._objectsMap.set(object.id, serialized);
|
|
174
|
+
}, origin);
|
|
175
|
+
}
|
|
21
176
|
return true;
|
|
22
177
|
}
|
|
23
178
|
remove(predicate) {
|
|
24
179
|
for (const [id, object] of this.map) {
|
|
25
180
|
if (predicate(object)) {
|
|
26
181
|
this.map.delete(id);
|
|
182
|
+
if (this._objectsMap && this.isPersistable(object)) {
|
|
183
|
+
this._ydoc.transact(() => {
|
|
184
|
+
this._objectsMap.delete(id);
|
|
185
|
+
}, 'local');
|
|
186
|
+
}
|
|
27
187
|
}
|
|
28
188
|
}
|
|
29
189
|
}
|
|
@@ -39,5 +199,104 @@ export class KritzelObjectMap {
|
|
|
39
199
|
allObjects() {
|
|
40
200
|
return Array.from(this.map.values());
|
|
41
201
|
}
|
|
202
|
+
isPersistable(object) {
|
|
203
|
+
if (object instanceof KritzelSelectionBox) {
|
|
204
|
+
return false;
|
|
205
|
+
}
|
|
206
|
+
return true;
|
|
207
|
+
}
|
|
208
|
+
undo() {
|
|
209
|
+
if (this._undoManager && this._undoManager.canUndo()) {
|
|
210
|
+
this._undoManager.undo();
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
redo() {
|
|
214
|
+
if (this._undoManager && this._undoManager.canRedo()) {
|
|
215
|
+
this._undoManager.redo();
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
canUndo() {
|
|
219
|
+
return this._undoManager ? this._undoManager.canUndo() : false;
|
|
220
|
+
}
|
|
221
|
+
canRedo() {
|
|
222
|
+
return this._undoManager ? this._undoManager.canRedo() : false;
|
|
223
|
+
}
|
|
224
|
+
clearHistory() {
|
|
225
|
+
if (this._undoManager) {
|
|
226
|
+
this._undoManager.clear();
|
|
227
|
+
this._temporaryItemsCount = 0;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Consolidates all temporary items in the undo stack into a single undo item.
|
|
232
|
+
* Call this when you want to merge multiple temporary changes (e.g., keystrokes) into one.
|
|
233
|
+
*/
|
|
234
|
+
consolidateTemporaryItems() {
|
|
235
|
+
if (!this._undoManager || this._temporaryItemsCount === 0) {
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
// Get current stack length
|
|
239
|
+
const stackLength = this._undoManager.undoStack.length;
|
|
240
|
+
if (stackLength === 0) {
|
|
241
|
+
this._temporaryItemsCount = 0;
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
// Stop tracking temporarily
|
|
245
|
+
this._undoManager.stopCapturing();
|
|
246
|
+
// The temporary items should be at the end of the stack
|
|
247
|
+
// We'll need to undo them all, then redo as a single transaction
|
|
248
|
+
const itemsToConsolidate = Math.min(this._temporaryItemsCount, stackLength);
|
|
249
|
+
if (itemsToConsolidate > 1) {
|
|
250
|
+
// Store the current state before undoing
|
|
251
|
+
const undoneItems = [];
|
|
252
|
+
// Undo all temporary items
|
|
253
|
+
for (let i = 0; i < itemsToConsolidate; i++) {
|
|
254
|
+
if (this._undoManager.canUndo()) {
|
|
255
|
+
undoneItems.push(this._undoManager.undoStack[this._undoManager.undoStack.length - 1]);
|
|
256
|
+
this._undoManager.undo();
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
// Now redo them all as a single 'local' transaction
|
|
260
|
+
// This will consolidate them into one undo item
|
|
261
|
+
this._ydoc.transact(() => {
|
|
262
|
+
for (let i = itemsToConsolidate - 1; i >= 0; i--) {
|
|
263
|
+
if (this._undoManager.canRedo()) {
|
|
264
|
+
this._undoManager.redo();
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
}, 'local');
|
|
268
|
+
}
|
|
269
|
+
else if (itemsToConsolidate === 1) {
|
|
270
|
+
// If only one temporary item, just change its origin to 'local'
|
|
271
|
+
// This is implicit - next transaction will be separate
|
|
272
|
+
}
|
|
273
|
+
this._temporaryItemsCount = 0;
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Removes all temporary items from the undo stack without consolidating them.
|
|
277
|
+
* Use this to discard temporary changes completely.
|
|
278
|
+
*/
|
|
279
|
+
clearTemporaryItems() {
|
|
280
|
+
if (!this._undoManager || this._temporaryItemsCount === 0) {
|
|
281
|
+
return;
|
|
282
|
+
}
|
|
283
|
+
const stackLength = this._undoManager.undoStack.length;
|
|
284
|
+
const itemsToRemove = Math.min(this._temporaryItemsCount, stackLength);
|
|
285
|
+
// Remove items from the end of the stack
|
|
286
|
+
for (let i = 0; i < itemsToRemove; i++) {
|
|
287
|
+
if (this._undoManager.undoStack.length > 0) {
|
|
288
|
+
this._undoManager.undoStack.pop();
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
this._temporaryItemsCount = 0;
|
|
292
|
+
}
|
|
293
|
+
destroy() {
|
|
294
|
+
this._providers.forEach(p => p.destroy());
|
|
295
|
+
this._providers = [];
|
|
296
|
+
if (this._ydoc) {
|
|
297
|
+
this._ydoc.destroy();
|
|
298
|
+
}
|
|
299
|
+
this.map.clear();
|
|
300
|
+
}
|
|
42
301
|
}
|
|
43
302
|
//# sourceMappingURL=object-map.structure.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"object-map.structure.js","sourceRoot":"","sources":["../../../src/classes/structures/object-map.structure.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,gBAAgB;IACnB,GAAG,CAAiB;IAE5B;QACE,IAAI,CAAC,GAAG,GAAG,IAAI,GAAG,EAAa,CAAC;IAClC,CAAC;IAED,KAAK;QACH,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC;IACnB,CAAC;IAED,MAAM,CAAC,MAAS;QACd,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;YACf,OAAO,KAAK,CAAC;QACf,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;QAChC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,CAAC,MAAS;QACd,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC;YAC3C,OAAO,KAAK,CAAC;QACf,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;QAChC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,CAAC,SAAiC;QACtC,KAAK,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;YACpC,IAAI,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;gBACtB,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YACtB,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,CAAC,SAAiC;QACtC,MAAM,OAAO,GAAQ,EAAE,CAAC;QACxB,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,EAAE,CAAC;YACvC,IAAI,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;gBACtB,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACvB,CAAC;QACH,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,UAAU;QACR,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;IACvC,CAAC;CACF","sourcesContent":["import { KritzelBaseObject } from '../objects/base-object.class';\r\n\r\nexport class KritzelObjectMap<T extends KritzelBaseObject<any>> {\r\n private map: Map<string, T>;\r\n\r\n constructor() {\r\n this.map = new Map<string, T>();\r\n }\r\n\r\n reset(): void {\r\n this.map.clear();\r\n }\r\n\r\n insert(object: T): boolean {\r\n if (!object.id) {\r\n return false;\r\n }\r\n this.map.set(object.id, object);\r\n return true;\r\n }\r\n\r\n update(object: T): boolean {\r\n if (!object.id || !this.map.has(object.id)) {\r\n return false;\r\n }\r\n this.map.set(object.id, object);\r\n return true;\r\n }\r\n\r\n remove(predicate: (object: T) => boolean): void {\r\n for (const [id, object] of this.map) {\r\n if (predicate(object)) {\r\n this.map.delete(id);\r\n }\r\n }\r\n }\r\n\r\n filter(predicate: (object: T) => boolean): T[] {\r\n const results: T[] = [];\r\n for (const object of this.map.values()) {\r\n if (predicate(object)) {\r\n results.push(object);\r\n }\r\n }\r\n return results;\r\n }\r\n\r\n allObjects(): T[] {\r\n return Array.from(this.map.values());\r\n }\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"object-map.structure.js","sourceRoot":"","sources":["../../../src/classes/structures/object-map.structure.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AACzB,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAEvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,EAAE,qBAAqB,EAAE,MAAM,kCAAkC,CAAC;AAIzE,OAAO,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AAExE,MAAM,OAAO,gBAAgB;IACnB,GAAG,CAAiB;IACpB,KAAK,GAAiB,IAAI,CAAC;IAC3B,WAAW,GAAsB,IAAI,CAAC;IACtC,UAAU,GAAoB,EAAE,CAAC;IACjC,YAAY,GAAyB,IAAI,CAAC;IAC1C,QAAQ,GAA0B,IAAI,CAAC;IACvC,KAAK,GAAuB,IAAI,CAAC;IACjC,YAAY,GAAkB,IAAI,CAAC;IACnC,QAAQ,GAAY,KAAK,CAAC;IAC1B,oBAAoB,GAAW,CAAC,CAAC;IAEzC,IAAI,OAAO;QACT,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;IAED,IAAI,WAAW;QACb,OAAO,IAAI,CAAC,YAAY,CAAC;IAC3B,CAAC;IAED,IAAI,WAAW;QACb,OAAO,IAAI,CAAC,YAAY,CAAC;IAC3B,CAAC;IAED;QACE,IAAI,CAAC,GAAG,GAAG,IAAI,GAAG,EAAa,CAAC;IAClC,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,IAAiB,EAAE,WAAmB,EAAE,MAA0B;QACjF,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QAClB,IAAI,CAAC,YAAY,GAAG,WAAW,CAAC;QAChC,IAAI,CAAC,QAAQ,GAAG,IAAI,cAAc,CAAC,IAAI,CAAC,CAAC;QAEzC,8CAA8C;QAC9C,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,GAAG,EAAE,CAAC;QACzB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAEhD,MAAM,OAAO,GAAG,qBAAqB,WAAW,EAAE,CAAC;QACnD,MAAM,WAAW,GAAG,MAAM,IAAI,mBAAmB,CAAC;QAElD,2CAA2C;QAC3C,KAAK,MAAM,cAAc,IAAI,WAAW,CAAC,SAAS,EAAE,CAAC;YACnD,IAAI,QAAuB,CAAC;YAE5B,iDAAiD;YACjD,IAAI,OAAO,cAAc,KAAK,UAAU,EAAE,CAAC;gBACzC,2BAA2B;gBAC3B,QAAQ,GAAG,IAAI,cAAc,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;YACrD,CAAC;iBAAM,CAAC;gBACN,sCAAsC;gBACtC,QAAQ,GAAG,cAAc,CAAC,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;YACxD,CAAC;YAED,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACjC,CAAC;QAED,8CAA8C;QAC9C,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE;YACxD,cAAc,EAAE,GAAG;YACnB,cAAc,EAAE,IAAI,GAAG,CAAC,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;YAC/C,sBAAsB,EAAE,IAAI;SAC7B,CAAC,CAAC;QAEH,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC,kBAAkB,EAAE,KAAK,CAAC,EAAE;YAC/C,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;gBAC1B,qCAAqC;gBACrC,IAAI,KAAK,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;oBACjC,IAAI,CAAC,oBAAoB,EAAE,CAAC;gBAC9B,CAAC;gBACD,OAAO,CAAC,GAAG,CAAC,8BAA8B,EAAE,WAAW,EAAE,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;YACnI,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC,mBAAmB,EAAE,KAAK,CAAC,EAAE;YAChD,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;gBAC1B,+CAA+C;gBAC/C,IAAI,KAAK,CAAC,MAAM,KAAK,WAAW,IAAI,IAAI,CAAC,oBAAoB,GAAG,CAAC,EAAE,CAAC;oBAClE,IAAI,CAAC,oBAAoB,EAAE,CAAC;gBAC9B,CAAC;gBACD,OAAO,CAAC,GAAG,CAAC,8BAA8B,EAAE,WAAW,EAAE,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;YACnI,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,6DAA6D;QAC7D,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;YAC/B,IAAI,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC;QAClC,CAAC,CAAC,CAAC;QAEH,oCAAoC;QACpC,MAAM,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QACzD,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QAErB,wBAAwB;QACxB,IAAI,CAAC,WAAW,EAAE,CAAC;IACrB,CAAC;IAEO,mBAAmB,CAAC,KAAuB;QACjD,iFAAiF;QACjF,uEAAuE;QACvE,IAAI,KAAK,CAAC,WAAW,CAAC,MAAM,KAAK,OAAO,IAAI,KAAK,CAAC,WAAW,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;YACrF,IAAI,CAAC,KAAK,EAAE,QAAQ,EAAE,CAAC;YACvB,OAAO;QACT,CAAC;QAED,MAAM,WAAW,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QAClD,MAAM,eAAe,GAAG,EAAE,CAAC;QAC3B,MAAM,uBAAuB,GAAG,EAAE,CAAC;QACnC,MAAM,eAAe,GAAG,EAAE,CAAC;QAE3B,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;YACxB,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YAE3C,IAAI,MAAM,IAAI,MAAM,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;gBACzC,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAC5B,CAAC;iBAAM,CAAC;gBACN,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;gBAC7C,IAAI,UAAU,EAAE,CAAC;oBACf,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;oBAEhD,iEAAiE;oBACjE,IAAI,MAAM,YAAY,qBAAqB,EAAE,CAAC;wBAC5C,uBAAuB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;oBACvC,CAAC;yBAAM,CAAC;wBACN,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;oBAC/B,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,gCAAgC;QAChC,eAAe,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE;YACjC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC5B,CAAC,CAAC,CAAC;QAEH,0CAA0C;QAC1C,eAAe,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;YAC/B,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;QAClC,CAAC,CAAC,CAAC;QAEH,yCAAyC;QACzC,uBAAuB,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;YACvC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;QAClC,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,KAAK,EAAE,QAAQ,EAAE,CAAC;IACzB,CAAC;IACD,WAAW,CAAC,QAAoB;QAC9B,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACzC,CAAC;IACH,CAAC;IAED,WAAW;QACT,IAAI,CAAC,IAAI,CAAC,WAAW,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACxC,OAAO;QACT,CAAC;QAED,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC;QACjB,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,UAAU,EAAE,GAAG,EAAE,EAAE;YAC3C,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAI,UAAU,CAAC,CAAC;YACnD,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QAC5B,CAAC,CAAC,CAAC;IACL,CAAC;IAED,KAAK;QACH,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC;QACjB,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,EAAE;YACvB,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC;QAC3B,CAAC,EAAE,OAAO,CAAC,CAAC;IACd,CAAC;IAED,MAAM,CAAC,MAAS;QACd,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;YACf,OAAO,KAAK,CAAC;QACf,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;QAEhC,IAAI,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC;YACnD,MAAM,UAAU,GAAG,MAAM,CAAC,SAAS,EAAE,CAAC;YACtC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,EAAE;gBACvB,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC;YAC9C,CAAC,EAAE,OAAO,CAAC,CAAC;QACd,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,CAAC,MAAS,EAAE,UAAmC,EAAE;QACrD,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC;YAC3C,OAAO,KAAK,CAAC;QACf,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;QAEhC,IAAI,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC;YACnD,MAAM,UAAU,GAAG,MAAM,CAAC,SAAS,EAAE,CAAC;YAEtC,MAAM,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC;YAEzD,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,EAAE;gBACvB,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC;YAC9C,CAAC,EAAE,MAAM,CAAC,CAAC;QACb,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,CAAC,SAAiC;QACtC,KAAK,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;YACpC,IAAI,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;gBACtB,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;gBAEpB,IAAI,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC;oBACnD,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,EAAE;wBACvB,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;oBAC9B,CAAC,EAAE,OAAO,CAAC,CAAC;gBACd,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,CAAC,SAAiC;QACtC,MAAM,OAAO,GAAQ,EAAE,CAAC;QACxB,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,EAAE,CAAC;YACvC,IAAI,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;gBACtB,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACvB,CAAC;QACH,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,UAAU;QACR,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;IACvC,CAAC;IAEO,aAAa,CAAC,MAAS;QAC7B,IAAI,MAAM,YAAY,mBAAmB,EAAE,CAAC;YAC1C,OAAO,KAAK,CAAC;QACf,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI;QACF,IAAI,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,EAAE,CAAC;YACrD,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC;QAC3B,CAAC;IACH,CAAC;IAED,IAAI;QACF,IAAI,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,EAAE,CAAC;YACrD,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC;QAC3B,CAAC;IACH,CAAC;IAED,OAAO;QACL,OAAO,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;IACjE,CAAC;IAED,OAAO;QACL,OAAO,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;IACjE,CAAC;IAED,YAAY;QACV,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACtB,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,CAAC;YAC1B,IAAI,CAAC,oBAAoB,GAAG,CAAC,CAAC;QAChC,CAAC;IACH,CAAC;IAED;;;OAGG;IACH,yBAAyB;QACvB,IAAI,CAAC,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,oBAAoB,KAAK,CAAC,EAAE,CAAC;YAC1D,OAAO;QACT,CAAC;QAED,2BAA2B;QAC3B,MAAM,WAAW,GAAG,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,MAAM,CAAC;QAEvD,IAAI,WAAW,KAAK,CAAC,EAAE,CAAC;YACtB,IAAI,CAAC,oBAAoB,GAAG,CAAC,CAAC;YAC9B,OAAO;QACT,CAAC;QAED,4BAA4B;QAC5B,IAAI,CAAC,YAAY,CAAC,aAAa,EAAE,CAAC;QAElC,wDAAwD;QACxD,iEAAiE;QACjE,MAAM,kBAAkB,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,oBAAoB,EAAE,WAAW,CAAC,CAAC;QAE5E,IAAI,kBAAkB,GAAG,CAAC,EAAE,CAAC;YAC3B,yCAAyC;YACzC,MAAM,WAAW,GAAU,EAAE,CAAC;YAE9B,2BAA2B;YAC3B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,kBAAkB,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC5C,IAAI,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,EAAE,CAAC;oBAChC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;oBACtF,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC;gBAC3B,CAAC;YACH,CAAC;YAED,oDAAoD;YACpD,gDAAgD;YAChD,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,EAAE;gBACvB,KAAK,IAAI,CAAC,GAAG,kBAAkB,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;oBACjD,IAAI,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,EAAE,CAAC;wBAChC,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC;oBAC3B,CAAC;gBACH,CAAC;YACH,CAAC,EAAE,OAAO,CAAC,CAAC;QACd,CAAC;aAAM,IAAI,kBAAkB,KAAK,CAAC,EAAE,CAAC;YACpC,gEAAgE;YAChE,uDAAuD;QACzD,CAAC;QAED,IAAI,CAAC,oBAAoB,GAAG,CAAC,CAAC;IAChC,CAAC;IAED;;;OAGG;IACH,mBAAmB;QACjB,IAAI,CAAC,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,oBAAoB,KAAK,CAAC,EAAE,CAAC;YAC1D,OAAO;QACT,CAAC;QAED,MAAM,WAAW,GAAG,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,MAAM,CAAC;QACvD,MAAM,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,oBAAoB,EAAE,WAAW,CAAC,CAAC;QAEvE,yCAAyC;QACzC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,aAAa,EAAE,CAAC,EAAE,EAAE,CAAC;YACvC,IAAI,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC3C,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC;YACpC,CAAC;QACH,CAAC;QAED,IAAI,CAAC,oBAAoB,GAAG,CAAC,CAAC;IAChC,CAAC;IAED,OAAO;QACL,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;QAC1C,IAAI,CAAC,UAAU,GAAG,EAAE,CAAC;QAErB,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;QACvB,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC;IACnB,CAAC;CACF","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\n\r\nexport class KritzelObjectMap<T extends KritzelBaseObject<any>> {\r\n private map: Map<string, 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 constructor() {\r\n this.map = new Map<string, T>();\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 console.log('Undo performed for workspace', workspaceId, this._undoManager.undoStack.length, this._undoManager.redoStack.length);\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 console.log('Redo performed for workspace', workspaceId, this._undoManager.undoStack.length, this._undoManager.redoStack.length);\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.map.delete(objectId);\r\n });\r\n\r\n // First, update or insert regular objects\r\n objectsToUpdate.forEach(object => {\r\n this.map.set(object.id, object);\r\n });\r\n\r\n // Then, update or insert SelectionGroups\r\n selectionGroupsToUpdate.forEach(object => {\r\n this.map.set(object.id, object);\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.map.clear();\r\n this._objectsMap.forEach((serialized, key) => {\r\n const object = this._reviver.revive<T>(serialized);\r\n this.map.set(key, object);\r\n });\r\n }\r\n\r\n reset(): void {\r\n this.map.clear();\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.map.set(object.id, 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 || !this.map.has(object.id)) {\r\n return false;\r\n }\r\n this.map.set(object.id, 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 for (const [id, object] of this.map) {\r\n if (predicate(object)) {\r\n this.map.delete(id);\r\n\r\n if (this._objectsMap && this.isPersistable(object)) {\r\n this._ydoc.transact(() => {\r\n this._objectsMap.delete(id);\r\n }, 'local');\r\n }\r\n }\r\n }\r\n }\r\n\r\n filter(predicate: (object: T) => boolean): T[] {\r\n const results: T[] = [];\r\n for (const object of this.map.values()) {\r\n if (predicate(object)) {\r\n results.push(object);\r\n }\r\n }\r\n return results;\r\n }\r\n\r\n allObjects(): T[] {\r\n return Array.from(this.map.values());\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 }\r\n }\r\n\r\n redo(): void {\r\n if (this._undoManager && this._undoManager.canRedo()) {\r\n this._undoManager.redo();\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 this.map.clear();\r\n }\r\n}\r\n"]}
|