@canvas-harness/core 0.0.5 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -1495,14 +1495,21 @@ interface CanvasStore {
1495
1495
  * Adds a node. Returns its id. If `node.style.autoFit !== false` and
1496
1496
  * `node.content` is set, height is grown to fit.
1497
1497
  *
1498
+ * `z` is optional — omit to land on top of the current stack (uses
1499
+ * the internal `topZ` counter). Pass a literal value (incl. `0` or
1500
+ * negative) to place the node at that exact z.
1501
+ *
1498
1502
  * @example
1503
+ * // Omit z → goes on top of the current stack.
1499
1504
  * const id = store.addNode({
1500
1505
  * id: asNodeId(store.generateId()),
1501
1506
  * type: 'rect', x: 0, y: 0, w: 200, h: 100,
1502
- * angle: 0, z: 0, groups: [],
1507
+ * angle: 0, groups: [],
1503
1508
  * })
1504
1509
  */
1505
- addNode(node: Node): NodeId;
1510
+ addNode(node: Omit<Node, 'z'> & {
1511
+ z?: number;
1512
+ }): NodeId;
1506
1513
  /**
1507
1514
  * Patches fields on an existing node. Captures the previous slice on
1508
1515
  * the op so undo is free. Autofit re-runs when `content` or font
@@ -1566,8 +1573,13 @@ interface CanvasStore {
1566
1573
  alt?: string;
1567
1574
  style?: Style;
1568
1575
  }): Promise<NodeId>;
1569
- /** Adds an edge. Returns its id. */
1570
- addEdge(edge: Edge): EdgeId;
1576
+ /**
1577
+ * Adds an edge. Returns its id. `z` is optional — same auto-top
1578
+ * semantics as {@link CanvasStore.addNode}.
1579
+ */
1580
+ addEdge(edge: Omit<Edge, 'z'> & {
1581
+ z?: number;
1582
+ }): EdgeId;
1571
1583
  /** Patches fields on an existing edge. */
1572
1584
  updateEdge(id: EdgeId, patch: Partial<Edge>): void;
1573
1585
  /** Removes an edge. */
package/dist/index.d.ts CHANGED
@@ -1495,14 +1495,21 @@ interface CanvasStore {
1495
1495
  * Adds a node. Returns its id. If `node.style.autoFit !== false` and
1496
1496
  * `node.content` is set, height is grown to fit.
1497
1497
  *
1498
+ * `z` is optional — omit to land on top of the current stack (uses
1499
+ * the internal `topZ` counter). Pass a literal value (incl. `0` or
1500
+ * negative) to place the node at that exact z.
1501
+ *
1498
1502
  * @example
1503
+ * // Omit z → goes on top of the current stack.
1499
1504
  * const id = store.addNode({
1500
1505
  * id: asNodeId(store.generateId()),
1501
1506
  * type: 'rect', x: 0, y: 0, w: 200, h: 100,
1502
- * angle: 0, z: 0, groups: [],
1507
+ * angle: 0, groups: [],
1503
1508
  * })
1504
1509
  */
1505
- addNode(node: Node): NodeId;
1510
+ addNode(node: Omit<Node, 'z'> & {
1511
+ z?: number;
1512
+ }): NodeId;
1506
1513
  /**
1507
1514
  * Patches fields on an existing node. Captures the previous slice on
1508
1515
  * the op so undo is free. Autofit re-runs when `content` or font
@@ -1566,8 +1573,13 @@ interface CanvasStore {
1566
1573
  alt?: string;
1567
1574
  style?: Style;
1568
1575
  }): Promise<NodeId>;
1569
- /** Adds an edge. Returns its id. */
1570
- addEdge(edge: Edge): EdgeId;
1576
+ /**
1577
+ * Adds an edge. Returns its id. `z` is optional — same auto-top
1578
+ * semantics as {@link CanvasStore.addNode}.
1579
+ */
1580
+ addEdge(edge: Omit<Edge, 'z'> & {
1581
+ z?: number;
1582
+ }): EdgeId;
1571
1583
  /** Patches fields on an existing edge. */
1572
1584
  updateEdge(id: EdgeId, patch: Partial<Edge>): void;
1573
1585
  /** Removes an edge. */
package/dist/index.js CHANGED
@@ -3242,8 +3242,15 @@ var createCanvasStore = (opts = {}) => {
3242
3242
  };
3243
3243
  const incidentEdges = /* @__PURE__ */ new Map();
3244
3244
  let topZ = 0;
3245
- for (const n of Object.values(initial.nodes)) if (n.z > topZ) topZ = n.z;
3246
- for (const e of Object.values(initial.edges)) if (e.z > topZ) topZ = e.z;
3245
+ let bottomZ = 0;
3246
+ for (const n of Object.values(initial.nodes)) {
3247
+ if (n.z > topZ) topZ = n.z;
3248
+ if (n.z < bottomZ) bottomZ = n.z;
3249
+ }
3250
+ for (const e of Object.values(initial.edges)) {
3251
+ if (e.z > topZ) topZ = e.z;
3252
+ if (e.z < bottomZ) bottomZ = e.z;
3253
+ }
3247
3254
  const getNodeForGeo = (id) => nodeAtoms.get(id)?.value;
3248
3255
  let currentBatchOps = null;
3249
3256
  let batchDepth = 0;
@@ -3332,6 +3339,8 @@ var createCanvasStore = (opts = {}) => {
3332
3339
  nodeAtoms.set(op.node.id, a);
3333
3340
  nodeIdsAtom.update((ids) => [...ids, op.node.id]);
3334
3341
  reindexNode(op.node);
3342
+ if (op.node.z > topZ) topZ = op.node.z;
3343
+ if (op.node.z < bottomZ) bottomZ = op.node.z;
3335
3344
  if (op.node.type === "frame") {
3336
3345
  frameOrderAtom.update((ids) => ids.includes(op.node.id) ? ids : [...ids, op.node.id]);
3337
3346
  }
@@ -3343,6 +3352,10 @@ var createCanvasStore = (opts = {}) => {
3343
3352
  const next = { ...a.value, ...op.patch };
3344
3353
  a.set(next);
3345
3354
  reindexNode(next);
3355
+ if (op.patch.z !== void 0) {
3356
+ if (op.patch.z > topZ) topZ = op.patch.z;
3357
+ if (op.patch.z < bottomZ) bottomZ = op.patch.z;
3358
+ }
3346
3359
  const incident = incidentEdges.get(op.id);
3347
3360
  if (incident) {
3348
3361
  for (const eid of incident) {
@@ -3371,6 +3384,8 @@ var createCanvasStore = (opts = {}) => {
3371
3384
  trackIncidence(op.edge);
3372
3385
  bumpEdgeVersion(op.edge.id);
3373
3386
  reindexEdge(op.edge);
3387
+ if (op.edge.z > topZ) topZ = op.edge.z;
3388
+ if (op.edge.z < bottomZ) bottomZ = op.edge.z;
3374
3389
  break;
3375
3390
  }
3376
3391
  case "edge.update": {
@@ -3383,6 +3398,10 @@ var createCanvasStore = (opts = {}) => {
3383
3398
  a.set(next);
3384
3399
  bumpEdgeVersion(op.id);
3385
3400
  reindexEdge(next);
3401
+ if (op.patch.z !== void 0) {
3402
+ if (op.patch.z > topZ) topZ = op.patch.z;
3403
+ if (op.patch.z < bottomZ) bottomZ = op.patch.z;
3404
+ }
3386
3405
  break;
3387
3406
  }
3388
3407
  case "edge.remove": {
@@ -3470,9 +3489,8 @@ var createCanvasStore = (opts = {}) => {
3470
3489
  clientId,
3471
3490
  generateId: () => idGenerator(),
3472
3491
  addNode(node) {
3473
- const withZ = node.z === 0 ? { ...node, z: ++topZ } : node;
3474
- if (withZ.z > topZ) topZ = withZ.z;
3475
- const fitted = withAutoFitHeight(withZ);
3492
+ const z = node.z ?? ++topZ;
3493
+ const fitted = withAutoFitHeight({ ...node, z });
3476
3494
  enqueueOp({ type: "node.add", node: fitted });
3477
3495
  return fitted.id;
3478
3496
  },
@@ -3535,7 +3553,6 @@ var createCanvasStore = (opts = {}) => {
3535
3553
  w,
3536
3554
  h,
3537
3555
  angle: 0,
3538
- z: 0,
3539
3556
  groups: [],
3540
3557
  style: opts2.style,
3541
3558
  data: { src, naturalW, naturalH, alt: opts2.alt }
@@ -3558,7 +3575,6 @@ var createCanvasStore = (opts = {}) => {
3558
3575
  w,
3559
3576
  h,
3560
3577
  angle: 0,
3561
- z: 0,
3562
3578
  groups: [],
3563
3579
  ...mergedStyle ? { style: mergedStyle } : {},
3564
3580
  data: { src: sanitized, alt: opts2.alt }
@@ -3566,8 +3582,8 @@ var createCanvasStore = (opts = {}) => {
3566
3582
  return id;
3567
3583
  },
3568
3584
  addEdge(edge) {
3569
- const withZ = edge.z === 0 ? { ...edge, z: ++topZ } : edge;
3570
- if (withZ.z > topZ) topZ = withZ.z;
3585
+ const z = edge.z ?? ++topZ;
3586
+ const withZ = { ...edge, z };
3571
3587
  enqueueOp({ type: "edge.add", edge: withZ });
3572
3588
  return withZ.id;
3573
3589
  },
@@ -3590,29 +3606,10 @@ var createCanvasStore = (opts = {}) => {
3590
3606
  });
3591
3607
  },
3592
3608
  sendToBack(ids) {
3593
- const targets = new Set(ids);
3594
- let minZ = 0;
3595
- let initialized = false;
3596
- for (const a of nodeAtoms.values()) {
3597
- if (targets.has(a.value.id)) continue;
3598
- if (!initialized || a.value.z < minZ) {
3599
- minZ = a.value.z;
3600
- initialized = true;
3601
- }
3602
- }
3603
- for (const a of edgeAtoms.values()) {
3604
- if (targets.has(a.value.id)) continue;
3605
- if (!initialized || a.value.z < minZ) {
3606
- minZ = a.value.z;
3607
- initialized = true;
3608
- }
3609
- }
3610
3609
  this.batch(() => {
3611
- let next = (initialized ? minZ : 0) - 1;
3612
3610
  for (const id of ids) {
3613
- if (nodeAtoms.has(id)) this.updateNode(id, { z: next });
3614
- else if (edgeAtoms.has(id)) this.updateEdge(id, { z: next });
3615
- next -= 1;
3611
+ if (nodeAtoms.has(id)) this.updateNode(id, { z: --bottomZ });
3612
+ else if (edgeAtoms.has(id)) this.updateEdge(id, { z: --bottomZ });
3616
3613
  }
3617
3614
  });
3618
3615
  },
@@ -3630,7 +3627,6 @@ var createCanvasStore = (opts = {}) => {
3630
3627
  if (currentZ === void 0) continue;
3631
3628
  const idx = binaryFirstGreater(allZ, currentZ);
3632
3629
  const nextZ = idx >= 0 ? allZ[idx] + 1 : currentZ + 1;
3633
- if (nextZ > topZ) topZ = nextZ;
3634
3630
  if (node) this.updateNode(id, { z: nextZ });
3635
3631
  else this.updateEdge(id, { z: nextZ });
3636
3632
  }
@@ -4291,7 +4287,7 @@ var paintBackground = (ctx, opts) => {
4291
4287
  }
4292
4288
  };
4293
4289
  var paintDots = (ctx, minX, minY, maxX, maxY, gap, color, zoom) => {
4294
- const sizeWorld = Math.max(1, 2.4 / zoom);
4290
+ const sizeWorld = Math.max(1, 1.6 / zoom);
4295
4291
  const half = sizeWorld / 2;
4296
4292
  ctx.save();
4297
4293
  ctx.fillStyle = color;