@paged-media/plugin-api 0.2.37-canary.0 → 0.2.39-canary.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/editor.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { ComponentType } from "react";
2
- import type { EditContextContribution, ObjectTypeContribution } from "./host";
2
+ import type { EditContextContribution, ObjectTypeContribution, SceneImage, SceneImageTile } from "./host";
3
3
  import type { CollectionName, ContentSelection, DocumentMeta, ElementGeometryItem, ElementId, MainToWorkerKind, Mutation, PageId, PathAnchorsResult, ProviderTileWire, ResourceTilesNeededWire, SceneLayer, SelectionMode, WorkerToMain } from "./wire";
4
4
  /** C-6 (I-06) — the editor-channel claim shape (the v44
5
5
  * `claimImageResource` payload, named for the `PagedEditor.images`
@@ -485,7 +485,35 @@ export interface PagedEditor {
485
485
  */
486
486
  submit(elementId: string, layer: SceneLayer, caller?: string): Promise<void>;
487
487
  clear(elementId: string): Promise<void>;
488
+ /** Protocol 66 — the BINARY scene-image lane (canvas-wasm
489
+ * `submitSceneImageDirect`): the bytes cross as a `Uint8Array`,
490
+ * transferred when `transfer` is true. Optional: absent on an older
491
+ * host, and the SDK then falls back to `submit()`. */
492
+ submitImage?(elementId: string, image: SceneImage, caller?: string, transfer?: boolean): Promise<void>;
493
+ /** Protocol 66 — patch tiles of the image `submitImage` set
494
+ * (canvas-wasm `submitSceneImageTilesDirect`). Optional with
495
+ * `submitImage`; the SDK uses the lane only when both exist. */
496
+ submitImageTiles?(elementId: string, tiles: readonly SceneImageTile[], caller?: string, transfer?: boolean): Promise<void>;
488
497
  };
498
+ /** Protocol 66 — the BINARY `.paged` parts lane (canvas-wasm
499
+ * `writePagedPartDirect` / `readPagedPartDirect` + `deletePagedPart`).
500
+ * FULL paths (`paged/<plugin-id>/…`); the SDK adapter scopes them.
501
+ * Optional: absent on an older host, and the SDK falls back to the
502
+ * JSON `client.send` messages. */
503
+ parts?: {
504
+ write(path: string, bytes: Uint8Array, caller?: string): Promise<void>;
505
+ read(path: string): Promise<Uint8Array | null>;
506
+ delete(path: string, caller?: string): Promise<boolean>;
507
+ };
508
+ /** Protocol 66 — the BINARY commit lane (canvas-wasm
509
+ * `mutateWithBytesDirect`): apply `mutation` (a `batch` included) after
510
+ * handing `bytes` to its FIRST `replaceImageBytes` whose `bytes` is `[]`,
511
+ * depth-first through batches. The engine refuses a mutation with no such
512
+ * slot. The buffer moves to the worker when `transfer` is true. Resolves
513
+ * with the same reply `client.mutate` does. Optional: absent on an older
514
+ * host, and the SDK then splices `Array.from(bytes)` into that slot and
515
+ * calls `client.mutate`. */
516
+ mutateWithBytes?(mutation: Mutation, bytes: Uint8Array, transfer?: boolean): Promise<WorkerToMain>;
489
517
  /** C-6 (I-06) — the renderer RESOURCE-PROVIDER channel. The editor
490
518
  * routes these to the canvas-wasm `claimImageResource` /
491
519
  * `submitResourceTiles` / `releaseImageResource` messages (the v44
package/dist/host.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { CollectionName, DocumentMeta, ElementGeometryItem, ElementId, HitFilter, HitResult, Mutation, PageId, ElementProperties, PathAnchorsResult, PathAnchorTriple, SceneTreeNode, SelectionMode } from "./wire";
1
+ import type { CollectionName, DocumentMeta, ElementGeometryItem, ElementId, HitFilter, HitResult, MintedElement, Mutation, PageId, ElementProperties, PathAnchorsResult, PathAnchorTriple, SceneTreeNode, SelectionMode, SnapPointQuery, SnapPointResult } from "./wire";
2
2
  import type { CommandContribution, ExporterContribution, ImporterContribution, KeybindingContribution, OverlayContribution, PagedEditor, PanelContribution, ToolContribution, ToolPreviewShape } from "./editor";
3
3
  import type { SceneLayer } from "./wire";
4
4
  import type { AssetSurface } from "./assets";
@@ -144,6 +144,12 @@ export interface EditContextContribution {
144
144
  /** K-1 — a key while the context is active. The shell owns Esc (→
145
145
  * `onCancel`) and Enter (→ `onCommit`); every other key forwards here. */
146
146
  onContentKey?(e: KeyboardEvent): void;
147
+ /** A plain wheel over the ACTIVE context's frame, in frame-content
148
+ * points. Return `true` when the context scrolled its own content (a
149
+ * sheet's in-frame grid window) — the canvas then does not pan;
150
+ * `false` keeps the host's pan. Cmd/Ctrl wheel is the host's zoom and
151
+ * never reaches here. Optional: absent ⇒ the canvas always pans. */
152
+ onContentWheel?(e: ContentWheelEvent): boolean;
147
153
  /** K-1 — unsaved-edit probe: gates the discard prompt + the §8.0
148
154
  * seamless-undo boundary. Absent ⇒ treated as never dirty. */
149
155
  isDirty?(): boolean;
@@ -171,6 +177,11 @@ export interface EditContextContribution {
171
177
  * always enabled. */
172
178
  onCanUndo?(): boolean;
173
179
  onCanRedo?(): boolean;
180
+ /** Labels for the host's Edit-menu items while this context owns undo
181
+ * (e.g. "Undo Brush Stroke"). `null` or absent ⇒ the host's generic
182
+ * label. Read when the menu renders, so return the current step. */
183
+ undoLabel?(): string | null;
184
+ redoLabel?(): string | null;
174
185
  /** HOST-STAMPED, not author-supplied: the `x-paged:<manifest id>`
175
186
  * metadata key the host resolves the candidate's `metadata` from
176
187
  * before calling `matches`. The SDK adapter fills this from the
@@ -201,6 +212,24 @@ export interface ContentPointerEvent {
201
212
  /** Mouse button (0 = primary). */
202
213
  button: number;
203
214
  }
215
+ /** A wheel delivered to the ACTIVE edit context (`onContentWheel`).
216
+ * `delta` is the scroll in frame-content points — the screen delta
217
+ * divided by the camera scale, line/page modes normalised to pixels
218
+ * first — x right / y down, the same axes as `contentPoint`. */
219
+ export interface ContentWheelEvent {
220
+ /** Pointer in frame-content points (origin = the content-box top-left). */
221
+ contentPoint: [number, number];
222
+ /** The frame the active context edits (the stack's scope root). */
223
+ elementId: string;
224
+ /** Scroll amount in frame-content points [x, y]. */
225
+ delta: [number, number];
226
+ modifiers: {
227
+ shift: boolean;
228
+ alt: boolean;
229
+ cmd: boolean;
230
+ ctrl: boolean;
231
+ };
232
+ }
204
233
  /**
205
234
  * A plugin-defined OBJECT TYPE (paged.web §9.1.2). A webFrame is an
206
235
  * ordinary rectangle with attached `x-paged:media.paged.web` source
@@ -428,6 +457,52 @@ export interface SceneLayerSurface extends Disposable {
428
457
  /** Clear the layer for `elementId` (returns the frame to native
429
458
  * content). */
430
459
  clear(elementId: string): Promise<void>;
460
+ /**
461
+ * Make the frame's layer ONE RGBA8 image (protocol 66). Where the host
462
+ * wires the binary lane (`supports("rendering.sceneLayer.binary@1")`)
463
+ * the bytes cross as a `Uint8Array` — no `number[]`, no JSON parse —
464
+ * and only the pages showing the frame repaint. On an older host the
465
+ * SDK falls back to `submit()` with an image item; the bundle calls
466
+ * the same method either way. Replaces any previous layer.
467
+ */
468
+ submitImage(elementId: string, image: SceneImage, options?: SceneImageSubmitOptions): Promise<void>;
469
+ /**
470
+ * Patch rectangles of the image this surface last `submitImage`d for
471
+ * `elementId` (a brush stroke dirties a window, not the image). Rejects
472
+ * when no image was submitted for the element. A tile outside the
473
+ * image, or a byte count that does not match `width*height*4`, rejects
474
+ * the whole call and changes nothing.
475
+ */
476
+ submitImageTiles(elementId: string, tiles: readonly SceneImageTile[], options?: SceneImageSubmitOptions): Promise<void>;
477
+ }
478
+ /** One whole RGBA8 image for {@link SceneLayerSurface.submitImage}. */
479
+ export interface SceneImage {
480
+ /** Tightly packed RGBA8, row-major, `width*height*4` bytes. */
481
+ rgba: Uint8Array;
482
+ /** Pixel width of the buffer. */
483
+ width: number;
484
+ /** Pixel height of the buffer. */
485
+ height: number;
486
+ /** Destination `[x, y, w, h]` in frame-content points. */
487
+ dest: [number, number, number, number];
488
+ }
489
+ /** One rectangle of new pixels for
490
+ * {@link SceneLayerSurface.submitImageTiles}; the origin is in IMAGE
491
+ * pixels of the submitted image. */
492
+ export interface SceneImageTile {
493
+ x: number;
494
+ y: number;
495
+ width: number;
496
+ height: number;
497
+ /** Tightly packed RGBA8, `width*height*4` bytes. */
498
+ rgba: Uint8Array;
499
+ }
500
+ /** How the bytes of a scene-image submission are handed over. */
501
+ export interface SceneImageSubmitOptions {
502
+ /** `true`: the buffers are TRANSFERRED to the host and are detached
503
+ * (unusable) in the bundle afterwards — no copy. Default `false`: the
504
+ * host copies, and the bundle keeps its buffers. */
505
+ transfer?: boolean;
431
506
  }
432
507
  /** One pyramid tile the bundle's `source` callback returns (C-6). `rgba`
433
508
  * is tightly packed RGBA8 (`width*height*4` bytes, row-major); `[x, y]`
@@ -590,15 +665,37 @@ export interface SecretsSurface {
590
665
  forget(ref: string): Promise<void>;
591
666
  }
592
667
  /** Expected mutation failures are results, not throws — mirroring the
593
- * editor's mutate-never-throws convention. */
668
+ * editor's mutate-never-throws convention.
669
+ *
670
+ * `createdId` is the engine's single-creation answer: for a `batch` it is
671
+ * only the LAST element the batch minted. `minted` is the whole list, in
672
+ * mint order — every element a `batch` (or a `duplicateElements`)
673
+ * created, each with the `bindCreated` handle that named it (`null` when
674
+ * none did) and the story minted alongside it (a text frame's
675
+ * `ParentStory`, else `null`). Present whenever the engine reported it
676
+ * (it is additive on the wire; an older engine omits it), so a bundle
677
+ * placing a frame + table + chart in ONE mutate reads back every id here
678
+ * instead of re-discovering them with a scene walk. */
594
679
  export type MutationOutcome = {
595
680
  applied: true;
596
681
  createdId: ElementId | null;
597
682
  pageIds: PageId[];
683
+ minted?: MintedElement[];
598
684
  } | {
599
685
  applied: false;
600
686
  error: unknown;
601
687
  };
688
+ /** Options of {@link DocumentSurface.mutateWithBytes}. */
689
+ export interface MutateWithBytesOptions {
690
+ /** Hand the buffer to the host instead of copying it; it may be detached
691
+ * afterwards. Default `false`. */
692
+ transfer?: boolean;
693
+ }
694
+ /** What {@link DocumentSurface.onWillSave} listeners receive. */
695
+ export interface WillSaveEvent {
696
+ /** The container being written. */
697
+ format: "paged";
698
+ }
602
699
  export interface DocumentChangeEvent {
603
700
  kind: "mutationApplied" | "undoApplied" | "redoApplied";
604
701
  pageIds: PageId[];
@@ -739,6 +836,37 @@ export interface DocumentSurface {
739
836
  * hasn't absorbed yet (see mutations.ts). Widening an accepted
740
837
  * input is additive: every `Mutation` still passes. */
741
838
  mutate(mutation: MutationInput): Promise<MutationOutcome>;
839
+ /**
840
+ * Protocol 66 — the same write door as {@link mutate}, with image bytes
841
+ * that cross as a `Uint8Array` instead of a JSON `number[]`. `bytes` goes
842
+ * to the FIRST `replaceImageBytes` in `mutation` whose `bytes` is `[]`
843
+ * (depth-first through a `batch`), so a baked image and the
844
+ * `setPluginMetadata` that describes it commit as one undoable step:
845
+ *
846
+ * ```ts
847
+ * await host.document.mutateWithBytes(
848
+ * { op: "batch", args: { ops: [
849
+ * { op: "replaceImageBytes", args: { elementId, bytes: [] } },
850
+ * { op: "setPluginMetadata", args: { elementId, key, value } },
851
+ * ] } },
852
+ * png,
853
+ * { transfer: true },
854
+ * );
855
+ * ```
856
+ *
857
+ * A mutation with no such slot is refused (`applied: false`) rather
858
+ * than applied without the bytes. Same gates and outcome as `mutate`:
859
+ * `capabilities.document.write`, metadata only under this plugin's own
860
+ * key, never a throw. `options.transfer: true` hands the buffer to the
861
+ * host, which may detach it; the default copies.
862
+ *
863
+ * Call it unconditionally. Where the host wires the binary lane,
864
+ * `supports("document.mutateBinary@1")` is true and the bytes are not
865
+ * converted; otherwise the SDK splices `Array.from(bytes)` into the slot
866
+ * and takes the `mutate` path (the size limit of the JSON channel then
867
+ * applies).
868
+ */
869
+ mutateWithBytes(mutation: MutationInput, bytes: Uint8Array, options?: MutateWithBytesOptions): Promise<MutationOutcome>;
742
870
  undo(): Promise<void>;
743
871
  redo(): Promise<void>;
744
872
  collection<T>(name: CollectionName): Promise<readonly T[]>;
@@ -776,6 +904,25 @@ export interface DocumentSurface {
776
904
  * forwards at all.
777
905
  */
778
906
  planarRegions(elementIds: ElementId[], point?: [number, number]): Promise<PlanarRegionsResult>;
907
+ /**
908
+ * v67 (RFI C-68) — snap one page-local point the way the host's own
909
+ * tools do: to the anchors, frame corners and centres of every visible
910
+ * element, the page, the x / y lines through all of them (smart
911
+ * guides), ruler guides, the document grid and the nearest outline,
912
+ * with the session's tolerance and switches. One engine resolver
913
+ * answers the Pen, Direct Selection, a move and this door, so a plugin
914
+ * tool snaps exactly like the host.
915
+ *
916
+ * Leave the path being edited out with `exclude` (`anchors` names the
917
+ * dragged ones; the element's outline is then skipped too, since the
918
+ * host is previewing a shape the engine has not seen), and add the
919
+ * points of a path still being drawn with `extraPoints`.
920
+ *
921
+ * Pure READ, gated on `capabilities.document.read`. Never throws: a
922
+ * host whose engine predates v67 answers the point unsnapped
923
+ * (`snapped: false`). Probe `supports("document.snapPoint@1")`.
924
+ */
925
+ snapPoint(query: SnapPointQuery): Promise<SnapPointResult>;
779
926
  /** D-01 (protocol v43) — enumerate every plugin-tagged placeholder
780
927
  * field in the document, in story order. Offsets are FRESH-READ
781
928
  * addresses (a placeholder is its own tagged run; re-enumerate
@@ -826,6 +973,14 @@ export interface DocumentSurface {
826
973
  * throws `PluginApiNotImplemented` (a visible seam, never a fake value). */
827
974
  storyContent(storyId: string): Promise<StoryContent | null>;
828
975
  onDidChange(listener: (e: DocumentChangeEvent) => void): Disposable;
976
+ /**
977
+ * Called before the host serialises the document to a file; the save
978
+ * WAITS for the returned promise, so a bundle can commit pending state
979
+ * (write parts, bake pixels) first. An error is logged and does not
980
+ * stop the save. Probe `supports("document.onWillSave@1")`: without a
981
+ * host backend the listener is held but never called.
982
+ */
983
+ onWillSave(listener: (e: WillSaveEvent) => void | Promise<void>): Disposable;
829
984
  /**
830
985
  * Plugin-metadata carrier (protocol v33) — read this plugin's
831
986
  * metadata envelope on a leaf page item, or `null` when absent.
@@ -1021,6 +1176,16 @@ export interface ShellSurface {
1021
1176
  * `false`.
1022
1177
  */
1023
1178
  saveFile(options: SaveFileOptions): Promise<boolean>;
1179
+ /**
1180
+ * Enter one of THIS bundle's registered edit contexts on `elementId`
1181
+ * programmatically (a panel button, an importer that just placed a
1182
+ * frame) — the same stack push a double-click on the frame performs.
1183
+ * Throws for a type the bundle did not register. Resolves `false` when
1184
+ * the host could not enter (no backend — probe
1185
+ * `supports("shell.enterEditContext@1")` — or the element does not
1186
+ * exist / is not the context's).
1187
+ */
1188
+ enterEditContext(type: string, elementId: ElementId): Promise<boolean>;
1024
1189
  }
1025
1190
  /** What `ShellSurface.saveFile` delivers (K-10) — the inverse of
1026
1191
  * {@link PickedFile}, field-for-field, so bytes picked from disk can be
@@ -1117,6 +1282,10 @@ export interface PartsSurface {
1117
1282
  /** List part paths under `prefix` (relative) — this plugin's namespace only,
1118
1283
  * returned as relative paths. */
1119
1284
  list(prefix?: string): Promise<string[]>;
1285
+ /** Delete the part at `path` (protocol 66, `storage.parts@2`). Resolves
1286
+ * `true` when it existed. A part the loaded file carries is dropped
1287
+ * from the next save, not only hidden. Not undoable, like `write`. */
1288
+ delete(path: string): Promise<boolean>;
1120
1289
  }
1121
1290
  export interface NativeDocumentSurface {
1122
1291
  /** Read the core-owned native MODEL part (`paged/core/model/document.pgm`)
@@ -1284,6 +1453,17 @@ export interface BindingsSurface {
1284
1453
  * subscription; the argument is the changed name). */
1285
1454
  onDidChange(listener: (name: string) => void): Disposable;
1286
1455
  }
1456
+ /** A tool-option value as the host's tool-options UI stores it. */
1457
+ export type ToolSettingValue = number | boolean | string;
1458
+ /** Read access to the values the host's tool-options UI holds for this
1459
+ * bundle's tools (the fields declared in `ToolContribution.options`).
1460
+ * `toolId` must be one of this bundle's own tool ids. Probe
1461
+ * `supports("tools.settings@1")`: without a host backend `settings`
1462
+ * answers `{}` and `onDidChangeSettings` never fires. */
1463
+ export interface ToolsSurface {
1464
+ settings(toolId: string): Readonly<Record<string, ToolSettingValue>>;
1465
+ onDidChangeSettings(toolId: string, listener: (settings: Readonly<Record<string, ToolSettingValue>>) => void): Disposable;
1466
+ }
1287
1467
  /**
1288
1468
  * What `activate(host)` receives. Types from `@paged-media/plugin-api`,
1289
1469
  * values from here — never import host values into a bundle's module
@@ -1401,6 +1581,11 @@ export interface BundleHost {
1401
1581
  * `capabilities.clipboard`: `"full"` grants text + tabular, `"vector"`
1402
1582
  * grants text only, `"none"`/absent denies. */
1403
1583
  readonly clipboard: ClipboardSurface;
1584
+ /** The tool-settings READ door: the option values the host's
1585
+ * tool-options UI holds for this bundle's tools, plus a change
1586
+ * subscription. Always present; `supports("tools.settings@1")`
1587
+ * reports whether a host store is wired. */
1588
+ readonly tools: ToolsSurface;
1404
1589
  /** Capability detection over version sniffing: feature strings of
1405
1590
  * the form `"area.member@major"` (see HOST_FEATURES in plugin-sdk). */
1406
1591
  supports(feature: string): boolean;
package/dist/index.d.ts CHANGED
@@ -1,11 +1,13 @@
1
1
  export type { PluginId, PluginManifest, PluginCapabilities, PluginContributions, NetworkCapability, DataProvidersCapability, StorageCapability, WasmArtifact, WasmPurpose, WorkersCapability, SecretsCapability, GpuCapability, } from "./manifest";
2
2
  export type { BundleHandle, PagedBundle } from "./bundle";
3
- export type { BundleHost, ContributionSurface, SceneLayerSurface, ImagesSurface, ImageResourceClaimOptions, TileBytes, WorkersSurface, BundleWorker, SpawnWorkerOptions, SecretsSurface, SecretMaterial, DocumentSurface, SelectionSurface, ViewportSurface, TextSurface, TextMetrics, TextCaret, FrameChainLink, PlanarFace, PlanarRegionsResult, StoryContent, ParagraphContent, RunContent, OverlaySurface, ShellSurface, FilePickerOptions, PickedFile, SaveFileOptions, StorageSurface, BlobSurface, BlobUsage, PartsSurface, NativeDocumentSurface, NetworkSurface, ConsentResult, DataProvidersSurface, DataProviderRegistration, DataProviderHandle, DataProviderInfo, DataProviderSnapshot, ProviderSchema, ProviderField, ProviderRecordSet, DiagnosticsSurface, JournalSurface, JournalRecord, BindingsSurface, Diagnostic, DocumentChangeEvent, MutationOutcome, Disposable, PluginLogger, EditContextContribution, ObjectTypeContribution, EditContextCandidate, EnteredEditContext, ContentPointerEvent, EditContextDescriptor, ObjectTypeDescriptor, PluginMetadataEnvelope, ObjectTypeBaker, BakeContext, MenuContribution, } from "./host";
3
+ export type { BundleHost, ContributionSurface, SceneLayerSurface, SceneImage, SceneImageTile, SceneImageSubmitOptions, WillSaveEvent, ToolsSurface, ToolSettingValue, ImagesSurface, ImageResourceClaimOptions, TileBytes, WorkersSurface, BundleWorker, SpawnWorkerOptions, SecretsSurface, SecretMaterial, DocumentSurface, MutateWithBytesOptions, SelectionSurface, ViewportSurface, TextSurface, TextMetrics, TextCaret, FrameChainLink, PlanarFace, PlanarRegionsResult, StoryContent, ParagraphContent, RunContent, OverlaySurface, ShellSurface, FilePickerOptions, PickedFile, SaveFileOptions, StorageSurface, BlobSurface, BlobUsage, PartsSurface, NativeDocumentSurface, NetworkSurface, ConsentResult, DataProvidersSurface, DataProviderRegistration, DataProviderHandle, DataProviderInfo, DataProviderSnapshot, ProviderSchema, ProviderField, ProviderRecordSet, DiagnosticsSurface, JournalSurface, JournalRecord, BindingsSurface, Diagnostic, DocumentChangeEvent, MutationOutcome, Disposable, PluginLogger, EditContextContribution, ObjectTypeContribution, EditContextCandidate, EnteredEditContext, ContentPointerEvent, ContentWheelEvent, EditContextDescriptor, ObjectTypeDescriptor, PluginMetadataEnvelope, ObjectTypeBaker, BakeContext, MenuContribution, } from "./host";
4
4
  export type { PanelSchema, PanelSchemaSection, PanelSchemaRow, SchemaPanelContribution, SchemaPanelRenderer, SchemaPanelRendererProps, WidgetValueBinding, BindingRef, SchemaGate, WidgetCollectionBinding, SchemaRowAction, SchemaListAction, SchemaListSpec, } from "./panel-schema";
5
- export type { WidgetSurface, CodeEditorProps, CodeEditorDiagnostic, CodeEditorLanguage, } from "./widgets";
5
+ export type { WidgetSurface, ColorPickerProps, CodeEditorProps, CodeEditorDiagnostic, CodeEditorLanguage, } from "./widgets";
6
6
  export type { BindingTarget, BindingPropertyRequest, BindingPropertyWrite, BindingCollectionRequest, BindingRead, BindingResolved, BindingDecline, BindingWrite, BindingCollection, BindingOp, BindingProvider, BindingProviderScope, BindingProviderHandle, BindingReadResult, BindingWriteResult, BindingCollectionResult, ActiveBindingProvider, } from "./binding-provider";
7
7
  export type { AssetSurface, AssetKind, FontFaceAsset, FontFaceFormat, } from "./assets";
8
8
  export type { ProviderTileWire } from "./wire";
9
+ export type { SnapPointQuery, SnapPointResult, SnapPointHit, SnapAxisHit, SnapSegmentHit, SnapExclude, SnapSource, SnapSettings, } from "./wire";
10
+ export type { MintedElement } from "./wire";
9
11
  export type { ClipboardSurface, ClipboardPayload, TabularClipboard, } from "./clipboard";
10
12
  export type * from "./contributions";
11
13
  export type * from "./mutations";
package/dist/widgets.d.ts CHANGED
@@ -45,4 +45,21 @@ export interface WidgetSurface {
45
45
  * editor. Always present: a plain-textarea fallback stands in when
46
46
  * the host app injects no real widget catalog. */
47
47
  readonly CodeEditor: ComponentType<CodeEditorProps>;
48
+ /** The host's colour picker (the same mixer the host's own colour UI
49
+ * uses). It edits a value the BUNDLE owns — it never writes the
50
+ * document or adds a swatch. Always present: an
51
+ * `<input type="color">` fallback stands in when the host injects
52
+ * none (probe `host.supports("widgets.colorPicker@1")`). */
53
+ readonly ColorPicker: ComponentType<ColorPickerProps>;
54
+ }
55
+ /** Props of {@link WidgetSurface.ColorPicker}. Colours are sRGB hex. */
56
+ export interface ColorPickerProps {
57
+ /** `#rrggbb`. */
58
+ value: string;
59
+ /** Every change while the user drags / types. */
60
+ onChange(next: string): void;
61
+ /** The settled value (pointer up, picker closed, Enter). */
62
+ onCommit?(next: string): void;
63
+ disabled?: boolean;
64
+ ariaLabel?: string;
48
65
  }
package/dist/wire.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  // GENERATED — do not edit. Vendored verbatim from the published
2
2
  // @paged-media/canvas-wasm .d.ts (tsify output from paged-media/core,
3
3
  // MPL-2.0 OR PMEL). Sync: node scripts/sync-wire.mjs · Check: --check.
4
- // Synced from @paged-media/canvas-wasm@0.64.0
4
+ // Synced from @paged-media/canvas-wasm@0.67.0
5
5
  /* tslint:disable */
6
6
  /* eslint-disable */
7
7
 
@@ -51,7 +51,7 @@ export type SceneBlendMode = "multiply" | "screen" | "overlay" | "darken" | "lig
51
51
  * `paged-mutate`, and the read-only viewer SDK must not link that.
52
52
  * See the crate docs.
53
53
  */
54
- export type Mutation = { op: "insertText"; args: { storyId: string; offset: number; text: string; cell?: TextCellAddr | null } } | { op: "deleteRange"; args: { storyId: string; start: number; end: number; cell?: TextCellAddr | null } } | { op: "applyStyle"; args: { storyId: string; start: number; end: number; style: string; scope: StyleScope; cell?: TextCellAddr | null } } | { op: "insertField"; args: { storyId: string; offset: number; field: FieldKind } } | { op: "insertAnchoredFrame"; args: { storyId: string; offset: number; width: number; height: number; imageUri?: string | null } } | { op: "insertHyperlink"; args: { storyId: string; start: number; end: number; url: string } } | { op: "setFieldValue"; args: { storyId: string; offset: number; value?: string | null } } | { op: "placeImage"; args: { elementId: string; uri: string; fit?: string | null } } | { op: "replaceImageBytes"; args: { elementId: string; bytes?: number[] | null } } | { op: "moveFrame"; args: { frameId: string; transform: [number, number, number, number, number, number] } } | { op: "resizeFrame"; args: { frameId: string; bounds: [number, number, number, number] } } | { op: "linkFrames"; args: { from: string; to: string } } | { op: "unlinkFrames"; args: { frame: string } } | { op: "insertPage"; args: { afterPageId: PageId | null; masterId: string | null } } | { op: "deletePage"; args: { pageId: PageId } } | { op: "resizePage"; args: { pageId: PageId; bounds: [number, number, number, number] } } | { op: "insertFrame"; args: { pageId: PageId; bounds: [number, number, number, number] } } | { op: "insertTextFrame"; args: { pageId: PageId; bounds: [number, number, number, number] } } | { op: "deleteFrame"; args: { frameId: string } } | { op: "insertLine"; args: { pageId: PageId; start: [number, number]; end: [number, number] } } | { op: "insertPath"; args: { pageId: PageId; anchors: PathAnchorSpec[]; open: boolean; smooth?: boolean } } | { op: "setDocumentDefaults"; args: { fillColor: string | null; strokeColor: string | null; strokeWeight: number | null } } | { op: "setColorSettings"; args: { cmykProfileName: string | null; rgbPolicy: string | null; intent: string | null; bpc: boolean | null } } | { op: "setProofSetup"; args: { profileName: string | null; simulatePaperWhite?: boolean; intent: string | null } } | { op: "importSwatchLibrary"; args: { bytes: number[]; groupName?: string | null } } | { op: "setInkSetting"; args: { spotId: string; convertToProcess?: boolean; aliasTo?: string | null } } | { op: "setUseStandardLabForSpots"; args: { enabled: boolean } } | { op: "pathPointInsert"; args: { elementId: ElementId; index: number; anchor: PathAnchorSpec; prevSubpathStarts?: number[] | null } } | { op: "pathPointRemove"; args: { elementId: ElementId; index: number } } | { op: "pathOpenAt"; args: { elementId: ElementId; index: number } } | { op: "outlineStroke"; args: { elementId: ElementId; width: number; cap: string; join: string; miterLimit: number } } | { op: "offsetPath"; args: { elementId: ElementId; delta: number; join: string; miterLimit: number } } | { op: "simplifyPath"; args: { elementId: ElementId; tolerance: number } } | { op: "closePath"; args: { elementId: ElementId; subpath?: number | null } } | { op: "joinPaths"; args: { elementId: ElementId; otherId: ElementId } } | { op: "pasteInto"; args: { containerId: ElementId; childId: ElementId } } | { op: "releaseFrom"; args: { childId: ElementId } } | { op: "reorderElement"; args: { elementId: ElementId; to: ZOrderTarget } } | { op: "applyOpacityMask"; args: { targetId: ElementId; maskId: ElementId; maskType?: string | null; invert?: boolean | null } } | { op: "releaseOpacityMask"; args: { targetId: ElementId } } | { op: "attachTextToPath"; args: { elementId: ElementId; storyId: string; pathTypeAlignment?: string | null; flipPathEffect?: string | null; startBracket?: number | null; endBracket?: number | null } } | { op: "detachTextFromPath"; args: { elementId: ElementId } } | { op: "createGroup"; args: { memberIds: ElementId[] } } | { op: "dissolveGroup"; args: { groupId: string } } | { op: "setGroupTransform"; args: { groupId: string; transform?: [number, number, number, number, number, number] | null } } | { op: "setPluginMetadata"; args: { elementId: ElementId; key: string; value?: string | null; caller?: string | null } } | { op: "pathPointCurveType"; args: { elementId: ElementId; index: number; smooth: boolean } } | { op: "pathPointSet"; args: { elementId: ElementId; index: number; role: PathPointRole; position: [number, number] } } | { op: "batch"; args: { ops: Mutation[] } } | { op: "bindCreated"; args: { handle: string } } | { op: "layerSetVisible"; args: { layerId: string; visible: boolean } } | { op: "layerSetLocked"; args: { layerId: string; locked: boolean } } | { op: "layerSetPrintable"; args: { layerId: string; printable: boolean } } | { op: "layerSetName"; args: { layerId: string; name: string } } | { op: "layerMove"; args: { layerId: string; newIndex: number } } | { op: "layerInsert"; args: { position: number; name: string } } | { op: "layerRemove"; args: { layerId: string } } | { op: "setElementProperty"; args: { elementId: ElementId; path: PropertyPath; value: Value } } | { op: "pathfinderBoolean"; args: { kept: ElementId; others: ElementId[]; kind: PathfinderKind } } | { op: "pathfinderDivide"; args: { elementIds: ElementId[] } } | { op: "pathfinderTrim"; args: { elementIds: ElementId[] } } | { op: "pathfinderMerge"; args: { elementIds: ElementId[] } } | { op: "pathfinderCrop"; args: { elementIds: ElementId[] } } | { op: "pathfinderOutline"; args: { elementIds: ElementId[] } } | { op: "pathfinderMinusBack"; args: { elementIds: ElementId[] } } | { op: "pathfinderFaces"; args: { elementIds: ElementId[]; faces: string[]; mode: FaceSelectMode } } | { op: "createSwatch"; args: { spec: SwatchSpec } } | { op: "editSwatch"; args: { swatchId: string; spec: SwatchSpec } } | { op: "deleteSwatch"; args: { swatchId: string } } | { op: "createGradient"; args: { spec: GradientSpec } } | { op: "editGradient"; args: { gradientId: string; spec: GradientSpec } } | { op: "deleteGradient"; args: { gradientId: string } } | { op: "createColorGroup"; args: { spec: ColorGroupSpec } } | { op: "editColorGroup"; args: { groupId: string; spec: ColorGroupSpec } } | { op: "deleteColorGroup"; args: { groupId: string } } | { op: "createNumberingList"; args: { spec: NumberingListSpec } } | { op: "editNumberingList"; args: { listId: string; spec: NumberingListSpec } } | { op: "deleteNumberingList"; args: { listId: string } } | { op: "createParagraphStyle"; args: { selfId?: string | null; name?: string | null; basedOn?: string | null } } | { op: "renameParagraphStyle"; args: { styleId: string; name: string } } | { op: "deleteParagraphStyle"; args: { styleId: string } } | { op: "createCharacterStyle"; args: { selfId?: string | null; name?: string | null; basedOn?: string | null } } | { op: "renameCharacterStyle"; args: { styleId: string; name: string } } | { op: "deleteCharacterStyle"; args: { styleId: string } } | { op: "createObjectStyle"; args: { selfId?: string | null; name?: string | null; basedOn?: string | null } } | { op: "renameObjectStyle"; args: { styleId: string; name: string } } | { op: "deleteObjectStyle"; args: { styleId: string } } | { op: "createCellStyle"; args: { selfId?: string | null; name?: string | null; basedOn?: string | null } } | { op: "renameCellStyle"; args: { styleId: string; name: string } } | { op: "deleteCellStyle"; args: { styleId: string } } | { op: "createTableStyle"; args: { selfId?: string | null; name?: string | null; basedOn?: string | null } } | { op: "renameTableStyle"; args: { styleId: string; name: string } } | { op: "deleteTableStyle"; args: { styleId: string } } | { op: "setStyleProperty"; args: { collection: StyleCollection; styleId: string; path: PropertyPath; value: Value } } | { op: "insertOval"; args: { pageId: PageId; bounds: [number, number, number, number] } } | { op: "insertGuide"; args: { spreadId: string; orientation: GuideOrientationSpec; position: number; pageIndex?: number } } | { op: "moveGuide"; args: { guideId: string; position: number } } | { op: "deleteGuide"; args: { guideId: string } } | { op: "setConditionVisible"; args: { condition: string; visible: boolean } } | { op: "setFlowGrowRule"; args: { storyId: string; grow: boolean; maxPages?: number | null; copyFrameOptions?: boolean | null } } | { op: "activateConditionSet"; args: { set: string } } | { op: "applyMasterToPage"; args: { page: PageId; master?: string | null } } | { op: "duplicatePage"; args: { page: PageId } } | { op: "insertSection"; args: { atPage: PageId; prefix?: string | null; numberingStyle?: string | null; startAt?: number | null } } | { op: "editSection"; args: { sectionId: string; prefix?: string | null | null; numberingStyle?: string | null; startAt?: number | null | null } } | { op: "deleteSection"; args: { sectionId: string } } | { op: "setRowHeight"; args: { storyId: string; tableId: string; row: number; height?: number | null } } | { op: "setColumnWidth"; args: { storyId: string; tableId: string; col: number; width?: number | null } } | { op: "insertTableRow"; args: { storyId: string; tableId: string; at: number } } | { op: "deleteTableRow"; args: { storyId: string; tableId: string; at: number } } | { op: "insertTableColumn"; args: { storyId: string; tableId: string; at: number } } | { op: "deleteTableColumn"; args: { storyId: string; tableId: string; at: number } } | { op: "insertHeaderRow"; args: { storyId: string; tableId: string } } | { op: "removeHeaderRow"; args: { storyId: string; tableId: string } } | { op: "insertFooterRow"; args: { storyId: string; tableId: string } } | { op: "removeFooterRow"; args: { storyId: string; tableId: string } } | { op: "setCellSpan"; args: { storyId: string; tableId: string; row: number; col: number; rowSpan: number; columnSpan: number } } | { op: "insertTable"; args: { storyId: string; rows: number; cols: number; headerRows?: number; footerRows?: number; columnWidths?: number[]; rowHeights?: number[] } };
54
+ export type Mutation = { op: "insertText"; args: { storyId: string; offset: number; text: string; cell?: TextCellAddr | null } } | { op: "deleteRange"; args: { storyId: string; start: number; end: number; cell?: TextCellAddr | null } } | { op: "applyStyle"; args: { storyId: string; start: number; end: number; style: string; scope: StyleScope; cell?: TextCellAddr | null; paragraph?: number | null } } | { op: "insertField"; args: { storyId: string; offset: number; field: FieldKind } } | { op: "insertAnchoredFrame"; args: { storyId: string; offset: number; width: number; height: number; imageUri?: string | null; paragraph?: number | null } } | { op: "insertHyperlink"; args: { storyId: string; start: number; end: number; url: string } } | { op: "setFieldValue"; args: { storyId: string; offset: number; value?: string | null } } | { op: "placeImage"; args: { elementId: string; uri: string; fit?: string | null } } | { op: "replaceImageBytes"; args: { elementId: string; bytes?: number[] | null } } | { op: "moveFrame"; args: { frameId: string; transform: [number, number, number, number, number, number] } } | { op: "resizeFrame"; args: { frameId: string; bounds: [number, number, number, number] } } | { op: "linkFrames"; args: { from: string; to: string } } | { op: "unlinkFrames"; args: { frame: string } } | { op: "insertPage"; args: { afterPageId: PageId | null; masterId: string | null } } | { op: "deletePage"; args: { pageId: PageId } } | { op: "resizePage"; args: { pageId: PageId; bounds: [number, number, number, number] } } | { op: "insertFrame"; args: { pageId: PageId; bounds: [number, number, number, number] } } | { op: "insertTextFrame"; args: { pageId: PageId; bounds: [number, number, number, number] } } | { op: "deleteFrame"; args: { frameId: string } } | { op: "insertLine"; args: { pageId: PageId; start: [number, number]; end: [number, number] } } | { op: "insertPath"; args: { pageId: PageId; anchors: PathAnchorSpec[]; open: boolean; smooth?: boolean } } | { op: "setDocumentDefaults"; args: { fillColor: string | null; strokeColor: string | null; strokeWeight: number | null } } | { op: "setColorSettings"; args: { cmykProfileName: string | null; rgbPolicy: string | null; intent: string | null; bpc: boolean | null } } | { op: "setProofSetup"; args: { profileName: string | null; simulatePaperWhite?: boolean; intent: string | null } } | { op: "importSwatchLibrary"; args: { bytes: number[]; groupName?: string | null } } | { op: "setInkSetting"; args: { spotId: string; convertToProcess?: boolean; aliasTo?: string | null } } | { op: "setUseStandardLabForSpots"; args: { enabled: boolean } } | { op: "pathPointInsert"; args: { elementId: ElementId; index: number; anchor: PathAnchorSpec; prevSubpathStarts?: number[] | null } } | { op: "pathPointRemove"; args: { elementId: ElementId; index: number } } | { op: "pathOpenAt"; args: { elementId: ElementId; index: number } } | { op: "outlineStroke"; args: { elementId: ElementId; width: number; cap: string; join: string; miterLimit: number } } | { op: "offsetPath"; args: { elementId: ElementId; delta: number; join: string; miterLimit: number } } | { op: "simplifyPath"; args: { elementId: ElementId; tolerance: number } } | { op: "closePath"; args: { elementId: ElementId; subpath?: number | null } } | { op: "joinPaths"; args: { elementId: ElementId; otherId: ElementId } } | { op: "pasteInto"; args: { containerId: ElementId; childId: ElementId } } | { op: "releaseFrom"; args: { childId: ElementId } } | { op: "reorderElement"; args: { elementId: ElementId; to: ZOrderTarget } } | { op: "applyOpacityMask"; args: { targetId: ElementId; maskId: ElementId; maskType?: string | null; invert?: boolean | null } } | { op: "releaseOpacityMask"; args: { targetId: ElementId } } | { op: "attachTextToPath"; args: { elementId: ElementId; storyId: string; pathTypeAlignment?: string | null; flipPathEffect?: string | null; startBracket?: number | null; endBracket?: number | null } } | { op: "detachTextFromPath"; args: { elementId: ElementId } } | { op: "createGroup"; args: { memberIds: ElementId[] } } | { op: "dissolveGroup"; args: { groupId: string } } | { op: "duplicateElements"; args: { elementIds: ElementId[]; offset: [number, number] } } | { op: "setGroupTransform"; args: { groupId: string; transform?: [number, number, number, number, number, number] | null } } | { op: "setPluginMetadata"; args: { elementId: ElementId; key: string; value?: string | null; caller?: string | null } } | { op: "pathPointCurveType"; args: { elementId: ElementId; index: number; smooth: boolean } } | { op: "pathPointSet"; args: { elementId: ElementId; index: number; role: PathPointRole; position: [number, number] } } | { op: "batch"; args: { ops: Mutation[] } } | { op: "bindCreated"; args: { handle: string } } | { op: "layerSetVisible"; args: { layerId: string; visible: boolean } } | { op: "layerSetLocked"; args: { layerId: string; locked: boolean } } | { op: "layerSetPrintable"; args: { layerId: string; printable: boolean } } | { op: "layerSetName"; args: { layerId: string; name: string } } | { op: "layerMove"; args: { layerId: string; newIndex: number } } | { op: "layerInsert"; args: { position: number; name: string } } | { op: "layerRemove"; args: { layerId: string } } | { op: "setElementProperty"; args: { elementId: ElementId; path: PropertyPath; value: Value } } | { op: "pathfinderBoolean"; args: { kept: ElementId; others: ElementId[]; kind: PathfinderKind } } | { op: "pathfinderDivide"; args: { elementIds: ElementId[] } } | { op: "pathfinderTrim"; args: { elementIds: ElementId[] } } | { op: "pathfinderMerge"; args: { elementIds: ElementId[] } } | { op: "pathfinderCrop"; args: { elementIds: ElementId[] } } | { op: "pathfinderOutline"; args: { elementIds: ElementId[] } } | { op: "pathfinderMinusBack"; args: { elementIds: ElementId[] } } | { op: "pathfinderFaces"; args: { elementIds: ElementId[]; faces: string[]; mode: FaceSelectMode } } | { op: "createSwatch"; args: { spec: SwatchSpec } } | { op: "editSwatch"; args: { swatchId: string; spec: SwatchSpec } } | { op: "deleteSwatch"; args: { swatchId: string } } | { op: "createGradient"; args: { spec: GradientSpec } } | { op: "editGradient"; args: { gradientId: string; spec: GradientSpec } } | { op: "deleteGradient"; args: { gradientId: string } } | { op: "createColorGroup"; args: { spec: ColorGroupSpec } } | { op: "editColorGroup"; args: { groupId: string; spec: ColorGroupSpec } } | { op: "deleteColorGroup"; args: { groupId: string } } | { op: "createNumberingList"; args: { spec: NumberingListSpec } } | { op: "editNumberingList"; args: { listId: string; spec: NumberingListSpec } } | { op: "deleteNumberingList"; args: { listId: string } } | { op: "createParagraphStyle"; args: { selfId?: string | null; name?: string | null; basedOn?: string | null } } | { op: "renameParagraphStyle"; args: { styleId: string; name: string } } | { op: "deleteParagraphStyle"; args: { styleId: string } } | { op: "createCharacterStyle"; args: { selfId?: string | null; name?: string | null; basedOn?: string | null } } | { op: "renameCharacterStyle"; args: { styleId: string; name: string } } | { op: "deleteCharacterStyle"; args: { styleId: string } } | { op: "createObjectStyle"; args: { selfId?: string | null; name?: string | null; basedOn?: string | null } } | { op: "renameObjectStyle"; args: { styleId: string; name: string } } | { op: "deleteObjectStyle"; args: { styleId: string } } | { op: "createCellStyle"; args: { selfId?: string | null; name?: string | null; basedOn?: string | null } } | { op: "renameCellStyle"; args: { styleId: string; name: string } } | { op: "deleteCellStyle"; args: { styleId: string } } | { op: "createTableStyle"; args: { selfId?: string | null; name?: string | null; basedOn?: string | null } } | { op: "renameTableStyle"; args: { styleId: string; name: string } } | { op: "deleteTableStyle"; args: { styleId: string } } | { op: "setStyleProperty"; args: { collection: StyleCollection; styleId: string; path: PropertyPath; value: Value } } | { op: "insertOval"; args: { pageId: PageId; bounds: [number, number, number, number] } } | { op: "insertGuide"; args: { spreadId: string; orientation: GuideOrientationSpec; position: number; pageIndex?: number } } | { op: "moveGuide"; args: { guideId: string; position: number } } | { op: "deleteGuide"; args: { guideId: string } } | { op: "setConditionVisible"; args: { condition: string; visible: boolean } } | { op: "setFlowGrowRule"; args: { storyId: string; grow: boolean; maxPages?: number | null; copyFrameOptions?: boolean | null } } | { op: "activateConditionSet"; args: { set: string } } | { op: "applyMasterToPage"; args: { page: PageId; master?: string | null } } | { op: "duplicatePage"; args: { page: PageId } } | { op: "insertSection"; args: { atPage: PageId; prefix?: string | null; numberingStyle?: string | null; startAt?: number | null } } | { op: "editSection"; args: { sectionId: string; prefix?: string | null | null; numberingStyle?: string | null; startAt?: number | null | null } } | { op: "deleteSection"; args: { sectionId: string } } | { op: "setRowHeight"; args: { storyId: string; tableId: string; row: number; height?: number | null } } | { op: "setColumnWidth"; args: { storyId: string; tableId: string; col: number; width?: number | null } } | { op: "insertTableRow"; args: { storyId: string; tableId: string; at: number } } | { op: "deleteTableRow"; args: { storyId: string; tableId: string; at: number } } | { op: "insertTableColumn"; args: { storyId: string; tableId: string; at: number } } | { op: "deleteTableColumn"; args: { storyId: string; tableId: string; at: number } } | { op: "insertHeaderRow"; args: { storyId: string; tableId: string } } | { op: "removeHeaderRow"; args: { storyId: string; tableId: string } } | { op: "insertFooterRow"; args: { storyId: string; tableId: string } } | { op: "removeFooterRow"; args: { storyId: string; tableId: string } } | { op: "setCellSpan"; args: { storyId: string; tableId: string; row: number; col: number; rowSpan: number; columnSpan: number } } | { op: "insertTable"; args: { storyId: string; rows: number; cols: number; headerRows?: number; footerRows?: number; columnWidths?: number[]; rowHeights?: number[] } } | { op: "deleteTable"; args: { storyId: string; tableId: string } };
55
55
 
56
56
  /**
57
57
  * A per-run script budget on the wire (v63). Every field is optional
@@ -102,6 +102,19 @@ export interface SceneLayer {
102
102
  items: SceneItem[];
103
103
  }
104
104
 
105
+ /**
106
+ * A point target the query landed on.
107
+ */
108
+ export interface SnapPointHit {
109
+ source: SnapSource;
110
+ at: [number, number];
111
+ element?: ElementId | null;
112
+ /**
113
+ * Flat anchor index when `source` is `anchor` on a path.
114
+ */
115
+ anchorIndex?: number | null;
116
+ }
117
+
105
118
  /**
106
119
  * A single-line text run in frame-content coordinates (C-1.1).
107
120
  */
@@ -159,6 +172,25 @@ export interface WordBounds {
159
172
  end: number;
160
173
  }
161
174
 
175
+ /**
176
+ * An alignment line the query was pulled onto (one per axis).
177
+ */
178
+ export interface SnapAxisHit {
179
+ source: SnapSource;
180
+ /**
181
+ * x for the vertical line, y for the horizontal one (page-local).
182
+ */
183
+ position: number;
184
+ /**
185
+ * The element whose point the line runs through, for smart guides.
186
+ */
187
+ element?: ElementId | null;
188
+ /**
189
+ * That point, so a host can draw the guide from it to the pointer.
190
+ */
191
+ through?: [number, number] | null;
192
+ }
193
+
162
194
  /**
163
195
  * Axis the snap line guides. `X` is a vertical guide (snaps the x
164
196
  * coordinate); `Y` is a horizontal guide (snaps the y coordinate).
@@ -198,28 +230,40 @@ export interface GroupSpec {
198
230
  * a fresh top-level create never has). `None` ⇒ identity.
199
231
  */
200
232
  itemTransform?: [number, number, number, number, number, number] | null;
233
+ /**
234
+ * C-63 inverse-only — the group\'s own `<BlendingSetting Opacity>`
235
+ * to restore on re-creation. Group opacity became settable
236
+ * (`FrameOpacity` on a `NodeId::Group`), and ungrouping drops the
237
+ * wrapper that carried it; without this an undo of that ungroup
238
+ * brought the group back fully opaque. A fresh create omits it.
239
+ */
240
+ opacity?: number | null;
241
+ /**
242
+ * C-63 inverse-only — the group\'s own `<BlendingSetting
243
+ * BlendMode>`; see [`GroupSpec::opacity`].
244
+ */
245
+ blendMode?: string | null;
201
246
  }
202
247
 
203
248
  /**
204
249
  * B-06 — `RequestNearestPathPoint` reply payload. Coordinates are
205
250
  * in the element\'s local space (the `PathAnchors` space).
206
- */
207
- export interface NearestPathPointResult {
208
- /**
209
- * Flat index of the segment\'s START anchor.
210
- */
211
- segStart: number;
212
- /**
213
- * Flat index of the segment\'s END anchor (wraps to the subpath
214
- * start on a closing segment).
215
- */
216
- segEnd: number;
251
+ * v66 (RFI C-69) — `RequestTextOutlines` reply payload: the frame\'s
252
+ * composed glyphs as closed outlines, in PAGE space (the space
253
+ * `insertPath` takes), grouped into one run per fill colour so each
254
+ * becomes one compound path. Outlines are exactly the shapes the
255
+ * renderer fills (the same `FillPath` commands), so what is inserted
256
+ * looks like what was on screen. Stroked text, gradients on text and
257
+ * overset text are not included.
258
+ */
259
+ export interface TextOutlinesResult {
260
+ id: ElementId;
261
+ pageId: PageId;
262
+ runs: TextOutlineRun[];
217
263
  /**
218
- * Curve parameter on that segment, 0..=1.
264
+ * Glyphs left out (stroked, or a non-solid paint).
219
265
  */
220
- t: number;
221
- point: [number, number];
222
- distance: number;
266
+ skippedGlyphs?: number;
223
267
  }
224
268
 
225
269
  /**
@@ -355,6 +399,14 @@ export interface TextPathSpec {
355
399
  endBracket?: number | null;
356
400
  }
357
401
 
402
+ /**
403
+ * C-65 — one plugin-metadata Label entry on a scene-tree node.
404
+ */
405
+ export interface PluginMetadataEntry {
406
+ key: string;
407
+ value: string;
408
+ }
409
+
358
410
  /**
359
411
  * Canonical selection / caret. `start == end` is a caret;
360
412
  * `start < end` is a range. Endpoints are normalised so `start ≤
@@ -525,16 +577,19 @@ export interface RunContent {
525
577
  }
526
578
 
527
579
  /**
528
- * Description of a node about to be inserted. Carries the minimal
529
- * Stage-1 supported field set plus `item_transform` — `RemoveNode` →
530
- * undo → re-insertion round-trips these reliably. (Without the
531
- * transform, undoing a deleteFrame snapped the frame back to the page
532
- * origin — the editor-suite AC-E2E-PROVE-3 finding.) Remaining
533
- * non-essential fields (drop_shadow, opacity, effects, …) still
534
- * default on re-insertion; that residue of the Stage 1 limitation
535
- * tightens in later stages.
580
+ * Description of a node about to be inserted. The per-kind variants
581
+ * carry what a CREATION names — geometry, the fill/stroke triple, the
582
+ * path tables, a transform — and everything else takes its default.
583
+ *
584
+ * They used to double as what `RemoveNode` captured for its inverse,
585
+ * which is how a delete → undo brought back a bare frame: opacity,
586
+ * effects, corners, a placed image, every field outside this short
587
+ * list re-defaulted (RFI C-75; the transform had been added for the
588
+ * same reason one field at a time). A removed node is now captured
589
+ * WHOLE, as [`NodeSpec::Captured`], and these variants describe new
590
+ * nodes only.
536
591
  */
537
- export type NodeSpec = { kind: "textFrame"; self_id: string; bounds: [number, number, number, number]; fill_color?: string | null; stroke_color?: string | null; stroke_weight?: number | null; item_transform?: [number, number, number, number, number, number] | null; parent_story?: string | null } | { kind: "rectangle"; self_id: string; bounds: [number, number, number, number]; fill_color?: string | null; stroke_color?: string | null; stroke_weight?: number | null; item_transform?: [number, number, number, number, number, number] | null } | { kind: "oval"; self_id: string; bounds: [number, number, number, number]; fill_color?: string | null; stroke_color?: string | null; stroke_weight?: number | null; item_transform?: [number, number, number, number, number, number] | null } | { kind: "graphicLine"; self_id: string; bounds: [number, number, number, number]; anchors?: PathAnchorSpec[]; subpath_starts?: number[]; subpath_open?: boolean[]; stroke_color?: string | null; stroke_weight?: number | null; item_transform?: [number, number, number, number, number, number] | null } | { kind: "polygon"; self_id: string; bounds: [number, number, number, number]; anchors?: PathAnchorSpec[]; subpath_starts?: number[]; subpath_open?: boolean[]; fill_color?: string | null; stroke_color?: string | null; stroke_weight?: number | null; item_transform?: [number, number, number, number, number, number] | null } | { kind: "cloneTranslate"; self_id: string; source: NodeId; dx: number; dy: number; destination_spread_id?: string | null } | { kind: "table"; self_id: string; rows: number; cols: number; header_rows?: number; footer_rows?: number; column_widths?: number[]; row_heights?: number[] };
592
+ export type NodeSpec = { kind: "textFrame"; self_id: string; bounds: [number, number, number, number]; fill_color?: string | null; stroke_color?: string | null; stroke_weight?: number | null; item_transform?: [number, number, number, number, number, number] | null; parent_story?: string | null } | { kind: "rectangle"; self_id: string; bounds: [number, number, number, number]; fill_color?: string | null; stroke_color?: string | null; stroke_weight?: number | null; item_transform?: [number, number, number, number, number, number] | null } | { kind: "oval"; self_id: string; bounds: [number, number, number, number]; fill_color?: string | null; stroke_color?: string | null; stroke_weight?: number | null; item_transform?: [number, number, number, number, number, number] | null } | { kind: "graphicLine"; self_id: string; bounds: [number, number, number, number]; anchors?: PathAnchorSpec[]; subpath_starts?: number[]; subpath_open?: boolean[]; stroke_color?: string | null; stroke_weight?: number | null; item_transform?: [number, number, number, number, number, number] | null } | { kind: "polygon"; self_id: string; bounds: [number, number, number, number]; anchors?: PathAnchorSpec[]; subpath_starts?: number[]; subpath_open?: boolean[]; fill_color?: string | null; stroke_color?: string | null; stroke_weight?: number | null; item_transform?: [number, number, number, number, number, number] | null } | { kind: "cloneTranslate"; self_id: string; source: NodeId; dx: number; dy: number; destination_spread_id?: string | null } | { kind: "captured"; node: NodeId; json: string; image_bytes?: number[] | null } | { kind: "table"; self_id: string; rows: number; cols: number; header_rows?: number; footer_rows?: number; column_widths?: number[]; row_heights?: number[] };
538
593
 
539
594
  /**
540
595
  * Direction for [`caret_nav`].
@@ -544,7 +599,7 @@ export type CaretDirection = "up" | "down";
544
599
  /**
545
600
  * Discriminated payload of a `WorkerToMain` message.
546
601
  */
547
- export type WorkerToMainKind = { kind: "ready"; payload: { protocol: ProtocolVersion } } | { kind: "documentLoaded"; payload: DocumentHandle } | { kind: "loadFailed"; payload: { error: LoadError } } | { kind: "mutationFailed"; payload: { error: WorkerError } } | { kind: "displayListReady"; payload: { pageId: PageId; lod: LodTier; commands: number; layoutGeneration: number; numberingGeneration: number } } | { kind: "hitResult"; payload: HitResult } | { kind: "pagesDirty"; payload: { pageIds: PageId[] } } | { kind: "storyDirty"; payload: { storyId: string } } | { kind: "warning"; payload: { kind: string; details: string } } | { kind: "stats"; payload: DocumentStats } | { kind: "snapshotReady"; payload: SnapshotPng } | { kind: "snapshotFailed"; payload: { error: SnapshotError } } | { kind: "mutationApplied"; payload: { clientSeq: number; appliedSeq: number; pageIds: PageId[]; cacheStats: LayoutCacheStats; createdId?: ElementId | null; minted?: MintedElement[]; pageStructureChanged?: boolean; pageSizesPt?: [number, number][] | null; reflow?: FrameReflowInfo | null } } | { kind: "selectionGeometry"; payload: { rects: SelectionRect[] } } | { kind: "caretGeometry"; payload: { caret: CaretGeometry | null } } | { kind: "caretNavResult"; payload: { offset?: number | null } } | { kind: "lineBoundsResult"; payload: { bounds?: LineBounds | null } } | { kind: "wordBoundsResult"; payload: { bounds?: WordBounds | null } } | { kind: "paragraphBoundsResult"; payload: { bounds?: ParagraphBounds | null } } | { kind: "storyContentResult"; payload: { content?: StoryContent | null } } | { kind: "undoApplied"; payload: { undoneSeq: number; appliedSeq: number; pageIds: PageId[]; cacheStats: LayoutCacheStats; pageStructureChanged?: boolean; pageSizesPt?: [number, number][] | null } } | { kind: "redoApplied"; payload: { redoneSeq: number; appliedSeq: number; pageIds: PageId[]; cacheStats: LayoutCacheStats; pageStructureChanged?: boolean; pageSizesPt?: [number, number][] | null } } | { kind: "fontRegistered"; payload: { family: string } } | { kind: "fontRegistryCleared" } | { kind: "colorProfileRegistered"; payload: { name: string } } | { kind: "elementSelectionApplied"; payload: { ids: ElementId[] } } | { kind: "marqueeHits"; payload: { ids: ElementId[] } } | { kind: "elementGeometry"; payload: { items: ElementGeometryItem[] } } | { kind: "groupLeaves"; payload: { ids: ElementId[] } } | { kind: "pathAnchors"; payload: { result: PathAnchorsResult | null } } | { kind: "planarRegions"; payload: { result: PlanarRegionsResult } } | { kind: "nearestPathPoint"; payload: { result: NearestPathPointResult | null } } | { kind: "layers"; payload: { items: LayerSummary[] } } | { kind: "collectionReply"; payload: { name: CollectionName; items: any } } | { kind: "frameChainResult"; payload: { links: FrameChainLink[] } } | { kind: "documentPlaceholders"; payload: { items: PlaceholderItem[] } } | { kind: "placedAssetBytes"; payload: { elementId: string; found: boolean; uri: string; width: number; height: number; encoded: number[] } } | { kind: "fontFaceBytes"; payload: { found: boolean; family: string; style: string | null; postscriptName: string | null; format: string; bytes: number[] } } | { kind: "measureTextResult"; payload: { advance: number; ascender: number; descender: number } } | { kind: "sceneLayerApplied"; payload: { elementId: string; applied: boolean } } | { kind: "resourceClaimApplied"; payload: { imageId: string; applied: boolean; needed?: ResourceTilesNeededWire[] } } | { kind: "resourceTilesNeeded"; payload: ResourceTilesNeededWire } | { kind: "frameReflow"; payload: { frameId: string; contentBox: [number, number, number, number] } } | { kind: "documentMetaReply"; payload: { meta: DocumentMeta } } | { kind: "colorPreviewReply"; payload: { result: ColorPreview | null } } | { kind: "colorComputeReply"; payload: { rgbHex: string; cmyk: [number, number, number, number] | null; outOfGamut: boolean } } | { kind: "gradientDetailReply"; payload: { result: GradientDetail | null } } | { kind: "swatchLibraryExported"; payload: { aseBytes: number[] } } | { kind: "exportPdfBegun"; payload: { session: number; pageCount: number } } | { kind: "exportPdfProgress"; payload: { session: number; done: number; total: number } } | { kind: "pdfExported"; payload: { pdfBytes: number[]; diagnostics: string[]; findings?: PreflightFinding[] } } | { kind: "exportPdfCancelled"; payload: { session: number } } | { kind: "exportPdfFailed"; payload: { error: string } } | { kind: "idmlExported"; payload: { idmlBytes: number[]; lost?: string[]; links?: ExportedLinkWire[] } } | { kind: "exportIdmlFailed"; payload: { error: string } } | { kind: "pagedPartWritten"; payload: {} } | { kind: "pagedPartRead"; payload: { found: boolean; bytes: number[] } } | { kind: "pagedPartList"; payload: { paths: string[] } } | { kind: "pagedExported"; payload: { bytes: number[] } } | { kind: "pagedPartFailed"; payload: { error: string } } | { kind: "elementProperties"; payload: { result: ElementProperties | null } } | { kind: "sceneTree"; payload: { roots: SceneTreeNode[] } } | { kind: "scriptResult"; payload: { output: string[]; error: string | null; budgetKind?: ScriptBudgetKind } } | { kind: "gestureBegun"; payload: { handle: GestureHandle } } | { kind: "gestureUpdated"; payload: { handle: GestureHandle; pageIds: PageId[]; snapLines?: SnapLine[] } } | { kind: "gestureCommitted"; payload: { handle: GestureHandle; appliedSeq: number; pageIds: PageId[]; cacheStats: LayoutCacheStats } } | { kind: "gestureCancelled"; payload: { handle: GestureHandle; pageIds: PageId[] } } | { kind: "gestureFailed"; payload: { error: GestureFailure } } | { kind: "attachReady"; payload: { gpuActive: boolean; sceneCacheBudget: number } } | { kind: "gestureSnapLines"; payload: { snapLines: SnapLine[] } } | { kind: "resolutionDone"; payload: ResolutionResult };
602
+ export type WorkerToMainKind = { kind: "ready"; payload: { protocol: ProtocolVersion } } | { kind: "documentLoaded"; payload: DocumentHandle } | { kind: "loadFailed"; payload: { error: LoadError } } | { kind: "mutationFailed"; payload: { error: WorkerError } } | { kind: "displayListReady"; payload: { pageId: PageId; lod: LodTier; commands: number; layoutGeneration: number; numberingGeneration: number } } | { kind: "hitResult"; payload: HitResult } | { kind: "pagesDirty"; payload: { pageIds: PageId[] } } | { kind: "storyDirty"; payload: { storyId: string } } | { kind: "warning"; payload: { kind: string; details: string } } | { kind: "stats"; payload: DocumentStats } | { kind: "snapshotReady"; payload: SnapshotPng } | { kind: "snapshotFailed"; payload: { error: SnapshotError } } | { kind: "mutationApplied"; payload: { clientSeq: number; appliedSeq: number; pageIds: PageId[]; cacheStats: LayoutCacheStats; createdId?: ElementId | null; minted?: MintedElement[]; pageStructureChanged?: boolean; pageSizesPt?: [number, number][] | null; reflow?: FrameReflowInfo | null } } | { kind: "selectionGeometry"; payload: { rects: SelectionRect[] } } | { kind: "caretGeometry"; payload: { caret: CaretGeometry | null } } | { kind: "caretNavResult"; payload: { offset?: number | null } } | { kind: "lineBoundsResult"; payload: { bounds?: LineBounds | null } } | { kind: "wordBoundsResult"; payload: { bounds?: WordBounds | null } } | { kind: "paragraphBoundsResult"; payload: { bounds?: ParagraphBounds | null } } | { kind: "storyContentResult"; payload: { content?: StoryContent | null } } | { kind: "undoApplied"; payload: { undoneSeq: number; appliedSeq: number; pageIds: PageId[]; cacheStats: LayoutCacheStats; pageStructureChanged?: boolean; pageSizesPt?: [number, number][] | null } } | { kind: "redoApplied"; payload: { redoneSeq: number; appliedSeq: number; pageIds: PageId[]; cacheStats: LayoutCacheStats; pageStructureChanged?: boolean; pageSizesPt?: [number, number][] | null } } | { kind: "fontRegistered"; payload: { family: string; pageIds?: PageId[]; pageStructureChanged?: boolean; pageSizesPt?: [number, number][] | null } } | { kind: "fontRegistryCleared"; payload: { pageIds?: PageId[]; pageStructureChanged?: boolean; pageSizesPt?: [number, number][] | null } } | { kind: "colorProfileRegistered"; payload: { name: string } } | { kind: "elementSelectionApplied"; payload: { ids: ElementId[] } } | { kind: "marqueeHits"; payload: { ids: ElementId[] } } | { kind: "elementGeometry"; payload: { items: ElementGeometryItem[] } } | { kind: "groupLeaves"; payload: { ids: ElementId[] } } | { kind: "pathAnchors"; payload: { result: PathAnchorsResult | null } } | { kind: "textOutlines"; payload: { result: TextOutlinesResult | null } } | { kind: "snapPoint"; payload: { result: SnapPointResult } } | { kind: "snapSettingsApplied"; payload: { settings: SnapSettings } } | { kind: "planarRegions"; payload: { result: PlanarRegionsResult } } | { kind: "nearestPathPoint"; payload: { result: NearestPathPointResult | null } } | { kind: "layers"; payload: { items: LayerSummary[] } } | { kind: "collectionReply"; payload: { name: CollectionName; items: any } } | { kind: "frameChainResult"; payload: { links: FrameChainLink[] } } | { kind: "documentPlaceholders"; payload: { items: PlaceholderItem[] } } | { kind: "placedAssetBytes"; payload: { elementId: string; found: boolean; uri: string; width: number; height: number; encoded: number[] } } | { kind: "fontFaceBytes"; payload: { found: boolean; family: string; style: string | null; postscriptName: string | null; format: string; bytes: number[] } } | { kind: "measureTextResult"; payload: { advance: number; ascender: number; descender: number } } | { kind: "sceneLayerApplied"; payload: { elementId: string; applied: boolean; pageIds?: PageId[] } } | { kind: "resourceClaimApplied"; payload: { imageId: string; applied: boolean; needed?: ResourceTilesNeededWire[] } } | { kind: "resourceTilesNeeded"; payload: ResourceTilesNeededWire } | { kind: "frameReflow"; payload: { frameId: string; contentBox: [number, number, number, number] } } | { kind: "documentMetaReply"; payload: { meta: DocumentMeta } } | { kind: "colorPreviewReply"; payload: { result: ColorPreview | null } } | { kind: "colorComputeReply"; payload: { rgbHex: string; cmyk: [number, number, number, number] | null; outOfGamut: boolean } } | { kind: "gradientDetailReply"; payload: { result: GradientDetail | null } } | { kind: "swatchLibraryExported"; payload: { aseBytes: number[] } } | { kind: "exportPdfBegun"; payload: { session: number; pageCount: number } } | { kind: "exportPdfProgress"; payload: { session: number; done: number; total: number } } | { kind: "pdfExported"; payload: { pdfBytes: number[]; diagnostics: string[]; findings?: PreflightFinding[] } } | { kind: "exportPdfCancelled"; payload: { session: number } } | { kind: "exportPdfFailed"; payload: { error: string } } | { kind: "idmlExported"; payload: { idmlBytes: number[]; lost?: string[]; links?: ExportedLinkWire[] } } | { kind: "exportIdmlFailed"; payload: { error: string } } | { kind: "pagedPartWritten"; payload: {} } | { kind: "pagedPartRead"; payload: { found: boolean; bytes: number[] } } | { kind: "pagedPartList"; payload: { paths: string[] } } | { kind: "pagedPartDeleted"; payload: { existed: boolean } } | { kind: "pagedExported"; payload: { bytes: number[] } } | { kind: "pagedPartFailed"; payload: { error: string } } | { kind: "elementProperties"; payload: { result: ElementProperties | null } } | { kind: "styleProperties"; payload: { result: StyleProperties | null } } | { kind: "sceneTree"; payload: { roots: SceneTreeNode[] } } | { kind: "scriptResult"; payload: { output: string[]; error: string | null; budgetKind?: ScriptBudgetKind } } | { kind: "gestureBegun"; payload: { handle: GestureHandle } } | { kind: "gestureUpdated"; payload: { handle: GestureHandle; pageIds: PageId[]; snapLines?: SnapLine[] } } | { kind: "gestureCommitted"; payload: { handle: GestureHandle; appliedSeq: number; pageIds: PageId[]; cacheStats: LayoutCacheStats } } | { kind: "gestureCancelled"; payload: { handle: GestureHandle; pageIds: PageId[] } } | { kind: "gestureFailed"; payload: { error: GestureFailure } } | { kind: "attachReady"; payload: { gpuActive: boolean; sceneCacheBudget: number } } | { kind: "gestureSnapLines"; payload: { snapLines: SnapLine[] } } | { kind: "resolutionDone"; payload: ResolutionResult };
548
603
 
549
604
  /**
550
605
  * Editor-ops — wire mirror of `paged_model::GradientFeatherParams`.
@@ -586,7 +641,7 @@ export interface GradientFeatherStopSpec {
586
641
  * text-side caret + range live in `ContentSelection`); the
587
642
  * variant exists so the apply layer can be reached via the
588
643
  * existing `Mutation::SetElementProperty` wire shape — see
589
- * `docs/paged/sdk-implementation-plan.md` §3c.1 ADR.
644
+ * the editor\'s client-SDK implementation plan §3c.1 (not published).
590
645
  */
591
646
  export type ElementId = { kind: "textFrame"; id: string } | { kind: "rectangle"; id: string } | { kind: "oval"; id: string } | { kind: "polygon"; id: string } | { kind: "graphicLine"; id: string } | { kind: "group"; id: string } | { kind: "storyRange"; id: { story_id: string; start: number; end: number } } | { kind: "table"; id: { story_id: string; table_id: string } } | { kind: "tableCell"; id: { story_id: string; table_id: string; row: number; col: number } };
592
647
 
@@ -681,6 +736,18 @@ export interface SceneTreeNode {
681
736
  */
682
737
  label: string;
683
738
  children?: SceneTreeNode[];
739
+ /**
740
+ * C-65 — the item\'s plugin metadata (its reserved-namespace
741
+ * `x-paged:` Label entries, the same rows `RequestElementProperties`
742
+ * reports as `pluginMetadata`), so one tree read answers what used to
743
+ * take one property read PER LEAF: paged.draw\'s link discovery cost
744
+ * 1 403 round trips on a 1 403-leaf document. PRESENT on every page
745
+ * ITEM row — empty when the item carries none — and omitted only for
746
+ * spread / page rows, so a reader can tell \"this engine reports
747
+ * metadata here and there is none\" from \"this engine predates the
748
+ * field\" (an older engine omits it everywhere). Additive.
749
+ */
750
+ pluginMetadata?: PluginMetadataEntry[];
684
751
  }
685
752
 
686
753
  /**
@@ -718,6 +785,18 @@ export interface ElementProperties {
718
785
  entries: PropertyEntry[];
719
786
  }
720
787
 
788
+ /**
789
+ * Leave an element (or some of its anchors) out of the targets. With
790
+ * `anchors` absent the whole element is ignored; with `anchors` given,
791
+ * those anchors (flat indices, the `pathAnchors` numbering) are not
792
+ * targets and neither are the element\'s segments, since a host editing
793
+ * those anchors is previewing a path the engine has not seen yet.
794
+ */
795
+ export interface SnapExclude {
796
+ id: ElementId;
797
+ anchors?: number[] | null;
798
+ }
799
+
721
800
  /**
722
801
  * Lightweight serialisable variant — the canvas worker hands this
723
802
  * (encoded as a `WorkerToMain` message) to the main thread. The
@@ -839,6 +918,12 @@ export type SceneItem = { kind: "fillPath"; path: ScenePathSeg[]; paint: ScenePa
839
918
  * each) or re-discover the ids with a scene walk. This is the list it
840
919
  * could not get.
841
920
  *
921
+ * A `DuplicateElements` fills it too (C-64): it is the one single
922
+ * mutation that mints more than one element — a clone per source, in
923
+ * the order the sources were named — so `created_id` (its LAST clone)
924
+ * could not carry the answer. A group\'s clone is one entry, its group
925
+ * id; a text frame\'s clone carries the story copied for it.
926
+ *
842
927
  * `handle` is the name a C-15 `BindCreated` child gave the element
843
928
  * (`None` when nothing named it); `story_id` is the story the creating
844
929
  * child minted alongside it — a text frame\'s `ParentStory` — which is
@@ -876,6 +961,41 @@ export interface FieldChange {
876
961
  newText: string;
877
962
  }
878
963
 
964
+ /**
965
+ * One fill colour\'s glyph outlines (see [`TextOutlinesResult`]).
966
+ */
967
+ export interface TextOutlineRun {
968
+ /**
969
+ * sRGB, 0..1 — the colour the renderer filled with.
970
+ */
971
+ rgb: [number, number, number];
972
+ /**
973
+ * The CMYK the paint carried, 0..1, when it was a process colour.
974
+ */
975
+ cmyk?: [number, number, number, number] | null;
976
+ anchors: PathAnchorTriple[];
977
+ subpathStarts: number[];
978
+ glyphs: number;
979
+ }
980
+
981
+ /**
982
+ * One point query. `point` is page-local pt on `page_id`.
983
+ */
984
+ export interface SnapPointQuery {
985
+ pageId: PageId;
986
+ point: [number, number];
987
+ /**
988
+ * CSS px per pt at the current zoom. Absent ⇒ 1.
989
+ */
990
+ cameraScale?: number | null;
991
+ exclude?: SnapExclude[];
992
+ /**
993
+ * Points only the caller knows about, page-local — the anchors of a
994
+ * path still being drawn. Targets as points and as alignment lines.
995
+ */
996
+ extraPoints?: [number, number][];
997
+ }
998
+
879
999
  /**
880
1000
  * One stop of a gradient on the wire. Mirrors `GradientStopRef`.
881
1001
  */
@@ -992,6 +1112,14 @@ export interface ElementGeometryItem {
992
1112
  * of `Translate`.
993
1113
  */
994
1114
  hasImage?: boolean;
1115
+ /**
1116
+ * The story a TEXT FRAME shows (its `ParentStory`); `None` for every
1117
+ * other kind. `hitTest` answers `storyId: null` for an EMPTY frame
1118
+ * (the text hit path needs a laid-out line), so a frame\'s story was
1119
+ * discoverable only by diffing the stories collection around its
1120
+ * insert. Additive: absent from the JSON when `None`.
1121
+ */
1122
+ storyId?: string;
995
1123
  }
996
1124
 
997
1125
  /**
@@ -1075,6 +1203,15 @@ export type ResizeHandle = "north" | "south" | "east" | "west" | "northEast" | "
1075
1203
  export interface GestureAnchor {
1076
1204
  pageId: PageId;
1077
1205
  pointInPage: [number, number];
1206
+ /**
1207
+ * C-67 — the point Rotate / Scale / Shear turn about, page-local on
1208
+ * the same page as `point_in_page`. Absent (every caller before it
1209
+ * existed) keeps the union centroid of the targets — Illustrator\'s
1210
+ * default reference point; a click-to-set pivot, a reference-point
1211
+ * grid or \"about a corner\" pass it. Additive (`serde(default)`), so
1212
+ * it needs no protocol bump.
1213
+ */
1214
+ pivotInPage?: [number, number];
1078
1215
  }
1079
1216
 
1080
1217
  /**
@@ -1204,6 +1341,12 @@ export interface StorySummary {
1204
1341
  * older client that ignores it still reads the `overset` flag.
1205
1342
  */
1206
1343
  oversetAt?: OversetAt;
1344
+ /**
1345
+ * v65 (thoughts ADR 026) — the story\'s grow rule, in the shape
1346
+ * `Mutation::SetFlowGrowRule` takes (`grow` is always `true` here:
1347
+ * a cleared rule reads as `None`). `None` = a fixed chain.
1348
+ */
1349
+ growRule?: StoryGrowRule | null;
1207
1350
  }
1208
1351
 
1209
1352
  /**
@@ -1833,7 +1976,7 @@ export interface DocumentStats {
1833
1976
  * document\'s `BTreeMap` palettes/stylesheets rather than the scene
1834
1977
  * tree, so they\'re top-level variants rather than `InsertNode`.
1835
1978
  */
1836
- export type Operation = { kind: "SetProperty"; node: NodeId; path: PropertyPath; value: Value } | { kind: "InsertNode"; parent: NodeId; position: number; node: NodeSpec; z_slot?: number | null } | { kind: "RemoveNode"; node: NodeId } | { kind: "MoveNode"; node: NodeId; new_parent: NodeId; position: number } | { kind: "ReorderNode"; node: NodeId; target: ZOrderTarget } | { kind: "Batch"; ops: Operation[] } | { kind: "InsertPage"; after_page_id?: string | null; master_id?: string | null; spread_self_id?: string | null; page_self_id?: string | null; restore_spread_json?: string | null } | { kind: "RemovePage"; page_id: string } | { kind: "MoveLayer"; layer_id: string; new_index: number } | { kind: "InsertLayer"; position: number; name: string; self_id?: string | null } | { kind: "RemoveLayer"; layer_id: string } | { kind: "CreateSwatch"; spec: SwatchSpec } | { kind: "EditSwatch"; swatch_id: string; spec: SwatchSpec } | { kind: "DeleteSwatch"; swatch_id: string } | { kind: "CreateParagraphStyle"; self_id?: string | null; name?: string | null; based_on?: string | null; restore_json?: string | null } | { kind: "RenameParagraphStyle"; style_id: string; name: string } | { kind: "DeleteParagraphStyle"; style_id: string } | { kind: "CreateCharacterStyle"; self_id?: string | null; name?: string | null; based_on?: string | null; restore_json?: string | null } | { kind: "RenameCharacterStyle"; style_id: string; name: string } | { kind: "DeleteCharacterStyle"; style_id: string } | { kind: "CreateObjectStyle"; self_id?: string | null; name?: string | null; based_on?: string | null; restore_json?: string | null } | { kind: "RenameObjectStyle"; style_id: string; name: string } | { kind: "DeleteObjectStyle"; style_id: string } | { kind: "CreateCellStyle"; self_id?: string | null; name?: string | null; based_on?: string | null; restore_json?: string | null } | { kind: "RenameCellStyle"; style_id: string; name: string } | { kind: "DeleteCellStyle"; style_id: string } | { kind: "CreateTableStyle"; self_id?: string | null; name?: string | null; based_on?: string | null; restore_json?: string | null } | { kind: "RenameTableStyle"; style_id: string; name: string } | { kind: "DeleteTableStyle"; style_id: string } | { kind: "CreateGroup"; spec: GroupSpec } | { kind: "DissolveGroup"; group_id: string; restore_slots?: number[] | null } | { kind: "SetGroupTransform"; group: string; transform?: [number, number, number, number, number, number] | null; prev?: [number, number, number, number, number, number] | null } | { kind: "CreateGradient"; spec: GradientSpec } | { kind: "EditGradient"; gradient_id: string; spec: GradientSpec } | { kind: "DeleteGradient"; gradient_id: string } | { kind: "CreateColorGroup"; spec: ColorGroupSpec } | { kind: "EditColorGroup"; group_id: string; spec: ColorGroupSpec } | { kind: "DeleteColorGroup"; group_id: string } | { kind: "CreateNumberingList"; spec: NumberingListSpec } | { kind: "EditNumberingList"; list_id: string; spec: NumberingListSpec } | { kind: "DeleteNumberingList"; list_id: string } | { kind: "SetStyleProperty"; collection: StyleCollection; style_id: string; path: PropertyPath; value: Value } | { kind: "PathfinderBoolean"; kept: NodeId; others: NodeId[]; opKind: PathfinderKind } | { kind: "PathfinderRegion"; elements: NodeId[]; verb: PathfinderRegionVerb } | { kind: "PathfinderFaces"; elements: NodeId[]; faces: string[]; mode: FaceSelectMode } | { kind: "JoinPaths"; kept: NodeId; other: NodeId } | { kind: "PasteInto"; container: NodeId; child: NodeId; child_index?: number | null } | { kind: "ReleaseFrom"; child: NodeId; restore_slot?: number | null } | { kind: "ApplyOpacityMask"; target: NodeId; mask: NodeId; mask_type?: OpacityMaskMode; invert?: boolean } | { kind: "ReleaseOpacityMask"; target: NodeId; restore_slot?: number | null } | { kind: "AttachTextToPath"; host: NodeId; story_id: string; spec?: TextPathSpec } | { kind: "DetachTextFromPath"; host: NodeId; index?: number | null; restore?: TextPathSpec | null } | { kind: "LinkFrames"; from: string; to: string } | { kind: "UnlinkFrames"; frame: string; prev_next?: string | null; restore_target?: [string, string | null, string | null] | null } | { kind: "ApplyStyle"; story_id: string; start: number; end: number; style: string; scope: StyleScope; cell?: CellAddr | null } | { kind: "InsertField"; story_id: string; offset: number; field: FieldKind } | { kind: "DeleteField"; story_id: string; offset: number; field: FieldKind } | { kind: "InsertAnchoredFrame"; story_id: string; offset: number; width: number; height: number; image_uri?: string | null; self_id: string } | { kind: "RemoveAnchoredFrame"; story_id: string; self_id: string } | { kind: "InsertHyperlink"; story_id: string; start: number; end: number; url: string; source_id: string; dest_id: string; hyperlink_id: string } | { kind: "RemoveHyperlink"; story_id: string; start: number; end: number; url: string; source_id: string; dest_id: string; hyperlink_id: string } | { kind: "SetFieldValue"; story_id: string; offset: number; value?: string | null } | { kind: "PlaceImage"; frame: NodeId; image_uri?: string | null; fit?: string | null } | { kind: "ReplaceImageBytes"; frame: NodeId; bytes?: number[] | null; prior_has_image_element?: boolean | null } | { kind: "InsertGuide"; spread_id: string; orientation: GuideOrientationSpec; position: number; page_index?: number; guide_id?: string | null } | { kind: "MoveGuide"; guide_id: string; position: number } | { kind: "DeleteGuide"; guide_id: string } | { kind: "SetConditionVisible"; condition: string; visible: boolean } | { kind: "SetFlowGrowRule"; story_id: string; rule: FlowGrowRule | null } | { kind: "ActivateConditionSet"; set: string } | { kind: "RestoreConditionVisibility"; states: [string, boolean][] } | { kind: "ApplyMasterToPage"; page: string; master?: string | null } | { kind: "DuplicatePage"; page: string; clone_spread_json?: string | null } | { kind: "InsertSection"; at_page: string; prefix?: string | null; numbering_style?: string | null; start_at?: number | null; self_id?: string | null } | { kind: "EditSection"; section_id: string; prefix?: string | null | null; numbering_style?: string | null; start_at?: number | null | null } | { kind: "DeleteSection"; section_id: string } | { kind: "SetRowHeight"; story_id: string; table_id: string; row: number; height?: number | null } | { kind: "SetColumnWidth"; story_id: string; table_id: string; col: number; width?: number | null } | { kind: "InsertTableRow"; story_id: string; table_id: string; at: number; restore?: TableLineRestoreJson | null } | { kind: "DeleteTableRow"; story_id: string; table_id: string; at: number } | { kind: "InsertTableColumn"; story_id: string; table_id: string; at: number; restore?: TableLineRestoreJson | null } | { kind: "DeleteTableColumn"; story_id: string; table_id: string; at: number } | { kind: "InsertHeaderRow"; story_id: string; table_id: string; restore?: TableLineRestoreJson | null } | { kind: "RemoveHeaderRow"; story_id: string; table_id: string } | { kind: "InsertFooterRow"; story_id: string; table_id: string; restore?: TableLineRestoreJson | null } | { kind: "RemoveFooterRow"; story_id: string; table_id: string } | { kind: "SetCellSpan"; story_id: string; table_id: string; row: number; col: number; row_span: number; column_span: number };
1979
+ export type Operation = { kind: "SetProperty"; node: NodeId; path: PropertyPath; value: Value } | { kind: "InsertNode"; parent: NodeId; position: number; node: NodeSpec; z_slot?: number | null } | { kind: "RemoveNode"; node: NodeId } | { kind: "MoveNode"; node: NodeId; new_parent: NodeId; position: number } | { kind: "ReorderNode"; node: NodeId; target: ZOrderTarget } | { kind: "Batch"; ops: Operation[] } | { kind: "RemoveStory"; story_id: string } | { kind: "RestoreStory"; position: number; story_json: string } | { kind: "InsertPage"; after_page_id?: string | null; master_id?: string | null; spread_self_id?: string | null; page_self_id?: string | null; restore_spread_json?: string | null } | { kind: "RemovePage"; page_id: string } | { kind: "MoveLayer"; layer_id: string; new_index: number } | { kind: "InsertLayer"; position: number; name: string; self_id?: string | null } | { kind: "RemoveLayer"; layer_id: string } | { kind: "CreateSwatch"; spec: SwatchSpec } | { kind: "EditSwatch"; swatch_id: string; spec: SwatchSpec } | { kind: "DeleteSwatch"; swatch_id: string } | { kind: "CreateParagraphStyle"; self_id?: string | null; name?: string | null; based_on?: string | null; restore_json?: string | null } | { kind: "RenameParagraphStyle"; style_id: string; name: string } | { kind: "DeleteParagraphStyle"; style_id: string } | { kind: "CreateCharacterStyle"; self_id?: string | null; name?: string | null; based_on?: string | null; restore_json?: string | null } | { kind: "RenameCharacterStyle"; style_id: string; name: string } | { kind: "DeleteCharacterStyle"; style_id: string } | { kind: "CreateObjectStyle"; self_id?: string | null; name?: string | null; based_on?: string | null; restore_json?: string | null } | { kind: "RenameObjectStyle"; style_id: string; name: string } | { kind: "DeleteObjectStyle"; style_id: string } | { kind: "CreateCellStyle"; self_id?: string | null; name?: string | null; based_on?: string | null; restore_json?: string | null } | { kind: "RenameCellStyle"; style_id: string; name: string } | { kind: "DeleteCellStyle"; style_id: string } | { kind: "CreateTableStyle"; self_id?: string | null; name?: string | null; based_on?: string | null; restore_json?: string | null } | { kind: "RenameTableStyle"; style_id: string; name: string } | { kind: "DeleteTableStyle"; style_id: string } | { kind: "CreateGroup"; spec: GroupSpec } | { kind: "DissolveGroup"; group_id: string; restore_slots?: number[] | null } | { kind: "DuplicateNodes"; sources: NodeId[]; dx: number; dy: number; ids?: string[]; story_ids?: string[] } | { kind: "RemoveDuplicates"; sources: NodeId[]; dx: number; dy: number; ids?: string[]; story_ids?: string[] } | { kind: "SetGroupTransform"; group: string; transform?: [number, number, number, number, number, number] | null; prev?: [number, number, number, number, number, number] | null } | { kind: "CreateGradient"; spec: GradientSpec } | { kind: "EditGradient"; gradient_id: string; spec: GradientSpec } | { kind: "DeleteGradient"; gradient_id: string } | { kind: "CreateColorGroup"; spec: ColorGroupSpec } | { kind: "EditColorGroup"; group_id: string; spec: ColorGroupSpec } | { kind: "DeleteColorGroup"; group_id: string } | { kind: "CreateNumberingList"; spec: NumberingListSpec } | { kind: "EditNumberingList"; list_id: string; spec: NumberingListSpec } | { kind: "DeleteNumberingList"; list_id: string } | { kind: "SetStyleProperty"; collection: StyleCollection; style_id: string; path: PropertyPath; value: Value } | { kind: "PathfinderBoolean"; kept: NodeId; others: NodeId[]; opKind: PathfinderKind } | { kind: "PathfinderRegion"; elements: NodeId[]; verb: PathfinderRegionVerb } | { kind: "PathfinderFaces"; elements: NodeId[]; faces: string[]; mode: FaceSelectMode } | { kind: "JoinPaths"; kept: NodeId; other: NodeId } | { kind: "PasteInto"; container: NodeId; child: NodeId; child_index?: number | null } | { kind: "ReleaseFrom"; child: NodeId; restore_slot?: number | null } | { kind: "ApplyOpacityMask"; target: NodeId; mask: NodeId; mask_type?: OpacityMaskMode; invert?: boolean } | { kind: "ReleaseOpacityMask"; target: NodeId; restore_slot?: number | null } | { kind: "AttachTextToPath"; host: NodeId; story_id: string; spec?: TextPathSpec } | { kind: "DetachTextFromPath"; host: NodeId; index?: number | null; restore?: TextPathSpec | null } | { kind: "LinkFrames"; from: string; to: string } | { kind: "UnlinkFrames"; frame: string; prev_next?: string | null; restore_target?: [string, string | null, string | null] | null } | { kind: "ApplyStyle"; story_id: string; start: number; end: number; style: string; scope: StyleScope; cell?: CellAddr | null; paragraph?: number | null } | { kind: "InsertField"; story_id: string; offset: number; field: FieldKind } | { kind: "DeleteField"; story_id: string; offset: number; field: FieldKind } | { kind: "InsertAnchoredFrame"; story_id: string; offset: number; width: number; height: number; image_uri?: string | null; self_id: string; paragraph?: number | null } | { kind: "RemoveAnchoredFrame"; story_id: string; self_id: string } | { kind: "InsertHyperlink"; story_id: string; start: number; end: number; url: string; source_id: string; dest_id: string; hyperlink_id: string } | { kind: "RemoveHyperlink"; story_id: string; start: number; end: number; url: string; source_id: string; dest_id: string; hyperlink_id: string } | { kind: "SetFieldValue"; story_id: string; offset: number; value?: string | null } | { kind: "PlaceImage"; frame: NodeId; image_uri?: string | null; fit?: string | null } | { kind: "ReplaceImageBytes"; frame: NodeId; bytes?: number[] | null; prior_has_image_element?: boolean | null } | { kind: "InsertGuide"; spread_id: string; orientation: GuideOrientationSpec; position: number; page_index?: number; guide_id?: string | null } | { kind: "MoveGuide"; guide_id: string; position: number } | { kind: "DeleteGuide"; guide_id: string } | { kind: "SetConditionVisible"; condition: string; visible: boolean } | { kind: "SetFlowGrowRule"; story_id: string; rule: FlowGrowRule | null } | { kind: "ActivateConditionSet"; set: string } | { kind: "RestoreConditionVisibility"; states: [string, boolean][] } | { kind: "ApplyMasterToPage"; page: string; master?: string | null } | { kind: "DuplicatePage"; page: string; clone_spread_json?: string | null } | { kind: "InsertSection"; at_page: string; prefix?: string | null; numbering_style?: string | null; start_at?: number | null; self_id?: string | null } | { kind: "EditSection"; section_id: string; prefix?: string | null | null; numbering_style?: string | null; start_at?: number | null | null } | { kind: "DeleteSection"; section_id: string } | { kind: "SetRowHeight"; story_id: string; table_id: string; row: number; height?: number | null } | { kind: "SetColumnWidth"; story_id: string; table_id: string; col: number; width?: number | null } | { kind: "InsertTableRow"; story_id: string; table_id: string; at: number; restore?: TableLineRestoreJson | null } | { kind: "DeleteTableRow"; story_id: string; table_id: string; at: number } | { kind: "InsertTableColumn"; story_id: string; table_id: string; at: number; restore?: TableLineRestoreJson | null } | { kind: "DeleteTableColumn"; story_id: string; table_id: string; at: number } | { kind: "InsertHeaderRow"; story_id: string; table_id: string; restore?: TableLineRestoreJson | null } | { kind: "RemoveHeaderRow"; story_id: string; table_id: string } | { kind: "InsertFooterRow"; story_id: string; table_id: string; restore?: TableLineRestoreJson | null } | { kind: "RemoveFooterRow"; story_id: string; table_id: string } | { kind: "SetCellSpan"; story_id: string; table_id: string; row: number; col: number; row_span: number; column_span: number };
1837
1980
 
1838
1981
  /**
1839
1982
  * The discriminated payload of a `MainToWorker` message. Tagged so
@@ -1842,7 +1985,64 @@ export type Operation = { kind: "SetProperty"; node: NodeId; path: PropertyPath;
1842
1985
  * variants so e.g. `cmyk_icc_profile` becomes `cmykIccProfile` on
1843
1986
  * the wire — the TS protocol mirror locks the camelCase contract.
1844
1987
  */
1845
- export type MainToWorkerKind = { kind: "hello" } | { kind: "loadDocument"; payload: { bytes: number[]; font?: number[] | null; cmykIccProfile?: number[] | null } } | { kind: "newBlankDocument"; payload: { widthPt: number; heightPt: number; font?: number[] | null } } | { kind: "registerFont"; payload: { family: string; style?: string | null; bytes: number[] } } | { kind: "clearFontRegistry" } | { kind: "registerColorProfile"; payload: { name: string; bytes: number[] } } | { kind: "mutate"; payload: Mutation } | { kind: "requestPage"; payload: { pageId: PageId; lod: LodTier } } | { kind: "hitTest"; payload: { pageId: PageId; docPoint: [number, number]; filter: HitFilter } } | { kind: "requestSnapshot"; payload: { pageId: PageId; targetWidthPx: number; dpi?: number | null } } | { kind: "setSelection"; payload: { selection: ContentSelection | null } } | { kind: "requestSelectionGeometry"; payload: { selection: ContentSelection } } | { kind: "requestCaretGeometry"; payload: { selection: ContentSelection } } | { kind: "requestCaretNav"; payload: { storyId: string; offset: number; direction: CaretDirection; cell?: TextCellAddr | null } } | { kind: "requestLineBounds"; payload: { storyId: string; offset: number; cell?: TextCellAddr | null } } | { kind: "requestWordBounds"; payload: { storyId: string; offset: number; cell?: TextCellAddr | null } } | { kind: "requestParagraphBounds"; payload: { storyId: string; offset: number; cell?: TextCellAddr | null } } | { kind: "undo" } | { kind: "redo" } | { kind: "setElementSelection"; payload: { ids: ElementId[]; mode: SelectionMode } } | { kind: "requestMarqueeHits"; payload: { pageId: PageId; rect: [number, number, number, number] } } | { kind: "requestElementGeometry"; payload: { ids: ElementId[] } } | { kind: "requestGroupLeaves"; payload: { groupId: string } } | { kind: "requestPathAnchors"; payload: { id: ElementId } } | { kind: "requestNearestPathPoint"; payload: { id: ElementId; point: [number, number] } } | { kind: "requestPlanarRegions"; payload: { elementIds: ElementId[]; point?: [number, number] | null } } | { kind: "requestLayers" } | { kind: "requestCollection"; payload: { name: CollectionName } } | { kind: "requestFrameChain"; payload: { storyId: string } } | { kind: "requestStoryContent"; payload: { storyId: string } } | { kind: "requestPlacedAssetBytes"; payload: { elementId: string } } | { kind: "requestFontFaceBytes"; payload: { family: string; style?: string | null } } | { kind: "requestMeasureText"; payload: { family: string; style?: string | null; text: string; sizePt: number } } | { kind: "submitSceneLayer"; payload: { elementId: string; layer: SceneLayer; caller?: string } } | { kind: "clearSceneLayer"; payload: { elementId: string } } | { kind: "submitPixelLayer"; payload: { elementId: string; layer: PixelLayer } } | { kind: "clearPixelLayer"; payload: { elementId: string } } | { kind: "claimImageResource"; payload: { imageId: string; levels: number; tileSize: number; baseWidth: number; baseHeight: number; revision: number } } | { kind: "releaseImageResource"; payload: { imageId: string } } | { kind: "submitResourceTiles"; payload: { imageId: string; level: number; tiles: ProviderTileWire[]; generation: number } } | { kind: "requestDocumentMeta" } | { kind: "requestDocumentPlaceholders" } | { kind: "requestColorPreview"; payload: { swatchId: string } } | { kind: "requestColorCompute"; payload: { space: string; value: number[]; tint?: number | null; model?: string | null; alternateSpace?: string | null; alternateValue?: number[] | null } } | { kind: "requestGradientDetail"; payload: { gradientId: string } } | { kind: "exportSwatchLibrary"; payload: { groupId?: string | null } } | { kind: "executeScript"; payload: { source: string; budget?: ScriptBudgetWire | null } } | { kind: "exportPdfBegin"; payload: { options: ExportPdfWireOptions } } | { kind: "exportPdfPage"; payload: { session: number } } | { kind: "exportPdfFinish"; payload: { session: number } } | { kind: "exportPdfCancel"; payload: { session: number } } | { kind: "exportIdml"; payload: { linkBase?: string | null } } | { kind: "writePagedPart"; payload: { path: string; bytes: number[]; caller?: string } } | { kind: "readPagedPart"; payload: { path: string } } | { kind: "listPagedParts"; payload: { prefix: string } } | { kind: "exportPaged"; payload: {} } | { kind: "requestElementProperties"; payload: { id: ElementId } } | { kind: "requestSceneTree" } | { kind: "beginGesture"; payload: { nodes: ElementId[]; gesture: GestureType; anchor?: GestureAnchor | null; cameraScale?: number | null } } | { kind: "updateGesture"; payload: { handle: GestureHandle; delta: [number, number]; modifiers: GestureModifiers } } | { kind: "commitGesture"; payload: { handle: GestureHandle } } | { kind: "cancelGesture"; payload: { handle: GestureHandle } };
1988
+ export type MainToWorkerKind = { kind: "hello" } | { kind: "loadDocument"; payload: { bytes: number[]; font?: number[] | null; cmykIccProfile?: number[] | null } } | { kind: "newBlankDocument"; payload: { widthPt: number; heightPt: number; font?: number[] | null } } | { kind: "registerFont"; payload: { family: string; style?: string | null; bytes: number[] } } | { kind: "clearFontRegistry" } | { kind: "registerColorProfile"; payload: { name: string; bytes: number[] } } | { kind: "mutate"; payload: Mutation } | { kind: "requestPage"; payload: { pageId: PageId; lod: LodTier } } | { kind: "hitTest"; payload: { pageId: PageId; docPoint: [number, number]; filter: HitFilter } } | { kind: "requestSnapshot"; payload: { pageId: PageId; targetWidthPx: number; dpi?: number | null } } | { kind: "setSelection"; payload: { selection: ContentSelection | null } } | { kind: "requestSelectionGeometry"; payload: { selection: ContentSelection } } | { kind: "requestCaretGeometry"; payload: { selection: ContentSelection } } | { kind: "requestCaretNav"; payload: { storyId: string; offset: number; direction: CaretDirection; cell?: TextCellAddr | null } } | { kind: "requestLineBounds"; payload: { storyId: string; offset: number; cell?: TextCellAddr | null } } | { kind: "requestWordBounds"; payload: { storyId: string; offset: number; cell?: TextCellAddr | null } } | { kind: "requestParagraphBounds"; payload: { storyId: string; offset: number; cell?: TextCellAddr | null } } | { kind: "undo" } | { kind: "redo" } | { kind: "setElementSelection"; payload: { ids: ElementId[]; mode: SelectionMode } } | { kind: "requestMarqueeHits"; payload: { pageId: PageId; rect: [number, number, number, number] } } | { kind: "requestElementGeometry"; payload: { ids: ElementId[] } } | { kind: "requestGroupLeaves"; payload: { groupId: string } } | { kind: "requestPathAnchors"; payload: { id: ElementId } } | { kind: "requestTextOutlines"; payload: { id: ElementId } } | { kind: "requestSnapPoint"; payload: { query: SnapPointQuery } } | { kind: "setSnapSettings"; payload: { settings: SnapSettings } } | { kind: "requestNearestPathPoint"; payload: { id: ElementId; point: [number, number] } } | { kind: "requestPlanarRegions"; payload: { elementIds: ElementId[]; point?: [number, number] | null } } | { kind: "requestLayers" } | { kind: "requestCollection"; payload: { name: CollectionName } } | { kind: "requestFrameChain"; payload: { storyId: string } } | { kind: "requestStoryContent"; payload: { storyId: string } } | { kind: "requestStyleProperties"; payload: { collection: StyleCollection; styleId: string } } | { kind: "requestPlacedAssetBytes"; payload: { elementId: string } } | { kind: "requestFontFaceBytes"; payload: { family: string; style?: string | null } } | { kind: "requestMeasureText"; payload: { family: string; style?: string | null; text: string; sizePt: number } } | { kind: "submitSceneLayer"; payload: { elementId: string; layer: SceneLayer; caller?: string } } | { kind: "clearSceneLayer"; payload: { elementId: string } } | { kind: "submitPixelLayer"; payload: { elementId: string; layer: PixelLayer } } | { kind: "clearPixelLayer"; payload: { elementId: string } } | { kind: "claimImageResource"; payload: { imageId: string; levels: number; tileSize: number; baseWidth: number; baseHeight: number; revision: number } } | { kind: "releaseImageResource"; payload: { imageId: string } } | { kind: "submitResourceTiles"; payload: { imageId: string; level: number; tiles: ProviderTileWire[]; generation: number } } | { kind: "requestDocumentMeta" } | { kind: "requestDocumentPlaceholders" } | { kind: "requestColorPreview"; payload: { swatchId: string } } | { kind: "requestColorCompute"; payload: { space: string; value: number[]; tint?: number | null; model?: string | null; alternateSpace?: string | null; alternateValue?: number[] | null } } | { kind: "requestGradientDetail"; payload: { gradientId: string } } | { kind: "exportSwatchLibrary"; payload: { groupId?: string | null } } | { kind: "executeScript"; payload: { source: string; budget?: ScriptBudgetWire | null } } | { kind: "exportPdfBegin"; payload: { options: ExportPdfWireOptions } } | { kind: "exportPdfPage"; payload: { session: number } } | { kind: "exportPdfFinish"; payload: { session: number } } | { kind: "exportPdfCancel"; payload: { session: number } } | { kind: "exportIdml"; payload: { linkBase?: string | null } } | { kind: "writePagedPart"; payload: { path: string; bytes: number[]; caller?: string } } | { kind: "readPagedPart"; payload: { path: string } } | { kind: "listPagedParts"; payload: { prefix: string } } | { kind: "deletePagedPart"; payload: { path: string; caller?: string } } | { kind: "exportPaged"; payload: {} } | { kind: "requestElementProperties"; payload: { id: ElementId } } | { kind: "requestSceneTree" } | { kind: "beginGesture"; payload: { nodes: ElementId[]; gesture: GestureType; anchor?: GestureAnchor | null; cameraScale?: number | null } } | { kind: "updateGesture"; payload: { handle: GestureHandle; delta: [number, number]; modifiers: GestureModifiers } } | { kind: "commitGesture"; payload: { handle: GestureHandle } } | { kind: "cancelGesture"; payload: { handle: GestureHandle } };
1989
+
1990
+ /**
1991
+ * The document\'s snapping preferences — one set for every tool and
1992
+ * gesture, so a move and a pen click agree on what \"close\" means.
1993
+ * Session state, not document state: it is not saved and not undoable.
1994
+ */
1995
+ export interface SnapSettings {
1996
+ /**
1997
+ * Master switch. Off ⇒ no gesture snaps and every query answers the
1998
+ * point it was given.
1999
+ */
2000
+ enabled?: boolean;
2001
+ /**
2002
+ * Tolerance in CSS px, converted to pt through the camera scale.
2003
+ */
2004
+ tolerancePx?: number;
2005
+ /**
2006
+ * Anchors, frame corners, oval quadrant points and element centres.
2007
+ */
2008
+ points?: boolean;
2009
+ /**
2010
+ * The x / y lines through those points (smart guides).
2011
+ */
2012
+ alignment?: boolean;
2013
+ /**
2014
+ * The nearest point on an element\'s outline.
2015
+ */
2016
+ segments?: boolean;
2017
+ /**
2018
+ * Page corners, centre, edges and centre lines.
2019
+ */
2020
+ page?: boolean;
2021
+ /**
2022
+ * Ruler guides.
2023
+ */
2024
+ guides?: boolean;
2025
+ /**
2026
+ * The document grid (`GridPreference` gridline divisions). Off by
2027
+ * default, as in InDesign.
2028
+ */
2029
+ grid?: boolean;
2030
+ }
2031
+
2032
+ /**
2033
+ * The segment the query landed on.
2034
+ */
2035
+ export interface SnapSegmentHit {
2036
+ element: ElementId;
2037
+ /**
2038
+ * Flat index of the segment\'s start / end anchor. Absent for an
2039
+ * outline the element does not store as anchors (a box-drawn
2040
+ * frame, an oval).
2041
+ */
2042
+ segStart?: number | null;
2043
+ segEnd?: number | null;
2044
+ t: number;
2045
+ }
1846
2046
 
1847
2047
  /**
1848
2048
  * Track J — wire-shape mirror of `paged_model::PathAnchor`. The
@@ -1962,7 +2162,7 @@ export type Value = { type: "bounds"; value: [number, number, number, number] }
1962
2162
  * (`\"fill.color\"`) — so JS callers don\'t need to learn the Rust
1963
2163
  * enum shape.
1964
2164
  */
1965
- export type PropertyPath = "frameBounds" | "frameFillColor" | "frameStrokeColor" | "frameStrokeWeight" | "frameOpacity" | "frameTransform" | "imageContentTransform" | "framePathPoint" | "pathPointInsert" | "pathPointRemove" | "pathPointCurveType" | "layerVisible" | "layerLocked" | "layerPrintable" | "layerName" | "characterFontSize" | "characterLeading" | "characterTracking" | "characterFillColor" | "paragraphSpaceBefore" | "paragraphSpaceAfter" | "paragraphFirstLineIndent" | "appliedParagraphStyle" | "appliedCharacterStyle" | "appliedObjectStyle" | "itemLayer" | "appliedCellStyle" | "appliedTableStyle" | "framePath" | "frameNonprinting" | "frameFillTint" | "frameGradientFillAngle" | "frameGradientFillLength" | "frameGradientStrokeAngle" | "frameGradientStrokeLength" | "pathOpenAt" | "outlineStroke" | "outlineStrokeVariable" | "offsetPath" | "simplifyPath" | "closePath" | "frameGradientFeather" | "pageBounds" | "frameDropShadowMode" | "frameDropShadowXOffset" | "frameDropShadowYOffset" | "frameDropShadowSize" | "frameDropShadowOpacity" | "frameDropShadowColor" | "frameDropShadow" | "frameFittingCrops" | "frameFittingType" | "frameTextWrapMode" | "frameTextWrapOffsets" | "frameTextWrapContourType" | "frameTextWrapContourIncludeInside" | "paragraphJustification" | "paragraphStyleNextStyle" | "paragraphAppliedNumberingList" | "frameStrokeEndCap" | "frameInsetSpacing" | "appliedConditions" | "characterFontFamily" | "characterFontStyle" | "characterKerningMethod" | "characterCase" | "characterPosition" | "characterLanguage" | "characterBaselineShift" | "characterHorizontalScale" | "characterVerticalScale" | "characterSkew" | "characterUnderline" | "characterStrikethru" | "characterLigatures" | "characterOtfFeatures" | "paragraphLeftIndent" | "paragraphRightIndent" | "paragraphDropCapCharacters" | "paragraphDropCapLines" | "paragraphHyphenation" | "paragraphHyphenationZone" | "paragraphKeepLinesTogether" | "paragraphKeepWithNext" | "paragraphKeepAllLinesTogether" | "paragraphKeepFirstLines" | "paragraphKeepLastLines" | "paragraphStartParagraph" | "paragraphSpanColumnType" | "paragraphSpanSplitColumnCount" | "paragraphSpanColumnMinSpaceBefore" | "paragraphSpanColumnMinSpaceAfter" | "paragraphSplitColumnInsideGutter" | "paragraphSplitColumnOutsideGutter" | "paragraphRuleAbove" | "paragraphRuleBelow" | "paragraphTabStops" | "paragraphListType" | "paragraphBulletCharacter" | "paragraphNumberingFormat" | "paragraphBulletsTextAfter" | "paragraphNumberingExpression" | "paragraphNumberingStartAt" | "paragraphNumberingContinue" | "paragraphBulletsCharacterStyle" | "paragraphNumberingCharacterStyle" | "textFrameColumnCount" | "textFrameColumnGutter" | "textFrameColumnBalance" | "textFrameVerticalJustification" | "textFrameAutoSizing" | "textFrameFirstBaseline" | "textWrapInvert" | "frameFittingReferencePoint" | "frameAutoFit" | "frameStrokeType" | "frameStrokeJoin" | "frameStrokeMiterLimit" | "frameStrokeAlignment" | "frameStrokeGapColor" | "frameStrokeGapTint" | "frameStrokeDashArray" | "frameCornerOptionTopLeft" | "frameCornerOptionTopRight" | "frameCornerOptionBottomLeft" | "frameCornerOptionBottomRight" | "frameCornerRadiusTopLeft" | "frameCornerRadiusTopRight" | "frameCornerRadiusBottomLeft" | "frameCornerRadiusBottomRight" | "frameRotationAngle" | "frameScaleX" | "frameScaleY" | "frameFlipH" | "frameFlipV" | "frameOverprintFill" | "frameOverprintStroke" | "frameInnerShadowEnabled" | "frameInnerShadowBlendMode" | "frameInnerShadowColor" | "frameInnerShadowOpacity" | "frameInnerShadowAngle" | "frameInnerShadowDistance" | "frameInnerShadowSize" | "frameInnerShadowChoke" | "frameInnerShadowNoise" | "frameOuterGlowEnabled" | "frameOuterGlowBlendMode" | "frameOuterGlowColor" | "frameOuterGlowOpacity" | "frameOuterGlowSpread" | "frameOuterGlowSize" | "frameOuterGlowNoise" | "frameInnerGlowEnabled" | "frameInnerGlowBlendMode" | "frameInnerGlowColor" | "frameInnerGlowOpacity" | "frameInnerGlowChoke" | "frameInnerGlowSize" | "frameInnerGlowSource" | "frameInnerGlowNoise" | "frameBevelEnabled" | "frameBevelStyle" | "frameBevelTechnique" | "frameBevelDepth" | "frameBevelDirection" | "frameBevelSize" | "frameBevelSoften" | "frameBevelAngle" | "frameBevelAltitude" | "frameBevelHighlightColor" | "frameBevelShadowColor" | "frameBevelHighlightOpacity" | "frameBevelShadowOpacity" | "frameSatinEnabled" | "frameSatinBlendMode" | "frameSatinColor" | "frameSatinOpacity" | "frameSatinAngle" | "frameSatinDistance" | "frameSatinSize" | "frameSatinInvert" | "frameFeatherEnabled" | "frameFeatherWidth" | "frameFeatherCornerType" | "frameFeatherNoise" | "frameFeatherChoke" | "frameDirectionalFeatherEnabled" | "frameDirectionalFeatherLeftWidth" | "frameDirectionalFeatherRightWidth" | "frameDirectionalFeatherTopWidth" | "frameDirectionalFeatherBottomWidth" | "frameDirectionalFeatherAngle" | "frameDirectionalFeatherNoise" | "frameDirectionalFeatherChoke" | "frameBlendMode" | "nextTextFrame" | "previousTextFrame" | "cellFillColor" | "cellFillTint" | "cellInsetTop" | "cellInsetLeft" | "cellInsetBottom" | "cellInsetRight" | "cellVerticalJustification" | "cellTopEdgeStrokeColor" | "cellTopEdgeStrokeWeight" | "cellTopEdgeStrokeTint" | "cellBottomEdgeStrokeColor" | "cellBottomEdgeStrokeWeight" | "cellBottomEdgeStrokeTint" | "cellLeftEdgeStrokeColor" | "cellLeftEdgeStrokeWeight" | "cellLeftEdgeStrokeTint" | "cellRightEdgeStrokeColor" | "cellRightEdgeStrokeWeight" | "cellRightEdgeStrokeTint" | "tableRowCount" | "tableColumnCount" | "pluginMetadata" | "anchoredPosition" | "anchorPoint" | "anchoredXOffset" | "anchoredYOffset" | "anchoredHorizontalReference" | "anchoredVerticalReference" | "anchoredHorizontalAlignment" | "anchoredVerticalAlignment" | "anchoredSpineRelative" | "anchoredLockPosition" | "elementVisible" | "elementLocked" | "frameStrokeStartArrowhead" | "frameStrokeEndArrowhead";
2165
+ export type PropertyPath = "frameBounds" | "frameFillColor" | "frameStrokeColor" | "frameStrokeWeight" | "frameOpacity" | "frameTransform" | "imageContentTransform" | "framePathPoint" | "pathPointInsert" | "pathPointRemove" | "pathPointCurveType" | "layerVisible" | "layerLocked" | "layerPrintable" | "layerName" | "characterFontSize" | "characterLeading" | "characterTracking" | "characterFillColor" | "paragraphSpaceBefore" | "paragraphSpaceAfter" | "paragraphFirstLineIndent" | "appliedParagraphStyle" | "appliedCharacterStyle" | "appliedObjectStyle" | "itemLayer" | "appliedCellStyle" | "appliedTableStyle" | "framePath" | "frameNonprinting" | "frameFillTint" | "frameGradientFillAngle" | "frameGradientFillLength" | "frameGradientStrokeAngle" | "frameGradientStrokeLength" | "pathOpenAt" | "outlineStroke" | "outlineStrokeVariable" | "offsetPath" | "simplifyPath" | "closePath" | "frameGradientFeather" | "pageBounds" | "frameDropShadowMode" | "frameDropShadowXOffset" | "frameDropShadowYOffset" | "frameDropShadowSize" | "frameDropShadowOpacity" | "frameDropShadowColor" | "frameDropShadow" | "frameFittingCrops" | "frameFittingType" | "frameTextWrapMode" | "frameTextWrapOffsets" | "frameTextWrapContourType" | "frameTextWrapContourIncludeInside" | "paragraphJustification" | "paragraphStyleNextStyle" | "paragraphAppliedNumberingList" | "frameStrokeEndCap" | "frameInsetSpacing" | "appliedConditions" | "characterFontFamily" | "characterFontStyle" | "characterKerningMethod" | "characterCase" | "characterPosition" | "characterLanguage" | "characterBaselineShift" | "characterHorizontalScale" | "characterVerticalScale" | "characterSkew" | "characterUnderline" | "characterStrikethru" | "characterLigatures" | "characterOtfFeatures" | "paragraphLeftIndent" | "paragraphRightIndent" | "paragraphDropCapCharacters" | "paragraphDropCapLines" | "paragraphHyphenation" | "paragraphHyphenationZone" | "paragraphKeepLinesTogether" | "paragraphKeepWithNext" | "paragraphKeepAllLinesTogether" | "paragraphKeepFirstLines" | "paragraphKeepLastLines" | "paragraphStartParagraph" | "paragraphSpanColumnType" | "paragraphSpanSplitColumnCount" | "paragraphSpanColumnMinSpaceBefore" | "paragraphSpanColumnMinSpaceAfter" | "paragraphSplitColumnInsideGutter" | "paragraphSplitColumnOutsideGutter" | "paragraphRuleAbove" | "paragraphRuleBelow" | "paragraphTabStops" | "paragraphListType" | "paragraphBulletCharacter" | "paragraphNumberingFormat" | "paragraphBulletsTextAfter" | "paragraphNumberingExpression" | "paragraphNumberingStartAt" | "paragraphNumberingContinue" | "paragraphBulletsCharacterStyle" | "paragraphNumberingCharacterStyle" | "paragraphComposer" | "textFrameColumnCount" | "textFrameColumnGutter" | "textFrameColumnBalance" | "textFrameVerticalJustification" | "textFrameAutoSizing" | "textFrameFirstBaseline" | "textWrapInvert" | "frameFittingReferencePoint" | "frameAutoFit" | "frameStrokeType" | "frameStrokeJoin" | "frameStrokeMiterLimit" | "frameStrokeAlignment" | "frameStrokeGapColor" | "frameStrokeGapTint" | "frameStrokeDashArray" | "frameCornerOptionTopLeft" | "frameCornerOptionTopRight" | "frameCornerOptionBottomLeft" | "frameCornerOptionBottomRight" | "frameCornerRadiusTopLeft" | "frameCornerRadiusTopRight" | "frameCornerRadiusBottomLeft" | "frameCornerRadiusBottomRight" | "frameRotationAngle" | "frameScaleX" | "frameScaleY" | "frameFlipH" | "frameFlipV" | "frameOverprintFill" | "frameOverprintStroke" | "frameInnerShadowEnabled" | "frameInnerShadowBlendMode" | "frameInnerShadowColor" | "frameInnerShadowOpacity" | "frameInnerShadowAngle" | "frameInnerShadowDistance" | "frameInnerShadowSize" | "frameInnerShadowChoke" | "frameInnerShadowNoise" | "frameOuterGlowEnabled" | "frameOuterGlowBlendMode" | "frameOuterGlowColor" | "frameOuterGlowOpacity" | "frameOuterGlowSpread" | "frameOuterGlowSize" | "frameOuterGlowNoise" | "frameInnerGlowEnabled" | "frameInnerGlowBlendMode" | "frameInnerGlowColor" | "frameInnerGlowOpacity" | "frameInnerGlowChoke" | "frameInnerGlowSize" | "frameInnerGlowSource" | "frameInnerGlowNoise" | "frameBevelEnabled" | "frameBevelStyle" | "frameBevelTechnique" | "frameBevelDepth" | "frameBevelDirection" | "frameBevelSize" | "frameBevelSoften" | "frameBevelAngle" | "frameBevelAltitude" | "frameBevelHighlightColor" | "frameBevelShadowColor" | "frameBevelHighlightOpacity" | "frameBevelShadowOpacity" | "frameSatinEnabled" | "frameSatinBlendMode" | "frameSatinColor" | "frameSatinOpacity" | "frameSatinAngle" | "frameSatinDistance" | "frameSatinSize" | "frameSatinInvert" | "frameFeatherEnabled" | "frameFeatherWidth" | "frameFeatherCornerType" | "frameFeatherNoise" | "frameFeatherChoke" | "frameDirectionalFeatherEnabled" | "frameDirectionalFeatherLeftWidth" | "frameDirectionalFeatherRightWidth" | "frameDirectionalFeatherTopWidth" | "frameDirectionalFeatherBottomWidth" | "frameDirectionalFeatherAngle" | "frameDirectionalFeatherNoise" | "frameDirectionalFeatherChoke" | "frameBlendMode" | "nextTextFrame" | "previousTextFrame" | "cellFillColor" | "cellFillTint" | "cellInsetTop" | "cellInsetLeft" | "cellInsetBottom" | "cellInsetRight" | "cellVerticalJustification" | "cellTopEdgeStrokeColor" | "cellTopEdgeStrokeWeight" | "cellTopEdgeStrokeTint" | "cellBottomEdgeStrokeColor" | "cellBottomEdgeStrokeWeight" | "cellBottomEdgeStrokeTint" | "cellLeftEdgeStrokeColor" | "cellLeftEdgeStrokeWeight" | "cellLeftEdgeStrokeTint" | "cellRightEdgeStrokeColor" | "cellRightEdgeStrokeWeight" | "cellRightEdgeStrokeTint" | "tableRowCount" | "tableColumnCount" | "pluginMetadata" | "anchoredPosition" | "anchorPoint" | "anchoredXOffset" | "anchoredYOffset" | "anchoredHorizontalReference" | "anchoredVerticalReference" | "anchoredHorizontalAlignment" | "anchoredVerticalAlignment" | "anchoredSpineRelative" | "anchoredLockPosition" | "elementVisible" | "elementLocked" | "frameStrokeStartArrowhead" | "frameStrokeEndArrowhead";
1966
2166
 
1967
2167
  /**
1968
2168
  * Typed worker-side error for non-load operations. Mutations,
@@ -2184,6 +2384,11 @@ export interface TableHitContext {
2184
2384
  col: number;
2185
2385
  }
2186
2386
 
2387
+ /**
2388
+ * What a snap landed on.
2389
+ */
2390
+ export type SnapSource = "anchor" | "corner" | "center" | "page" | "guide" | "grid" | "extra";
2391
+
2187
2392
  /**
2188
2393
  * What the resolver produced this pass. The canvas worker reads
2189
2394
  * `numbering_map` to drive the running-header / page-number
@@ -2340,6 +2545,29 @@ export interface LineBounds {
2340
2545
  lineEnd: number;
2341
2546
  }
2342
2547
 
2548
+ /**
2549
+ * `RequestSnapPoint` reply payload.
2550
+ */
2551
+ export interface SnapPointResult {
2552
+ /**
2553
+ * The point after snapping; the query\'s point when nothing snapped.
2554
+ */
2555
+ point: [number, number];
2556
+ snapped: boolean;
2557
+ pointTarget?: SnapPointHit | null;
2558
+ xTarget?: SnapAxisHit | null;
2559
+ yTarget?: SnapAxisHit | null;
2560
+ segmentTarget?: SnapSegmentHit | null;
2561
+ /**
2562
+ * The guides to draw, same shape the translate gesture reports.
2563
+ */
2564
+ lines: SnapLine[];
2565
+ /**
2566
+ * The tolerance the query ran with, in pt.
2567
+ */
2568
+ tolerancePt: number;
2569
+ }
2570
+
2343
2571
  /**
2344
2572
  * panels.md gap 20 — one structured PDF-export preflight finding for
2345
2573
  * the export dialog\'s findings list. The wire mirror of
@@ -2511,6 +2739,39 @@ export interface ProviderTileWire {
2511
2739
  */
2512
2740
  export type ZOrderTarget = "front" | "back" | "forward" | "backward" | { index: number };
2513
2741
 
2742
+ /**
2743
+ * v65 — a story\'s grow rule on the read side ([`StorySummary::grow_rule`]).
2744
+ * Mirrors the `setFlowGrowRule` payload so a host can show the rule and
2745
+ * send it back unchanged.
2746
+ */
2747
+ export interface StoryGrowRule {
2748
+ grow: boolean;
2749
+ /**
2750
+ * Upper bound on generated pages; `None` = the renderer\'s default.
2751
+ */
2752
+ maxPages?: number | null;
2753
+ /**
2754
+ * Generated frames copy the chain\'s last frame\'s text-frame options.
2755
+ */
2756
+ copyFrameOptions: boolean;
2757
+ }
2758
+
2759
+ /**
2760
+ * v65 — one style definition\'s settable properties
2761
+ * (`RequestStyleProperties`). `entries` uses the inspector\'s row shape;
2762
+ * every value is `Some` (a style has one value per field, never \"mixed\").
2763
+ */
2764
+ export interface StyleProperties {
2765
+ collection: StyleCollection;
2766
+ styleId: string;
2767
+ name?: string | null;
2768
+ /**
2769
+ * The style\'s `BasedOn` reference, verbatim.
2770
+ */
2771
+ basedOn?: string | null;
2772
+ entries: PropertyEntry[];
2773
+ }
2774
+
2514
2775
  /**
2515
2776
  * §21 advanced prepress — one ink plate\'s coverage on one page.
2516
2777
  *
@@ -2698,6 +2959,24 @@ export interface FrameBounds {
2698
2959
  bottom: number;
2699
2960
  }
2700
2961
 
2962
+ export interface NearestPathPointResult {
2963
+ /**
2964
+ * Flat index of the segment\'s START anchor.
2965
+ */
2966
+ segStart: number;
2967
+ /**
2968
+ * Flat index of the segment\'s END anchor (wraps to the subpath
2969
+ * start on a closing segment).
2970
+ */
2971
+ segEnd: number;
2972
+ /**
2973
+ * Curve parameter on that segment, 0..=1.
2974
+ */
2975
+ t: number;
2976
+ point: [number, number];
2977
+ distance: number;
2978
+ }
2979
+
2701
2980
  export interface RunningHeader {
2702
2981
  pageId: PageId;
2703
2982
  pageNumber: number;
@@ -2809,6 +3088,13 @@ export class CanvasWorker {
2809
3088
  * to the default face when one is registered.
2810
3089
  */
2811
3090
  measureText(family: string, style: string | null | undefined, text: string, size_pt: number): any;
3091
+ /**
3092
+ * v66 — apply one wire `Mutation` (JSON; a `batch` too) whose
3093
+ * first `replaceImageBytes` with `bytes: []` takes `bytes` — the
3094
+ * commit lane for processed pixels without a `number[]`. Returns
3095
+ * the `Mutate` reply envelope as JSON.
3096
+ */
3097
+ mutateWithBytesDirect(seq: number, mutation_json: string, bytes: Uint8Array): string;
2812
3098
  constructor();
2813
3099
  /**
2814
3100
  * Number of pages in the loaded document, or 0 if no
@@ -2824,6 +3110,12 @@ export class CanvasWorker {
2824
3110
  * serialised as a JS array.
2825
3111
  */
2826
3112
  pageInfo(index: number): Array<any> | undefined;
3113
+ /**
3114
+ * v66 — a frame's placed image as `{ uri, width, height, encoded }`
3115
+ * with `encoded` a `Uint8Array`, or `undefined` when there is none
3116
+ * (the cases `placedAssetBytes` answers `found: false`).
3117
+ */
3118
+ placedAssetBytesDirect(element_id: string): object | undefined;
2827
3119
  /**
2828
3120
  * Render the visible pages at the current camera into the
2829
3121
  * bound surface. Camera operates in CSS pixels; the
@@ -2835,6 +3127,11 @@ export class CanvasWorker {
2835
3127
  * CPU path in that case.
2836
3128
  */
2837
3129
  presentFrame(scale: number, tx: number, ty: number, dpr: number): boolean;
3130
+ /**
3131
+ * v66 — a `.paged` part's bytes as a `Uint8Array`, or `undefined`
3132
+ * when the part is absent or no document is loaded.
3133
+ */
3134
+ readPagedPartDirect(path: string): Uint8Array | undefined;
2838
3135
  /**
2839
3136
  * Sub-phase D — render `page_id` to a PNG via the Vello GPU
2840
3137
  * path (off-surface). Returns `None` if GPU is not
@@ -2888,6 +3185,24 @@ export class CanvasWorker {
2888
3185
  * when measuring memory behaviour.
2889
3186
  */
2890
3187
  setSceneCacheBudget(max_entries: number): void;
3188
+ /**
3189
+ * v66 — binary sibling of `SubmitSceneLayer` for the one-image
3190
+ * case: the frame's scene layer becomes the RGBA8 image in `rgba`
3191
+ * (`width*height*4` bytes) drawn at `x, y, w, h` frame-content
3192
+ * points. Take a `Uint8Array` (transfer it to the worker first);
3193
+ * no `number[]`, no JSON parse. Returns the `sceneLayerApplied`
3194
+ * envelope as JSON, like `handleMessage`. Only the pages showing
3195
+ * the frame lose their cached scene.
3196
+ */
3197
+ submitSceneImageDirect(seq: number, element_id: string, caller: string | null | undefined, rgba: Uint8Array, width: number, height: number, x: number, y: number, w: number, h: number): string;
3198
+ /**
3199
+ * v66 — patch rectangles of the image `submitSceneImageDirect`
3200
+ * set: `rects` is a `Uint32Array` of `x, y, w, h` (image pixels)
3201
+ * per tile, `rgba` the tiles' pixels back to back in that order.
3202
+ * Validated whole before any byte moves. Returns the
3203
+ * `sceneLayerApplied` envelope as JSON.
3204
+ */
3205
+ submitSceneImageTilesDirect(seq: number, element_id: string, caller: string | null | undefined, rects: Uint32Array, rgba: Uint8Array): string;
2891
3206
  /**
2892
3207
  * Handle one main-thread message. Input is the JSON string
2893
3208
  * the JS side produced via `JSON.stringify(msg)`. Output is
@@ -2910,6 +3225,11 @@ export class CanvasWorker {
2910
3225
  * in `packages/shell/src/gestures/gesture-sab.ts`.
2911
3226
  */
2912
3227
  updateGestureRaw(handle_lo: number, handle_hi: number, dx: number, dy: number, modifier_bits: number): string;
3228
+ /**
3229
+ * v66 — `WritePagedPart` with a `Uint8Array` body. Returns the
3230
+ * `pagedPartWritten` / `pagedPartFailed` envelope as JSON.
3231
+ */
3232
+ writePagedPartDirect(seq: number, path: string, caller: string | null | undefined, bytes: Uint8Array): string;
2913
3233
  /**
2914
3234
  * Protocol version constant; the JS side compares against
2915
3235
  * its bundled value before sending `LoadDocument`.
@@ -2940,11 +3260,14 @@ export interface InitOutput {
2940
3260
  readonly canvasworker_initGpu: (a: number, b: any, c: number, d: number) => any;
2941
3261
  readonly canvasworker_loadDocumentDirect: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number) => [number, number];
2942
3262
  readonly canvasworker_measureText: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number) => any;
3263
+ readonly canvasworker_mutateWithBytesDirect: (a: number, b: number, c: number, d: number, e: number, f: number) => [number, number];
2943
3264
  readonly canvasworker_new: () => number;
2944
3265
  readonly canvasworker_pageCount: (a: number) => number;
2945
3266
  readonly canvasworker_pageInfo: (a: number, b: number) => any;
3267
+ readonly canvasworker_placedAssetBytesDirect: (a: number, b: number, c: number) => any;
2946
3268
  readonly canvasworker_presentFrame: (a: number, b: number, c: number, d: number, e: number) => [number, number, number];
2947
3269
  readonly canvasworker_protocolVersion: (a: number) => number;
3270
+ readonly canvasworker_readPagedPartDirect: (a: number, b: number, c: number) => [number, number];
2948
3271
  readonly canvasworker_renderPageVelloPng: (a: number, b: number, c: number, d: number) => any;
2949
3272
  readonly canvasworker_renderTilePng: (a: number, b: number, c: number, d: number) => [number, number];
2950
3273
  readonly canvasworker_resizeGpu: (a: number, b: number, c: number) => void;
@@ -2952,7 +3275,10 @@ export interface InitOutput {
2952
3275
  readonly canvasworker_sceneCacheSize: (a: number) => number;
2953
3276
  readonly canvasworker_selectionGeometryJson: (a: number, b: number, c: number) => [number, number];
2954
3277
  readonly canvasworker_setSceneCacheBudget: (a: number, b: number) => void;
3278
+ readonly canvasworker_submitSceneImageDirect: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number, k: number, l: number, m: number, n: number) => [number, number];
3279
+ readonly canvasworker_submitSceneImageTilesDirect: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number) => [number, number];
2955
3280
  readonly canvasworker_updateGestureRaw: (a: number, b: number, c: number, d: number, e: number, f: number) => [number, number];
3281
+ readonly canvasworker_writePagedPartDirect: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number) => [number, number];
2956
3282
  readonly gestureSabBytes: () => number;
2957
3283
  readonly gestureSabLayout: () => any;
2958
3284
  readonly on_start: () => void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@paged-media/plugin-api",
3
- "version": "0.2.37-canary.0",
3
+ "version": "0.2.39-canary.0",
4
4
  "description": "The Paged plugin contract: manifest, bundle lifecycle, the BundleHost surface, and the contribution + engine wire types. Type-only.",
5
5
  "license": "MPL-2.0 OR LicenseRef-PMEL",
6
6
  "type": "module",