@paged-media/plugin-api 0.2.6-canary.0 → 0.2.9-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/assets.d.ts +75 -0
- package/dist/contributions.d.ts +1 -1
- package/dist/editor.d.ts +152 -2
- package/dist/host.d.ts +464 -14
- package/dist/index.d.ts +5 -2
- package/dist/manifest.d.ts +137 -4
- package/dist/mutations.d.ts +1 -1
- package/dist/panel-schema.d.ts +92 -0
- package/dist/widgets.d.ts +48 -0
- package/dist/wire.d.ts +370 -27
- package/package.json +1 -1
- package/src/manifest.schema.json +104 -1
package/dist/manifest.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { AssetKind } from "./assets";
|
|
1
2
|
/** Reverse-DNS plugin identity, e.g. `media.paged.draw`. Doubles as
|
|
2
3
|
* the namespace prefix for every contribution id the bundle
|
|
3
4
|
* registers (`media.paged.draw.tool.pen`). */
|
|
@@ -15,20 +16,144 @@ export interface PluginManifest {
|
|
|
15
16
|
contributes?: PluginContributions;
|
|
16
17
|
}
|
|
17
18
|
export interface PluginCapabilities {
|
|
18
|
-
/** read-broad / write-scoped is the intended default.
|
|
19
|
+
/** read-broad / write-scoped is the intended default. Declaring
|
|
20
|
+
* `document` is the PREREQUISITE for the document surface: a bundle
|
|
21
|
+
* with no `document` capability cannot read OR write the document
|
|
22
|
+
* (the host gate throws). `read` gates the read doors
|
|
23
|
+
* (collection/meta/tree/pathAnchors/elementGeometry/getMetadata/
|
|
24
|
+
* onDidChange); `write` gates the write doors (mutate/undo/redo/
|
|
25
|
+
* setMetadata) AND `selection.set` (a document-level action). When
|
|
26
|
+
* enforcement is on, an absent sub-field denies that direction. */
|
|
19
27
|
document?: {
|
|
20
28
|
read?: "broad" | "scoped";
|
|
21
29
|
write?: "broad" | "scoped";
|
|
22
30
|
};
|
|
23
31
|
/** Render-pipeline surfaces the bundle uses. v0: `overlay` means
|
|
24
|
-
* the shared TS overlay signals (tool previews)
|
|
25
|
-
*
|
|
32
|
+
* the shared TS overlay signals (tool previews) AND
|
|
33
|
+
* `contribute.overlay`; `hitTest` gates `document.hitTest`;
|
|
34
|
+
* `sceneLayer` is reserved for the P2 channel. Declaring a surface
|
|
35
|
+
* is the prerequisite for the matching door (the host gate throws
|
|
36
|
+
* on an undeclared use). */
|
|
26
37
|
rendering?: Array<"sceneLayer" | "overlay" | "hitTest">;
|
|
38
|
+
/** The bundle registers keybindings directly via
|
|
39
|
+
* `contribute.keybinding`. Keybindings have no id to list under
|
|
40
|
+
* `contributes`, so this boolean is their declaration. v0 first-
|
|
41
|
+
* party bundles let the HOST derive activation shortcuts from the
|
|
42
|
+
* tool registry (B-15), so this stays `false`/absent for them; a
|
|
43
|
+
* bundle that wires its OWN keybindings must declare it. */
|
|
44
|
+
keybindings?: boolean;
|
|
27
45
|
/** Edit-context content types the bundle claims (P0 shell work —
|
|
28
46
|
* reserved, not yet wired). */
|
|
29
47
|
editContext?: string[];
|
|
30
|
-
|
|
48
|
+
/**
|
|
49
|
+
* Asset-store reads the bundle uses (paged.web W-06). A closed array
|
|
50
|
+
* vocabulary: v1 has exactly `"fonts"` (gates `host.assets.getFontFace`
|
|
51
|
+
* — serving DOCUMENT font face bytes for `@font-face`). `"images"` is
|
|
52
|
+
* RESERVED for v2 and REJECTED by validation today (the door has no
|
|
53
|
+
* image read yet; accepting the declaration would claim a capability
|
|
54
|
+
* the host cannot honor). Declaring `"fonts"` is the prerequisite for
|
|
55
|
+
* the door (the host gate throws on an undeclared use). See
|
|
56
|
+
* DESIGN.md §13. */
|
|
57
|
+
assets?: AssetKind[];
|
|
58
|
+
/**
|
|
59
|
+
* Persistent BINARY storage the bundle uses (K-4 / S-08). The KV
|
|
60
|
+
* `host.storage` (localStorage JSON) is always available ungated; this
|
|
61
|
+
* capability gates the OPFS-backed `host.blob` byte store for payloads
|
|
62
|
+
* too large for KV (multi-MB workbook bytes, decode spill). Declaring
|
|
63
|
+
* `blob: true` is the prerequisite for every `host.blob` door (the host
|
|
64
|
+
* gate throws on an undeclared use). `quotaBytes`, when present,
|
|
65
|
+
* REQUESTS a ceiling — the host enforces the stricter of it and its
|
|
66
|
+
* hard per-plugin cap; `host.blob.usage()` reports the granted value.
|
|
67
|
+
*/
|
|
68
|
+
storage?: StorageCapability;
|
|
69
|
+
/**
|
|
70
|
+
* Network reach the bundle declares (paged.data D-03; base-idea §11). The
|
|
71
|
+
* boolean form is the legacy shorthand (`true` = the bundle reaches the
|
|
72
|
+
* network, every origin still gated behind runtime consent; `false`/absent =
|
|
73
|
+
* no network). The object form declares a per-origin allow-list + a
|
|
74
|
+
* human-readable purpose the consent UI shows. Reach is NEVER silent: every
|
|
75
|
+
* origin is gated behind `host.network.requestConsent` (the visible
|
|
76
|
+
* data-source manifest), and a document does NOT fetch on open — external
|
|
77
|
+
* sources are inert until the user reviews + consents (base-idea §11). This
|
|
78
|
+
* is the OUTER bound; consent is the inner gate.
|
|
79
|
+
*/
|
|
80
|
+
network?: boolean | NetworkCapability;
|
|
81
|
+
/**
|
|
82
|
+
* Data-provider roles (paged.data §7.1 / D-09): the neutral cross-plugin
|
|
83
|
+
* composition where one plugin PUBLISHES a resolved dataset and another
|
|
84
|
+
* CONSUMES it (e.g. a sheet sourced from a governed query) — they rendezvous
|
|
85
|
+
* ONLY at the core `host.dataProviders` registry, never by direct contact.
|
|
86
|
+
* `publish` = the categories this bundle may register providers in; `consume`
|
|
87
|
+
* = the categories it may discover + read. A bundle declaring neither role
|
|
88
|
+
* gets no surface.
|
|
89
|
+
*/
|
|
90
|
+
dataProviders?: DataProvidersCapability;
|
|
31
91
|
clipboard?: "none" | "vector" | "full";
|
|
92
|
+
/**
|
|
93
|
+
* Declared WebAssembly artifacts the bundle ships and loads at
|
|
94
|
+
* runtime (paged.web W-07 — e.g. a future HTML/CSS layout engine
|
|
95
|
+
* compiled to wasm). Capability-gated: a bundle CANNOT instantiate a
|
|
96
|
+
* module the host has not granted via the loader, and only the paths
|
|
97
|
+
* listed here are loadable (declared-only). See DESIGN.md §10 and
|
|
98
|
+
* `docs/wasm-packaging.md` for the budget rules and trust line.
|
|
99
|
+
*
|
|
100
|
+
* The wasm gets NO ambient authority: it has no direct engine/DOM/
|
|
101
|
+
* network handle and talks only through the bundle's already-gated
|
|
102
|
+
* JS. Threads/SharedArrayBuffer are OFF in v1.
|
|
103
|
+
*/
|
|
104
|
+
wasm?: WasmArtifact[];
|
|
105
|
+
}
|
|
106
|
+
/** Persistent binary-storage declaration (K-4 / S-08). `blob` gates the
|
|
107
|
+
* OPFS-backed `host.blob` byte store; `quotaBytes` requests a ceiling
|
|
108
|
+
* (the host enforces the stricter of it and its hard per-plugin cap). */
|
|
109
|
+
export interface StorageCapability {
|
|
110
|
+
blob?: boolean;
|
|
111
|
+
quotaBytes?: number;
|
|
112
|
+
}
|
|
113
|
+
/** A structured network declaration (paged.data D-03; base-idea §11). The
|
|
114
|
+
* `origins` allow-list is the OUTER bound — the set of `scheme://host[:port]`
|
|
115
|
+
* the bundle may EVER request; runtime per-origin consent is the inner gate.
|
|
116
|
+
* The string `"consent"` means the bundle has no fixed list (author-supplied
|
|
117
|
+
* sources) — every reach requires runtime consent and none is pre-allowed. */
|
|
118
|
+
export interface NetworkCapability {
|
|
119
|
+
origins: string[] | "consent";
|
|
120
|
+
/** Human-readable reason shown in the consent UI / data-source manifest. */
|
|
121
|
+
purpose?: string;
|
|
122
|
+
}
|
|
123
|
+
/** Data-provider roles (paged.data §7.1 / D-09). Categories are a neutral, open
|
|
124
|
+
* string vocabulary (`"dataset"`, …) — discovery is BY CATEGORY, never by
|
|
125
|
+
* plugin identity. The PROVIDER and CONSUMER plugins each declare only their
|
|
126
|
+
* own role; they never name or import each other (§2.1). */
|
|
127
|
+
export interface DataProvidersCapability {
|
|
128
|
+
/** Categories this bundle MAY register providers in (the publish role). */
|
|
129
|
+
publish?: string[];
|
|
130
|
+
/** Categories this bundle MAY discover + read (the consume role). */
|
|
131
|
+
consume?: string[];
|
|
132
|
+
}
|
|
133
|
+
/** Purposes a bundle may declare for a shipped wasm module. A closed
|
|
134
|
+
* vocabulary (like `rendering`) so the host can reason about grants;
|
|
135
|
+
* unknown purposes are rejected at validation. v1:
|
|
136
|
+
* - `layout` — a foreign-document layout/measure engine (paged.web).
|
|
137
|
+
* - `codec` — encode/decode (image/font transforms).
|
|
138
|
+
* - `compute` — generic pure computation with no special host role. */
|
|
139
|
+
export type WasmPurpose = "layout" | "codec" | "compute";
|
|
140
|
+
/** One declared wasm artifact. `path` is bundle-relative (no leading
|
|
141
|
+
* slash, no `..`); `maxBytes`, when present, tightens — never widens —
|
|
142
|
+
* the host's per-artifact ceiling (see the budget table in
|
|
143
|
+
* `docs/wasm-packaging.md`). */
|
|
144
|
+
export interface WasmArtifact {
|
|
145
|
+
/** Logical name the bundle passes to the host loader
|
|
146
|
+
* (`loadBundleWasm(bundle, name)`). Unique within the manifest. */
|
|
147
|
+
name: string;
|
|
148
|
+
/** Bundle-relative path to the `.wasm` file. No leading `/`, no `..`
|
|
149
|
+
* segment (path-traversal is rejected at validation). */
|
|
150
|
+
path: string;
|
|
151
|
+
/** Why the bundle ships this module — gates what the host grants. */
|
|
152
|
+
purpose: WasmPurpose;
|
|
153
|
+
/** Optional per-artifact byte ceiling the bundle self-imposes. Must
|
|
154
|
+
* be ≤ the host's hard per-artifact ceiling; the loader enforces the
|
|
155
|
+
* stricter of the two. */
|
|
156
|
+
maxBytes?: number;
|
|
32
157
|
}
|
|
33
158
|
export interface PluginContributions {
|
|
34
159
|
/** Tool ids the bundle registers. Must be namespaced by `id`. */
|
|
@@ -57,4 +182,12 @@ export interface PluginContributions {
|
|
|
57
182
|
type: string;
|
|
58
183
|
bakedFallback: "group" | "rectangle" | "raster";
|
|
59
184
|
}>;
|
|
185
|
+
/** Importer ids the bundle registers (K-2 / S-06). Must be namespaced
|
|
186
|
+
* by `id`. The rich `ImporterContribution` (extensions, MIME, the
|
|
187
|
+
* `import()` callback) is handed in at `host.contribute.importer(...)`
|
|
188
|
+
* — the manifest only DECLARES which ids may register. */
|
|
189
|
+
importers?: string[];
|
|
190
|
+
/** Exporter ids the bundle registers (K-2 / S-06). Must be namespaced
|
|
191
|
+
* by `id`. */
|
|
192
|
+
exporters?: string[];
|
|
60
193
|
}
|
package/dist/mutations.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
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, GestureType, GestureHandle, GestureModifiers, SwatchSpec, GradientSpec, GradientStopSpec, SwatchSummary, GradientSummary, LayerSummary, } from "./wire";
|
|
1
|
+
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";
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import type { ComponentType } from "react";
|
|
2
|
+
import type { BindingsSurface } from "./host";
|
|
3
|
+
import type { PropertyPath, Value } from "./wire";
|
|
4
|
+
export type WidgetValueBinding = {
|
|
5
|
+
kind: "literal";
|
|
6
|
+
value: Value;
|
|
7
|
+
} | {
|
|
8
|
+
kind: "selectionProperty";
|
|
9
|
+
/** Which selection surface to address (defaults to `"element"`). */
|
|
10
|
+
scope?: "element" | "content";
|
|
11
|
+
/** The PropertyPath the widget reads from + commits to. */
|
|
12
|
+
path: PropertyPath;
|
|
13
|
+
/** Optional unit coercion on read + write (`pt` / `px` / `%`). */
|
|
14
|
+
coerce?: "pt" | "px" | "%";
|
|
15
|
+
};
|
|
16
|
+
export interface BindingRef {
|
|
17
|
+
/** The published binding name to look up (`host.bindings.publish`). */
|
|
18
|
+
bind: string;
|
|
19
|
+
/** Invert the looked-up boolean. The only transform — NOT a DSL. */
|
|
20
|
+
negate?: boolean;
|
|
21
|
+
}
|
|
22
|
+
/** A visibility / enablement gate: either a static literal or a
|
|
23
|
+
* lookup of a published plugin binding. Absent = always shown /
|
|
24
|
+
* enabled. A non-boolean published value is coerced with `Boolean()`
|
|
25
|
+
* (and a missing name reads as `false` — a visible seam, never a
|
|
26
|
+
* throw). */
|
|
27
|
+
export type SchemaGate = boolean | BindingRef;
|
|
28
|
+
export interface PanelSchemaRow {
|
|
29
|
+
/** Catalog widget id (a curated primitive-leaf id the host
|
|
30
|
+
* registered). An unknown id renders a visible "unknown widget"
|
|
31
|
+
* placeholder, not a throw. */
|
|
32
|
+
widget: string;
|
|
33
|
+
/** Static props forwarded to the leaf (label, options, placeholder,
|
|
34
|
+
* …). Must match the leaf's declared `PropSchema`; unknown keys are
|
|
35
|
+
* ignored by the leaf. */
|
|
36
|
+
props?: Record<string, unknown>;
|
|
37
|
+
/** The widget's primary value binding — the §11.5 ceiling
|
|
38
|
+
* (`literal | selectionProperty`). Absent = a layout-only / display
|
|
39
|
+
* leaf (label, section). */
|
|
40
|
+
value?: WidgetValueBinding;
|
|
41
|
+
/** Show the row only when this gate is truthy. Absent = always. */
|
|
42
|
+
visible?: SchemaGate;
|
|
43
|
+
/** Enable the row's control only when this gate is truthy. Absent =
|
|
44
|
+
* always enabled (subject to the widget's own no-write-path
|
|
45
|
+
* disable). */
|
|
46
|
+
enabled?: SchemaGate;
|
|
47
|
+
}
|
|
48
|
+
export interface PanelSchemaSection {
|
|
49
|
+
/** Section title (the kicker / disclosure header). Absent = an
|
|
50
|
+
* untitled flat group. */
|
|
51
|
+
title?: string;
|
|
52
|
+
/** Render as a collapsible disclosure (the catalog section's
|
|
53
|
+
* `collapsible` chrome). */
|
|
54
|
+
collapsible?: boolean;
|
|
55
|
+
rows: PanelSchemaRow[];
|
|
56
|
+
/** Hide the entire section (title + rows) on this gate. */
|
|
57
|
+
visible?: SchemaGate;
|
|
58
|
+
}
|
|
59
|
+
export interface PanelSchema {
|
|
60
|
+
/** Stable id, `<namespace>.<panel>` — namespace-checked at register
|
|
61
|
+
* exactly like a React panel. */
|
|
62
|
+
id: string;
|
|
63
|
+
title: string;
|
|
64
|
+
icon?: string;
|
|
65
|
+
defaultDock?: "left" | "right" | "top" | "bottom" | "center";
|
|
66
|
+
defaultGroup?: string;
|
|
67
|
+
sections: PanelSchemaSection[];
|
|
68
|
+
}
|
|
69
|
+
/** A panel contribution that is a declarative SCHEMA rather than an
|
|
70
|
+
* expert-leaf React component. The host renders it from the catalog
|
|
71
|
+
* and subscribes to the bundle's published bindings. Carries no
|
|
72
|
+
* React — the isolate-ready panel form. */
|
|
73
|
+
export interface SchemaPanelContribution {
|
|
74
|
+
id: string;
|
|
75
|
+
title: string;
|
|
76
|
+
icon?: string;
|
|
77
|
+
defaultDock?: "left" | "right" | "top" | "bottom" | "center";
|
|
78
|
+
defaultGroup?: string;
|
|
79
|
+
/** The declarative body (sections/rows/widgets from the catalog). */
|
|
80
|
+
schema: PanelSchema;
|
|
81
|
+
closable?: boolean;
|
|
82
|
+
movable?: boolean;
|
|
83
|
+
}
|
|
84
|
+
export interface SchemaPanelRendererProps {
|
|
85
|
+
schema: PanelSchema;
|
|
86
|
+
/** The bundle's published-bindings surface — the renderer subscribes
|
|
87
|
+
* to it so `visible`/`enabled` gates react to plugin state. */
|
|
88
|
+
bindings: BindingsSurface;
|
|
89
|
+
}
|
|
90
|
+
/** The host-injected schema-panel renderer (React). Resolves a schema
|
|
91
|
+
* through the host's catalog + the bundle's bindings. */
|
|
92
|
+
export type SchemaPanelRenderer = ComponentType<SchemaPanelRendererProps>;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { ComponentType } from "react";
|
|
2
|
+
/** Languages the host code editor highlights. `text` = no
|
|
3
|
+
* highlighting (line numbers + gutter only). Additive: a host MAY
|
|
4
|
+
* accept more, but only these are contract-guaranteed. */
|
|
5
|
+
export type CodeEditorLanguage = "html" | "css" | "text";
|
|
6
|
+
/** A per-line marker rendered in the editor's diagnostics gutter and,
|
|
7
|
+
* where the host supports it, as an inline squiggle. Structurally a
|
|
8
|
+
* subset of `Diagnostic` (host.ts) — `line` is 1-based. */
|
|
9
|
+
export interface CodeEditorDiagnostic {
|
|
10
|
+
severity: "error" | "warning" | "info";
|
|
11
|
+
message: string;
|
|
12
|
+
/** 1-based line the marker attaches to. Out-of-range = clamped. */
|
|
13
|
+
line: number;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Props the host code-editor widget accepts. Controlled: the bundle
|
|
17
|
+
* owns `value` and applies `onChange`. The widget never mutates the
|
|
18
|
+
* document — it is a pure text surface (the panel persists through
|
|
19
|
+
* `host.document`/`host.storage` as it already does for a textarea).
|
|
20
|
+
*/
|
|
21
|
+
export interface CodeEditorProps {
|
|
22
|
+
value: string;
|
|
23
|
+
onChange(next: string): void;
|
|
24
|
+
/** Syntax-highlight language; default `"text"`. */
|
|
25
|
+
language?: CodeEditorLanguage;
|
|
26
|
+
/** Per-line markers (squiggles + gutter dots). */
|
|
27
|
+
diagnostics?: readonly CodeEditorDiagnostic[];
|
|
28
|
+
/** Non-editable view (still highlighted + line-numbered). */
|
|
29
|
+
readOnly?: boolean;
|
|
30
|
+
/** Min editor height in CSS px (the widget grows with content). */
|
|
31
|
+
minHeight?: number;
|
|
32
|
+
/** Accessible label / test hook passthrough (`data-*` is host'd). */
|
|
33
|
+
ariaLabel?: string;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* The widget catalog the host injects. Members are React component
|
|
37
|
+
* TYPES (the knowingly-non-clonable exit, same class as panel
|
|
38
|
+
* components — DESIGN.md §6): they live in the host's UI package and
|
|
39
|
+
* are handed to in-process bundles. Across the future isolate boundary
|
|
40
|
+
* a widget is addressed by a serializable descriptor instead; that is
|
|
41
|
+
* a second `WidgetSurface` implementation, not a contract change.
|
|
42
|
+
*/
|
|
43
|
+
export interface WidgetSurface {
|
|
44
|
+
/** The line-numbered, syntax-highlighting, diagnostics-gutter source
|
|
45
|
+
* editor. Always present: a plain-textarea fallback stands in when
|
|
46
|
+
* the host app injects no real widget catalog. */
|
|
47
|
+
readonly CodeEditor: ComponentType<CodeEditorProps>;
|
|
48
|
+
}
|