@paged-media/plugin-api 0.2.27-canary.1 → 0.2.29-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/binding-provider.d.ts +331 -0
- package/dist/contributions.d.ts +1 -1
- package/dist/editor.d.ts +46 -1
- package/dist/host.d.ts +270 -5
- package/dist/index.d.ts +3 -2
- package/dist/mutations.d.ts +274 -0
- package/dist/panel-schema.d.ts +68 -0
- package/dist/wire.d.ts +427 -40
- package/package.json +1 -1
package/dist/host.d.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import type { CollectionName, DocumentMeta, ElementGeometryItem, ElementId, HitFilter, HitResult, Mutation, PageId, ElementProperties, PathAnchorsResult, SceneTreeNode, SelectionMode } from "./wire";
|
|
1
|
+
import type { CollectionName, DocumentMeta, ElementGeometryItem, ElementId, HitFilter, HitResult, Mutation, PageId, ElementProperties, PathAnchorsResult, PathAnchorTriple, SceneTreeNode, SelectionMode } 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";
|
|
5
|
+
import type { BindingProvider, BindingProviderHandle } from "./binding-provider";
|
|
5
6
|
import type { ClipboardSurface } from "./clipboard";
|
|
7
|
+
import type { MutationInput } from "./mutations";
|
|
6
8
|
import type { PluginManifest } from "./manifest";
|
|
7
9
|
import type { SchemaPanelContribution } from "./panel-schema";
|
|
8
10
|
import type { WidgetSurface } from "./widgets";
|
|
@@ -74,7 +76,25 @@ export interface EditContextContribution {
|
|
|
74
76
|
* names. Empty = no restriction (all tools stay available). */
|
|
75
77
|
toolIds?: string[];
|
|
76
78
|
/** Panel ids the cockpit emphasizes / raises on enter (the panel-set
|
|
77
|
-
* swap).
|
|
79
|
+
* swap).
|
|
80
|
+
*
|
|
81
|
+
* These are the context's OWN panels. There is deliberately no sibling
|
|
82
|
+
* field naming the SHARED host panels a context serves (ADR-023), and
|
|
83
|
+
* the reason is worth stating because the gap looks like an omission:
|
|
84
|
+
* a plugin naming `paged.layers` here would be host-panel IDENTITY in
|
|
85
|
+
* plugin code — the exact coupling binding providers removed from the
|
|
86
|
+
* value lane — and it could drift from `provides`, which is the only
|
|
87
|
+
* declaration that decides who actually answers. The host infers
|
|
88
|
+
* "serves" from `BindingProviderScope` instead (DESIGN.md §18.12).
|
|
89
|
+
*
|
|
90
|
+
* WHAT THE HOST GUARANTEES, corrected 2026-08-05: it OPENS these. It
|
|
91
|
+
* raises them too, EXCEPT when raising would displace a panel the
|
|
92
|
+
* entering context's own binding providers serve — because in a dock
|
|
93
|
+
* that shows one panel at a time, "raise mine" IS "hide the shared
|
|
94
|
+
* one", and hiding it at the instant it retargets defeats the whole
|
|
95
|
+
* point. (This comment used to promise "it does not hide others"
|
|
96
|
+
* unconditionally; that was never true in such a dock.) A withheld
|
|
97
|
+
* raise still opens the tab, so the surface is reachable either way. */
|
|
78
98
|
panelIds?: string[];
|
|
79
99
|
/** Called when the context becomes active (after the stack push + the
|
|
80
100
|
* scope narrowing). The element entered on is passed so the hook can
|
|
@@ -252,6 +272,35 @@ export interface ContributionSurface {
|
|
|
252
272
|
* `contributes.exporters[]`.
|
|
253
273
|
*/
|
|
254
274
|
exporter(contribution: ExporterContribution): Disposable;
|
|
275
|
+
/**
|
|
276
|
+
* Register a BINDING PROVIDER (ADR-023 phase A): while the edit
|
|
277
|
+
* context named by `contextType` is ACTIVE, this bundle resolves what
|
|
278
|
+
* the HOST's own panels bind to — typed property paths, named
|
|
279
|
+
* collections, and first refusal on structural mutation ops. Reads and
|
|
280
|
+
* writes both.
|
|
281
|
+
*
|
|
282
|
+
* This is the inversion the panel-duplication problem needs: instead
|
|
283
|
+
* of minting a fourth Layers panel, a bundle serves the ONE host
|
|
284
|
+
* Layers panel's values for its own content type. See
|
|
285
|
+
* binding-provider.ts for the three-lane shape, the core-vocabulary-
|
|
286
|
+
* only rule, and the precedence model.
|
|
287
|
+
*
|
|
288
|
+
* LIFETIME is borrowed, not declared: `contextType` must be a type
|
|
289
|
+
* this SAME bundle already registered through `contribute.editContext`
|
|
290
|
+
* (an unregistered type is refused loudly — a provider that can never
|
|
291
|
+
* activate is a bug, not a stance). The capability gate is that
|
|
292
|
+
* context's: `contributes.editContexts[]` must declare the type. There
|
|
293
|
+
* is deliberately NO separate manifest field and NO separate
|
|
294
|
+
* capability — the authority a provider exercises is the authority the
|
|
295
|
+
* active context already holds over the selection it owns.
|
|
296
|
+
*
|
|
297
|
+
* Always present. When the host wires no shared registry, the door
|
|
298
|
+
* warns + returns an inert handle (nothing will ever consult the
|
|
299
|
+
* provider) and `supports("bindings.provider@1")` is false; probe
|
|
300
|
+
* `supports("contribute.bindingProvider@1")` for whether this SDK has
|
|
301
|
+
* the door at all.
|
|
302
|
+
*/
|
|
303
|
+
bindingProvider(contextType: string, provider: BindingProvider): BindingProviderHandle;
|
|
255
304
|
/**
|
|
256
305
|
* Open a SCENE-LAYER surface (C-1): submit vector content that renders
|
|
257
306
|
* INSIDE a frame, in frame-content coordinates — core applies the
|
|
@@ -516,8 +565,75 @@ export interface RunContent {
|
|
|
516
565
|
position?: string | null;
|
|
517
566
|
tracking?: number | null;
|
|
518
567
|
}
|
|
568
|
+
/**
|
|
569
|
+
* B-22 (protocol v57) — one FACE of a planar arrangement: a connected
|
|
570
|
+
* region of the plane whose containment signature is constant. This is
|
|
571
|
+
* the level BELOW element hit-testing (the areas overlapping paths
|
|
572
|
+
* divide the plane into), which is what a Shape Builder needs.
|
|
573
|
+
*
|
|
574
|
+
* Coordinates are in the RAW path space `pathAnchors` reports —
|
|
575
|
+
* per-element `itemTransform`s are NOT composed in (the arrangement runs
|
|
576
|
+
* on the anchors as stored, exactly like `pathfinderBoolean`). A consumer
|
|
577
|
+
* that draws faces on canvas maps them with the frontmost input's
|
|
578
|
+
* `itemTransform`, the same chain the anchor overlays use.
|
|
579
|
+
*/
|
|
580
|
+
export interface PlanarFace {
|
|
581
|
+
/** Stable id (`"<signature>#<component>"`, e.g. `"0-1#0"`) — stable
|
|
582
|
+
* across calls with the same inputs, which is what lets a hovered
|
|
583
|
+
* face's id ride straight into the `pathfinderFaces` mutation
|
|
584
|
+
* (mutations.ts) without a second query. */
|
|
585
|
+
id: string;
|
|
586
|
+
/** Indices into the REQUEST's `elementIds` whose interior contains
|
|
587
|
+
* this face. */
|
|
588
|
+
signature: number[];
|
|
589
|
+
/** The face outline (closed). A face with holes carries them as extra
|
|
590
|
+
* contours. */
|
|
591
|
+
anchors: PathAnchorTriple[];
|
|
592
|
+
/** Per-contour boundaries into `anchors`. */
|
|
593
|
+
subpathStarts: number[];
|
|
594
|
+
/** Unsigned area, outer contour minus holes. */
|
|
595
|
+
area: number;
|
|
596
|
+
/** A point strictly inside the face — what a hover highlight or a fill
|
|
597
|
+
* drop keys off without re-deriving containment. */
|
|
598
|
+
inside: [number, number];
|
|
599
|
+
}
|
|
600
|
+
/**
|
|
601
|
+
* B-22 (protocol v57) — the full result of `document.planarRegions`.
|
|
602
|
+
*
|
|
603
|
+
* Deliberately NOT a bare face array: the door has THREE distinct
|
|
604
|
+
* answers a caller must be able to tell apart, and flattening them
|
|
605
|
+
* would make a refusal indistinguishable from "these paths divide into
|
|
606
|
+
* nothing":
|
|
607
|
+
* · `found: true` — `faces` is the answer (possibly empty: a point
|
|
608
|
+
* query outside every input);
|
|
609
|
+
* · `found: false` + `reason` — a REFUSAL (no document, an id that
|
|
610
|
+
* doesn't resolve, more inputs than the kernel's cap, or a host
|
|
611
|
+
* whose engine predates the door). Never a truncated answer;
|
|
612
|
+
* surface the engine's own words, never an empty face list.
|
|
613
|
+
* · `complete: false` — the listed faces are all REAL but do not tile
|
|
614
|
+
* the union of the inputs (the enumeration missed a sliver). Always
|
|
615
|
+
* `true` for a point query — one face is not a tiling claim.
|
|
616
|
+
*/
|
|
617
|
+
export interface PlanarRegionsResult {
|
|
618
|
+
/** `false` ⇒ the query could not be answered at all; read `reason`. */
|
|
619
|
+
found: boolean;
|
|
620
|
+
/** Populated when `found`. With a `point` in the request this holds at
|
|
621
|
+
* most one face (empty ⇒ the point is outside every input). */
|
|
622
|
+
faces: PlanarFace[];
|
|
623
|
+
/** How many inputs the arrangement was built from. */
|
|
624
|
+
inputCount: number;
|
|
625
|
+
/** `true` when the resolved faces tile the union of the inputs. */
|
|
626
|
+
complete: boolean;
|
|
627
|
+
/** Why `found` is false — the engine's own words (or the host
|
|
628
|
+
* adapter's, when no v57 engine answered). Absent on success. */
|
|
629
|
+
reason?: string | null;
|
|
630
|
+
}
|
|
519
631
|
export interface DocumentSurface {
|
|
520
|
-
|
|
632
|
+
/** The single write door. Accepts `MutationInput` — the vendored
|
|
633
|
+
* `Mutation` union PLUS the protocol-ahead ops the vendored wire
|
|
634
|
+
* hasn't absorbed yet (see mutations.ts). Widening an accepted
|
|
635
|
+
* input is additive: every `Mutation` still passes. */
|
|
636
|
+
mutate(mutation: MutationInput): Promise<MutationOutcome>;
|
|
521
637
|
undo(): Promise<void>;
|
|
522
638
|
redo(): Promise<void>;
|
|
523
639
|
collection<T>(name: CollectionName): Promise<readonly T[]>;
|
|
@@ -528,6 +644,33 @@ export interface DocumentSurface {
|
|
|
528
644
|
* against). Retires the v0 `host.editor.client.send` escape hatch
|
|
529
645
|
* the draw fill panel used. `null` for an unknown element. */
|
|
530
646
|
elementProperties(id: ElementId): Promise<ElementProperties | null>;
|
|
647
|
+
/**
|
|
648
|
+
* B-22 (protocol v57) — the planar-REGION read door: resolve the faces
|
|
649
|
+
* of the arrangement `elementIds` forms (the areas the overlapping
|
|
650
|
+
* paths divide the plane into, one level below element hit-testing).
|
|
651
|
+
* Retires the v0 `host.editor.client.send({ kind:
|
|
652
|
+
* "requestPlanarRegions" })` escape hatch paged.draw's Shape Builder
|
|
653
|
+
* used.
|
|
654
|
+
*
|
|
655
|
+
* With `point` (in the RAW path space `pathAnchors` reports) it answers
|
|
656
|
+
* ONLY the face under it — the hover query, which costs N
|
|
657
|
+
* point-in-path tests plus one region materialisation instead of a
|
|
658
|
+
* full enumeration. Without it, every face comes back.
|
|
659
|
+
*
|
|
660
|
+
* Pure READ, gated on `capabilities.document.read`. Face ids are stable
|
|
661
|
+
* for the same inputs, so a hovered id is handed straight to the
|
|
662
|
+
* `pathfinderFaces` mutation.
|
|
663
|
+
*
|
|
664
|
+
* Answers the FULL {@link PlanarRegionsResult} — never a bare face
|
|
665
|
+
* array — because a refusal (`found: false` + `reason`: input cap,
|
|
666
|
+
* unresolvable id, or a host whose engine predates the door) must not
|
|
667
|
+
* be readable as "no regions". A host that cannot answer comes back as
|
|
668
|
+
* a refusal with a reason — never a throw (the undeclared-capability
|
|
669
|
+
* gate is the one exception, as on every read door). Probe
|
|
670
|
+
* `supports("document.planarRegions@1")` for whether the facade
|
|
671
|
+
* forwards at all.
|
|
672
|
+
*/
|
|
673
|
+
planarRegions(elementIds: ElementId[], point?: [number, number]): Promise<PlanarRegionsResult>;
|
|
531
674
|
/** D-01 (protocol v43) — enumerate every plugin-tagged placeholder
|
|
532
675
|
* field in the document, in story order. Offsets are FRESH-READ
|
|
533
676
|
* addresses (a placeholder is its own tagged run; re-enumerate
|
|
@@ -538,6 +681,31 @@ export interface DocumentSurface {
|
|
|
538
681
|
hitTest(pageId: PageId, point: [number, number], filter?: HitFilter): Promise<HitResult | null>;
|
|
539
682
|
elementGeometry(ids: ElementId[]): Promise<ElementGeometryItem[]>;
|
|
540
683
|
tree(): Promise<SceneTreeNode[]>;
|
|
684
|
+
/**
|
|
685
|
+
* C-16 — the per-element PARENTAGE read: the nearest ANCESTOR that is
|
|
686
|
+
* itself an addressable element (a group today — the only element kind
|
|
687
|
+
* that nests page items), or `null` when there is none.
|
|
688
|
+
*
|
|
689
|
+
* Consumer: paged.draw's `selectParentGroup` command
|
|
690
|
+
* (`draw-bundle/src/commands/select-parent-group.ts`), which climbs to
|
|
691
|
+
* the containing group on every press. Without this door it re-read
|
|
692
|
+
* `tree()` and walked the WHOLE scene tree per invocation — O(document)
|
|
693
|
+
* per keystroke, a cost its own module header records as a named gap.
|
|
694
|
+
*
|
|
695
|
+
* `null` is the honest answer for three distinct cases a caller need
|
|
696
|
+
* not distinguish: the element is top-level (its container is a Page /
|
|
697
|
+
* Spread, which is NOT an element and never a selection target), the
|
|
698
|
+
* id does not resolve, or the address is a story/table range (those
|
|
699
|
+
* never nest in groups).
|
|
700
|
+
*
|
|
701
|
+
* A pure READ gated on `capabilities.document.read`, resolved from the
|
|
702
|
+
* SAME scene-tree the `tree()` door reads — no extra engine query and
|
|
703
|
+
* no wire op of its own (DESIGN.md §4.3d). The host keeps a parent
|
|
704
|
+
* index and rebuilds it when the document changes, so the O(document)
|
|
705
|
+
* walk happens once per EDIT rather than once per press. It is
|
|
706
|
+
* therefore exactly as fresh as `tree()` and no fresher.
|
|
707
|
+
*/
|
|
708
|
+
parentOf(id: ElementId): Promise<ElementId | null>;
|
|
541
709
|
/** Read a text frame's thread topology (protocol v38, C-2/S-05) — the
|
|
542
710
|
* ordered chain of frames a story flows through, tail-overflow flagged.
|
|
543
711
|
* Empty when the story has no frame or no document is loaded. A
|
|
@@ -629,6 +797,23 @@ export interface TextMetrics {
|
|
|
629
797
|
/** Face descender at `sizePt` (negative below the baseline). */
|
|
630
798
|
descender: number;
|
|
631
799
|
}
|
|
800
|
+
/**
|
|
801
|
+
* C-9 — the user's text caret: the story + insertion offset a
|
|
802
|
+
* text-inserting plugin should target (paged.data first-insert
|
|
803
|
+
* placement — without this door a freshly-placed variable field lands
|
|
804
|
+
* at story start, offset 0).
|
|
805
|
+
*
|
|
806
|
+
* `offset` is a story-local content offset in the SAME convention the
|
|
807
|
+
* engine's text mutations consume (`insertText.offset`,
|
|
808
|
+
* `deleteRange.start/end` — the `ContentSelection` addressing: run
|
|
809
|
+
* bytes plus one synthetic `\n` per inter-paragraph boundary), so the
|
|
810
|
+
* value can be passed straight to `host.document.mutate`.
|
|
811
|
+
*/
|
|
812
|
+
export interface TextCaret {
|
|
813
|
+
storyId: string;
|
|
814
|
+
/** Insertion offset (see the offset-convention note above). */
|
|
815
|
+
offset: number;
|
|
816
|
+
}
|
|
632
817
|
/**
|
|
633
818
|
* Text measurement against the loaded document's fonts (S-13). A read
|
|
634
819
|
* door — no capability gate (like {@link ViewportSurface}); it wraps the
|
|
@@ -640,12 +825,51 @@ export interface TextMetrics {
|
|
|
640
825
|
*/
|
|
641
826
|
export interface TextSurface {
|
|
642
827
|
measureString(family: string, style: string | null, text: string, sizePt: number): Promise<TextMetrics>;
|
|
828
|
+
/**
|
|
829
|
+
* C-9 — read the user's text caret (the active `ContentSelection`),
|
|
830
|
+
* or `null` when no text caret is active OR the host injects no
|
|
831
|
+
* caret reader (probe `supports("text.caret@1")` to tell the two
|
|
832
|
+
* apart). For a collapsed selection this is the caret offset; for a
|
|
833
|
+
* RANGE selection it answers the range START (where a replace
|
|
834
|
+
* inserts). Honest v1 gap: a caret inside a TABLE CELL
|
|
835
|
+
* (cell-qualified selection) answers `null` — cell-local offsets
|
|
836
|
+
* would be misread as story-local body offsets.
|
|
837
|
+
*/
|
|
838
|
+
caret(): TextCaret | null;
|
|
643
839
|
}
|
|
644
840
|
/** The v0 overlay channel: the shared tool-preview signal (polyline /
|
|
645
|
-
* rect
|
|
646
|
-
*
|
|
841
|
+
* rect / path — and, with `supports("overlay.text@1")`, the TEXT
|
|
842
|
+
* primitive `ToolPreviewText` for on-canvas readouts). Retained
|
|
843
|
+
* plugin scene layers are the P2 channel — reserved, not faked. */
|
|
647
844
|
export interface OverlaySurface {
|
|
648
845
|
setToolPreview(shape: ToolPreviewShape | null): void;
|
|
846
|
+
/**
|
|
847
|
+
* K-9 — publish MANY preview shapes at once (DESIGN.md §4.5a). The
|
|
848
|
+
* single-slot `setToolPreview` is last-write-wins, so a tool could
|
|
849
|
+
* show geometry OR a label, never both: paged.draw's **Measure** trades
|
|
850
|
+
* the frozen line for the frozen readout at pointer-up, and its region
|
|
851
|
+
* **Shape Builder** can highlight one hovered face but not shade the
|
|
852
|
+
* whole collected set. Both trades are named in that bundle's code;
|
|
853
|
+
* this door retires them.
|
|
854
|
+
*
|
|
855
|
+
* ONE SLOT, two writers: this REPLACES whatever the tool-preview slot
|
|
856
|
+
* holds with `shapes` (rendered in array order, first = bottom-most);
|
|
857
|
+
* `null` — or an empty array — clears it, exactly like
|
|
858
|
+
* `setToolPreview(null)`. It is not a second overlay layer (that would
|
|
859
|
+
* resurrect z-ordering and double the teardown paths).
|
|
860
|
+
*
|
|
861
|
+
* Shapes may address DIFFERENT pages: each carries its own `pageId`
|
|
862
|
+
* and the host resolves the page rect per shape.
|
|
863
|
+
*
|
|
864
|
+
* Same `capabilities.rendering` ∋ `"overlay"` gate as
|
|
865
|
+
* `setToolPreview` — one channel, one gate. Probe
|
|
866
|
+
* `supports("overlay.multiPreview@1")`: it is DYNAMIC (unlike the
|
|
867
|
+
* static `overlay.text@1`), true only when the host wired a real
|
|
868
|
+
* multi-shape sink. When it is false the door still works and never
|
|
869
|
+
* throws — it forwards the FIRST shape through the single slot, which
|
|
870
|
+
* is precisely the pre-K-9 behaviour a bundle used to hand-code.
|
|
871
|
+
*/
|
|
872
|
+
setToolPreviews(shapes: readonly ToolPreviewShape[] | null): void;
|
|
649
873
|
}
|
|
650
874
|
/**
|
|
651
875
|
* Shell actions the HOST APP injects at `loadBundle` time (the
|
|
@@ -653,6 +877,11 @@ export interface OverlaySurface {
|
|
|
653
877
|
* function over the editor handle). When the host app provides no
|
|
654
878
|
* implementation, calls warn and no-op — probe with
|
|
655
879
|
* `host.supports("shell.openPanel@1")`.
|
|
880
|
+
*
|
|
881
|
+
* The two FILE doors are a pair: `pickFile` reads bytes IN (K-5 / S-11),
|
|
882
|
+
* `saveFile` hands bytes OUT (K-10). Both are byte-level by design —
|
|
883
|
+
* no DOM `File`/`Blob` ever crosses the contract — and both answer an
|
|
884
|
+
* honest "nothing happened" value rather than throwing.
|
|
656
885
|
*/
|
|
657
886
|
export interface ShellSurface {
|
|
658
887
|
/** Open a REGISTERED panel as the active dock tab (the
|
|
@@ -665,6 +894,42 @@ export interface ShellSurface {
|
|
|
665
894
|
* the user cancels OR no picker is wired (the honest no-picker door);
|
|
666
895
|
* probe `host.supports("shell.pickFile@1")` for the latter. */
|
|
667
896
|
pickFile(options?: FilePickerOptions): Promise<readonly PickedFile[]>;
|
|
897
|
+
/**
|
|
898
|
+
* K-10 — the WRITE half of the picker door: hand the host bytes to
|
|
899
|
+
* deliver to the user's filesystem under `suggestedName` (DESIGN.md
|
|
900
|
+
* §4.5c). The mirror of `pickFile`: bytes cross, never a DOM `File`
|
|
901
|
+
* or a `Blob`, so a bundle stays isolate-ready.
|
|
902
|
+
*
|
|
903
|
+
* Consumer: **paged.image**, which can compute an adjusted
|
|
904
|
+
* PSD/PNG/JPEG but — with `pickFile` READ-only — could only deliver it
|
|
905
|
+
* through the Export Center's exporter registry, so "Save adjusted
|
|
906
|
+
* copy…" was unofferable from the bundle's own panel.
|
|
907
|
+
*
|
|
908
|
+
* Answers `true` when the host ACCEPTED the bytes and handed them to
|
|
909
|
+
* its save path, `false` when it did not — no saver wired (probe
|
|
910
|
+
* `supports("shell.saveFile@1")` to know that up front), the user
|
|
911
|
+
* declined, or the host refused. Never throws: a refused save is a
|
|
912
|
+
* result, like a refused mutation. Honest ceiling: a host backed by
|
|
913
|
+
* the browser's anchor-download cannot observe a user cancel, so
|
|
914
|
+
* `true` means "delivered to the browser's download path", not "a file
|
|
915
|
+
* exists on disk"; a File System Access backing can answer a real
|
|
916
|
+
* `false`.
|
|
917
|
+
*/
|
|
918
|
+
saveFile(options: SaveFileOptions): Promise<boolean>;
|
|
919
|
+
}
|
|
920
|
+
/** What `ShellSurface.saveFile` delivers (K-10) — the inverse of
|
|
921
|
+
* {@link PickedFile}, field-for-field, so bytes picked from disk can be
|
|
922
|
+
* handed straight back after an edit. */
|
|
923
|
+
export interface SaveFileOptions {
|
|
924
|
+
/** File name incl. extension the host proposes to the user (it may
|
|
925
|
+
* sanitize or de-duplicate it — the name is a suggestion, not a
|
|
926
|
+
* path; a bundle can never target a location). */
|
|
927
|
+
suggestedName: string;
|
|
928
|
+
/** The bytes to write. */
|
|
929
|
+
bytes: Uint8Array;
|
|
930
|
+
/** MIME type for the saved file (same field name as `PickedFile`).
|
|
931
|
+
* Absent ⇒ the host uses `application/octet-stream`. */
|
|
932
|
+
mimeType?: string;
|
|
668
933
|
}
|
|
669
934
|
/** Filter + multiplicity for `ShellSurface.pickFile` (K-5 / S-11). */
|
|
670
935
|
export interface FilePickerOptions {
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
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, FrameChainLink, StoryContent, ParagraphContent, RunContent, OverlaySurface, ShellSurface, FilePickerOptions, PickedFile, StorageSurface, BlobSurface, BlobUsage, PartsSurface, NativeDocumentSurface, NetworkSurface, ConsentResult, DataProvidersSurface, DataProviderRegistration, DataProviderHandle, DataProviderInfo, DataProviderSnapshot, ProviderSchema, ProviderField, ProviderRecordSet, DiagnosticsSurface, BindingsSurface, Diagnostic, DocumentChangeEvent, MutationOutcome, Disposable, PluginLogger, EditContextContribution, ObjectTypeContribution, EditContextCandidate, EnteredEditContext, ContentPointerEvent, EditContextDescriptor, ObjectTypeDescriptor, PluginMetadataEnvelope, ObjectTypeBaker, BakeContext, } from "./host";
|
|
4
|
-
export type { PanelSchema, PanelSchemaSection, PanelSchemaRow, SchemaPanelContribution, SchemaPanelRenderer, SchemaPanelRendererProps, WidgetValueBinding, BindingRef, SchemaGate, } from "./panel-schema";
|
|
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, BindingsSurface, Diagnostic, DocumentChangeEvent, MutationOutcome, Disposable, PluginLogger, EditContextContribution, ObjectTypeContribution, EditContextCandidate, EnteredEditContext, ContentPointerEvent, EditContextDescriptor, ObjectTypeDescriptor, PluginMetadataEnvelope, ObjectTypeBaker, BakeContext, } from "./host";
|
|
4
|
+
export type { PanelSchema, PanelSchemaSection, PanelSchemaRow, SchemaPanelContribution, SchemaPanelRenderer, SchemaPanelRendererProps, WidgetValueBinding, BindingRef, SchemaGate, WidgetCollectionBinding, SchemaRowAction, SchemaListAction, SchemaListSpec, } from "./panel-schema";
|
|
5
5
|
export type { WidgetSurface, CodeEditorProps, CodeEditorDiagnostic, CodeEditorLanguage, } from "./widgets";
|
|
6
|
+
export type { BindingTarget, BindingPropertyRequest, BindingPropertyWrite, BindingCollectionRequest, BindingRead, BindingResolved, BindingDecline, BindingWrite, BindingCollection, BindingOp, BindingProvider, BindingProviderScope, BindingProviderHandle, BindingReadResult, BindingWriteResult, BindingCollectionResult, ActiveBindingProvider, } from "./binding-provider";
|
|
6
7
|
export type { AssetSurface, AssetKind, FontFaceAsset, FontFaceFormat, } from "./assets";
|
|
7
8
|
export type { ProviderTileWire } from "./wire";
|
|
8
9
|
export type { ClipboardSurface, ClipboardPayload, TabularClipboard, } from "./clipboard";
|
package/dist/mutations.d.ts
CHANGED
|
@@ -1 +1,275 @@
|
|
|
1
|
+
import type { ElementId, Mutation } from "./wire";
|
|
1
2
|
export type { ElementId, PageId, NodeId, NodeSpec, Mutation, Operation, PropertyPath, Value, PathAnchorSpec, PathAnchorTriple, PathAnchorsResult, PathPointAddress, PathPointRole, PathfinderKind, HitFilter, HitResult, CollectionName, DocumentMeta, ElementGeometryItem, SceneTreeNode, SelectionMode, ContentSelection, MainToWorker, MainToWorkerKind, WorkerToMain, SceneLayer, SceneItem, ScenePathSeg, ScenePaint, GestureType, GestureHandle, GestureModifiers, SwatchSpec, GradientSpec, GradientStopSpec, SwatchSummary, GradientSummary, LayerSummary, } from "./wire";
|
|
3
|
+
/** v56 (Wave B) — close an OPEN subpath of a path element: the inverse
|
|
4
|
+
* gesture of `pathOpenAt`'s scissors cut. `subpath` picks the contour
|
|
5
|
+
* by index; omit for the default (the single/last open subpath).
|
|
6
|
+
* Coincident endpoints — the duplicated pair a cut leaves — merge back
|
|
7
|
+
* into one anchor; endpoints apart gain the implicit closing edge. */
|
|
8
|
+
export type ClosePathMutation = {
|
|
9
|
+
op: "closePath";
|
|
10
|
+
args: {
|
|
11
|
+
elementId: ElementId;
|
|
12
|
+
subpath?: number | null;
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
/** v56 (Wave B) — weld two OPEN single-contour path elements into one
|
|
16
|
+
* (InDesign's Join): connect the NEAREST endpoints of `elementId` and
|
|
17
|
+
* `otherId`, then delete `otherId`. Both endpoint pairs coincident
|
|
18
|
+
* closes the result into a ring. Non-path / closed / multi-contour
|
|
19
|
+
* inputs are rejected with an honest error (no-op). One undo step
|
|
20
|
+
* restores BOTH elements. */
|
|
21
|
+
export type JoinPathsMutation = {
|
|
22
|
+
op: "joinPaths";
|
|
23
|
+
args: {
|
|
24
|
+
elementId: ElementId;
|
|
25
|
+
otherId: ElementId;
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
/** v56 (B-18) — InDesign paste-into: nest an existing TOP-LEVEL page
|
|
29
|
+
* item inside a container Rectangle / Oval / Polygon. The child keeps
|
|
30
|
+
* its document-space geometry (nothing moves on canvas) and renders
|
|
31
|
+
* clipped by the container's outline. Grouped / already-nested
|
|
32
|
+
* children and non-container hosts are rejected with an honest error.
|
|
33
|
+
* One undo pops the child back to its exact stacking slot. */
|
|
34
|
+
export type PasteIntoMutation = {
|
|
35
|
+
op: "pasteInto";
|
|
36
|
+
args: {
|
|
37
|
+
containerId: ElementId;
|
|
38
|
+
childId: ElementId;
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
/** v56 (B-18) — the inverse gesture: pop a pasted-in child back to top
|
|
42
|
+
* level (stacks on top), world transform preserved. One undo re-nests
|
|
43
|
+
* it at the same child index. */
|
|
44
|
+
export type ReleaseFromMutation = {
|
|
45
|
+
op: "releaseFrom";
|
|
46
|
+
args: {
|
|
47
|
+
childId: ElementId;
|
|
48
|
+
};
|
|
49
|
+
};
|
|
50
|
+
/** v57 (B-22) — every face of the arrangement becomes its own object,
|
|
51
|
+
* keeping the attributes of the topmost input covering it. */
|
|
52
|
+
export type PathfinderDivideMutation = {
|
|
53
|
+
op: "pathfinderDivide";
|
|
54
|
+
args: {
|
|
55
|
+
elementIds: ElementId[];
|
|
56
|
+
};
|
|
57
|
+
};
|
|
58
|
+
/** v57 (B-22) — each input is clipped to the part nothing above it
|
|
59
|
+
* covers, and loses its stroke. Inputs entirely hidden are deleted. */
|
|
60
|
+
export type PathfinderTrimMutation = {
|
|
61
|
+
op: "pathfinderTrim";
|
|
62
|
+
args: {
|
|
63
|
+
elementIds: ElementId[];
|
|
64
|
+
};
|
|
65
|
+
};
|
|
66
|
+
/** v57 (B-22) — Trim, then coalesce: inputs that share a fill colour
|
|
67
|
+
* merge into one object. */
|
|
68
|
+
export type PathfinderMergeMutation = {
|
|
69
|
+
op: "pathfinderMerge";
|
|
70
|
+
args: {
|
|
71
|
+
elementIds: ElementId[];
|
|
72
|
+
};
|
|
73
|
+
};
|
|
74
|
+
/** v57 (B-22) — keep only what falls inside the TOPMOST input, coloured
|
|
75
|
+
* by the objects beneath it; the topmost input is consumed as the
|
|
76
|
+
* cookie cutter and disappears. */
|
|
77
|
+
export type PathfinderCropMutation = {
|
|
78
|
+
op: "pathfinderCrop";
|
|
79
|
+
args: {
|
|
80
|
+
elementIds: ElementId[];
|
|
81
|
+
};
|
|
82
|
+
};
|
|
83
|
+
/** v57 (B-22) — fills become strokes: every arrangement edge (split at
|
|
84
|
+
* each crossing) becomes an open `GraphicLine` stroked with the fill of
|
|
85
|
+
* the input that contributed it. All inputs are consumed. */
|
|
86
|
+
export type PathfinderOutlineMutation = {
|
|
87
|
+
op: "pathfinderOutline";
|
|
88
|
+
args: {
|
|
89
|
+
elementIds: ElementId[];
|
|
90
|
+
};
|
|
91
|
+
};
|
|
92
|
+
/** v57 (B-22) — the BACKMOST object minus every object in front of it. */
|
|
93
|
+
export type PathfinderMinusBackMutation = {
|
|
94
|
+
op: "pathfinderMinusBack";
|
|
95
|
+
args: {
|
|
96
|
+
elementIds: ElementId[];
|
|
97
|
+
};
|
|
98
|
+
};
|
|
99
|
+
/** v57 (B-22) — whether `pathfinderFaces` KEEPS the named faces or
|
|
100
|
+
* REMOVES them (Shape Builder's drag vs alt-drag). */
|
|
101
|
+
export type FaceSelectMode = "keep" | "remove";
|
|
102
|
+
/** v57 (B-22) — Shape Builder's click/drag output: unite the named faces
|
|
103
|
+
* of the arrangement into one result element. `faces` carries the
|
|
104
|
+
* STABLE ids `host.document.planarRegions` reported for the SAME
|
|
105
|
+
* `elementIds` (ids are only stable per input set); `mode` picks
|
|
106
|
+
* whether they are the faces kept or the faces removed. An unknown id
|
|
107
|
+
* is REFUSED, not ignored — a stale face set fails loudly. */
|
|
108
|
+
export type PathfinderFacesMutation = {
|
|
109
|
+
op: "pathfinderFaces";
|
|
110
|
+
args: {
|
|
111
|
+
elementIds: ElementId[];
|
|
112
|
+
faces: string[];
|
|
113
|
+
mode: FaceSelectMode;
|
|
114
|
+
};
|
|
115
|
+
};
|
|
116
|
+
/** v58 (C-28) — how the mask artwork's coverage is read. `luminosity`
|
|
117
|
+
* is Illustrator's default and PDF's `/S /Luminosity`; `alpha` reads
|
|
118
|
+
* the artwork's alpha channel instead. Unpainted area means HIDDEN for
|
|
119
|
+
* both (PDF's black backdrop). Omitted = `luminosity`. */
|
|
120
|
+
export type OpacityMaskType = "luminosity" | "alpha";
|
|
121
|
+
/** v58 (C-28) — **Make Opacity Mask**: `maskId`'s artwork becomes a soft
|
|
122
|
+
* mask over `targetId`. The mask item leaves the page's z-order (its
|
|
123
|
+
* slot is captured) and one undo pops it back exactly.
|
|
124
|
+
*
|
|
125
|
+
* RENDERS EVERYWHERE. An earlier revision of this comment warned that
|
|
126
|
+
* the mask was honoured by the CPU rasterizer and PDF export but NOT by
|
|
127
|
+
* the Vello/WebGPU backend the editor canvas uses, so a plugin must not
|
|
128
|
+
* imply WYSIWYG. **That is no longer true, and it was never as
|
|
129
|
+
* fundamental as it read**: the claim rested on the belief that Vello
|
|
130
|
+
* lacked a coverage-buffer API, when the pinned version has
|
|
131
|
+
* `Scene::push_luminance_mask_layer` (an unrelated 0.3.0 entry in
|
|
132
|
+
* `Cargo.lock`, belonging to a spike crate, was misread as the resolved
|
|
133
|
+
* version). Alpha masks need no mask layer at all — `Compose::DestIn`
|
|
134
|
+
* IS `dst · src.a`.
|
|
135
|
+
*
|
|
136
|
+
* Vello output is now byte-identical to the CPU rasterizer across
|
|
137
|
+
* luminosity, alpha and both inverted forms. Safe to build WYSIWYG UI
|
|
138
|
+
* over. */
|
|
139
|
+
export type ApplyOpacityMaskMutation = {
|
|
140
|
+
op: "applyOpacityMask";
|
|
141
|
+
args: {
|
|
142
|
+
targetId: ElementId;
|
|
143
|
+
maskId: ElementId;
|
|
144
|
+
maskType?: OpacityMaskType | null;
|
|
145
|
+
invert?: boolean | null;
|
|
146
|
+
};
|
|
147
|
+
};
|
|
148
|
+
/** v58 (C-28) — drop the mask relation; the artwork returns to top level
|
|
149
|
+
* with its geometry untouched. One undo re-applies the mask with its
|
|
150
|
+
* original mode/invert at the same z slot. */
|
|
151
|
+
export type ReleaseOpacityMaskMutation = {
|
|
152
|
+
op: "releaseOpacityMask";
|
|
153
|
+
args: {
|
|
154
|
+
targetId: ElementId;
|
|
155
|
+
};
|
|
156
|
+
};
|
|
157
|
+
/** v58 (C-29) — **Type on a Path**: flow an existing story along an
|
|
158
|
+
* existing path element. The engine could already RENDER type on a path
|
|
159
|
+
* loaded from an IDML; until v58 nothing could create one.
|
|
160
|
+
*
|
|
161
|
+
* Hosts are Rectangle / GraphicLine / Polygon. A TextFrame is refused
|
|
162
|
+
* WITH a reason: its glyphs are emitted by the story pass, so accepting
|
|
163
|
+
* it would produce a visible lie. `pathTypeAlignment` (Baseline /
|
|
164
|
+
* Center honoured), `flipPathEffect` and the `startBracket`/`endBracket`
|
|
165
|
+
* range are all live. `PathEffect` is deliberately NOT exposed — only
|
|
166
|
+
* `RainbowPathEffect` actually renders. */
|
|
167
|
+
export type AttachTextToPathMutation = {
|
|
168
|
+
op: "attachTextToPath";
|
|
169
|
+
args: {
|
|
170
|
+
elementId: ElementId;
|
|
171
|
+
storyId: string;
|
|
172
|
+
pathTypeAlignment?: string | null;
|
|
173
|
+
flipPathEffect?: string | null;
|
|
174
|
+
startBracket?: number | null;
|
|
175
|
+
endBracket?: number | null;
|
|
176
|
+
};
|
|
177
|
+
};
|
|
178
|
+
/** v58 (C-29) — unlink the text from the path; the exact inverse. */
|
|
179
|
+
export type DetachTextFromPathMutation = {
|
|
180
|
+
op: "detachTextFromPath";
|
|
181
|
+
args: {
|
|
182
|
+
elementId: ElementId;
|
|
183
|
+
};
|
|
184
|
+
};
|
|
185
|
+
/** v59 (Arrange) — where `reorderElement` puts its target inside the
|
|
186
|
+
* sibling list it already belongs to. `0` is the BACKMOST slot (painted
|
|
187
|
+
* first). Prefer the four verbs: they are evaluated against the order
|
|
188
|
+
* the engine holds at apply time, so a concurrent insert or delete
|
|
189
|
+
* cannot make them restack the wrong item. `{ index }` is absolute and
|
|
190
|
+
* therefore CAN go stale — an out-of-range index is refused with an
|
|
191
|
+
* honest error, never clamped. */
|
|
192
|
+
export type ZOrderTarget = "front" | "back" | "forward" | "backward" | {
|
|
193
|
+
index: number;
|
|
194
|
+
};
|
|
195
|
+
/** v59 (Arrange) — **the z-order door**: restack an element within the
|
|
196
|
+
* sibling list it already belongs to. Nothing on the wire could change
|
|
197
|
+
* stacking before v59, which is why so many bundles carry "inserted
|
|
198
|
+
* items land on top of the z-order" as an accepted limit — that
|
|
199
|
+
* sentence is retired by this op.
|
|
200
|
+
*
|
|
201
|
+
* The sibling list is DERIVED from where the element already is: a
|
|
202
|
+
* top-level item restacks in the spread's z table, a group member
|
|
203
|
+
* inside its group, a pasted-in child inside its container. There is no
|
|
204
|
+
* parent argument, so a reorder can never move an element between those
|
|
205
|
+
* scopes — for that use `createGroup` / `dissolveGroup` /
|
|
206
|
+
* `pasteInto` / `releaseFrom`. An opacity-mask artwork is painted from
|
|
207
|
+
* no list at all and is refused. One undo restores the previous order
|
|
208
|
+
* exactly (the engine's inverse carries the slot the item came from).
|
|
209
|
+
*
|
|
210
|
+
* CREATE-THEN-ARRANGE in one undo step — the Live Paint shape (fill a
|
|
211
|
+
* face, then put the fill UNDER the strokes bounding it) — is a batch
|
|
212
|
+
* of `[insert…, bindCreated { handle }, reorderElement
|
|
213
|
+
* { elementId: "$h:<handle>", to: "back" }]`. The `bindCreated` is
|
|
214
|
+
* required: the bare `$created` sentinel is understood by
|
|
215
|
+
* `setPluginMetadata` / `setElementProperty` only, while the generic
|
|
216
|
+
* handle resolver — the one that rewrites any id position of any op —
|
|
217
|
+
* is armed by a `bindCreated` child being present.
|
|
218
|
+
*
|
|
219
|
+
* HONEST LIMIT 1 — Arrange is WITHIN a layer. The renderer sorts by
|
|
220
|
+
* `ItemLayer` before it paints, so bring-to-front cannot lift an
|
|
221
|
+
* element above one on a higher layer. That is InDesign's model:
|
|
222
|
+
* crossing layers is a property write, not an Arrange.
|
|
223
|
+
*
|
|
224
|
+
* HONEST LIMIT 2 — the new order shows on canvas and survives a
|
|
225
|
+
* `.paged` save, but NOT an `.idml` export: the IDML writer re-emits
|
|
226
|
+
* existing source elements byte-for-byte and only places new ones, so a
|
|
227
|
+
* reorder reverts on an export/reopen round trip. Do not present
|
|
228
|
+
* Arrange as durable across IDML interchange yet. */
|
|
229
|
+
export type ReorderElementMutation = {
|
|
230
|
+
op: "reorderElement";
|
|
231
|
+
args: {
|
|
232
|
+
elementId: ElementId;
|
|
233
|
+
to: ZOrderTarget;
|
|
234
|
+
};
|
|
235
|
+
};
|
|
236
|
+
/** The protocol-ahead ops, as one union — the delta between the
|
|
237
|
+
* vendored `Mutation` (protocol 51) and core's protocol 59. Empties
|
|
238
|
+
* itself on the next `sync-wire.mjs` run. */
|
|
239
|
+
/** v57 (C-15) — name the id a creating sibling is about to mint, so a
|
|
240
|
+
* LATER child of the same batch can address it as `"$h:<handle>"`.
|
|
241
|
+
*
|
|
242
|
+
* This is what collapses a two-batch flow into ONE undo step. Before it,
|
|
243
|
+
* a bundle that inserted geometry and then painted or grouped it had to
|
|
244
|
+
* issue two batches, because a batch op could not reference an id minted
|
|
245
|
+
* in the same batch — paged.draw's appearance bake, pattern bake and
|
|
246
|
+
* re-plan, compound-path release, symbol place, image trace and
|
|
247
|
+
* live-paint fill all pay two undo steps for exactly that reason.
|
|
248
|
+
*
|
|
249
|
+
* Three rules, each of which was measured against the engine rather than
|
|
250
|
+
* assumed, because getting any of them wrong fails in a confusing way:
|
|
251
|
+
*
|
|
252
|
+
* 1. **Order matters.** The bind must come AFTER the creating child.
|
|
253
|
+
* Placed before, the batch is refused BY NAME (an honest error, not a
|
|
254
|
+
* silent no-op).
|
|
255
|
+
* 2. **It is its own op, not a field.** Passing a handle inside a
|
|
256
|
+
* creating op's own `args` is SILENTLY IGNORED — which is what made
|
|
257
|
+
* an early probe read as "the engine doesn't support this".
|
|
258
|
+
* 3. **Scope is the declaring batch**, visible to its own later children
|
|
259
|
+
* including nested batches, never outward. A `$h:` appearing in TEXT
|
|
260
|
+
* content is content and is never rewritten.
|
|
261
|
+
*
|
|
262
|
+
* Generalises the v34 `$created` sentinel — which only two mutation
|
|
263
|
+
* kinds understood — to any number of live names addressable from any
|
|
264
|
+
* mutation kind. */
|
|
265
|
+
export type BindCreatedMutation = {
|
|
266
|
+
op: "bindCreated";
|
|
267
|
+
args: {
|
|
268
|
+
handle: string;
|
|
269
|
+
};
|
|
270
|
+
};
|
|
271
|
+
export type PendingMutation = BindCreatedMutation | ClosePathMutation | JoinPathsMutation | PasteIntoMutation | ReleaseFromMutation | PathfinderDivideMutation | PathfinderTrimMutation | PathfinderMergeMutation | PathfinderCropMutation | PathfinderOutlineMutation | PathfinderMinusBackMutation | PathfinderFacesMutation | ApplyOpacityMaskMutation | ReleaseOpacityMaskMutation | AttachTextToPathMutation | DetachTextFromPathMutation | ReorderElementMutation;
|
|
272
|
+
/** What `host.document.mutate` ACCEPTS: the vendored op union plus the
|
|
273
|
+
* protocol-ahead ops. Widening an accepted-input type is additive —
|
|
274
|
+
* every existing `Mutation` call site still compiles. */
|
|
275
|
+
export type MutationInput = Mutation | PendingMutation;
|