kritzel-stencil 0.1.74 → 0.1.76

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 (43) hide show
  1. package/dist/cjs/index.cjs.js +131 -86
  2. package/dist/cjs/kritzel-active-users_42.cjs.entry.js +132 -19
  3. package/dist/cjs/{workspace.migrations-Dyt35LBC.js → workspace.migrations-DkmVO6dE.js} +106 -44
  4. package/dist/collection/classes/core/viewport.class.js +32 -3
  5. package/dist/collection/classes/managers/anchor.manager.js +101 -44
  6. package/dist/collection/classes/providers/broadcast-sync-provider.class.js +5 -0
  7. package/dist/collection/classes/providers/hocuspocus-sync-provider.class.js +120 -85
  8. package/dist/collection/classes/providers/indexeddb-sync-provider.class.js +5 -0
  9. package/dist/collection/classes/providers/websocket-sync-provider.class.js +5 -0
  10. package/dist/collection/classes/structures/app-state-map.structure.js +15 -4
  11. package/dist/collection/classes/structures/object-map.structure.js +75 -7
  12. package/dist/collection/components/core/kritzel-awareness-cursors/kritzel-awareness-cursors.css +2 -2
  13. package/dist/collection/components/core/kritzel-awareness-cursors/kritzel-awareness-cursors.js +7 -2
  14. package/dist/collection/constants/version.js +1 -1
  15. package/dist/components/index.js +1 -1
  16. package/dist/components/kritzel-awareness-cursors.js +1 -1
  17. package/dist/components/kritzel-editor.js +1 -1
  18. package/dist/components/kritzel-engine.js +1 -1
  19. package/dist/components/kritzel-settings.js +1 -1
  20. package/dist/components/{p-B4Oqnl55.js → p-31FVoNWR.js} +1 -1
  21. package/dist/components/p-jdYmu4SA.js +9 -0
  22. package/dist/components/p-xNwOWoiT.js +1 -0
  23. package/dist/esm/index.js +132 -87
  24. package/dist/esm/kritzel-active-users_42.entry.js +132 -19
  25. package/dist/esm/{workspace.migrations-B99F1MdT.js → workspace.migrations-D48_Bqvh.js} +106 -44
  26. package/dist/stencil/index.esm.js +1 -1
  27. package/dist/stencil/p-775a7246.entry.js +9 -0
  28. package/dist/stencil/{p-B99F1MdT.js → p-D48_Bqvh.js} +1 -1
  29. package/dist/stencil/stencil.esm.js +1 -1
  30. package/dist/types/classes/core/viewport.class.d.ts +8 -0
  31. package/dist/types/classes/managers/anchor.manager.d.ts +4 -0
  32. package/dist/types/classes/providers/broadcast-sync-provider.class.d.ts +2 -0
  33. package/dist/types/classes/providers/hocuspocus-sync-provider.class.d.ts +37 -1
  34. package/dist/types/classes/providers/indexeddb-sync-provider.class.d.ts +2 -0
  35. package/dist/types/classes/providers/websocket-sync-provider.class.d.ts +2 -0
  36. package/dist/types/classes/structures/object-map.structure.d.ts +6 -0
  37. package/dist/types/constants/version.d.ts +1 -1
  38. package/dist/types/interfaces/remote-cursor.interface.d.ts +1 -0
  39. package/dist/types/interfaces/sync-provider.interface.d.ts +16 -0
  40. package/package.json +1 -1
  41. package/dist/components/p-BSipRoFx.js +0 -1
  42. package/dist/components/p-RJWe82kG.js +0 -9
  43. package/dist/stencil/p-2a60e1bc.entry.js +0 -9
@@ -22364,6 +22364,7 @@ class KritzelSelectionTool extends KritzelBaseTool {
22364
22364
  * IndexedDB sync provider for local persistence
22365
22365
  */
22366
22366
  class IndexedDBSyncProvider {
22367
+ type = 'local';
22367
22368
  provider;
22368
22369
  isConnected = false;
22369
22370
  constructor(docName, doc, options) {
@@ -22385,6 +22386,10 @@ class IndexedDBSyncProvider {
22385
22386
  // IndexedDB doesn't need explicit disconnect
22386
22387
  this.isConnected = false;
22387
22388
  }
22389
+ async reconnect() {
22390
+ this.disconnect();
22391
+ return this.connect();
22392
+ }
22388
22393
  destroy() {
22389
22394
  if (this.provider) {
22390
22395
  this.provider.destroy();
@@ -25580,16 +25585,22 @@ class KritzelAnchorManager {
25580
25585
  if (!KritzelClassHelper.isInstanceOf(selectedObject, 'KritzelLine'))
25581
25586
  return null;
25582
25587
  const line = selectedObject;
25583
- const startAnchorViz = this.computeAnchorVisualization(line, 'start');
25584
- const endAnchorViz = this.computeAnchorVisualization(line, 'end');
25588
+ const startAnchorVizRaw = this.computeAnchorVisualization(line, 'start');
25589
+ const endAnchorVizRaw = this.computeAnchorVisualization(line, 'end');
25590
+ const startAnchorViz = this.isFiniteAnchorVisualization(startAnchorVizRaw) ? startAnchorVizRaw : null;
25591
+ const endAnchorViz = this.isFiniteAnchorVisualization(endAnchorVizRaw) ? endAnchorVizRaw : null;
25585
25592
  if (!startAnchorViz && !endAnchorViz)
25586
25593
  return null;
25587
- const scale = this._core.store.state.scale;
25588
- const lineStrokeWidth = line.strokeWidth / line.scale;
25594
+ const scale = this.getSafeScale(this._core.store.state.scale);
25595
+ const lineScale = this.getSafeScale(line.scale);
25596
+ const lineStrokeWidth = line.strokeWidth / lineScale;
25589
25597
  const indicatorStrokeWidth = `${2 / scale}`;
25590
25598
  const dashLength = Math.max(lineStrokeWidth * 2, 4 / scale);
25591
25599
  const dashArray = `${dashLength} ${dashLength}`;
25592
25600
  const indicatorRadius = 8 / scale;
25601
+ if (!this.areFiniteNumbers(lineStrokeWidth, dashLength, indicatorRadius)) {
25602
+ return null;
25603
+ }
25593
25604
  return {
25594
25605
  lineStrokeWidth,
25595
25606
  indicatorStrokeWidth,
@@ -25611,31 +25622,39 @@ class KritzelAnchorManager {
25611
25622
  const snapCandidate = this.getSnapCandidate();
25612
25623
  if (!snapCandidate)
25613
25624
  return null;
25614
- const scale = this._core.store.state.scale;
25625
+ if (!this.areFiniteNumbers(snapCandidate.centerX, snapCandidate.centerY, snapCandidate.lineEndpointX, snapCandidate.lineEndpointY)) {
25626
+ return null;
25627
+ }
25628
+ const scale = this.getSafeScale(this._core.store.state.scale);
25615
25629
  const indicatorRadius = 8 / scale;
25616
25630
  const indicatorStrokeWidth = `${2 / scale}`;
25617
- const lineStrokeWidth = snapCandidate.lineStrokeWidth
25618
- ? `${snapCandidate.lineStrokeWidth}`
25619
- : `${4 / scale}`;
25620
- const lineStrokeWidthNum = snapCandidate.lineStrokeWidth || (4 / scale);
25631
+ const lineStrokeWidthNum = this.areFiniteNumbers(snapCandidate.lineStrokeWidth) && snapCandidate.lineStrokeWidth > 0
25632
+ ? snapCandidate.lineStrokeWidth
25633
+ : (4 / scale);
25634
+ const lineStrokeWidth = `${lineStrokeWidthNum}`;
25621
25635
  const dashLength = Math.max(lineStrokeWidthNum * 2, 4 / scale);
25622
25636
  const dashArray = `${dashLength} ${dashLength}`;
25623
25637
  const lineStroke = snapCandidate.lineStroke || '#000000';
25624
- let solidLineEndX = snapCandidate.edgeX;
25625
- let solidLineEndY = snapCandidate.edgeY;
25638
+ let edgeX = this.areFiniteNumbers(snapCandidate.edgeX) ? snapCandidate.edgeX : undefined;
25639
+ let edgeY = this.areFiniteNumbers(snapCandidate.edgeY) ? snapCandidate.edgeY : undefined;
25640
+ let solidLineEndX = edgeX;
25641
+ let solidLineEndY = edgeY;
25626
25642
  let arrowPoints;
25627
- if (snapCandidate.arrowOffset && snapCandidate.edgeX !== undefined && snapCandidate.edgeY !== undefined) {
25628
- const dx = snapCandidate.lineEndpointX - snapCandidate.edgeX;
25629
- const dy = snapCandidate.lineEndpointY - snapCandidate.edgeY;
25643
+ const arrowOffset = this.areFiniteNumbers(snapCandidate.arrowOffset) && snapCandidate.arrowOffset > 0
25644
+ ? snapCandidate.arrowOffset
25645
+ : undefined;
25646
+ if (arrowOffset !== undefined && edgeX !== undefined && edgeY !== undefined) {
25647
+ const dx = snapCandidate.lineEndpointX - edgeX;
25648
+ const dy = snapCandidate.lineEndpointY - edgeY;
25630
25649
  const length = Math.sqrt(dx * dx + dy * dy);
25631
- if (length > snapCandidate.arrowOffset) {
25632
- solidLineEndX = snapCandidate.edgeX + (dx / length) * snapCandidate.arrowOffset;
25633
- solidLineEndY = snapCandidate.edgeY + (dy / length) * snapCandidate.arrowOffset;
25650
+ if (length > arrowOffset) {
25651
+ solidLineEndX = edgeX + (dx / length) * arrowOffset;
25652
+ solidLineEndY = edgeY + (dy / length) * arrowOffset;
25634
25653
  }
25635
25654
  // Calculate arrow head points
25636
25655
  // Direction from line endpoint to edge (arrow direction)
25637
- const arrowDx = snapCandidate.edgeX - snapCandidate.lineEndpointX;
25638
- const arrowDy = snapCandidate.edgeY - snapCandidate.lineEndpointY;
25656
+ const arrowDx = edgeX - snapCandidate.lineEndpointX;
25657
+ const arrowDy = edgeY - snapCandidate.lineEndpointY;
25639
25658
  const arrowLengthTotal = Math.sqrt(arrowDx * arrowDx + arrowDy * arrowDy);
25640
25659
  if (arrowLengthTotal > 0) {
25641
25660
  const ux = arrowDx / arrowLengthTotal;
@@ -25644,11 +25663,11 @@ class KritzelAnchorManager {
25644
25663
  const px = -uy;
25645
25664
  const py = ux;
25646
25665
  // Arrow dimensions
25647
- const arrowLength = snapCandidate.arrowOffset;
25666
+ const arrowLength = arrowOffset;
25648
25667
  const arrowWidth = arrowLength; // 1:1 ratio
25649
25668
  // Arrow tip at edge
25650
- const tipX = snapCandidate.edgeX;
25651
- const tipY = snapCandidate.edgeY;
25669
+ const tipX = edgeX;
25670
+ const tipY = edgeY;
25652
25671
  // Arrow base
25653
25672
  const baseX = tipX - ux * arrowLength;
25654
25673
  const baseY = tipY - uy * arrowLength;
@@ -25657,9 +25676,31 @@ class KritzelAnchorManager {
25657
25676
  const leftY = baseY + py * arrowWidth / 2;
25658
25677
  const rightX = baseX - px * arrowWidth / 2;
25659
25678
  const rightY = baseY - py * arrowWidth / 2;
25660
- arrowPoints = `${tipX},${tipY} ${leftX},${leftY} ${rightX},${rightY}`;
25679
+ if (this.areFiniteNumbers(tipX, tipY, leftX, leftY, rightX, rightY)) {
25680
+ arrowPoints = `${tipX},${tipY} ${leftX},${leftY} ${rightX},${rightY}`;
25681
+ }
25661
25682
  }
25662
25683
  }
25684
+ if (!this.areFiniteNumbers(indicatorRadius, lineStrokeWidthNum, dashLength)) {
25685
+ return null;
25686
+ }
25687
+ const snapLinePath = (() => {
25688
+ if (snapCandidate.controlX !== undefined &&
25689
+ snapCandidate.controlY !== undefined &&
25690
+ snapCandidate.t !== undefined &&
25691
+ this.areFiniteNumbers(snapCandidate.controlX, snapCandidate.controlY, snapCandidate.t)) {
25692
+ const startT = snapCandidate.endpoint === 'start' ? 1 - snapCandidate.t : snapCandidate.t;
25693
+ // Ensure meaningful range
25694
+ if (startT >= 1)
25695
+ return undefined;
25696
+ const segment = this.extractQuadraticSegment({ x: snapCandidate.lineEndpointX, y: snapCandidate.lineEndpointY }, { x: snapCandidate.controlX, y: snapCandidate.controlY }, { x: snapCandidate.centerX, y: snapCandidate.centerY }, startT, 1);
25697
+ if (!this.areFiniteNumbers(segment.start.x, segment.start.y, segment.control.x, segment.control.y, segment.end.x, segment.end.y)) {
25698
+ return undefined;
25699
+ }
25700
+ return `M ${segment.start.x} ${segment.start.y} Q ${segment.control.x} ${segment.control.y} ${segment.end.x} ${segment.end.y}`;
25701
+ }
25702
+ return undefined;
25703
+ })();
25663
25704
  return {
25664
25705
  indicatorRadius,
25665
25706
  indicatorStrokeWidth,
@@ -25670,27 +25711,15 @@ class KritzelAnchorManager {
25670
25711
  centerY: snapCandidate.centerY,
25671
25712
  lineEndpointX: snapCandidate.lineEndpointX,
25672
25713
  lineEndpointY: snapCandidate.lineEndpointY,
25673
- edgeX: snapCandidate.edgeX,
25674
- edgeY: snapCandidate.edgeY,
25675
- arrowOffset: snapCandidate.arrowOffset,
25714
+ edgeX,
25715
+ edgeY,
25716
+ arrowOffset,
25676
25717
  arrowStyle: snapCandidate.arrowStyle,
25677
25718
  arrowFill: snapCandidate.arrowFill,
25678
25719
  solidLineEndX,
25679
25720
  solidLineEndY,
25680
25721
  arrowPoints,
25681
- snapLinePath: (() => {
25682
- if (snapCandidate.controlX !== undefined &&
25683
- snapCandidate.controlY !== undefined &&
25684
- snapCandidate.t !== undefined) {
25685
- const startT = snapCandidate.endpoint === 'start' ? 1 - snapCandidate.t : snapCandidate.t;
25686
- // Ensure meaningful range
25687
- if (startT >= 1)
25688
- return undefined;
25689
- const segment = this.extractQuadraticSegment({ x: snapCandidate.lineEndpointX, y: snapCandidate.lineEndpointY }, { x: snapCandidate.controlX, y: snapCandidate.controlY }, { x: snapCandidate.centerX, y: snapCandidate.centerY }, startT, 1);
25690
- return `M ${segment.start.x} ${segment.start.y} Q ${segment.control.x} ${segment.control.y} ${segment.end.x} ${segment.end.y}`;
25691
- }
25692
- return undefined;
25693
- })(),
25722
+ snapLinePath,
25694
25723
  };
25695
25724
  }
25696
25725
  // ============================================
@@ -25868,12 +25897,19 @@ class KritzelAnchorManager {
25868
25897
  return null;
25869
25898
  const centerX = targetObject.centerX;
25870
25899
  const centerY = targetObject.centerY;
25900
+ if (!this.areFiniteNumbers(clipInfo.worldX, clipInfo.worldY, centerX, centerY)) {
25901
+ return null;
25902
+ }
25903
+ const pathD = this.buildAnchorPath(line, endpoint, clipInfo, targetObject) ?? undefined;
25904
+ if (pathD && !this.isFinitePathData(pathD)) {
25905
+ return null;
25906
+ }
25871
25907
  return {
25872
25908
  edgeX: clipInfo.worldX,
25873
25909
  edgeY: clipInfo.worldY,
25874
25910
  centerX,
25875
25911
  centerY,
25876
- pathD: this.buildAnchorPath(line, endpoint, clipInfo, targetObject) ?? undefined,
25912
+ pathD,
25877
25913
  };
25878
25914
  }
25879
25915
  /**
@@ -26586,9 +26622,10 @@ class KritzelAnchorManager {
26586
26622
  const sin = Math.sin(line.rotation);
26587
26623
  const rotatedX = (px - cx) * cos - (py - cy) * sin + cx;
26588
26624
  const rotatedY = (px - cx) * sin + (py - cy) * cos + cy;
26625
+ const safeLineScale = this.getSafeScale(line.scale);
26589
26626
  return {
26590
- x: rotatedX / line.scale + line.translateX,
26591
- y: rotatedY / line.scale + line.translateY,
26627
+ x: rotatedX / safeLineScale + line.translateX,
26628
+ y: rotatedY / safeLineScale + line.translateY,
26592
26629
  };
26593
26630
  }
26594
26631
  /**
@@ -26602,8 +26639,9 @@ class KritzelAnchorManager {
26602
26639
  * @returns Object with x and y coordinates in the line's local SVG space.
26603
26640
  */
26604
26641
  lineWorldToLocal(line, worldX, worldY) {
26605
- const dx = (worldX - line.translateX) * line.scale;
26606
- const dy = (worldY - line.translateY) * line.scale;
26642
+ const safeLineScale = this.getSafeScale(line.scale);
26643
+ const dx = (worldX - line.translateX) * safeLineScale;
26644
+ const dy = (worldY - line.translateY) * safeLineScale;
26607
26645
  const cx = line.totalWidth / 2;
26608
26646
  const cy = line.totalHeight / 2;
26609
26647
  const cos = Math.cos(-line.rotation);
@@ -26615,6 +26653,30 @@ class KritzelAnchorManager {
26615
26653
  y: rotatedY + line.y,
26616
26654
  };
26617
26655
  }
26656
+ getSafeScale(scale) {
26657
+ if (Number.isFinite(scale) && Math.abs(scale) > 1e-6) {
26658
+ return scale;
26659
+ }
26660
+ return 1;
26661
+ }
26662
+ areFiniteNumbers(...values) {
26663
+ return values.every(value => value !== undefined && Number.isFinite(value));
26664
+ }
26665
+ isFiniteAnchorVisualization(visualization) {
26666
+ if (!visualization) {
26667
+ return false;
26668
+ }
26669
+ if (!this.areFiniteNumbers(visualization.edgeX, visualization.edgeY, visualization.centerX, visualization.centerY)) {
26670
+ return false;
26671
+ }
26672
+ if (visualization.pathD && !this.isFinitePathData(visualization.pathD)) {
26673
+ return false;
26674
+ }
26675
+ return true;
26676
+ }
26677
+ isFinitePathData(pathD) {
26678
+ return !pathD.includes('Infinity') && !pathD.includes('NaN');
26679
+ }
26618
26680
  /**
26619
26681
  * Checks if an object can be used as an anchor target.
26620
26682
  * Excludes selection-related objects (SelectionBox, SelectionGroup) and
@@ -1 +1 @@
1
- import{H as a,a as T}from"./p-B99F1MdT.js";export{A as APP_STATE_MIGRATIONS,C as CURRENT_APP_STATE_SCHEMA_VERSION,w as CURRENT_WORKSPACE_SCHEMA_VERSION,D as DEFAULT_BRUSH_CONFIG,s as DEFAULT_LINE_TOOL_CONFIG,r as DEFAULT_TEXT_CONFIG,I as IndexedDBSyncProvider,v as KritzelAlignment,p as KritzelAnchorManager,g as KritzelBrushTool,m as KritzelCursorHelper,i as KritzelEraserTool,e as KritzelGroup,c as KritzelImage,j as KritzelImageTool,d as KritzelLine,h as KritzelLineTool,b as KritzelPath,n as KritzelSelectionTool,f as KritzelShape,l as KritzelShapeTool,K as KritzelText,k as KritzelTextTool,q as KritzelThemeManager,o as KritzelWorkspace,S as ShapeType,W as WORKSPACE_EXPORT_VERSION,y as WORKSPACE_MIGRATIONS,u as darkTheme,t as lightTheme,x as runMigrations}from"./p-B99F1MdT.js";import*as E from"yjs";import{WebsocketProvider as z}from"y-websocket";import"y-indexeddb";const _=Math.floor,P=127,R=Number.MAX_SAFE_INTEGER;class H{constructor(){this.cpos=0,this.cbuf=new Uint8Array(100),this.bufs=[]}}const U=()=>new H,O=t=>{const s=new Uint8Array((t=>{let s=t.cpos;for(let e=0;e<t.bufs.length;e++)s+=t.bufs[e].length;return s})(t));let e=0;for(let i=0;i<t.bufs.length;i++){const o=t.bufs[i];s.set(o,e),e+=o.length}return s.set(new Uint8Array(t.cbuf.buffer,0,t.cpos),e),s},$=(t,s)=>{const e=t.cbuf.length;t.cpos===e&&(t.bufs.push(t.cbuf),t.cbuf=new Uint8Array(2*e),t.cpos=0),t.cbuf[t.cpos++]=s},N=(t,s)=>{for(;s>P;)$(t,128|P&s),s=_(s/128);$(t,P&s)},M=(t,s)=>{N(t,s.byteLength),((t,s)=>{const e=t.cbuf.length,i=t.cpos,o=((t,s)=>t<s?t:s)(e-i,s.length),n=s.length-o;t.cbuf.set(s.subarray(0,o),i),t.cpos+=o,n>0&&(t.bufs.push(t.cbuf),t.cbuf=new Uint8Array(((t,s)=>t>s?t:s)(2*e,n)),t.cbuf.set(s.subarray(o)),t.cpos=n)})(t,s)},B=t=>new Error(t),F=B("Unexpected end of array"),L=B("Integer out of Range");class G{constructor(t){this.arr=t,this.pos=0}}const V=t=>((t,s)=>{const e=new Uint8Array(t.arr.buffer,t.pos+t.arr.byteOffset,s);return t.pos+=s,e})(t,X(t)),X=t=>{let s=0,e=1;const i=t.arr.length;for(;t.pos<i;){const i=t.arr[t.pos++];if(s+=(i&P)*e,e*=128,i<128)return s;if(s>R)throw L}throw F};class J{doc;channel;_synced=!1;constructor(t,s,e){this.doc=s,this.channel=new BroadcastChannel(t),this.channel.onmessage=t=>{this.handleMessage(t.data)},this.doc.on("update",this.handleDocUpdate),this.broadcastSync(),setTimeout((()=>{this._synced=!0}),100),e?.quiet||console.info(`BroadcastChannel Provider initialized: ${t}`)}handleDocUpdate=(t,s)=>{if(s!==this){const s=U();N(s,0),M(s,t),this.channel.postMessage(O(s))}};handleMessage(t){const s=(e=new Uint8Array(t),new G(e));var e;switch(X(s)){case 0:const t=V(s);E.applyUpdate(this.doc,t,this);break;case 1:this.broadcastSync();break;case 2:const e=V(s),i=E.encodeStateAsUpdate(this.doc,e);if(i.length>0){const t=U();N(t,0),M(t,i),this.channel.postMessage(O(t))}}}broadcastSync(){const t=U();N(t,2),M(t,E.encodeStateVector(this.doc)),this.channel.postMessage(O(t))}async connect(){if(!this._synced)return new Promise((t=>{const s=()=>{this._synced?t():setTimeout(s,50)};s()}))}disconnect(){}destroy(){this.doc.off("update",this.handleDocUpdate),this.channel.close()}}class Q{provider;isConnected=!1;_quiet=!1;get awareness(){return this.provider.awareness}constructor(t,s,e){const i=e?.url||"ws://localhost:1234",o=e?.roomName||t;this.provider=new z(i,o,s,{params:e?.params,protocols:e?.protocols,WebSocketPolyfill:e?.WebSocketPolyfill,awareness:e?.awareness,maxBackoffTime:e?.maxBackoffTime,disableBc:!0}),this._quiet=e?.quiet??!1,this.setupEventListeners(),this._quiet||console.info(`WebSocket Provider initialized: ${i}/${o}`)}static with(t){return{create:(s,e,i)=>{const o=i?{...t,...i}:t;return new Q(s,e,o)}}}setupEventListeners(){this.provider.on("status",(({status:t})=>{"connected"===t?(this.isConnected=!0,this._quiet||console.info("WebSocket connected")):"disconnected"===t&&(this.isConnected=!1,this._quiet||console.info("WebSocket disconnected"))})),this.provider.on("sync",(t=>{t&&!this._quiet&&console.info("WebSocket synced")}))}async connect(){if(!this.isConnected)return new Promise(((t,s)=>{const e=setTimeout((()=>{s(new Error("WebSocket connection timeout"))}),1e4),i=({status:s})=>{"connected"===s&&(clearTimeout(e),this.provider.off("status",i),this.isConnected=!0,t())};this.provider.on("status",i),this.provider.wsconnected&&(clearTimeout(e),this.provider.off("status",i),this.isConnected=!0,t())}))}disconnect(){this.provider&&this.provider.disconnect(),this.isConnected=!1}destroy(){this.provider&&this.provider.destroy(),this.isConnected=!1}}class Y{provider;isConnected=!1;isSynced=!1;usesSharedSocket=!1;isDestroyed=!1;connectTimeout=null;pendingConnectReject=null;get awareness(){return this.provider.awareness}static sharedWebSocketProvider=null;constructor(t,s,e){const i=e?.name||t,o=e?.url||"ws://localhost:1234",n=e?.websocketProvider||Y.sharedWebSocketProvider;if(n){this.usesSharedSocket=!0;const t={websocketProvider:n,name:i,document:s,token:e?.token||null,onStatus:t=>{e?.onStatus&&e.onStatus(t)},onConnect:()=>{this.isConnected||this.isDestroyed||(this.isConnected=!0,e?.quiet||console.info(`Hocuspocus connected: ${i}`),e?.onConnect&&e.onConnect())},onDisconnect:()=>{this.isDestroyed||!this.isConnected&&!this.isSynced||(this.isConnected=!1,this.isSynced=!1,e?.quiet||console.info(`Hocuspocus disconnected: ${i}`),e?.onDisconnect&&e.onDisconnect())},onSynced:()=>{this.isSynced||this.isDestroyed||(this.isSynced=!0,e?.quiet||console.info(`Hocuspocus synced: ${i}`),e?.onSynced&&e.onSynced())}};void 0!==e?.forceSyncInterval&&(t.forceSyncInterval=e.forceSyncInterval),e?.onAuthenticationFailed&&(t.onAuthenticationFailed=e.onAuthenticationFailed),this.provider=new a(t),this.provider.attach(),e?.quiet||console.info(`Hocuspocus Provider initialized (multiplexed): ${i}`)}else{this.usesSharedSocket=!1;const t={url:o,name:i,document:s,token:e?.token||null,autoConnect:!1,onStatus:t=>{e?.onStatus&&e.onStatus(t)},onConnect:()=>{this.isConnected||this.isDestroyed||(this.isConnected=!0,e?.quiet||console.info(`Hocuspocus connected: ${i}`),e?.onConnect&&e.onConnect())},onDisconnect:()=>{this.isDestroyed||!this.isConnected&&!this.isSynced||(this.isConnected=!1,this.isSynced=!1,e?.quiet||console.info(`Hocuspocus disconnected: ${i}`),e?.onDisconnect&&e.onDisconnect())},onSynced:()=>{this.isSynced||this.isDestroyed||(this.isSynced=!0,e?.quiet||console.info(`Hocuspocus synced: ${i}`),e?.onSynced&&e.onSynced())}};void 0!==e?.forceSyncInterval&&(t.forceSyncInterval=e.forceSyncInterval),e?.onAuthenticationFailed&&(t.onAuthenticationFailed=e.onAuthenticationFailed),e?.WebSocketPolyfill&&(t.WebSocketPolyfill=e.WebSocketPolyfill),this.provider=new a(t),e?.quiet||console.info(`Hocuspocus Provider initialized: ${o}/${i}`)}}static createSharedWebSocket(t){if(Y.sharedWebSocketProvider)return console.warn("Shared WebSocket already exists. Returning existing instance."),Y.sharedWebSocketProvider;const s={url:t.url};return t.WebSocketPolyfill&&(s.WebSocketPolyfill=t.WebSocketPolyfill),t.onConnect&&(s.onConnect=t.onConnect),t.onDisconnect&&(s.onDisconnect=t.onDisconnect),t.onStatus&&(s.onStatus=t.onStatus),Y.sharedWebSocketProvider=new T(s),console.info(`Shared Hocuspocus WebSocket created: ${t.url}`),Y.sharedWebSocketProvider}static destroySharedWebSocket(){Y.sharedWebSocketProvider&&(Y.sharedWebSocketProvider.destroy(),Y.sharedWebSocketProvider=null,console.info("Shared Hocuspocus WebSocket destroyed"))}static getSharedWebSocket(){return Y.sharedWebSocketProvider}static with(t){return{create:(s,e,i)=>{const o=i?{...t,...i}:t;return new Y(s,e,o)}}}async connect(){if(!this.isSynced&&!this.isDestroyed)return new Promise(((t,s)=>{this.pendingConnectReject=s,this.connectTimeout=setTimeout((()=>{this.pendingConnectReject=null,this.connectTimeout=null,s(new Error("Hocuspocus connection timeout"))}),1e4);const e=()=>{this.connectTimeout&&(clearTimeout(this.connectTimeout),this.connectTimeout=null),this.pendingConnectReject=null,this.provider.off("synced",e),this.isDestroyed||t()};if(this.provider.on("synced",e),this.provider.isSynced)return this.connectTimeout&&(clearTimeout(this.connectTimeout),this.connectTimeout=null),this.pendingConnectReject=null,this.provider.off("synced",e),void t();this.isConnected||this.usesSharedSocket||this.provider.connect()}))}disconnect(){this.connectTimeout&&(clearTimeout(this.connectTimeout),this.connectTimeout=null),this.pendingConnectReject&&(this.pendingConnectReject=null),this.provider&&(this.usesSharedSocket?this.provider.detach():this.provider.disconnect()),this.isConnected=!1,this.isSynced=!1}destroy(){this.isDestroyed=!0,this.connectTimeout&&(clearTimeout(this.connectTimeout),this.connectTimeout=null),this.pendingConnectReject&&(this.pendingConnectReject=null),this.provider&&this.provider.destroy(),this.isConnected=!1,this.isSynced=!1}}export{J as BroadcastSyncProvider,Y as HocuspocusSyncProvider,Q as WebSocketSyncProvider}
1
+ import{H as a,a as T}from"./p-D48_Bqvh.js";export{A as APP_STATE_MIGRATIONS,C as CURRENT_APP_STATE_SCHEMA_VERSION,w as CURRENT_WORKSPACE_SCHEMA_VERSION,D as DEFAULT_BRUSH_CONFIG,s as DEFAULT_LINE_TOOL_CONFIG,r as DEFAULT_TEXT_CONFIG,I as IndexedDBSyncProvider,v as KritzelAlignment,p as KritzelAnchorManager,g as KritzelBrushTool,m as KritzelCursorHelper,i as KritzelEraserTool,e as KritzelGroup,c as KritzelImage,j as KritzelImageTool,d as KritzelLine,h as KritzelLineTool,b as KritzelPath,n as KritzelSelectionTool,f as KritzelShape,l as KritzelShapeTool,K as KritzelText,k as KritzelTextTool,q as KritzelThemeManager,o as KritzelWorkspace,S as ShapeType,W as WORKSPACE_EXPORT_VERSION,y as WORKSPACE_MIGRATIONS,u as darkTheme,t as lightTheme,x as runMigrations}from"./p-D48_Bqvh.js";import*as E from"yjs";import{WebsocketProvider as _}from"y-websocket";import"y-indexeddb";const z=Math.floor,P=127,R=Number.MAX_SAFE_INTEGER;class H{constructor(){this.cpos=0,this.cbuf=new Uint8Array(100),this.bufs=[]}}const U=()=>new H,O=t=>{const e=new Uint8Array((t=>{let e=t.cpos;for(let s=0;s<t.bufs.length;s++)e+=t.bufs[s].length;return e})(t));let s=0;for(let i=0;i<t.bufs.length;i++){const n=t.bufs[i];e.set(n,s),s+=n.length}return e.set(new Uint8Array(t.cbuf.buffer,0,t.cpos),s),e},N=(t,e)=>{const s=t.cbuf.length;t.cpos===s&&(t.bufs.push(t.cbuf),t.cbuf=new Uint8Array(2*s),t.cpos=0),t.cbuf[t.cpos++]=e},B=(t,e)=>{for(;e>P;)N(t,128|P&e),e=z(e/128);N(t,P&e)},L=(t,e)=>{B(t,e.byteLength),((t,e)=>{const s=t.cbuf.length,i=t.cpos,n=((t,e)=>t<e?t:e)(s-i,e.length),o=e.length-n;t.cbuf.set(e.subarray(0,n),i),t.cpos+=n,o>0&&(t.bufs.push(t.cbuf),t.cbuf=new Uint8Array(((t,e)=>t>e?t:e)(2*s,o)),t.cbuf.set(e.subarray(n)),t.cpos=o)})(t,e)},M=t=>new Error(t),$=M("Unexpected end of array"),F=M("Integer out of Range");class G{constructor(t){this.arr=t,this.pos=0}}const V=t=>((t,e)=>{const s=new Uint8Array(t.arr.buffer,t.pos+t.arr.byteOffset,e);return t.pos+=e,s})(t,X(t)),X=t=>{let e=0,s=1;const i=t.arr.length;for(;t.pos<i;){const i=t.arr[t.pos++];if(e+=(i&P)*s,s*=128,i<128)return e;if(e>R)throw F}throw $};class J{type="local";doc;channel;_synced=!1;constructor(t,e,s){this.doc=e,this.channel=new BroadcastChannel(t),this.channel.onmessage=t=>{this.handleMessage(t.data)},this.doc.on("update",this.handleDocUpdate),this.broadcastSync(),setTimeout((()=>{this._synced=!0}),100),s?.quiet||console.info(`BroadcastChannel Provider initialized: ${t}`)}handleDocUpdate=(t,e)=>{if(e!==this){const e=U();B(e,0),L(e,t),this.channel.postMessage(O(e))}};handleMessage(t){const e=(s=new Uint8Array(t),new G(s));var s;switch(X(e)){case 0:const t=V(e);E.applyUpdate(this.doc,t,this);break;case 1:this.broadcastSync();break;case 2:const s=V(e),i=E.encodeStateAsUpdate(this.doc,s);if(i.length>0){const t=U();B(t,0),L(t,i),this.channel.postMessage(O(t))}}}broadcastSync(){const t=U();B(t,2),L(t,E.encodeStateVector(this.doc)),this.channel.postMessage(O(t))}async connect(){if(!this._synced)return new Promise((t=>{const e=()=>{this._synced?t():setTimeout(e,50)};e()}))}disconnect(){}async reconnect(){return this.disconnect(),this.connect()}destroy(){this.doc.off("update",this.handleDocUpdate),this.channel.close()}}class Q{type="network";provider;isConnected=!1;_quiet=!1;get awareness(){return this.provider.awareness}constructor(t,e,s){const i=s?.url||"ws://localhost:1234",n=s?.roomName||t;this.provider=new _(i,n,e,{params:s?.params,protocols:s?.protocols,WebSocketPolyfill:s?.WebSocketPolyfill,awareness:s?.awareness,maxBackoffTime:s?.maxBackoffTime,disableBc:!0}),this._quiet=s?.quiet??!1,this.setupEventListeners(),this._quiet||console.info(`WebSocket Provider initialized: ${i}/${n}`)}static with(t){return{create:(e,s,i)=>{const n=i?{...t,...i}:t;return new Q(e,s,n)}}}setupEventListeners(){this.provider.on("status",(({status:t})=>{"connected"===t?(this.isConnected=!0,this._quiet||console.info("WebSocket connected")):"disconnected"===t&&(this.isConnected=!1,this._quiet||console.info("WebSocket disconnected"))})),this.provider.on("sync",(t=>{t&&!this._quiet&&console.info("WebSocket synced")}))}async connect(){if(!this.isConnected)return new Promise(((t,e)=>{const s=setTimeout((()=>{e(new Error("WebSocket connection timeout"))}),1e4),i=({status:e})=>{"connected"===e&&(clearTimeout(s),this.provider.off("status",i),this.isConnected=!0,t())};this.provider.on("status",i),this.provider.wsconnected&&(clearTimeout(s),this.provider.off("status",i),this.isConnected=!0,t())}))}disconnect(){this.provider&&this.provider.disconnect(),this.isConnected=!1}async reconnect(){return this.disconnect(),this.connect()}destroy(){this.provider&&this.provider.destroy(),this.isConnected=!1}}class Y{type="network";provider;isConnected=!1;isSynced=!1;usesSharedSocket=!1;isDestroyed=!1;connectTimeout=null;pendingConnectReject=null;connectionTimeoutMs;_connectionStatus="disconnected";visibilityHandler=null;onlineHandler=null;get awareness(){return this.provider.awareness}get connectionStatus(){return this._connectionStatus}static sharedWebSocketProvider=null;constructor(t,e,s){const i=s?.name||t,n=s?.url||"ws://localhost:1234";this.connectionTimeoutMs=s?.connectionTimeout??1e4;const o=s?.websocketProvider||Y.sharedWebSocketProvider,c={};void 0!==s?.delay&&(c.delay=s.delay),void 0!==s?.factor&&(c.factor=s.factor),void 0!==s?.maxAttempts&&(c.maxAttempts=s.maxAttempts),void 0!==s?.minDelay&&(c.minDelay=s.minDelay),void 0!==s?.maxDelay&&(c.maxDelay=s.maxDelay);const r=()=>{this.isDestroyed||(this.isConnected=!0,this._connectionStatus="connected",s?.quiet||console.info(`Hocuspocus connected: ${i}`),s?.onConnect&&s.onConnect())},h=()=>{this.isDestroyed||(this.isConnected=!1,this.isSynced=!1,this._connectionStatus="disconnected",s?.quiet||console.info(`Hocuspocus disconnected: ${i}`),s?.onDisconnect&&s.onDisconnect())},l=()=>{this.isDestroyed||(this.isSynced=!0,this._connectionStatus="synced",s?.quiet||console.info(`Hocuspocus synced: ${i}`),s?.onSynced&&s.onSynced())},u=t=>{this.isDestroyed||("connecting"===t.status&&(this._connectionStatus="connecting"),s?.onStatus&&s.onStatus(t))};if(o){this.usesSharedSocket=!0;const t={websocketProvider:o,name:i,document:e,token:s?.token||null,onStatus:u,onConnect:r,onDisconnect:h,onSynced:l,...c};void 0!==s?.forceSyncInterval&&(t.forceSyncInterval=s.forceSyncInterval),s?.onAuthenticationFailed&&(t.onAuthenticationFailed=s.onAuthenticationFailed),this.provider=new a(t),this.provider.attach(),s?.quiet||console.info(`Hocuspocus Provider initialized (multiplexed): ${i}`)}else{this.usesSharedSocket=!1;const t={url:n,name:i,document:e,token:s?.token||null,autoConnect:!1,onStatus:u,onConnect:r,onDisconnect:h,onSynced:l,...c};void 0!==s?.forceSyncInterval&&(t.forceSyncInterval=s.forceSyncInterval),s?.onAuthenticationFailed&&(t.onAuthenticationFailed=s.onAuthenticationFailed),s?.WebSocketPolyfill&&(t.WebSocketPolyfill=s.WebSocketPolyfill),this.provider=new a(t),s?.quiet||console.info(`Hocuspocus Provider initialized: ${n}/${i}`)}this.setupBrowserEventListeners()}setupBrowserEventListeners(){"undefined"!=typeof document&&(this.visibilityHandler=()=>{"visible"!==document.visibilityState||this.isConnected||this.isDestroyed||this.provider.connect()},document.addEventListener("visibilitychange",this.visibilityHandler)),"undefined"!=typeof window&&(this.onlineHandler=()=>{this.isConnected||this.isDestroyed||this.provider.connect()},window.addEventListener("online",this.onlineHandler))}removeBrowserEventListeners(){this.visibilityHandler&&"undefined"!=typeof document&&(document.removeEventListener("visibilitychange",this.visibilityHandler),this.visibilityHandler=null),this.onlineHandler&&"undefined"!=typeof window&&(window.removeEventListener("online",this.onlineHandler),this.onlineHandler=null)}static createSharedWebSocket(t){if(Y.sharedWebSocketProvider)return console.warn("Shared WebSocket already exists. Returning existing instance."),Y.sharedWebSocketProvider;const e={url:t.url};return t.WebSocketPolyfill&&(e.WebSocketPolyfill=t.WebSocketPolyfill),t.onConnect&&(e.onConnect=t.onConnect),t.onDisconnect&&(e.onDisconnect=t.onDisconnect),t.onStatus&&(e.onStatus=t.onStatus),Y.sharedWebSocketProvider=new T(e),console.info(`Shared Hocuspocus WebSocket created: ${t.url}`),Y.sharedWebSocketProvider}static destroySharedWebSocket(){Y.sharedWebSocketProvider&&(Y.sharedWebSocketProvider.destroy(),Y.sharedWebSocketProvider=null,console.info("Shared Hocuspocus WebSocket destroyed"))}static getSharedWebSocket(){return Y.sharedWebSocketProvider}static with(t){return{create:(e,s,i)=>{const n=i?{...t,...i}:t;return new Y(e,s,n)}}}async connect(){if(!this.isSynced&&!this.isDestroyed)return this._connectionStatus="connecting",new Promise(((t,e)=>{this.pendingConnectReject=e,this.connectTimeout=setTimeout((()=>{this.pendingConnectReject=null,this.connectTimeout=null,e(new Error("Hocuspocus connection timeout"))}),this.connectionTimeoutMs);const s=()=>{this.connectTimeout&&(clearTimeout(this.connectTimeout),this.connectTimeout=null),this.pendingConnectReject=null,this.provider.off("synced",s),this.isDestroyed||t()};if(this.provider.on("synced",s),this.provider.isSynced)return this.connectTimeout&&(clearTimeout(this.connectTimeout),this.connectTimeout=null),this.pendingConnectReject=null,this.provider.off("synced",s),void t();this.isConnected||this.usesSharedSocket||this.provider.connect()}))}async reconnect(){return this.disconnect(),this.connect()}disconnect(){this.connectTimeout&&(clearTimeout(this.connectTimeout),this.connectTimeout=null),this.pendingConnectReject&&(this.pendingConnectReject=null),this.provider&&(this.usesSharedSocket?this.provider.detach():this.provider.disconnect()),this.isConnected=!1,this.isSynced=!1,this._connectionStatus="disconnected"}destroy(){this.isDestroyed=!0,this.connectTimeout&&(clearTimeout(this.connectTimeout),this.connectTimeout=null),this.pendingConnectReject&&(this.pendingConnectReject=null),this.removeBrowserEventListeners(),this.provider&&this.provider.destroy(),this.isConnected=!1,this.isSynced=!1,this._connectionStatus="disconnected"}}export{J as BroadcastSyncProvider,Y as HocuspocusSyncProvider,Q as WebSocketSyncProvider}