@paged-media/plugin-api 0.2.5-canary.0 → 0.2.8-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.
@@ -0,0 +1,49 @@
1
+ /** What `host.assets` can serve. v1: `"fonts"` only. `"images"` is
2
+ * DECLARED-but-RESERVED for v2 (placed-image / URL-import bytes) — it
3
+ * appears so the v2 direction is recorded, but `validate` REJECTS it
4
+ * in a manifest today (the door has no `getImage`, so honoring the
5
+ * declaration would be an honesty bug). */
6
+ export type AssetKind = "fonts" | "images";
7
+ /** Container/wrapper format of served font bytes — lets the consumer
8
+ * pick the right `@font-face` `format(...)` hint. */
9
+ export type FontFaceFormat = "truetype" | "opentype" | "woff" | "woff2";
10
+ /**
11
+ * One resolved DOCUMENT font face — the bytes the engine already holds
12
+ * for a face the document loads/embeds (the same faces the `fonts`
13
+ * collection NAMES). `bytes` is the raw face file; `family`/`style`
14
+ * echo what the bytes actually resolve (host-canonical, which may
15
+ * differ in casing from the requested family). Serializable
16
+ * (`Uint8Array` clones 1:1), so the door proxies across the future
17
+ * isolate boundary unchanged.
18
+ */
19
+ export interface FontFaceAsset {
20
+ /** The raw OpenType/TrueType/WOFF face bytes. */
21
+ bytes: Uint8Array;
22
+ /** Container format — the `@font-face` `format()` hint. */
23
+ format: FontFaceFormat;
24
+ /** The face's PostScript name when the host knows it. */
25
+ postscriptName?: string;
26
+ /** The family the bytes resolve (host-canonical casing). */
27
+ family: string;
28
+ /** The style the bytes resolve, when style-specific. */
29
+ style?: string;
30
+ }
31
+ /**
32
+ * The asset accessor a bundle reaches through `host.assets`. v1 has
33
+ * exactly ONE read: DOCUMENT-registered font face bytes by family
34
+ * (+ optional style). It is NOT an arbitrary filesystem/network
35
+ * reader — a bundle can only ask for a family the document already
36
+ * uses, and the host answers from what the document already has, or
37
+ * `null`. Capability-gated: `getFontFace` requires
38
+ * `capabilities.assets` ∋ `"fonts"` (the host gate throws in
39
+ * `'enforce'`, warns in `'warn'`).
40
+ */
41
+ export interface AssetSurface {
42
+ /**
43
+ * Serve the bytes of a DOCUMENT font face, or `null` when the host
44
+ * has no bytes for it (an unregistered family, a face the host can't
45
+ * reach, or an over-budget face). NEVER fetches from the network —
46
+ * `null` over a live fetch keeps "render offline forever" honest.
47
+ */
48
+ getFontFace(family: string, style?: string): Promise<FontFaceAsset | null>;
49
+ }
@@ -1 +1 @@
1
- export type { ShellRegistries, ToolRegistry, PanelRegistry, CommandRegistry, KeybindingRegistry, OverlayRegistry, ToolContribution, ToolId, ToolGroupId, ToolSectionId, ToolOptionsSpec, ToolOptionField, CursorSpec, CssCursorToken, GestureHandler, CanvasPointerEvent, OverlayContext, OverlayPrimitive, DeactivateReason, PanelContribution, PanelProps, PanelApi, OverlayContribution, OverlayProps, OverlayPageRect, CommandContribution, KeybindingContribution, DockEdge, VisibilityPredicate, PagedEditor, PagedClient, ToolPreviewShape, ToolPreviewPolyline, MarqueeRectPageLocal, } from "./editor";
1
+ export type { ShellRegistries, ToolRegistry, PanelRegistry, CommandRegistry, KeybindingRegistry, OverlayRegistry, EditContextRegistry, ObjectTypeRegistry, ImporterRegistry, ExporterRegistry, ToolContribution, ToolId, ToolGroupId, ToolSectionId, ToolOptionsSpec, ToolOptionField, CursorSpec, CssCursorToken, GestureHandler, CanvasPointerEvent, OverlayContext, OverlayPrimitive, DeactivateReason, PanelContribution, PanelProps, PanelApi, OverlayContribution, OverlayProps, OverlayPageRect, CommandContribution, KeybindingContribution, ImporterContribution, ImportRequest, ExporterContribution, ExportResult, DockEdge, VisibilityPredicate, PagedEditor, PagedClient, ToolPreviewShape, ToolPreviewPolyline, ToolPreviewPath, MarqueeRectPageLocal, } from "./editor";
package/dist/editor.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import type { ComponentType } from "react";
2
- import type { CollectionName, ContentSelection, DocumentMeta, ElementGeometryItem, ElementId, MainToWorkerKind, Mutation, PageId, PathAnchorsResult, SelectionMode, WorkerToMain } from "./wire";
2
+ import type { EditContextContribution, ObjectTypeContribution } from "./host";
3
+ import type { CollectionName, ContentSelection, DocumentMeta, ElementGeometryItem, ElementId, MainToWorkerKind, Mutation, PageId, PathAnchorsResult, SceneLayer, SelectionMode, WorkerToMain } from "./wire";
3
4
  export interface Disposable {
4
5
  dispose(): void;
5
6
  }
@@ -46,6 +47,26 @@ export interface CanvasPointerEvent {
46
47
  button: number;
47
48
  /** Underlying DOM target — handlers may read `data-*` hooks. */
48
49
  target: unknown;
50
+ /**
51
+ * Pointer-Events normalized pressure, 0..1 (B-08). Browser
52
+ * semantics are preserved verbatim: a pen reports its physical
53
+ * pressure; a mouse reports `0` with no button and `0.5` while a
54
+ * button is held; touch reports `0`/`0.5` likewise. The host reads
55
+ * `PointerEvent.pressure` straight through, so a stylus drives
56
+ * variable-width strokes (§13.12, Tier B) once the renderer can
57
+ * consume a pressure profile. Defaults to `0.5` on synthetic
58
+ * events that omit it.
59
+ */
60
+ pressure: number;
61
+ /** Pen tilt around the X axis, −90..90 deg (Pointer Events). `0`
62
+ * for mouse/touch and pens without tilt support. */
63
+ tiltX: number;
64
+ /** Pen tilt around the Y axis, −90..90 deg (Pointer Events). `0`
65
+ * for mouse/touch and pens without tilt support. */
66
+ tiltY: number;
67
+ /** Originating device class (Pointer Events `pointerType`). Lets a
68
+ * tool branch stylus-only behaviour. Defaults to `"mouse"`. */
69
+ pointerType: "mouse" | "pen" | "touch";
49
70
  }
50
71
  /** Ephemeral overlay primitive published during a gesture. Kept
51
72
  * opaque so the contract is stable across host overlay growth. */
@@ -175,6 +196,53 @@ export interface KeybindingContribution {
175
196
  command: string;
176
197
  when?: VisibilityPredicate;
177
198
  }
199
+ /** A file handed to an importer — bytes already read at the host boundary
200
+ * (the contract never leaks a DOM `File`, so a bundle stays environment-
201
+ * agnostic / isolate-ready). */
202
+ export interface ImportRequest {
203
+ /** Original file name incl. extension (e.g. `"budget.xlsx"`). */
204
+ name: string;
205
+ /** The file's raw bytes. */
206
+ bytes: Uint8Array;
207
+ /** MIME type the host reported (may be `""` when the OS gave none). */
208
+ mimeType: string;
209
+ }
210
+ export interface ImporterContribution {
211
+ /** Stable id, `<namespace>.<importer>` — namespace-checked at register. */
212
+ id: string;
213
+ /** Human label for the Open/Import UI (e.g. `"Spreadsheet"`). */
214
+ title: string;
215
+ /** Extensions this importer handles, leading dot, lowercased
216
+ * (`[".xlsx"]`). The host matches an opened file by extension first. */
217
+ extensions: readonly string[];
218
+ /** MIME types this importer also matches (optional; feeds the file
219
+ * picker's `accept` and a secondary match when the extension is
220
+ * ambiguous). */
221
+ mimeTypes?: readonly string[];
222
+ /** Handle an opened file. The importer drives the host through its own
223
+ * surfaces (load into an engine, lower into the document, …); it does
224
+ * not return a document. Async so it can boot wasm / await mutations. */
225
+ import(file: ImportRequest): void | Promise<void>;
226
+ }
227
+ /** What an exporter yields — bytes plus the suggested download name. */
228
+ export interface ExportResult {
229
+ bytes: Uint8Array;
230
+ /** Suggested file name (the host may still let the user rename). */
231
+ fileName: string;
232
+ }
233
+ export interface ExporterContribution {
234
+ /** Stable id, `<namespace>.<exporter>` — namespace-checked at register. */
235
+ id: string;
236
+ /** Human label for the Export UI (e.g. `"Workbook (.xlsx)"`). */
237
+ title: string;
238
+ /** The extension the produced file carries, leading dot (`".xlsx"`). */
239
+ extension: string;
240
+ /** MIME type to stamp on the produced blob (optional). */
241
+ mimeType?: string;
242
+ /** Produce the bytes to save, or null to abort silently (nothing to
243
+ * export). Async so it can pull from a wasm engine. */
244
+ export(): Promise<ExportResult | null> | ExportResult | null;
245
+ }
178
246
  export interface ToolRegistry {
179
247
  register(contribution: ToolContribution): Disposable;
180
248
  }
@@ -190,12 +258,46 @@ export interface KeybindingRegistry {
190
258
  export interface OverlayRegistry {
191
259
  register(contribution: OverlayContribution): Disposable;
192
260
  }
261
+ /** W3.2 — the edit-context registry (the shell owns the stack + chrome
262
+ * + write-scope; this narrow contract is just the registration door).
263
+ * The contribution type lives in ./host (the bundle-facing surface). */
264
+ export interface EditContextRegistry {
265
+ register(contribution: EditContextContribution): Disposable;
266
+ }
267
+ /** W3.2 — the object-type registry (the shell owns hit-routing; a
268
+ * matching element's double-click enters its `editContextType`). */
269
+ export interface ObjectTypeRegistry {
270
+ register(contribution: ObjectTypeContribution): Disposable;
271
+ }
272
+ /** K-2 / S-06 — the document-importer registry (the shell owns file→plugin
273
+ * routing in the open/drag-drop flow). Narrow: `register` only. */
274
+ export interface ImporterRegistry {
275
+ register(contribution: ImporterContribution): Disposable;
276
+ }
277
+ /** K-2 / S-06 — the document-exporter registry (the export UI lists the
278
+ * registered exporters and pulls bytes on demand). */
279
+ export interface ExporterRegistry {
280
+ register(contribution: ExporterContribution): Disposable;
281
+ }
193
282
  export interface ShellRegistries {
194
283
  tools: ToolRegistry;
195
284
  panels: PanelRegistry;
196
285
  commands: CommandRegistry;
197
286
  keybindings: KeybindingRegistry;
198
287
  overlays: OverlayRegistry;
288
+ /** W3.2 — edit contexts (B-02). Narrow: `register` only. Optional on
289
+ * the contract so a host that hasn't wired the registry yet stays
290
+ * assignable; the SDK adapter falls back to a recording stub. */
291
+ editContexts?: EditContextRegistry;
292
+ /** W3.2 — object types (W-03). Optional for the same reason. */
293
+ objectTypes?: ObjectTypeRegistry;
294
+ /** K-2 / S-06 — document importers (file → plugin). Optional on the
295
+ * contract so a host that hasn't wired the registry stays assignable;
296
+ * the SDK adapter falls back to a tracked no-op (the headless harness
297
+ * injects a recording registry). */
298
+ importers?: ImporterRegistry;
299
+ /** K-2 / S-06 — document exporters (plugin → file). Optional likewise. */
300
+ exporters?: ExporterRegistry;
199
301
  }
200
302
  export interface MarqueeRectPageLocal {
201
303
  pageId: PageId;
@@ -208,7 +310,35 @@ export interface ToolPreviewPolyline {
208
310
  /** Draw the closing edge (pen/polygon previews). */
209
311
  close?: boolean;
210
312
  }
211
- export type ToolPreviewShape = MarqueeRectPageLocal | ToolPreviewPolyline;
313
+ /**
314
+ * A path/cubic tool preview (B-07). Where `ToolPreviewPolyline` forces
315
+ * an in-progress pen run to FLATTEN its cubics (sampling artefacts at
316
+ * high zoom, wasted work per pointermove), this variant carries the
317
+ * true anchor/handle form so the host renders real Béziers — one SVG
318
+ * `<path>` of `C` commands, exact at any zoom.
319
+ *
320
+ * `anchors` is the engine's `PathAnchorSpec` form (on-curve `anchor` +
321
+ * incoming `left` + outgoing `right` handles, IDML `PathPointType`
322
+ * semantics — structurally `draw-tools`' `AnchorTriple` and what
323
+ * `insertPath` consumes, so the same run feeds both preview and
324
+ * commit). `close` draws the closing cubic back to anchor 0. `dashed`
325
+ * selects the dashed-vs-solid stroke from the shared preview vocabulary
326
+ * (solid by default, matching the rubber-band family).
327
+ */
328
+ export interface ToolPreviewPath {
329
+ pageId: PageId;
330
+ /** Cubic anchors in page-local pt (the `PathAnchorSpec` shape). */
331
+ anchors: ReadonlyArray<{
332
+ anchor: [number, number];
333
+ left: [number, number];
334
+ right: [number, number];
335
+ }>;
336
+ /** Close the contour (draw the cubic from the last anchor back to 0). */
337
+ close?: boolean;
338
+ /** Dashed stroke instead of the default solid (preview vocabulary). */
339
+ dashed?: boolean;
340
+ }
341
+ export type ToolPreviewShape = MarqueeRectPageLocal | ToolPreviewPolyline | ToolPreviewPath;
212
342
  export interface PagedClient {
213
343
  mutate(mutation: Mutation): Promise<WorkerToMain>;
214
344
  undo(): Promise<WorkerToMain>;
@@ -236,6 +366,26 @@ export interface PagedEditor {
236
366
  ty: number;
237
367
  };
238
368
  };
369
+ /** S-13 font measurement — the editor routes this to the canvas-wasm
370
+ * `CanvasWorker.measureText` query (async across the worker boundary).
371
+ * `undefined` when the host build wires no shaper (headless / older
372
+ * editor); the host surface then falls back to an estimate. */
373
+ text?: {
374
+ measure(family: string, style: string | null, text: string, sizePt: number): Promise<{
375
+ advance: number;
376
+ ascender: number;
377
+ descender: number;
378
+ }>;
379
+ };
380
+ /** C-1 — in-frame plugin scene layers. The editor routes these to the
381
+ * canvas-wasm `submitSceneLayer` / `clearSceneLayer` channel (async,
382
+ * across the worker boundary). `undefined` when the host build wires no
383
+ * scene channel (headless / older editor); `host.contribute.sceneLayer()`
384
+ * then warns + no-ops and `supports("rendering.sceneLayer@1")` is false. */
385
+ sceneLayers?: {
386
+ submit(elementId: string, layer: SceneLayer): Promise<void>;
387
+ clear(elementId: string): Promise<void>;
388
+ };
239
389
  overlaySignals: {
240
390
  setToolPreview(value: ToolPreviewShape | null): void;
241
391
  };