kritzel-react 0.1.30 → 0.1.32

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.
Files changed (209) hide show
  1. package/dist/kritzel-react/lib/components/stencil-generated/components.js +122 -0
  2. package/dist/kritzel-react/lib/index.js +2 -0
  3. package/dist/kritzel-stencil/src/classes/core/core.class.js +797 -0
  4. package/dist/kritzel-stencil/src/classes/core/reviver.class.js +97 -0
  5. package/dist/kritzel-stencil/src/classes/core/store.class.js +153 -0
  6. package/dist/kritzel-stencil/src/classes/core/viewport.class.js +311 -0
  7. package/dist/kritzel-stencil/src/classes/core/workspace.class.js +34 -0
  8. package/dist/kritzel-stencil/src/classes/handlers/base.handler.js +6 -0
  9. package/dist/kritzel-stencil/src/classes/handlers/context-menu.handler.js +63 -0
  10. package/dist/kritzel-stencil/src/classes/handlers/hover.handler.js +18 -0
  11. package/dist/kritzel-stencil/src/classes/handlers/key.handler.js +76 -0
  12. package/dist/kritzel-stencil/src/classes/handlers/line-handle.handler.js +382 -0
  13. package/dist/kritzel-stencil/src/classes/handlers/move.handler.js +213 -0
  14. package/dist/kritzel-stencil/src/classes/handlers/resize.handler.js +205 -0
  15. package/dist/kritzel-stencil/src/classes/handlers/rotation.handler.js +117 -0
  16. package/dist/kritzel-stencil/src/classes/handlers/selection.handler.js +313 -0
  17. package/dist/kritzel-stencil/src/classes/managers/anchor.manager.js +1056 -0
  18. package/dist/kritzel-stencil/src/classes/managers/cursor.manager.js +117 -0
  19. package/dist/kritzel-stencil/src/classes/managers/theme.manager.js +103 -0
  20. package/dist/kritzel-stencil/src/classes/objects/base-object.class.js +249 -0
  21. package/dist/kritzel-stencil/src/classes/objects/custom-element.class.js +60 -0
  22. package/dist/kritzel-stencil/src/classes/objects/group.class.js +407 -0
  23. package/dist/kritzel-stencil/src/classes/objects/image.class.js +55 -0
  24. package/dist/kritzel-stencil/src/classes/objects/line.class.js +608 -0
  25. package/dist/kritzel-stencil/src/classes/objects/path.class.js +401 -0
  26. package/dist/kritzel-stencil/src/classes/objects/selection-box.class.js +21 -0
  27. package/dist/kritzel-stencil/src/classes/objects/selection-group.class.js +409 -0
  28. package/dist/kritzel-stencil/src/classes/objects/shape.class.js +412 -0
  29. package/dist/kritzel-stencil/src/classes/objects/text.class.js +292 -0
  30. package/dist/kritzel-stencil/src/classes/providers/broadcast-sync-provider.class.js +101 -0
  31. package/dist/kritzel-stencil/src/classes/providers/hocuspocus-sync-provider.class.js +241 -0
  32. package/dist/kritzel-stencil/src/classes/providers/indexeddb-sync-provider.class.js +43 -0
  33. package/dist/kritzel-stencil/src/classes/providers/websocket-sync-provider.class.js +98 -0
  34. package/dist/kritzel-stencil/src/classes/registries/icon-registry.class.js +66 -0
  35. package/dist/kritzel-stencil/src/classes/registries/tool.registry.js +21 -0
  36. package/dist/kritzel-stencil/src/classes/structures/app-state-map.structure.js +212 -0
  37. package/dist/kritzel-stencil/src/classes/structures/object-map.structure.js +414 -0
  38. package/dist/kritzel-stencil/src/classes/structures/quadtree.structure.js +151 -0
  39. package/dist/kritzel-stencil/src/classes/tools/base-tool.class.js +36 -0
  40. package/dist/kritzel-stencil/src/classes/tools/brush-tool.class.js +161 -0
  41. package/dist/kritzel-stencil/src/classes/tools/eraser-tool.class.js +85 -0
  42. package/dist/kritzel-stencil/src/classes/tools/image-tool.class.js +83 -0
  43. package/dist/kritzel-stencil/src/classes/tools/line-tool.class.js +187 -0
  44. package/dist/kritzel-stencil/src/classes/tools/selection-tool.class.js +429 -0
  45. package/dist/kritzel-stencil/src/classes/tools/shape-tool.class.js +196 -0
  46. package/dist/kritzel-stencil/src/classes/tools/text-tool.class.js +100 -0
  47. package/dist/kritzel-stencil/src/components/core/kritzel-engine/kritzel-engine.js +1343 -0
  48. package/dist/kritzel-stencil/src/components/shared/kritzel-brush-style/kritzel-brush-style.js +46 -0
  49. package/dist/kritzel-stencil/src/components/shared/kritzel-dropdown/kritzel-dropdown.js +312 -0
  50. package/dist/kritzel-stencil/src/components/shared/kritzel-font-family/kritzel-font-family.js +60 -0
  51. package/dist/kritzel-stencil/src/components/shared/kritzel-line-endings/kritzel-line-endings.js +105 -0
  52. package/dist/kritzel-stencil/src/components/shared/kritzel-shape-fill/kritzel-shape-fill.js +53 -0
  53. package/dist/kritzel-stencil/src/components/ui/kritzel-context-menu/kritzel-context-menu.js +137 -0
  54. package/dist/kritzel-stencil/src/configs/default-brush-tool.config.js +9 -0
  55. package/dist/kritzel-stencil/src/configs/default-engine-config.js +63 -0
  56. package/dist/kritzel-stencil/src/configs/default-line-tool.config.js +9 -0
  57. package/dist/kritzel-stencil/src/configs/default-sync.config.js +9 -0
  58. package/dist/kritzel-stencil/src/configs/default-text-tool.config.js +7 -0
  59. package/dist/kritzel-stencil/src/constants/color-palette.constants.js +37 -0
  60. package/dist/kritzel-stencil/src/constants/engine.constants.js +2 -0
  61. package/dist/kritzel-stencil/src/enums/event-button.enum.js +6 -0
  62. package/dist/kritzel-stencil/src/enums/handle-type.enum.js +7 -0
  63. package/dist/kritzel-stencil/src/enums/shape-type.enum.js +6 -0
  64. package/dist/kritzel-stencil/src/helpers/class.helper.js +5 -0
  65. package/dist/kritzel-stencil/src/helpers/color.helper.js +106 -0
  66. package/dist/kritzel-stencil/src/helpers/cursor.helper.js +57 -0
  67. package/dist/kritzel-stencil/src/helpers/devices.helper.js +28 -0
  68. package/dist/kritzel-stencil/src/helpers/event.helper.js +58 -0
  69. package/dist/kritzel-stencil/src/helpers/geometry.helper.js +149 -0
  70. package/dist/kritzel-stencil/src/helpers/keyboard.helper.js +51 -0
  71. package/dist/kritzel-stencil/src/helpers/math.helper.js +5 -0
  72. package/dist/kritzel-stencil/src/helpers/object.helper.js +11 -0
  73. package/dist/kritzel-stencil/src/helpers/theme.helper.js +69 -0
  74. package/dist/kritzel-stencil/src/index.js +41 -0
  75. package/dist/kritzel-stencil/src/interfaces/anchor.interface.js +1 -0
  76. package/dist/kritzel-stencil/src/interfaces/arrow-head.interface.js +1 -0
  77. package/dist/kritzel-stencil/src/interfaces/bounding-box.interface.js +1 -0
  78. package/dist/kritzel-stencil/src/interfaces/clonable.interface.js +1 -0
  79. package/dist/kritzel-stencil/src/interfaces/context-menu-item.interface.js +1 -0
  80. package/dist/kritzel-stencil/src/interfaces/debug-info.interface.js +1 -0
  81. package/dist/kritzel-stencil/src/interfaces/dialog.interface.js +1 -0
  82. package/dist/kritzel-stencil/src/interfaces/displayable-shortcut.interface.js +1 -0
  83. package/dist/kritzel-stencil/src/interfaces/engine-state.interface.js +1 -0
  84. package/dist/kritzel-stencil/src/interfaces/line-options.interface.js +1 -0
  85. package/dist/kritzel-stencil/src/interfaces/master-detail.interface.js +1 -0
  86. package/dist/kritzel-stencil/src/interfaces/menu-item.interface.js +1 -0
  87. package/dist/kritzel-stencil/src/interfaces/object.interface.js +1 -0
  88. package/dist/kritzel-stencil/src/interfaces/path-options.interface.js +1 -0
  89. package/dist/kritzel-stencil/src/interfaces/point.interface.js +1 -0
  90. package/dist/kritzel-stencil/src/interfaces/polygon.interface.js +1 -0
  91. package/dist/kritzel-stencil/src/interfaces/serializable.interface.js +1 -0
  92. package/dist/kritzel-stencil/src/interfaces/settings.interface.js +1 -0
  93. package/dist/kritzel-stencil/src/interfaces/shortcut.interface.js +1 -0
  94. package/dist/kritzel-stencil/src/interfaces/sync-config.interface.js +1 -0
  95. package/dist/kritzel-stencil/src/interfaces/sync-provider.interface.js +1 -0
  96. package/dist/kritzel-stencil/src/interfaces/theme.interface.js +1 -0
  97. package/dist/kritzel-stencil/src/interfaces/tool-config.interface.js +1 -0
  98. package/dist/kritzel-stencil/src/interfaces/tool.interface.js +1 -0
  99. package/dist/kritzel-stencil/src/interfaces/toolbar-control.interface.js +1 -0
  100. package/dist/kritzel-stencil/src/interfaces/undo-state.interface.js +1 -0
  101. package/dist/kritzel-stencil/src/themes/dark-theme.js +198 -0
  102. package/dist/kritzel-stencil/src/themes/light-theme.js +199 -0
  103. package/dist/kritzel-stencil/src/types/shortcut.type.js +1 -0
  104. package/dist/kritzel-stencil/src/types/state.types.js +1 -0
  105. package/dist/types/kritzel-react/lib/components/stencil-generated/components.d.ts +74 -0
  106. package/dist/types/kritzel-react/lib/index.d.ts +2 -0
  107. package/dist/types/kritzel-stencil/src/classes/core/core.class.d.ts +101 -0
  108. package/dist/types/kritzel-stencil/src/classes/core/reviver.class.d.ts +6 -0
  109. package/dist/types/kritzel-stencil/src/classes/core/store.class.d.ts +53 -0
  110. package/dist/types/kritzel-stencil/src/classes/core/viewport.class.d.ts +48 -0
  111. package/dist/types/kritzel-stencil/src/classes/core/workspace.class.d.ts +24 -0
  112. package/dist/types/kritzel-stencil/src/classes/handlers/base.handler.d.ts +5 -0
  113. package/dist/types/kritzel-stencil/src/classes/handlers/context-menu.handler.d.ts +8 -0
  114. package/dist/types/kritzel-stencil/src/classes/handlers/hover.handler.d.ts +6 -0
  115. package/dist/types/kritzel-stencil/src/classes/handlers/key.handler.d.ts +11 -0
  116. package/dist/types/kritzel-stencil/src/classes/handlers/line-handle.handler.d.ts +34 -0
  117. package/dist/types/kritzel-stencil/src/classes/handlers/move.handler.d.ts +29 -0
  118. package/dist/types/kritzel-stencil/src/classes/handlers/resize.handler.d.ts +24 -0
  119. package/dist/types/kritzel-stencil/src/classes/handlers/rotation.handler.d.ts +12 -0
  120. package/dist/types/kritzel-stencil/src/classes/handlers/selection.handler.d.ts +27 -0
  121. package/dist/types/kritzel-stencil/src/classes/managers/anchor.manager.d.ts +180 -0
  122. package/dist/types/kritzel-stencil/src/classes/managers/cursor.manager.d.ts +43 -0
  123. package/dist/types/kritzel-stencil/src/classes/managers/theme.manager.d.ts +56 -0
  124. package/dist/types/kritzel-stencil/src/classes/objects/base-object.class.d.ts +76 -0
  125. package/dist/types/kritzel-stencil/src/classes/objects/custom-element.class.d.ts +26 -0
  126. package/dist/types/kritzel-stencil/src/classes/objects/group.class.d.ts +97 -0
  127. package/dist/types/kritzel-stencil/src/classes/objects/image.class.d.ts +17 -0
  128. package/dist/types/kritzel-stencil/src/classes/objects/line.class.d.ts +101 -0
  129. package/dist/types/kritzel-stencil/src/classes/objects/path.class.d.ts +62 -0
  130. package/dist/types/kritzel-stencil/src/classes/objects/selection-box.class.d.ts +6 -0
  131. package/dist/types/kritzel-stencil/src/classes/objects/selection-group.class.d.ts +67 -0
  132. package/dist/types/kritzel-stencil/src/classes/objects/shape.class.d.ts +124 -0
  133. package/dist/types/kritzel-stencil/src/classes/objects/text.class.d.ts +56 -0
  134. package/dist/types/kritzel-stencil/src/classes/providers/broadcast-sync-provider.class.d.ts +18 -0
  135. package/dist/types/kritzel-stencil/src/classes/providers/hocuspocus-sync-provider.class.d.ts +120 -0
  136. package/dist/types/kritzel-stencil/src/classes/providers/indexeddb-sync-provider.class.d.ts +22 -0
  137. package/dist/types/kritzel-stencil/src/classes/providers/websocket-sync-provider.class.d.ts +52 -0
  138. package/dist/types/kritzel-stencil/src/classes/registries/icon-registry.class.d.ts +9 -0
  139. package/dist/types/kritzel-stencil/src/classes/registries/tool.registry.d.ts +8 -0
  140. package/dist/types/kritzel-stencil/src/classes/structures/app-state-map.structure.d.ts +31 -0
  141. package/dist/types/kritzel-stencil/src/classes/structures/object-map.structure.d.ts +63 -0
  142. package/dist/types/kritzel-stencil/src/classes/structures/quadtree.structure.d.ts +36 -0
  143. package/dist/types/kritzel-stencil/src/classes/tools/base-tool.class.d.ts +20 -0
  144. package/dist/types/kritzel-stencil/src/classes/tools/brush-tool.class.d.ts +14 -0
  145. package/dist/types/kritzel-stencil/src/classes/tools/eraser-tool.class.d.ts +9 -0
  146. package/dist/types/kritzel-stencil/src/classes/tools/image-tool.class.d.ts +15 -0
  147. package/dist/types/kritzel-stencil/src/classes/tools/line-tool.class.d.ts +19 -0
  148. package/dist/types/kritzel-stencil/src/classes/tools/selection-tool.class.d.ts +54 -0
  149. package/dist/types/kritzel-stencil/src/classes/tools/shape-tool.class.d.ts +39 -0
  150. package/dist/types/kritzel-stencil/src/classes/tools/text-tool.class.d.ts +13 -0
  151. package/dist/types/kritzel-stencil/src/components/core/kritzel-engine/kritzel-engine.d.ts +111 -0
  152. package/dist/types/kritzel-stencil/src/components/shared/kritzel-brush-style/kritzel-brush-style.d.ts +11 -0
  153. package/dist/types/kritzel-stencil/src/components/shared/kritzel-dropdown/kritzel-dropdown.d.ts +46 -0
  154. package/dist/types/kritzel-stencil/src/components/shared/kritzel-font-family/kritzel-font-family.d.ts +13 -0
  155. package/dist/types/kritzel-stencil/src/components/shared/kritzel-line-endings/kritzel-line-endings.d.ts +21 -0
  156. package/dist/types/kritzel-stencil/src/components/shared/kritzel-shape-fill/kritzel-shape-fill.d.ts +10 -0
  157. package/dist/types/kritzel-stencil/src/components/ui/kritzel-context-menu/kritzel-context-menu.d.ts +21 -0
  158. package/dist/types/kritzel-stencil/src/configs/default-brush-tool.config.d.ts +2 -0
  159. package/dist/types/kritzel-stencil/src/configs/default-engine-config.d.ts +2 -0
  160. package/dist/types/kritzel-stencil/src/configs/default-line-tool.config.d.ts +2 -0
  161. package/dist/types/kritzel-stencil/src/configs/default-sync.config.d.ts +5 -0
  162. package/dist/types/kritzel-stencil/src/configs/default-text-tool.config.d.ts +2 -0
  163. package/dist/types/kritzel-stencil/src/constants/color-palette.constants.d.ts +29 -0
  164. package/dist/types/kritzel-stencil/src/constants/engine.constants.d.ts +2 -0
  165. package/dist/types/kritzel-stencil/src/enums/event-button.enum.d.ts +5 -0
  166. package/dist/types/kritzel-stencil/src/enums/handle-type.enum.d.ts +6 -0
  167. package/dist/types/kritzel-stencil/src/enums/shape-type.enum.d.ts +5 -0
  168. package/dist/types/kritzel-stencil/src/helpers/class.helper.d.ts +3 -0
  169. package/dist/types/kritzel-stencil/src/helpers/color.helper.d.ts +33 -0
  170. package/dist/types/kritzel-stencil/src/helpers/cursor.helper.d.ts +22 -0
  171. package/dist/types/kritzel-stencil/src/helpers/devices.helper.d.ts +8 -0
  172. package/dist/types/kritzel-stencil/src/helpers/event.helper.d.ts +6 -0
  173. package/dist/types/kritzel-stencil/src/helpers/geometry.helper.d.ts +38 -0
  174. package/dist/types/kritzel-stencil/src/helpers/keyboard.helper.d.ts +6 -0
  175. package/dist/types/kritzel-stencil/src/helpers/math.helper.d.ts +3 -0
  176. package/dist/types/kritzel-stencil/src/helpers/object.helper.d.ts +4 -0
  177. package/dist/types/kritzel-stencil/src/helpers/theme.helper.d.ts +41 -0
  178. package/dist/types/kritzel-stencil/src/index.d.ts +42 -0
  179. package/dist/types/kritzel-stencil/src/interfaces/anchor.interface.d.ts +137 -0
  180. package/dist/types/kritzel-stencil/src/interfaces/arrow-head.interface.d.ts +27 -0
  181. package/dist/types/kritzel-stencil/src/interfaces/bounding-box.interface.d.ts +8 -0
  182. package/dist/types/kritzel-stencil/src/interfaces/clonable.interface.d.ts +3 -0
  183. package/dist/types/kritzel-stencil/src/interfaces/context-menu-item.interface.d.ts +17 -0
  184. package/dist/types/kritzel-stencil/src/interfaces/debug-info.interface.d.ts +4 -0
  185. package/dist/types/kritzel-stencil/src/interfaces/dialog.interface.d.ts +4 -0
  186. package/dist/types/kritzel-stencil/src/interfaces/displayable-shortcut.interface.d.ts +5 -0
  187. package/dist/types/kritzel-stencil/src/interfaces/engine-state.interface.d.ts +73 -0
  188. package/dist/types/kritzel-stencil/src/interfaces/line-options.interface.d.ts +23 -0
  189. package/dist/types/kritzel-stencil/src/interfaces/master-detail.interface.d.ts +14 -0
  190. package/dist/types/kritzel-stencil/src/interfaces/menu-item.interface.d.ts +24 -0
  191. package/dist/types/kritzel-stencil/src/interfaces/object.interface.d.ts +53 -0
  192. package/dist/types/kritzel-stencil/src/interfaces/path-options.interface.d.ts +11 -0
  193. package/dist/types/kritzel-stencil/src/interfaces/point.interface.d.ts +4 -0
  194. package/dist/types/kritzel-stencil/src/interfaces/polygon.interface.d.ts +7 -0
  195. package/dist/types/kritzel-stencil/src/interfaces/serializable.interface.d.ts +5 -0
  196. package/dist/types/kritzel-stencil/src/interfaces/settings.interface.d.ts +11 -0
  197. package/dist/types/kritzel-stencil/src/interfaces/shortcut.interface.d.ts +10 -0
  198. package/dist/types/kritzel-stencil/src/interfaces/sync-config.interface.d.ts +22 -0
  199. package/dist/types/kritzel-stencil/src/interfaces/sync-provider.interface.d.ts +29 -0
  200. package/dist/types/kritzel-stencil/src/interfaces/theme.interface.d.ts +330 -0
  201. package/dist/types/kritzel-stencil/src/interfaces/tool-config.interface.d.ts +26 -0
  202. package/dist/types/kritzel-stencil/src/interfaces/tool.interface.d.ts +7 -0
  203. package/dist/types/kritzel-stencil/src/interfaces/toolbar-control.interface.d.ts +58 -0
  204. package/dist/types/kritzel-stencil/src/interfaces/undo-state.interface.d.ts +6 -0
  205. package/dist/types/kritzel-stencil/src/themes/dark-theme.d.ts +5 -0
  206. package/dist/types/kritzel-stencil/src/themes/light-theme.d.ts +5 -0
  207. package/dist/types/kritzel-stencil/src/types/shortcut.type.d.ts +1 -0
  208. package/dist/types/kritzel-stencil/src/types/state.types.d.ts +3 -0
  209. package/package.json +2 -2
@@ -0,0 +1,414 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import * as Y from 'yjs';
11
+ import { KritzelReviver } from '../core/reviver.class';
12
+ import { KritzelSelectionBox } from '../objects/selection-box.class';
13
+ import { KritzelSelectionGroup } from '../objects/selection-group.class';
14
+ import { DEFAULT_SYNC_CONFIG } from '../../configs/default-sync.config';
15
+ import { KritzelQuadtree } from './quadtree.structure';
16
+ export class KritzelObjectMap {
17
+ get isReady() {
18
+ return this._isReady;
19
+ }
20
+ get undoManager() {
21
+ return this._undoManager;
22
+ }
23
+ get workspaceId() {
24
+ return this._workspaceId;
25
+ }
26
+ get undoState() {
27
+ return {
28
+ canUndo: this._undoManager ? this._undoManager.canUndo() : false,
29
+ canRedo: this._undoManager ? this._undoManager.canRedo() : false,
30
+ undoStackSize: this._undoManager ? this._undoManager.undoStack.length : 0,
31
+ redoStackSize: this._undoManager ? this._undoManager.redoStack.length : 0,
32
+ };
33
+ }
34
+ get totalCount() {
35
+ return this.quadtree.size;
36
+ }
37
+ constructor() {
38
+ this._ydoc = null;
39
+ this._objectsMap = null;
40
+ this._providers = [];
41
+ this._undoManager = null;
42
+ this._reviver = null;
43
+ this._core = null;
44
+ this._workspaceId = null;
45
+ this._isReady = false;
46
+ this._temporaryItemsCount = 0;
47
+ // Store observer/listener references for cleanup
48
+ this._objectsObserver = null;
49
+ this._stackItemAddedHandler = null;
50
+ this._stackItemPoppedHandler = null;
51
+ this.quadtree = new KritzelQuadtree({
52
+ x: -Infinity,
53
+ y: -Infinity,
54
+ z: 0,
55
+ width: Infinity,
56
+ height: Infinity,
57
+ }, 8);
58
+ }
59
+ initialize(core, workspaceId, config) {
60
+ return __awaiter(this, void 0, void 0, function* () {
61
+ this._core = core;
62
+ this._workspaceId = workspaceId;
63
+ this._reviver = new KritzelReviver(core);
64
+ // Create a dedicated Y.Doc for this workspace
65
+ this._ydoc = new Y.Doc();
66
+ this._objectsMap = this._ydoc.getMap('objects');
67
+ const docName = `kritzel-workspace-${workspaceId}`;
68
+ const finalConfig = config !== null && config !== void 0 ? config : DEFAULT_SYNC_CONFIG;
69
+ // Instantiate providers from configuration
70
+ for (const providerConfig of finalConfig.providers) {
71
+ let provider;
72
+ // Check if it's a class constructor or a factory
73
+ if (typeof providerConfig === 'function') {
74
+ // It's a class constructor
75
+ provider = new providerConfig(docName, this._ydoc);
76
+ }
77
+ else {
78
+ // It's a factory with a create method
79
+ provider = providerConfig.create(docName, this._ydoc);
80
+ }
81
+ this._providers.push(provider);
82
+ }
83
+ // Set up undo/redo manager for this workspace
84
+ this._undoManager = new Y.UndoManager([this._objectsMap], {
85
+ captureTimeout: 200,
86
+ trackedOrigins: new Set(['local', 'temporary']),
87
+ ignoreRemoteMapChanges: true,
88
+ });
89
+ // Store handler references for cleanup
90
+ this._stackItemAddedHandler = event => {
91
+ if (event.type === 'undo') {
92
+ // Track if this was a temporary item
93
+ if (event.origin === 'temporary') {
94
+ this._temporaryItemsCount++;
95
+ }
96
+ }
97
+ };
98
+ this._stackItemPoppedHandler = event => {
99
+ if (event.type === 'undo') {
100
+ // Reduce temporary count when items are undone
101
+ if (event.origin === 'temporary' && this._temporaryItemsCount > 0) {
102
+ this._temporaryItemsCount--;
103
+ }
104
+ }
105
+ };
106
+ this._undoManager.on('stack-item-added', this._stackItemAddedHandler);
107
+ this._undoManager.on('stack-item-popped', this._stackItemPoppedHandler);
108
+ // Observe changes to objects and sync with application state
109
+ this._objectsObserver = event => {
110
+ this.handleObjectsChange(event);
111
+ };
112
+ this._objectsMap.observe(this._objectsObserver);
113
+ // Connect all providers in parallel
114
+ yield Promise.all(this._providers.map(p => p.connect()));
115
+ this._isReady = true;
116
+ // Load objects from Yjs
117
+ this.loadFromYjs();
118
+ });
119
+ }
120
+ handleObjectsChange(event) {
121
+ var _a, _b, _c;
122
+ // Skip Map updates for local changes (already done), but still trigger re-render
123
+ // 'temporary' is also a local change that shouldn't be re-deserialized
124
+ if (event.transaction.origin === 'local' || event.transaction.origin === 'temporary') {
125
+ (_a = this._core) === null || _a === void 0 ? void 0 : _a.rerender();
126
+ return;
127
+ }
128
+ const changedKeys = Array.from(event.keysChanged);
129
+ const objectsToUpdate = [];
130
+ const selectionGroupsToUpdate = [];
131
+ const objectsToDelete = [];
132
+ changedKeys.forEach(key => {
133
+ const change = event.changes.keys.get(key);
134
+ if (change && change.action === 'delete') {
135
+ objectsToDelete.push(key);
136
+ }
137
+ else {
138
+ const serialized = this._objectsMap.get(key);
139
+ if (serialized) {
140
+ const object = this._reviver.revive(serialized);
141
+ // Separate SelectionGroups to process them after regular objects
142
+ if (object instanceof KritzelSelectionGroup) {
143
+ selectionGroupsToUpdate.push(object);
144
+ }
145
+ else {
146
+ objectsToUpdate.push(object);
147
+ }
148
+ }
149
+ }
150
+ });
151
+ // Delete objects from local map
152
+ objectsToDelete.forEach(objectId => {
153
+ this.quadtree.remove(o => o.id === objectId);
154
+ });
155
+ // First, update or insert regular objects
156
+ objectsToUpdate.forEach(object => {
157
+ const existed = this.quadtree.filter(o => o.id === object.id).length > 0;
158
+ if (existed) {
159
+ this.quadtree.update(object);
160
+ }
161
+ else {
162
+ this.quadtree.insert(object);
163
+ }
164
+ });
165
+ // Then, update or insert SelectionGroups
166
+ const updatedSelectionGroupIds = new Set();
167
+ selectionGroupsToUpdate.forEach(object => {
168
+ const existed = this.quadtree.filter(o => o.id === object.id).length > 0;
169
+ if (existed) {
170
+ this.quadtree.update(object);
171
+ }
172
+ else {
173
+ this.quadtree.insert(object);
174
+ }
175
+ updatedSelectionGroupIds.add(object.id);
176
+ // After undo/redo, the SelectionGroup's dimensions may be stale because:
177
+ // 1. The serialized state contains the old bounding box
178
+ // 2. The child objects have been reverted to their previous positions
179
+ // We need to invalidate the cache and recalculate dimensions
180
+ // skipPersist=true prevents creating new undo entries
181
+ object.invalidateObjectsCache();
182
+ object.refreshObjectDimensions(undefined, true);
183
+ object.captureUnchangedSnapshots();
184
+ // Update quadtree again with corrected dimensions
185
+ this.quadtree.update(object);
186
+ });
187
+ // If regular objects were changed but their SelectionGroup wasn't explicitly updated,
188
+ // we still need to refresh that SelectionGroup's dimensions
189
+ if (objectsToUpdate.length > 0 || objectsToDelete.length > 0) {
190
+ const changedObjectIds = new Set([
191
+ ...objectsToUpdate.map(o => o.id),
192
+ ...objectsToDelete
193
+ ]);
194
+ // Find any existing SelectionGroups that contain changed objects
195
+ const existingSelectionGroups = this.quadtree.filter(o => o instanceof KritzelSelectionGroup && !updatedSelectionGroupIds.has(o.id));
196
+ for (const selectionGroup of existingSelectionGroups) {
197
+ const hasChangedChildren = selectionGroup.objectIds.some(id => changedObjectIds.has(id));
198
+ if (hasChangedChildren) {
199
+ selectionGroup.invalidateObjectsCache();
200
+ selectionGroup.refreshObjectDimensions(undefined, true);
201
+ selectionGroup.captureUnchangedSnapshots();
202
+ // Update quadtree with corrected dimensions
203
+ this.quadtree.update(selectionGroup);
204
+ }
205
+ }
206
+ }
207
+ // Invalidate the store's selection cache so it fetches the updated SelectionGroup
208
+ (_b = this._core) === null || _b === void 0 ? void 0 : _b.store.invalidateSelectionCache();
209
+ (_c = this._core) === null || _c === void 0 ? void 0 : _c.rerender();
210
+ }
211
+ transaction(callback) {
212
+ if (this._ydoc) {
213
+ this._ydoc.transact(callback, 'local');
214
+ }
215
+ }
216
+ loadFromYjs() {
217
+ if (!this._objectsMap || !this._reviver) {
218
+ return;
219
+ }
220
+ this.quadtree.reset();
221
+ this._objectsMap.forEach(serialized => {
222
+ const object = this._reviver.revive(serialized);
223
+ this.quadtree.insert(object);
224
+ });
225
+ }
226
+ reset() {
227
+ this.quadtree.reset();
228
+ this._ydoc.transact(() => {
229
+ this._objectsMap.clear();
230
+ }, 'local');
231
+ }
232
+ insert(object) {
233
+ if (!object.id) {
234
+ return false;
235
+ }
236
+ this.quadtree.insert(object);
237
+ if (this._objectsMap && this.isPersistable(object)) {
238
+ const serialized = object.serialize();
239
+ this._ydoc.transact(() => {
240
+ this._objectsMap.set(object.id, serialized);
241
+ }, 'local');
242
+ }
243
+ return true;
244
+ }
245
+ update(object, options = {}) {
246
+ if (!object.id) {
247
+ return false;
248
+ }
249
+ const existed = this.quadtree.filter(o => o.id === object.id).length > 0;
250
+ if (!existed) {
251
+ return false;
252
+ }
253
+ this.quadtree.update(object);
254
+ if (this._objectsMap && this.isPersistable(object)) {
255
+ const serialized = object.serialize();
256
+ const origin = options.temporary ? 'temporary' : 'local';
257
+ this._ydoc.transact(() => {
258
+ this._objectsMap.set(object.id, serialized);
259
+ }, origin);
260
+ }
261
+ return true;
262
+ }
263
+ remove(predicate) {
264
+ const objectsToRemove = this.quadtree.filter(predicate);
265
+ for (const object of objectsToRemove) {
266
+ this.quadtree.remove(o => o.id === object.id);
267
+ if (this._objectsMap && this.isPersistable(object)) {
268
+ this._ydoc.transact(() => {
269
+ this._objectsMap.delete(object.id);
270
+ }, 'local');
271
+ }
272
+ }
273
+ }
274
+ filter(predicate) {
275
+ return this.quadtree.filter(predicate);
276
+ }
277
+ allObjects() {
278
+ return this.quadtree.allObjects();
279
+ }
280
+ query(range) {
281
+ return this.quadtree.query(range);
282
+ }
283
+ isPersistable(object) {
284
+ if (object instanceof KritzelSelectionBox) {
285
+ return false;
286
+ }
287
+ return true;
288
+ }
289
+ undo() {
290
+ if (this._undoManager && this._undoManager.canUndo()) {
291
+ this._undoManager.undo();
292
+ this._core.engine.emitObjectsChange();
293
+ }
294
+ }
295
+ redo() {
296
+ if (this._undoManager && this._undoManager.canRedo()) {
297
+ this._undoManager.redo();
298
+ this._core.engine.emitObjectsChange();
299
+ }
300
+ }
301
+ canUndo() {
302
+ return this._undoManager ? this._undoManager.canUndo() : false;
303
+ }
304
+ canRedo() {
305
+ return this._undoManager ? this._undoManager.canRedo() : false;
306
+ }
307
+ clearHistory() {
308
+ if (this._undoManager) {
309
+ this._undoManager.clear();
310
+ this._temporaryItemsCount = 0;
311
+ }
312
+ }
313
+ /**
314
+ * Consolidates all temporary items in the undo stack into a single undo item.
315
+ * Call this when you want to merge multiple temporary changes (e.g., keystrokes) into one.
316
+ */
317
+ consolidateTemporaryItems() {
318
+ if (!this._undoManager || this._temporaryItemsCount === 0) {
319
+ return;
320
+ }
321
+ // Get current stack length
322
+ const stackLength = this._undoManager.undoStack.length;
323
+ if (stackLength === 0) {
324
+ this._temporaryItemsCount = 0;
325
+ return;
326
+ }
327
+ // Stop tracking temporarily
328
+ this._undoManager.stopCapturing();
329
+ // The temporary items should be at the end of the stack
330
+ // We'll need to undo them all, then redo as a single transaction
331
+ const itemsToConsolidate = Math.min(this._temporaryItemsCount, stackLength);
332
+ if (itemsToConsolidate > 1) {
333
+ // Store the current state before undoing
334
+ const undoneItems = [];
335
+ // Undo all temporary items
336
+ for (let i = 0; i < itemsToConsolidate; i++) {
337
+ if (this._undoManager.canUndo()) {
338
+ undoneItems.push(this._undoManager.undoStack[this._undoManager.undoStack.length - 1]);
339
+ this._undoManager.undo();
340
+ }
341
+ }
342
+ // Now redo them all as a single 'local' transaction
343
+ // This will consolidate them into one undo item
344
+ this._ydoc.transact(() => {
345
+ for (let i = itemsToConsolidate - 1; i >= 0; i--) {
346
+ if (this._undoManager.canRedo()) {
347
+ this._undoManager.redo();
348
+ }
349
+ }
350
+ }, 'local');
351
+ }
352
+ else if (itemsToConsolidate === 1) {
353
+ // If only one temporary item, just change its origin to 'local'
354
+ // This is implicit - next transaction will be separate
355
+ }
356
+ this._temporaryItemsCount = 0;
357
+ }
358
+ /**
359
+ * Removes all temporary items from the undo stack without consolidating them.
360
+ * Use this to discard temporary changes completely.
361
+ */
362
+ clearTemporaryItems() {
363
+ if (!this._undoManager || this._temporaryItemsCount === 0) {
364
+ return;
365
+ }
366
+ const stackLength = this._undoManager.undoStack.length;
367
+ const itemsToRemove = Math.min(this._temporaryItemsCount, stackLength);
368
+ // Remove items from the end of the stack
369
+ for (let i = 0; i < itemsToRemove; i++) {
370
+ if (this._undoManager.undoStack.length > 0) {
371
+ this._undoManager.undoStack.pop();
372
+ }
373
+ }
374
+ this._temporaryItemsCount = 0;
375
+ }
376
+ destroy() {
377
+ // Unobserve the objects map
378
+ if (this._objectsMap && this._objectsObserver) {
379
+ this._objectsMap.unobserve(this._objectsObserver);
380
+ this._objectsObserver = null;
381
+ }
382
+ // Remove undo manager event listeners
383
+ if (this._undoManager) {
384
+ if (this._stackItemAddedHandler) {
385
+ this._undoManager.off('stack-item-added', this._stackItemAddedHandler);
386
+ this._stackItemAddedHandler = null;
387
+ }
388
+ if (this._stackItemPoppedHandler) {
389
+ this._undoManager.off('stack-item-popped', this._stackItemPoppedHandler);
390
+ this._stackItemPoppedHandler = null;
391
+ }
392
+ this._undoManager.destroy();
393
+ this._undoManager = null;
394
+ }
395
+ // Reset quadtree
396
+ this.quadtree.reset();
397
+ // Destroy providers
398
+ this._providers.forEach(p => p.destroy());
399
+ this._providers = [];
400
+ // Clear object map reference
401
+ this._objectsMap = null;
402
+ // Destroy Y.Doc
403
+ if (this._ydoc) {
404
+ this._ydoc.destroy();
405
+ this._ydoc = null;
406
+ }
407
+ // Clear remaining references
408
+ this._core = null;
409
+ this._reviver = null;
410
+ this._workspaceId = null;
411
+ this._isReady = false;
412
+ this._temporaryItemsCount = 0;
413
+ }
414
+ }
@@ -0,0 +1,151 @@
1
+ export class KritzelQuadtree {
2
+ /** Total number of objects in the quadtree (O(1) access) */
3
+ get size() {
4
+ return this._size;
5
+ }
6
+ constructor(bounds, capacity = 16) {
7
+ this.objects = [];
8
+ this.children = null;
9
+ this._size = 0;
10
+ this.bounds = bounds;
11
+ this.capacity = capacity;
12
+ }
13
+ reset() {
14
+ this.objects = [];
15
+ this.children = null;
16
+ this._size = 0;
17
+ }
18
+ insert(object) {
19
+ if (!this.intersects(object.rotatedBoundingBox, this.bounds)) {
20
+ return false;
21
+ }
22
+ if (this.objects.length < this.capacity && this.children === null) {
23
+ this.objects.push(object);
24
+ this._size++;
25
+ return true;
26
+ }
27
+ if (this.children === null) {
28
+ this.subdivide();
29
+ }
30
+ for (const child of this.children) {
31
+ if (child.insert(object)) {
32
+ this._size++;
33
+ return true;
34
+ }
35
+ }
36
+ return false;
37
+ }
38
+ update(object) {
39
+ const index = this.objects.findIndex(o => o.id === object.id);
40
+ if (index !== -1) {
41
+ this.objects[index] = object;
42
+ return true;
43
+ }
44
+ if (this.children !== null) {
45
+ for (const child of this.children) {
46
+ if (child.update(object)) {
47
+ return true;
48
+ }
49
+ }
50
+ }
51
+ return false;
52
+ }
53
+ remove(predicate) {
54
+ let removed = 0;
55
+ const index = this.objects.findIndex(o => predicate(o));
56
+ if (index !== -1) {
57
+ this.objects.splice(index, 1);
58
+ removed++;
59
+ }
60
+ if (this.children !== null) {
61
+ for (const child of this.children) {
62
+ removed += child.remove(predicate);
63
+ }
64
+ }
65
+ this._size -= removed;
66
+ return removed;
67
+ }
68
+ query(range) {
69
+ const results = [];
70
+ this._queryInto(range, results);
71
+ return results;
72
+ }
73
+ /**
74
+ * Internal method that collects query results into a pre-allocated array.
75
+ * Avoids creating intermediate arrays from spread operators.
76
+ */
77
+ _queryInto(range, results) {
78
+ if (!this.intersects(range, this.bounds)) {
79
+ return;
80
+ }
81
+ for (const object of this.objects) {
82
+ if (this.intersects(object.rotatedBoundingBox, range)) {
83
+ results.push(object);
84
+ }
85
+ }
86
+ if (this.children !== null) {
87
+ for (const child of this.children) {
88
+ child._queryInto(range, results);
89
+ }
90
+ }
91
+ }
92
+ filter(predicate) {
93
+ const results = [];
94
+ this._filterInto(predicate, results);
95
+ return results;
96
+ }
97
+ /**
98
+ * Internal method that collects filter results into a pre-allocated array.
99
+ * Avoids creating intermediate arrays from spread operators.
100
+ */
101
+ _filterInto(predicate, results) {
102
+ for (const obj of this.objects) {
103
+ if (predicate(obj)) {
104
+ results.push(obj);
105
+ }
106
+ }
107
+ if (this.children !== null) {
108
+ for (const child of this.children) {
109
+ child._filterInto(predicate, results);
110
+ }
111
+ }
112
+ }
113
+ allObjects() {
114
+ const results = [];
115
+ this._collectAllInto(results);
116
+ return results;
117
+ }
118
+ /**
119
+ * Internal method that collects all objects into a pre-allocated array.
120
+ * Avoids creating intermediate arrays from spread operators.
121
+ */
122
+ _collectAllInto(results) {
123
+ for (const obj of this.objects) {
124
+ results.push(obj);
125
+ }
126
+ if (this.children !== null) {
127
+ for (const child of this.children) {
128
+ child._collectAllInto(results);
129
+ }
130
+ }
131
+ }
132
+ subdivide() {
133
+ const { x, y, z, width, height } = this.bounds;
134
+ const halfWidth = width / 2;
135
+ const halfHeight = height / 2;
136
+ // Create 4 quadrants: NW, NE, SW, SE
137
+ this.children = [
138
+ new KritzelQuadtree({ x, y, z, width: halfWidth, height: halfHeight }, this.capacity), // Northwest
139
+ new KritzelQuadtree({ x: x + halfWidth, y, z, width: halfWidth, height: halfHeight }, this.capacity), // Northeast
140
+ new KritzelQuadtree({ x, y: y + halfHeight, z, width: halfWidth, height: halfHeight }, this.capacity), // Southwest
141
+ new KritzelQuadtree({ x: x + halfWidth, y: y + halfHeight, z, width: halfWidth, height: halfHeight }, this.capacity), // Southeast
142
+ ];
143
+ }
144
+ intersects(a, b) {
145
+ return !(a.x >= b.x + b.width || // a is completely to the right of b
146
+ a.x + a.width <= b.x || // a is completely to the left of b
147
+ a.y >= b.y + b.height || // a is completely below b
148
+ a.y + a.height <= b.y // a is completely above b
149
+ );
150
+ }
151
+ }
@@ -0,0 +1,36 @@
1
+ export class KritzelBaseTool {
2
+ constructor(core) {
3
+ this.__class__ = this.constructor.name;
4
+ this.name = 'base-tool';
5
+ this._core = core;
6
+ void this._core; // Avoid unused variable warning
7
+ }
8
+ onActivate() {
9
+ // default implementation
10
+ }
11
+ onDeactivate() {
12
+ // default implementation
13
+ }
14
+ handlePointerDown(_event) {
15
+ // default implementation
16
+ }
17
+ handlePointerMove(_event) {
18
+ // default implementation
19
+ }
20
+ handlePointerUp(_event) {
21
+ // default implementation
22
+ }
23
+ handleWheel(_event) {
24
+ // default implementation
25
+ }
26
+ serialize() {
27
+ return {
28
+ __class__: this.__class__,
29
+ name: this.name,
30
+ };
31
+ }
32
+ deserialize(object) {
33
+ Object.assign(this, object);
34
+ return this;
35
+ }
36
+ }