@scrawl-board/board 0.1.0-beta.6 → 0.1.0-beta.8

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/core.d.ts CHANGED
@@ -181,6 +181,21 @@ interface CustomObjectDefinition<Props extends JsonValue = JsonValue> {
181
181
  /** One pure, synchronous step per consecutive schema version. */
182
182
  migrate?: Readonly<Record<number, (oldProps: JsonValue) => JsonValue>>;
183
183
  describe(object: ReadonlyCustomObject<Props>, context: ObjectDescribeContext): BoardScene;
184
+ /**
185
+ * Optional point-level hit-test precision (Phase 8). Every custom object
186
+ * hit-tests against its bounding box (`fallback.bounds`) by default — this
187
+ * lets a non-rectangular shape (e.g. a circular card, an L-shaped region)
188
+ * reject a point that's inside that box but outside its actual visible
189
+ * silhouette, tightening a click/marquee/raycast hit to the shape's real
190
+ * outline. `point` is in this object's own local space — the same
191
+ * untransformed space `describe`'s returned geometry already lives in
192
+ * (the caller inverse-transforms the pointer's board point through
193
+ * `object.transform` before calling this). Absent means every point
194
+ * inside the bounding box hits, matching pre-Phase-8 behavior exactly.
195
+ * Rejecting a point here does not fall through to whatever's underneath —
196
+ * the gesture simply misses this object, same as clicking empty space.
197
+ */
198
+ hitTest?(object: ReadonlyCustomObject<Props>, point: BoardPoint): boolean;
184
199
  }
185
200
  interface SceneNodeBase {
186
201
  key: string;
@@ -214,6 +229,15 @@ interface SceneGroup extends SceneNodeBase {
214
229
  kind: "group";
215
230
  children: readonly BoardScene[];
216
231
  }
232
+ /**
233
+ * **No renderer or SVG-export interpreter exists for this node kind yet**
234
+ * (tracked as deferred work — see `renderer/shapes/customObjects.ts`'s
235
+ * `"path"` case). Returning a `ScenePath` from `describe()` renders nothing,
236
+ * exports nothing, and contributes no hit-test bounds — it neither errors
237
+ * nor emits a diagnostic. Until an interpreter ships, build custom shapes
238
+ * from `SceneRect`/`SceneEllipse`/`SceneGroup`/`SceneText`/`SceneImage`
239
+ * instead.
240
+ */
217
241
  interface ScenePath extends SceneNodeBase {
218
242
  kind: "path";
219
243
  /** SVG-style path data, board-local coordinates. */
@@ -386,8 +410,23 @@ declare function canUnlockItem(item: Lockable | undefined, userId: string | unde
386
410
  /** Wire fields for a locked item; omitted entirely when unlocked. */
387
411
  declare function serializeLock(item: Lockable): Lockable;
388
412
 
413
+ /**
414
+ * Per-object visibility (Phase 8) — mirrors `itemLock.ts`'s `Lockable`
415
+ * pattern exactly, but simpler: unlike a lock, hidden state carries no
416
+ * holder/ownership concept, so there's no analogue to `LockHolder`/
417
+ * `canUnlockItem`. A hidden object stays fully present in the Document
418
+ * (still serializes, persists, syncs, undoes/redoes) — it just skips
419
+ * rendering and hit-testing/selection candidacy. `hidden` absent or
420
+ * `false` means visible; this keeps every pre-Phase-8 document (which has
421
+ * no `hidden` field on any object at all) implicitly fully visible with
422
+ * zero migration needed.
423
+ */
424
+ interface Hideable {
425
+ hidden?: boolean;
426
+ }
427
+
389
428
  /** A kitchen timer sitting on the board. Remaining time is derived, not ticked. */
390
- interface KitchenTimer extends Lockable {
429
+ interface KitchenTimer extends Lockable, Hideable {
391
430
  id: string;
392
431
  x: number;
393
432
  y: number;
@@ -412,6 +451,160 @@ declare function toggleTimer(timer: KitchenTimer, now: number): KitchenTimer;
412
451
  declare function setTimerDuration(timer: KitchenTimer, durationMs: number): KitchenTimer;
413
452
  declare function formatTimer(ms: number): string;
414
453
 
454
+ declare const SHAPE_MIN_SIZE = 0.5;
455
+ /**
456
+ * Centralized shape style defaults (Phase 8) — one object a Host can read
457
+ * to know (or, by not relying on the standalone constants below, override
458
+ * via its own UI state) what a newly drawn Rectangle/Ellipse/Line/Arrow/
459
+ * Polygon/Star/Heart starts with when the user hasn't picked a stroke/width
460
+ * yet. `shapeTool.ts` (commit-time), `renderer/shapes/lines.ts` (render-time
461
+ * fallback for an object missing these fields), and
462
+ * `persistence/serialization/svg.ts` (export-time fallback) all read from
463
+ * here — the two standalone constants below are kept for source
464
+ * compatibility and simply mirror this object's values, not a second
465
+ * source of truth.
466
+ */
467
+ declare const SHAPE_STYLE_DEFAULTS: {
468
+ readonly stroke: "#1C1C1E";
469
+ readonly strokeWidth: 0.12;
470
+ };
471
+ declare const SHAPE_DEFAULT_STROKE: "#1C1C1E";
472
+ declare const SHAPE_DEFAULT_STROKE_WIDTH: 0.12;
473
+ interface RectangleObject extends Lockable, Hideable {
474
+ id: string;
475
+ x: number;
476
+ y: number;
477
+ width: number;
478
+ height: number;
479
+ fill?: string;
480
+ stroke?: string;
481
+ strokeWidth?: number;
482
+ /** Corner radius in board units; clamped to at most half the shorter side at render time. */
483
+ cornerRadius?: number;
484
+ /** `[0, 1]`; undefined means fully opaque (Phase 4). */
485
+ opacity?: number;
486
+ /**
487
+ * Radians, about the shape's own center `(x + width/2, y - height/2)`.
488
+ * Undefined means 0 (Phase 3). `x`/`y`/`width`/`height` stay in the
489
+ * shape's own unrotated local frame — rotation is a separate, applied-last
490
+ * transform, not baked into them, matching how Stroke/CustomBoardObject
491
+ * keep geometry and placement independent via their own `matrix`.
492
+ */
493
+ rotation?: number;
494
+ }
495
+ interface EllipseObject extends Lockable, Hideable {
496
+ id: string;
497
+ x: number;
498
+ y: number;
499
+ width: number;
500
+ height: number;
501
+ fill?: string;
502
+ stroke?: string;
503
+ strokeWidth?: number;
504
+ /** `[0, 1]`; undefined means fully opaque (Phase 4). */
505
+ opacity?: number;
506
+ /** Radians, about the shape's own center — see RectangleObject's `rotation` doc. */
507
+ rotation?: number;
508
+ }
509
+ declare function cloneRectangle(rect: RectangleObject): RectangleObject;
510
+ declare function cloneEllipse(ellipse: EllipseObject): EllipseObject;
511
+ /** `"none"` is a plain line with no arrowhead; today's only real head shape is `"triangle"`. New head shapes extend this union without touching `ArrowObject`'s own fields. */
512
+ type ArrowHeadStyle = "triangle" | "none";
513
+ interface LineObject extends Lockable, Hideable {
514
+ id: string;
515
+ start: BoardPoint;
516
+ end: BoardPoint;
517
+ stroke?: string;
518
+ strokeWidth?: number;
519
+ opacity?: number;
520
+ }
521
+ interface ArrowObject extends Lockable, Hideable {
522
+ id: string;
523
+ start: BoardPoint;
524
+ end: BoardPoint;
525
+ head?: ArrowHeadStyle;
526
+ stroke?: string;
527
+ strokeWidth?: number;
528
+ opacity?: number;
529
+ }
530
+ /**
531
+ * Triangle(3)/Diamond(4)/Pentagon(5)/Hexagon(6)/Octagon(8) as one shared
532
+ * type instead of five near-duplicate interfaces — a regular N-gon
533
+ * inscribed in the same `x`/`y`/`width`/`height`/`rotation` bounding box
534
+ * Rectangle already uses, parameterized by `sides`. Diamond is exactly a
535
+ * 4-sided regular polygon with vertex 0 pointing right (not up, like
536
+ * Triangle/Pentagon/Hexagon) — see `polygonGeometry.ts`'s
537
+ * `polygonStartAngle`, which encodes each side count's own vertex
538
+ * orientation so the outline always matches the legacy drag-preview shape.
539
+ */
540
+ interface PolygonObject extends Lockable, Hideable {
541
+ id: string;
542
+ x: number;
543
+ y: number;
544
+ width: number;
545
+ height: number;
546
+ sides: 3 | 4 | 5 | 6 | 8;
547
+ fill?: string;
548
+ stroke?: string;
549
+ strokeWidth?: number;
550
+ opacity?: number;
551
+ /** Radians, about the shape's own center — see RectangleObject's `rotation` doc. */
552
+ rotation?: number;
553
+ }
554
+ declare function clonePolygon(polygon: PolygonObject): PolygonObject;
555
+ /** Same bounding-box/rotation convention as Rectangle; a 5-pointed star with a tuned inner-radius ratio, matching the legacy tool's own default (see `polygonGeometry.ts`'s `starPoints`). */
556
+ interface StarObject extends Lockable, Hideable {
557
+ id: string;
558
+ x: number;
559
+ y: number;
560
+ width: number;
561
+ height: number;
562
+ /** Vertex count; today's only shipped preset is 5, matching the legacy tool. */
563
+ points: number;
564
+ /** `(0, 1)` — inner vertex radius as a fraction of the outer radius. */
565
+ innerRadiusRatio: number;
566
+ fill?: string;
567
+ stroke?: string;
568
+ strokeWidth?: number;
569
+ opacity?: number;
570
+ rotation?: number;
571
+ }
572
+ declare function cloneStar(star: StarObject): StarObject;
573
+ /** Same bounding-box/rotation convention as Rectangle; the standard parametric heart curve (see `polygonGeometry.ts`'s `heartPoints`), no extra parameters beyond the shared shape fields. */
574
+ interface HeartObject extends Lockable, Hideable {
575
+ id: string;
576
+ x: number;
577
+ y: number;
578
+ width: number;
579
+ height: number;
580
+ fill?: string;
581
+ stroke?: string;
582
+ strokeWidth?: number;
583
+ opacity?: number;
584
+ rotation?: number;
585
+ }
586
+ declare function cloneHeart(heart: HeartObject): HeartObject;
587
+ declare function cloneLine(line: LineObject): LineObject;
588
+ declare function cloneArrow(arrow: ArrowObject): ArrowObject;
589
+ /**
590
+ * A logical grouping of other board objects (Phase 3 — Selection,
591
+ * Transformation & Grouping). Deliberately has no `x`/`y`/`transform` of its
592
+ * own — a group's bounds are always derived on demand from its (recursively
593
+ * resolved) children, and "moving/rotating/scaling the group" is exactly a
594
+ * multi-object transform applied to those children, nothing more. A group
595
+ * has no renderer/mesh of its own; its only visual presence is the
596
+ * selection gizmo's bounding box while it's the current selection.
597
+ *
598
+ * `children` may itself contain other group ids (nested groups) — expanding
599
+ * a group into its leaf members is always done by the caller (recursively,
600
+ * with cycle protection), never assumed here.
601
+ */
602
+ interface GroupObject extends Lockable, Hideable {
603
+ id: string;
604
+ children: string[];
605
+ }
606
+ declare function cloneGroup(group: GroupObject): GroupObject;
607
+
415
608
  interface BoardPoint {
416
609
  x: number;
417
610
  y: number;
@@ -432,7 +625,7 @@ interface StrokePoint extends BoardPoint {
432
625
  * geometric outline, not an expressive ink mark.
433
626
  */
434
627
  type StrokeTool = "marker" | "highlighter" | "shape";
435
- interface Stroke extends Lockable {
628
+ interface Stroke extends Lockable, Hideable {
436
629
  id: string;
437
630
  color: string;
438
631
  baseWidth: number;
@@ -451,7 +644,7 @@ interface Stroke extends Lockable {
451
644
  declare const ERASE_THRESHOLD = 0.95;
452
645
  declare function cloneStroke(stroke: Stroke): Stroke;
453
646
  type SerializedPoint = [number, number, number, number];
454
- interface SerializedStroke extends Lockable {
647
+ interface SerializedStroke extends Lockable, Hideable {
455
648
  id: string;
456
649
  color: string;
457
650
  baseWidth: number;
@@ -477,6 +670,31 @@ interface SerializedDocument {
477
670
  timers?: KitchenTimer[];
478
671
  /** Absent in documents saved before Custom board objects existed (ticket #22). */
479
672
  customObjects?: CustomBoardObject[];
673
+ /** Absent in documents saved before semantic Rectangle objects existed (Phase 2). */
674
+ rectangles?: RectangleObject[];
675
+ /** Absent in documents saved before semantic Ellipse objects existed (Phase 2). */
676
+ ellipses?: EllipseObject[];
677
+ /** Absent in documents saved before Groups existed (Phase 3). */
678
+ groups?: GroupObject[];
679
+ /** Absent in documents saved before semantic Line objects existed (Phase 4). */
680
+ lines?: LineObject[];
681
+ /** Absent in documents saved before semantic Arrow objects existed (Phase 4). */
682
+ arrows?: ArrowObject[];
683
+ /** Absent in documents saved before semantic Polygon objects existed (Phase 4). */
684
+ polygons?: PolygonObject[];
685
+ /** Absent in documents saved before semantic Star objects existed (Phase 4). */
686
+ stars?: StarObject[];
687
+ /** Absent in documents saved before semantic Heart objects existed (Phase 4). */
688
+ hearts?: HeartObject[];
689
+ /**
690
+ * Every content-object id (every type above except comments, which are
691
+ * host-synced and never enter this schema) in paint order, back to front.
692
+ * Absent in documents saved before per-object z-order existed (Phase 3) —
693
+ * migration synthesizes a default order preserving the old fixed-Z-band
694
+ * visual stacking exactly, so an existing document never visibly changes
695
+ * on load; only an explicit reorder action touches this from then on.
696
+ */
697
+ objectOrder?: string[];
480
698
  }
481
699
  declare const INK_COLORS: {
482
700
  readonly black: "#1C1C1E";
@@ -520,7 +738,7 @@ interface NoteVote {
520
738
  * A sticky note: content floating above the board at a z-offset (pillar 3 —
521
739
  * depth as an organizational axis). Center position in board space.
522
740
  */
523
- interface StickyNote extends Lockable {
741
+ interface StickyNote extends Lockable, Hideable {
524
742
  id: string;
525
743
  x: number;
526
744
  y: number;
@@ -538,7 +756,7 @@ interface StickyNote extends Lockable {
538
756
  * top-left corner; lines flow downward (-y). Text joins the clustering
539
757
  * system like handwriting (build prompt §6.4).
540
758
  */
541
- interface TextBlock extends Lockable {
759
+ interface TextBlock extends Lockable, Hideable {
542
760
  id: string;
543
761
  x: number;
544
762
  y: number;
@@ -568,7 +786,7 @@ declare function cloneNote(note: StickyNote): StickyNote;
568
786
  * Interactive structured table on the board. Position (x, y) is top-left in board units.
569
787
  * Cells are indexed as `${row},${col}` keys mapping to cell text content.
570
788
  */
571
- interface TableBlock extends Lockable {
789
+ interface TableBlock extends Lockable, Hideable {
572
790
  id: string;
573
791
  x: number;
574
792
  y: number;
@@ -594,7 +812,7 @@ declare const FOG_COLOR = "#FFFFFF";
594
812
  * An imported image block on the board plane.
595
813
  * Coordinates (x, y) represent the center of the image in board space.
596
814
  */
597
- interface ImageBlock extends Lockable {
815
+ interface ImageBlock extends Lockable, Hideable {
598
816
  id: string;
599
817
  /**
600
818
  * A legacy, read-only data URL (or, historically, an arbitrary string) —
@@ -644,6 +862,15 @@ type DocumentLoadResult = {
644
862
  declare function loadDocumentBytes(originalBytes: string): DocumentLoadResult;
645
863
  declare function migrateDocument(raw: unknown): DocumentLoadResult;
646
864
  declare function serializeDocument(document: unknown): string;
865
+ /**
866
+ * A Document's serialized size in bytes (Phase 5) — UTF-8, not UTF-16
867
+ * `string.length`, since a Document with non-ASCII note/text content (most
868
+ * of them, eventually) would otherwise under-report. Useful for a Host
869
+ * deciding when to warn about an unusually large board, or for logging/
870
+ * telemetry around save size — not consulted by anything inside this
871
+ * package itself, which has no size limit of its own.
872
+ */
873
+ declare function documentSize(document: CurrentSerializedDocument): number;
647
874
 
648
875
  interface SearchableComment {
649
876
  id: string;
@@ -728,6 +955,60 @@ interface DocumentChange {
728
955
  /** Ids of removed custom objects. */
729
956
  customObjectsRemoved: string[];
730
957
  customObjectsUpdated: CustomBoardObject[];
958
+ /** Semantic Rectangle objects (Phase 2). */
959
+ rectanglesAdded: RectangleObject[];
960
+ /** Ids of removed rectangles. */
961
+ rectanglesRemoved: string[];
962
+ rectanglesUpdated: RectangleObject[];
963
+ /** Semantic Ellipse objects (Phase 2). */
964
+ ellipsesAdded: EllipseObject[];
965
+ /** Ids of removed ellipses. */
966
+ ellipsesRemoved: string[];
967
+ ellipsesUpdated: EllipseObject[];
968
+ /** Groups (Phase 3). */
969
+ groupsAdded: GroupObject[];
970
+ /** Ids of removed groups (ungrouping, or deleting a group). */
971
+ groupsRemoved: string[];
972
+ groupsUpdated: GroupObject[];
973
+ /** Semantic Line objects (Phase 4). */
974
+ linesAdded: LineObject[];
975
+ /** Ids of removed lines. */
976
+ linesRemoved: string[];
977
+ linesUpdated: LineObject[];
978
+ /** Semantic Arrow objects (Phase 4). */
979
+ arrowsAdded: ArrowObject[];
980
+ /** Ids of removed arrows. */
981
+ arrowsRemoved: string[];
982
+ arrowsUpdated: ArrowObject[];
983
+ /** Semantic Polygon objects (Phase 4) — Triangle/Diamond/Pentagon/Hexagon/Octagon. */
984
+ polygonsAdded: PolygonObject[];
985
+ /** Ids of removed polygons. */
986
+ polygonsRemoved: string[];
987
+ polygonsUpdated: PolygonObject[];
988
+ /** Semantic Star objects (Phase 4). */
989
+ starsAdded: StarObject[];
990
+ /** Ids of removed stars. */
991
+ starsRemoved: string[];
992
+ starsUpdated: StarObject[];
993
+ /** Semantic Heart objects (Phase 4). */
994
+ heartsAdded: HeartObject[];
995
+ /** Ids of removed hearts. */
996
+ heartsRemoved: string[];
997
+ heartsUpdated: HeartObject[];
998
+ /**
999
+ * The full current paint order (back to front) of every flat content
1000
+ * object — strokes, texts, tables, images, rectangles, ellipses, lines,
1001
+ * arrows, custom objects, and groups. Populated whenever `objectOrder`
1002
+ * actually changed:
1003
+ * an explicit reorder (`bringForward` etc.), or any add/remove that
1004
+ * touches it — a removal shifts every id after it down one rank, not
1005
+ * just the removed one, so renderers need this to resync everyone, not
1006
+ * only the ids the same change's own `*Added`/`*Removed`/`*Updated`
1007
+ * fields name. Notes (their own `zOffset` peel depth) and Kitchen Timers
1008
+ * (genuine 3D objects, not a flat layer) are intentionally not part of
1009
+ * this order at all.
1010
+ */
1011
+ orderChanged: readonly string[];
731
1012
  }
732
1013
  type Listener = (change: DocumentChange) => void;
733
1014
  declare class BoardDocument {
@@ -742,12 +1023,73 @@ declare class BoardDocument {
742
1023
  private readonly timers;
743
1024
  /** All Custom board object types share one map, keyed by id — the envelope is already uniform. */
744
1025
  private readonly customObjects;
1026
+ private readonly rectangles;
1027
+ private readonly ellipses;
1028
+ private readonly groups;
1029
+ private readonly lines;
1030
+ private readonly arrows;
1031
+ private readonly polygons;
1032
+ private readonly stars;
1033
+ private readonly hearts;
745
1034
  private readonly bboxes;
746
1035
  private readonly listeners;
1036
+ /** Paint order (back to front) of every flat content object — see `DocumentChange.orderChanged`'s doc comment. */
1037
+ private objectOrder;
1038
+ private orderIndex;
747
1039
  constructor(id: DocumentId);
1040
+ private reindexOrder;
1041
+ /** The full current paint order, back to front. */
1042
+ order(): readonly string[];
1043
+ /** This object's rank in the paint order, or -1 if it doesn't participate (unknown id, a note, or a timer). */
1044
+ orderRank(id: string): number;
1045
+ private bringForward;
1046
+ private sendBackward;
1047
+ private bringToFront;
1048
+ private sendToBack;
1049
+ /** Reorders `id` relative to its current neighbors. A no-op for an id that doesn't participate in paint order (see `orderRank`). */
1050
+ reorder(id: string, direction: "forward" | "backward" | "front" | "back"): void;
1051
+ /**
1052
+ * Overwrites the paint order directly — used only when loading a document
1053
+ * that already carries a persisted `objectOrder`; every other order
1054
+ * mutation goes through `reorder`/the automatic append-on-add tracking in
1055
+ * `emit`. Ids not present in the document are dropped; ids present in the
1056
+ * document but missing from `order` are appended at the back, so a
1057
+ * partially-stale order (e.g. from a schema migration) never silently
1058
+ * drops an object from paint order entirely.
1059
+ */
1060
+ private setOrder;
748
1061
  get(id: string): Stroke | undefined;
749
1062
  all(): IterableIterator<Stroke>;
750
- bbox(id: string): BBox | undefined;
1063
+ /**
1064
+ * World-space bounds for any content object, of any type. Strokes hit
1065
+ * their cached-on-mutation fast path (`bboxes`, populated by
1066
+ * `addStrokes`/`transformStrokes` — many points, worth caching); every
1067
+ * other type computes on demand via `objectBounds.ts` (cheap arithmetic,
1068
+ * no caching needed). A group's bounds are the union of its (recursively
1069
+ * resolved) children — `seen` guards against a cycle in nested groups.
1070
+ */
1071
+ bbox(id: string, seen?: Set<string>): BBox | undefined;
1072
+ /**
1073
+ * True if `id` exists and is locked, for any type — the same per-type
1074
+ * probe pattern as `bbox`, for interactive gestures (drag/transform) that
1075
+ * need to gate on lock state regardless of what's selected. Custom
1076
+ * objects are deliberately excluded: their `lock` field is a different
1077
+ * shape (`{holderId, acquiredAt}`, no display name) with no interactive
1078
+ * lock UI yet, matching the existing, deliberate "always unlockable,
1079
+ * never gates a drag" treatment already established elsewhere (e.g.
1080
+ * `getSelectedItemInfo`'s custom branch hardcodes `isLocked: false`).
1081
+ */
1082
+ isLocked(id: string): boolean;
1083
+ /**
1084
+ * True if `id` exists and is hidden, for any type — the same per-type
1085
+ * probe pattern as {@link isLocked} (Phase 8). Custom objects are
1086
+ * excluded for the same reason `isLocked` excludes them: they have no
1087
+ * `Hideable` field at all, so "hidden" isn't a concept that applies to
1088
+ * them yet. Used by marquee selection (`selectTool.ts`) to keep a hidden
1089
+ * object out of a rubber-band selection even for object types whose own
1090
+ * renderer doesn't yet suppress click-based hit-testing.
1091
+ */
1092
+ isHidden(id: string): boolean;
751
1093
  subscribe(listener: Listener): () => void;
752
1094
  addStrokes(strokes: Stroke[]): void;
753
1095
  removeStrokes(ids: string[]): void;
@@ -790,6 +1132,54 @@ declare class BoardDocument {
790
1132
  removeCustomObjects(ids: string[]): void;
791
1133
  /** Replace a custom object's contents under the same id. */
792
1134
  setCustomObject(object: CustomBoardObject): void;
1135
+ getRectangle(id: string): RectangleObject | undefined;
1136
+ allRectangles(): IterableIterator<RectangleObject>;
1137
+ addRectangles(rectangles: RectangleObject[]): void;
1138
+ removeRectangles(ids: string[]): void;
1139
+ /** Replace a rectangle's contents (move, resize, restyle) under the same id. */
1140
+ setRectangle(rect: RectangleObject): void;
1141
+ getEllipse(id: string): EllipseObject | undefined;
1142
+ allEllipses(): IterableIterator<EllipseObject>;
1143
+ addEllipses(ellipses: EllipseObject[]): void;
1144
+ removeEllipses(ids: string[]): void;
1145
+ /** Replace an ellipse's contents (move, resize, restyle) under the same id. */
1146
+ setEllipse(ellipse: EllipseObject): void;
1147
+ getGroup(id: string): GroupObject | undefined;
1148
+ allGroups(): IterableIterator<GroupObject>;
1149
+ addGroups(groups: GroupObject[]): void;
1150
+ removeGroups(ids: string[]): void;
1151
+ /** Replace a group's contents (its children list) under the same id. */
1152
+ setGroup(group: GroupObject): void;
1153
+ getLine(id: string): LineObject | undefined;
1154
+ allLines(): IterableIterator<LineObject>;
1155
+ addLines(lines: LineObject[]): void;
1156
+ removeLines(ids: string[]): void;
1157
+ /** Replace a line's contents (move, restyle) under the same id. */
1158
+ setLine(line: LineObject): void;
1159
+ getArrow(id: string): ArrowObject | undefined;
1160
+ allArrows(): IterableIterator<ArrowObject>;
1161
+ addArrows(arrows: ArrowObject[]): void;
1162
+ removeArrows(ids: string[]): void;
1163
+ /** Replace an arrow's contents (move, restyle, change head) under the same id. */
1164
+ setArrow(arrow: ArrowObject): void;
1165
+ getPolygon(id: string): PolygonObject | undefined;
1166
+ allPolygons(): IterableIterator<PolygonObject>;
1167
+ addPolygons(polygons: PolygonObject[]): void;
1168
+ removePolygons(ids: string[]): void;
1169
+ /** Replace a polygon's contents (move, resize, rotate, restyle) under the same id. */
1170
+ setPolygon(polygon: PolygonObject): void;
1171
+ getStar(id: string): StarObject | undefined;
1172
+ allStars(): IterableIterator<StarObject>;
1173
+ addStars(stars: StarObject[]): void;
1174
+ removeStars(ids: string[]): void;
1175
+ /** Replace a star's contents (move, resize, rotate, restyle) under the same id. */
1176
+ setStar(star: StarObject): void;
1177
+ getHeart(id: string): HeartObject | undefined;
1178
+ allHearts(): IterableIterator<HeartObject>;
1179
+ addHearts(hearts: HeartObject[]): void;
1180
+ removeHearts(ids: string[]): void;
1181
+ /** Replace a heart's contents (move, resize, rotate, restyle) under the same id. */
1182
+ setHeart(heart: HeartObject): void;
793
1183
  setStrokeLocked(id: string, locked: boolean, by?: LockHolder | null): void;
794
1184
  setStrokesLocked(ids: string[], locked: boolean, by?: LockHolder | null): void;
795
1185
  setNoteLocked(id: string, locked: boolean, by?: LockHolder | null): void;
@@ -797,18 +1187,69 @@ declare class BoardDocument {
797
1187
  setTableLocked(id: string, locked: boolean, by?: LockHolder | null): void;
798
1188
  setImageLocked(id: string, locked: boolean, by?: LockHolder | null): void;
799
1189
  setTimerLocked(id: string, locked: boolean, by?: LockHolder | null): void;
1190
+ setRectangleLocked(id: string, locked: boolean, by?: LockHolder | null): void;
1191
+ setEllipseLocked(id: string, locked: boolean, by?: LockHolder | null): void;
1192
+ setGroupLocked(id: string, locked: boolean, by?: LockHolder | null): void;
1193
+ setLineLocked(id: string, locked: boolean, by?: LockHolder | null): void;
1194
+ setArrowLocked(id: string, locked: boolean, by?: LockHolder | null): void;
1195
+ setPolygonLocked(id: string, locked: boolean, by?: LockHolder | null): void;
1196
+ setStarLocked(id: string, locked: boolean, by?: LockHolder | null): void;
1197
+ setHeartLocked(id: string, locked: boolean, by?: LockHolder | null): void;
800
1198
  /** Replace all content (initial load). Does not touch `version`. */
801
- replaceAll(strokes: Stroke[], notes: StickyNote[], texts: TextBlock[], tables?: TableBlock[], images?: ImageBlock[], timers?: KitchenTimer[], customObjects?: CustomBoardObject[]): void;
1199
+ replaceAll(strokes: Stroke[], notes: StickyNote[], texts: TextBlock[], tables?: TableBlock[], images?: ImageBlock[], timers?: KitchenTimer[], customObjects?: CustomBoardObject[], rectangles?: RectangleObject[], ellipses?: EllipseObject[], groups?: GroupObject[], lines?: LineObject[], arrows?: ArrowObject[], polygons?: PolygonObject[], stars?: StarObject[], hearts?: HeartObject[],
1200
+ /** Persisted paint order; absent for a document saved before Phase 3, in which case one is synthesized (see `ORDERED_ADDED_FIELDS`'s doc comment). */
1201
+ objectOrder?: readonly string[]): void;
802
1202
  /** Apply incremental real-time change received from a remote collaborator over WebSocket. */
803
1203
  applyRemoteChange(change: Partial<DocumentChange>): void;
804
1204
  toJSON(): SerializedDocument;
1205
+ static deserializeGroups(data: SerializedDocument): GroupObject[];
1206
+ static deserializeLines(data: SerializedDocument): LineObject[];
1207
+ static deserializeArrows(data: SerializedDocument): ArrowObject[];
1208
+ static deserializePolygons(data: SerializedDocument): PolygonObject[];
1209
+ static deserializeStars(data: SerializedDocument): StarObject[];
1210
+ static deserializeHearts(data: SerializedDocument): HeartObject[];
805
1211
  static deserializeCustomObjects(data: SerializedDocument): CustomBoardObject[];
1212
+ static deserializeRectangles(data: SerializedDocument): RectangleObject[];
1213
+ static deserializeEllipses(data: SerializedDocument): EllipseObject[];
806
1214
  static deserializeImages(data: SerializedDocument): ImageBlock[];
807
1215
  static deserializeTimers(data: SerializedDocument): KitchenTimer[];
808
1216
  static deserializeNotes(data: SerializedDocument): StickyNote[];
809
1217
  static deserializeTexts(data: SerializedDocument): TextBlock[];
810
1218
  static deserializeTables(data: SerializedDocument): TableBlock[];
811
- static deserializeStrokes(data: SerializedDocument): Stroke[];
1219
+ /**
1220
+ * `onSkip` (Phase 9) replaces an unconditional `console.error` — `core`
1221
+ * must never do raw console I/O (no dev-gate, no way for a Host to
1222
+ * suppress or redirect it), so a skipped stroke is now reported only if
1223
+ * the caller asks for it, via whatever diagnostic channel it already
1224
+ * has (e.g. `controller-internal.ts` routes this into the same typed
1225
+ * `"error"` event every other diagnostic already uses). Silent by
1226
+ * default, matching how every other `deserialize*` method here already
1227
+ * behaves (no diagnostics at all).
1228
+ */
1229
+ static deserializeStrokes(data: SerializedDocument, onSkip?: (id: string, cause: unknown) => void): Stroke[];
1230
+ /**
1231
+ * Every mutation funnels through here, so paint-order tracking lives in
1232
+ * exactly one place rather than at every individual add/remove call site
1233
+ * (18 of them, times `replaceAll`/`applyRemoteChange`) — new ids are
1234
+ * appended to the back (front-most) of `objectOrder`, removed ids are
1235
+ * spliced out. An explicit reorder (`reorder`/`setOrder`) updates
1236
+ * `objectOrder` itself before calling this, so this step is a no-op for
1237
+ * ids already tracked (idempotent by construction: `orderIndex.has` gates
1238
+ * every append).
1239
+ *
1240
+ * `orderChanged` (Phase 9) reports exactly the ids whose rank actually
1241
+ * changed, using `orderIndex` throughout instead of `indexOf` — a pure
1242
+ * append never shifts any existing id's rank (new ids land at the tail,
1243
+ * already covered by this same change's own `Added` field, so
1244
+ * `orderChanged` stays unset), while a removal shifts every id at-or-
1245
+ * after the lowest removed rank down by one, computed in a single O(n)
1246
+ * filter pass (not one `indexOf`+`splice` per removed id) regardless of
1247
+ * how many ids this one change removes. Every renderer's `onChange` now
1248
+ * looks up only the ids actually in `orderChanged` instead of walking
1249
+ * its entire mesh map on any order-touching change — a broad, unfiltered
1250
+ * `orderChanged` here would silently defeat that fix, not just waste
1251
+ * cycles here.
1252
+ */
812
1253
  private emit;
813
1254
  }
814
1255
 
@@ -844,6 +1285,21 @@ interface Command {
844
1285
  apply(doc: BoardDocument): void;
845
1286
  revert(doc: BoardDocument): void;
846
1287
  }
1288
+ /**
1289
+ * Several commands applied/reverted together as one undo step (Phase 3
1290
+ * consolidation — this exact class used to be hand-duplicated as a private
1291
+ * `CommandBatch` in `controller-internal.ts` and an exported
1292
+ * `ExtensionCommandBatch` in `interaction/tools/customTool.ts`; both now
1293
+ * import this one instead). Revert runs in reverse order, so a batch that
1294
+ * depends on ordering (e.g. add-then-reference) undoes cleanly.
1295
+ */
1296
+ declare class CommandBatch implements Command {
1297
+ readonly label: string;
1298
+ private readonly commands;
1299
+ constructor(label: string, commands: readonly Command[]);
1300
+ apply(doc: BoardDocument): void;
1301
+ revert(doc: BoardDocument): void;
1302
+ }
847
1303
  /** How a command reached the document — undo/redo are audited distinctly. */
848
1304
  type CommandKind = "do" | "undo" | "redo";
849
1305
  declare class History {
@@ -908,6 +1364,40 @@ declare class TransformCommand implements Command {
908
1364
  revert(doc: BoardDocument): void;
909
1365
  private compose;
910
1366
  }
1367
+ /**
1368
+ * One move gesture over a mixed-type selection (Phase 3) — the general
1369
+ * successor to `TransformCommand` for translation. `TransformCommand`
1370
+ * itself stays as-is (still used for scale/rotate, which remain stroke-only
1371
+ * this phase — see `interaction/tools/selectTool.ts`'s `TransformState`):
1372
+ * its own per-id `doc.get(id)` check already no-ops safely for any id that
1373
+ * isn't a stroke, so it doesn't need touching for that narrower case.
1374
+ *
1375
+ * `delta` here is always a pure translation (never scale/rotate), so
1376
+ * `apply(delta, point)` is a safe, uniform way to move every position-only
1377
+ * type's `x`/`y` — translating commutes trivially regardless of a shape's
1378
+ * own rotation. Matrix-carrying types (stroke, Custom) instead compose
1379
+ * `delta` onto their existing matrix/transform, matching `TransformCommand`.
1380
+ *
1381
+ * A group id in `ids` is expanded into its (recursively resolved, cycle-
1382
+ * safe) children every time `compose` runs — deterministic, since group
1383
+ * membership never changes mid-command — so moving a selected group means
1384
+ * moving every one of its members by the same delta. This expansion is
1385
+ * `TransformObjectsCommand`'s own responsibility precisely so a caller that
1386
+ * doesn't itself expand groups (e.g. `ScrawlEngine.nudgeSelection`) still
1387
+ * gets correct behavior; `interaction/tools/selectTool.ts`'s `TransformState`
1388
+ * separately expands for its own reason (live per-child drag preview), which
1389
+ * makes this a no-op re-expansion for that caller, not a conflict.
1390
+ */
1391
+ declare class TransformObjectsCommand implements Command {
1392
+ private readonly ids;
1393
+ private readonly delta;
1394
+ readonly label = "move selection";
1395
+ private readonly inverse;
1396
+ constructor(ids: readonly string[], delta: Mat2x3);
1397
+ apply(doc: BoardDocument): void;
1398
+ revert(doc: BoardDocument): void;
1399
+ private compose;
1400
+ }
911
1401
  declare class AddNoteCommand implements Command {
912
1402
  readonly label = "add note";
913
1403
  private readonly note;
@@ -1029,8 +1519,213 @@ declare class DeleteTimerCommand implements Command {
1029
1519
  apply(doc: BoardDocument): void;
1030
1520
  revert(doc: BoardDocument): void;
1031
1521
  }
1522
+ /** Add/update/delete for semantic Rectangle objects (Phase 2). */
1523
+ declare class AddRectangleCommand implements Command {
1524
+ readonly label = "add rectangle";
1525
+ private readonly rect;
1526
+ constructor(rect: RectangleObject);
1527
+ apply(doc: BoardDocument): void;
1528
+ revert(doc: BoardDocument): void;
1529
+ }
1530
+ declare class UpdateRectangleCommand implements Command {
1531
+ readonly label = "update rectangle";
1532
+ private readonly before;
1533
+ private readonly after;
1534
+ constructor(before: RectangleObject, after: RectangleObject);
1535
+ apply(doc: BoardDocument): void;
1536
+ revert(doc: BoardDocument): void;
1537
+ }
1538
+ declare class DeleteRectangleCommand implements Command {
1539
+ readonly label = "delete rectangle";
1540
+ private readonly rect;
1541
+ constructor(rect: RectangleObject);
1542
+ apply(doc: BoardDocument): void;
1543
+ revert(doc: BoardDocument): void;
1544
+ }
1545
+ /** Add/update/delete for semantic Ellipse objects (Phase 2). */
1546
+ declare class AddEllipseCommand implements Command {
1547
+ readonly label = "add ellipse";
1548
+ private readonly ellipse;
1549
+ constructor(ellipse: EllipseObject);
1550
+ apply(doc: BoardDocument): void;
1551
+ revert(doc: BoardDocument): void;
1552
+ }
1553
+ declare class UpdateEllipseCommand implements Command {
1554
+ readonly label = "update ellipse";
1555
+ private readonly before;
1556
+ private readonly after;
1557
+ constructor(before: EllipseObject, after: EllipseObject);
1558
+ apply(doc: BoardDocument): void;
1559
+ revert(doc: BoardDocument): void;
1560
+ }
1561
+ declare class DeleteEllipseCommand implements Command {
1562
+ readonly label = "delete ellipse";
1563
+ private readonly ellipse;
1564
+ constructor(ellipse: EllipseObject);
1565
+ apply(doc: BoardDocument): void;
1566
+ revert(doc: BoardDocument): void;
1567
+ }
1568
+ /** Add/update/delete for semantic Line objects (Phase 4). */
1569
+ declare class AddLineCommand implements Command {
1570
+ readonly label = "add line";
1571
+ private readonly line;
1572
+ constructor(line: LineObject);
1573
+ apply(doc: BoardDocument): void;
1574
+ revert(doc: BoardDocument): void;
1575
+ }
1576
+ declare class UpdateLineCommand implements Command {
1577
+ readonly label = "update line";
1578
+ private readonly before;
1579
+ private readonly after;
1580
+ constructor(before: LineObject, after: LineObject);
1581
+ apply(doc: BoardDocument): void;
1582
+ revert(doc: BoardDocument): void;
1583
+ }
1584
+ declare class DeleteLineCommand implements Command {
1585
+ readonly label = "delete line";
1586
+ private readonly line;
1587
+ constructor(line: LineObject);
1588
+ apply(doc: BoardDocument): void;
1589
+ revert(doc: BoardDocument): void;
1590
+ }
1591
+ /** Add/update/delete for semantic Arrow objects (Phase 4). */
1592
+ declare class AddArrowCommand implements Command {
1593
+ readonly label = "add arrow";
1594
+ private readonly arrow;
1595
+ constructor(arrow: ArrowObject);
1596
+ apply(doc: BoardDocument): void;
1597
+ revert(doc: BoardDocument): void;
1598
+ }
1599
+ declare class UpdateArrowCommand implements Command {
1600
+ readonly label = "update arrow";
1601
+ private readonly before;
1602
+ private readonly after;
1603
+ constructor(before: ArrowObject, after: ArrowObject);
1604
+ apply(doc: BoardDocument): void;
1605
+ revert(doc: BoardDocument): void;
1606
+ }
1607
+ declare class DeleteArrowCommand implements Command {
1608
+ readonly label = "delete arrow";
1609
+ private readonly arrow;
1610
+ constructor(arrow: ArrowObject);
1611
+ apply(doc: BoardDocument): void;
1612
+ revert(doc: BoardDocument): void;
1613
+ }
1614
+ /** Add/update/delete for semantic Polygon objects (Phase 4) — Triangle/Diamond/Pentagon/Hexagon/Octagon. */
1615
+ declare class AddPolygonCommand implements Command {
1616
+ readonly label = "add polygon";
1617
+ private readonly polygon;
1618
+ constructor(polygon: PolygonObject);
1619
+ apply(doc: BoardDocument): void;
1620
+ revert(doc: BoardDocument): void;
1621
+ }
1622
+ declare class UpdatePolygonCommand implements Command {
1623
+ readonly label = "update polygon";
1624
+ private readonly before;
1625
+ private readonly after;
1626
+ constructor(before: PolygonObject, after: PolygonObject);
1627
+ apply(doc: BoardDocument): void;
1628
+ revert(doc: BoardDocument): void;
1629
+ }
1630
+ declare class DeletePolygonCommand implements Command {
1631
+ readonly label = "delete polygon";
1632
+ private readonly polygon;
1633
+ constructor(polygon: PolygonObject);
1634
+ apply(doc: BoardDocument): void;
1635
+ revert(doc: BoardDocument): void;
1636
+ }
1637
+ /** Add/update/delete for semantic Star objects (Phase 4). */
1638
+ declare class AddStarCommand implements Command {
1639
+ readonly label = "add star";
1640
+ private readonly star;
1641
+ constructor(star: StarObject);
1642
+ apply(doc: BoardDocument): void;
1643
+ revert(doc: BoardDocument): void;
1644
+ }
1645
+ declare class UpdateStarCommand implements Command {
1646
+ readonly label = "update star";
1647
+ private readonly before;
1648
+ private readonly after;
1649
+ constructor(before: StarObject, after: StarObject);
1650
+ apply(doc: BoardDocument): void;
1651
+ revert(doc: BoardDocument): void;
1652
+ }
1653
+ declare class DeleteStarCommand implements Command {
1654
+ readonly label = "delete star";
1655
+ private readonly star;
1656
+ constructor(star: StarObject);
1657
+ apply(doc: BoardDocument): void;
1658
+ revert(doc: BoardDocument): void;
1659
+ }
1660
+ /** Add/update/delete for semantic Heart objects (Phase 4). */
1661
+ declare class AddHeartCommand implements Command {
1662
+ readonly label = "add heart";
1663
+ private readonly heart;
1664
+ constructor(heart: HeartObject);
1665
+ apply(doc: BoardDocument): void;
1666
+ revert(doc: BoardDocument): void;
1667
+ }
1668
+ declare class UpdateHeartCommand implements Command {
1669
+ readonly label = "update heart";
1670
+ private readonly before;
1671
+ private readonly after;
1672
+ constructor(before: HeartObject, after: HeartObject);
1673
+ apply(doc: BoardDocument): void;
1674
+ revert(doc: BoardDocument): void;
1675
+ }
1676
+ declare class DeleteHeartCommand implements Command {
1677
+ readonly label = "delete heart";
1678
+ private readonly heart;
1679
+ constructor(heart: HeartObject);
1680
+ apply(doc: BoardDocument): void;
1681
+ revert(doc: BoardDocument): void;
1682
+ }
1683
+ /** Add/update/delete for Groups (Phase 3). */
1684
+ declare class AddGroupCommand implements Command {
1685
+ readonly label = "group";
1686
+ private readonly group;
1687
+ constructor(group: GroupObject);
1688
+ apply(doc: BoardDocument): void;
1689
+ revert(doc: BoardDocument): void;
1690
+ }
1691
+ declare class UpdateGroupCommand implements Command {
1692
+ readonly label = "update group";
1693
+ private readonly before;
1694
+ private readonly after;
1695
+ constructor(before: GroupObject, after: GroupObject);
1696
+ apply(doc: BoardDocument): void;
1697
+ revert(doc: BoardDocument): void;
1698
+ }
1699
+ declare class DeleteGroupCommand implements Command {
1700
+ readonly label = "ungroup";
1701
+ private readonly group;
1702
+ constructor(group: GroupObject);
1703
+ apply(doc: BoardDocument): void;
1704
+ revert(doc: BoardDocument): void;
1705
+ }
1706
+ type ReorderDirection = "forward" | "backward" | "front" | "back";
1707
+ /**
1708
+ * Bring-forward / send-backward / bring-to-front / send-to-back (Phase 3) —
1709
+ * one command family covering all four directions rather than four
1710
+ * near-identical classes, since the only difference between them is which
1711
+ * `BoardDocument.reorder` direction to replay. Captures the full paint order
1712
+ * on first `apply` rather than in the constructor — `BoardDocument.order()`
1713
+ * needs the doc, which a `Command` only ever receives via `apply`/`revert` —
1714
+ * so `revert` can restore it exactly; redo re-runs the same `reorder` call,
1715
+ * which is deterministic because `revert` always restores the identical
1716
+ * starting order first.
1717
+ */
1718
+ declare class ReorderObjectCommand implements Command {
1719
+ private readonly id;
1720
+ private readonly direction;
1721
+ readonly label: string;
1722
+ private before;
1723
+ constructor(id: string, direction: ReorderDirection);
1724
+ apply(doc: BoardDocument): void;
1725
+ revert(doc: BoardDocument): void;
1726
+ }
1032
1727
  interface LockTarget {
1033
- type: "stroke" | "note" | "text" | "table" | "image" | "timer";
1728
+ type: "stroke" | "note" | "text" | "table" | "image" | "timer" | "rectangle" | "ellipse" | "group" | "line" | "arrow" | "polygon" | "star" | "heart";
1034
1729
  id: string;
1035
1730
  locked: boolean;
1036
1731
  lockedBy?: string;
@@ -1047,7 +1742,7 @@ declare class LockItemsCommand implements Command {
1047
1742
  private applyLock;
1048
1743
  }
1049
1744
 
1050
- type OpCollection = "strokes" | "notes" | "textBlocks" | "tables" | "images" | "timers" | "customObjects";
1745
+ type OpCollection = "strokes" | "notes" | "textBlocks" | "tables" | "images" | "timers" | "rectangles" | "ellipses" | "groups" | "lines" | "arrows" | "polygons" | "stars" | "hearts" | "customObjects";
1051
1746
  type Op = {
1052
1747
  kind: "upsert";
1053
1748
  collection: OpCollection;
@@ -1091,10 +1786,10 @@ declare function ribbonEdges(points: StrokePoint[], baseWidth: number, handDrawn
1091
1786
  declare class SpatialIndex {
1092
1787
  private readonly doc;
1093
1788
  private readonly cells;
1094
- private readonly strokeCells;
1789
+ private readonly objectCells;
1095
1790
  private readonly unsubscribe;
1096
1791
  constructor(doc: BoardDocument);
1097
- /** Ids of strokes whose bbox may overlap the query rect. */
1792
+ /** Ids of content objects (any type except groups) whose bbox may overlap the query rect. */
1098
1793
  query(minX: number, minY: number, maxX: number, maxY: number): Set<string>;
1099
1794
  dispose(): void;
1100
1795
  private insert;
@@ -1176,5 +1871,5 @@ type BoardStroke = Stroke;
1176
1871
  type SerializedBoardStroke = SerializedStroke;
1177
1872
  type SerializedBoardDocument = CurrentSerializedDocument;
1178
1873
 
1179
- export { ASSET_CACHE_BYTES_DEFAULT, ASSET_CACHE_BYTES_MAX, ASSET_CACHE_BYTES_MIN, ASSET_EXPORT_MAX_DECODED_MEGAPIXELS, ASSET_EXPORT_MAX_ENCODED_BYTES, ASSET_MAX_CONCURRENT_RESOLUTIONS, ASSET_MAX_DECODED_MEGAPIXELS, ASSET_MAX_DIMENSION_PX, ASSET_MAX_ENCODED_BYTES, ASSET_REF_MAX_BYTES, ASSET_REF_PATTERN, AddImageCommand, AddNoteCommand, AddStrokesCommand, AddTableCommand, AddTextCommand, AddTimerCommand, AssetResolutionError, BEACON_INSET, BoardDocument, CURRENT_DOCUMENT_SCHEMA_VERSION, ClusterStore, DeleteImageCommand, DeleteNoteCommand, DeleteStrokesCommand, DeleteTableCommand, DeleteTextCommand, DeleteTimerCommand, DocumentRecoveryError, END_TAPER, ERASE_THRESHOLD, EraseCommand, FOG_COLOR, HIGHLIGHT_COLORS, History, IDENTITY, INK_COLORS, LockItemsCommand, MIN_WIDTH_FACTOR, NOTE_COLORS, NOTE_DEFAULT_SIZE, NOTE_DEFAULT_Z, NOTE_MAX_Z, NOTE_MIN_Z, NOTE_PEEL_STEP, SDK_DEVELOPMENT_VERSION, SDK_PACKAGE_NAME, STAMPS, STAMP_SIZE, SUPPORTED_ASSET_MEDIA_TYPES, SpatialIndex, TABLE_DEFAULT_CELL_HEIGHT, TABLE_DEFAULT_CELL_WIDTH, TABLE_DEFAULT_FONT_SIZE, TEXT_DEFAULT_SIZE, TIMER_DEFAULT_DURATION_MS, TIMER_DEFAULT_SIZE, TIMER_PRESETS_MS, TransformCommand, UpdateImageCommand, UpdateNoteCommand, UpdateTableCommand, UpdateTextCommand, UpdateTimerCommand, apply, applyItemLock, assetRef, avgScale, canUnlockItem, changeToOps, clampAssetCacheBytes, cloneCustomObject, cloneImage, cloneNote, cloneStroke, cloneTable, cloneText, cloneTimer, documentId, documentToSVG, formatTimer, invert, isAssetRef, isIdentity, isStampKind, loadDocumentBytes, measureTable, measureTextBlock, migrateDocument, mul, pauseTimer, placePresenceBeacon, ribbonEdges, rotationAbout, scalingAbout, searchBoard, serializeDocument, serializeLock, serializeStroke, setTimerDuration, stampDataUrl, startTimer, strokeId, timerExpired, timerRemaining, toggleTimer, translation };
1180
- export type { AssetDiagnostic, AssetIngestRequest, AssetIngestResult, AssetIngestor, AssetKind, AssetPurpose, AssetRef, AssetResolutionErrorCode, AssetResolveRequest, AssetResolveResult, AssetResolver, BBox, BoardKeyInput, BoardPoint, BoardPointerInput, BoardScene, BoardStroke, ClusterIdFactory, Command, CommandKind, CurrentSerializedDocument, CurrentSerializedStroke, CustomBoardObject, CustomObjectAddInput, CustomObjectDefinition, CustomTool, CustomToolDefinition, DocumentChange, DocumentId, DocumentLoadResult, DocumentRecoveryCode, ExtensionCommand, ExtensionDiagnostic, ExtensionHitResult, ExtensionId, ExtensionRequirement, ImageBlock, InputModifiers, JsonObject, JsonValue, KitchenTimer, LockHolder, LockTarget, Lockable, Mat2x3, NoteVote, ObjectDescribeContext, ObjectIntent, ObjectType, Op, OpCollection, PresencePlacement, QueryableBoardObject, ReadonlyCustomObject, RibbonEdgePoint, SceneEllipse, SceneGroup, SceneImage, ScenePath, SceneRect, SceneText, ScrawlExtension, SearchHit, SearchHitKind, SearchableBoard, SearchableComment, SerializedBoardDocument, SerializedBoardStroke, SerializedPoint, SerializedStroke, StampKind, StickyNote, Stroke, StrokeId, StrokePoint, StrokeTool, SupportedAssetMediaType, TableBlock, TextBlock, ToolCancelReason, ToolCapabilities, ToolCursor, ToolId, ViewportInset };
1874
+ export { ASSET_CACHE_BYTES_DEFAULT, ASSET_CACHE_BYTES_MAX, ASSET_CACHE_BYTES_MIN, ASSET_EXPORT_MAX_DECODED_MEGAPIXELS, ASSET_EXPORT_MAX_ENCODED_BYTES, ASSET_MAX_CONCURRENT_RESOLUTIONS, ASSET_MAX_DECODED_MEGAPIXELS, ASSET_MAX_DIMENSION_PX, ASSET_MAX_ENCODED_BYTES, ASSET_REF_MAX_BYTES, ASSET_REF_PATTERN, AddArrowCommand, AddEllipseCommand, AddGroupCommand, AddHeartCommand, AddImageCommand, AddLineCommand, AddNoteCommand, AddPolygonCommand, AddRectangleCommand, AddStarCommand, AddStrokesCommand, AddTableCommand, AddTextCommand, AddTimerCommand, AssetResolutionError, BEACON_INSET, BoardDocument, CURRENT_DOCUMENT_SCHEMA_VERSION, ClusterStore, CommandBatch, DeleteArrowCommand, DeleteEllipseCommand, DeleteGroupCommand, DeleteHeartCommand, DeleteImageCommand, DeleteLineCommand, DeleteNoteCommand, DeletePolygonCommand, DeleteRectangleCommand, DeleteStarCommand, DeleteStrokesCommand, DeleteTableCommand, DeleteTextCommand, DeleteTimerCommand, DocumentRecoveryError, END_TAPER, ERASE_THRESHOLD, EraseCommand, FOG_COLOR, HIGHLIGHT_COLORS, History, IDENTITY, INK_COLORS, LockItemsCommand, MIN_WIDTH_FACTOR, NOTE_COLORS, NOTE_DEFAULT_SIZE, NOTE_DEFAULT_Z, NOTE_MAX_Z, NOTE_MIN_Z, NOTE_PEEL_STEP, ReorderObjectCommand, SDK_DEVELOPMENT_VERSION, SDK_PACKAGE_NAME, SHAPE_DEFAULT_STROKE, SHAPE_DEFAULT_STROKE_WIDTH, SHAPE_MIN_SIZE, SHAPE_STYLE_DEFAULTS, STAMPS, STAMP_SIZE, SUPPORTED_ASSET_MEDIA_TYPES, SpatialIndex, TABLE_DEFAULT_CELL_HEIGHT, TABLE_DEFAULT_CELL_WIDTH, TABLE_DEFAULT_FONT_SIZE, TEXT_DEFAULT_SIZE, TIMER_DEFAULT_DURATION_MS, TIMER_DEFAULT_SIZE, TIMER_PRESETS_MS, TransformCommand, TransformObjectsCommand, UpdateArrowCommand, UpdateEllipseCommand, UpdateGroupCommand, UpdateHeartCommand, UpdateImageCommand, UpdateLineCommand, UpdateNoteCommand, UpdatePolygonCommand, UpdateRectangleCommand, UpdateStarCommand, UpdateTableCommand, UpdateTextCommand, UpdateTimerCommand, apply, applyItemLock, assetRef, avgScale, canUnlockItem, changeToOps, clampAssetCacheBytes, cloneArrow, cloneCustomObject, cloneEllipse, cloneGroup, cloneHeart, cloneImage, cloneLine, cloneNote, clonePolygon, cloneRectangle, cloneStar, cloneStroke, cloneTable, cloneText, cloneTimer, documentId, documentSize, documentToSVG, formatTimer, invert, isAssetRef, isIdentity, isStampKind, loadDocumentBytes, measureTable, measureTextBlock, migrateDocument, mul, pauseTimer, placePresenceBeacon, ribbonEdges, rotationAbout, scalingAbout, searchBoard, serializeDocument, serializeLock, serializeStroke, setTimerDuration, stampDataUrl, startTimer, strokeId, timerExpired, timerRemaining, toggleTimer, translation };
1875
+ export type { ArrowHeadStyle, ArrowObject, AssetDiagnostic, AssetIngestRequest, AssetIngestResult, AssetIngestor, AssetKind, AssetPurpose, AssetRef, AssetResolutionErrorCode, AssetResolveRequest, AssetResolveResult, AssetResolver, BBox, BoardKeyInput, BoardPoint, BoardPointerInput, BoardScene, BoardStroke, ClusterIdFactory, Command, CommandKind, CurrentSerializedDocument, CurrentSerializedStroke, CustomBoardObject, CustomObjectAddInput, CustomObjectDefinition, CustomTool, CustomToolDefinition, DocumentChange, DocumentId, DocumentLoadResult, DocumentRecoveryCode, EllipseObject, ExtensionCommand, ExtensionDiagnostic, ExtensionHitResult, ExtensionId, ExtensionRequirement, GroupObject, HeartObject, ImageBlock, InputModifiers, JsonObject, JsonValue, KitchenTimer, LineObject, LockHolder, LockTarget, Lockable, Mat2x3, NoteVote, ObjectDescribeContext, ObjectIntent, ObjectType, Op, OpCollection, PolygonObject, PresencePlacement, QueryableBoardObject, ReadonlyCustomObject, RectangleObject, ReorderDirection, RibbonEdgePoint, SceneEllipse, SceneGroup, SceneImage, ScenePath, SceneRect, SceneText, ScrawlExtension, SearchHit, SearchHitKind, SearchableBoard, SearchableComment, SerializedBoardDocument, SerializedBoardStroke, SerializedPoint, SerializedStroke, StampKind, StarObject, StickyNote, Stroke, StrokeId, StrokePoint, StrokeTool, SupportedAssetMediaType, TableBlock, TextBlock, ToolCancelReason, ToolCapabilities, ToolCursor, ToolId, ViewportInset };