@paged-media/plugin-api 0.2.17-canary.0 → 0.2.19

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/host.d.ts CHANGED
@@ -334,6 +334,107 @@ export interface ImagesSurface {
334
334
  * to the whole-image fallback lane). */
335
335
  claimImageResource(elementId: string, opts: ImageResourceClaimOptions): Disposable;
336
336
  }
337
+ /** Options for `host.workers.spawn` (K-3). `module` is a bundle-relative
338
+ * path the host resolves through the bundle's own asset base (the same
339
+ * `/@fs/`-allowed sibling path the wasm artifacts use) — never an
340
+ * arbitrary URL. `name` is an optional debug label. */
341
+ export interface SpawnWorkerOptions {
342
+ /** Bundle-relative path to the worker module (an ES-module worker — JS
343
+ * or wasm-bindgen worker glue). Resolved through the bundle's asset
344
+ * base; a bundle can only spawn a module it ships. */
345
+ module: string;
346
+ /** Optional debug label (surfaced in the host log / devtools). */
347
+ name?: string;
348
+ }
349
+ /**
350
+ * A host-spawned, bundle-owned worker (K-3). Talk over `post`/`onMessage`
351
+ * (structured-clone, optional transfer); `allocateShared` hands back a
352
+ * host-budgeted `SharedArrayBuffer` (or `null` when SAB is unavailable or
353
+ * the bundle didn't declare `sharedMemory` / would exceed its budget).
354
+ * `terminate` stops the worker — and the host runs it automatically on
355
+ * bundle dispose, so a bundle that forgets to terminate still leaks
356
+ * nothing (the platform-honesty smoke test by construction).
357
+ */
358
+ export interface BundleWorker {
359
+ /** Post a message to the worker (structured-clone; `transfer` moves
360
+ * ownership of the listed transferables, e.g. an `ArrayBuffer`). */
361
+ post(message: unknown, transfer?: Transferable[]): void;
362
+ /** Subscribe to messages FROM the worker. Dispose to stop listening
363
+ * (and free the listener); all subscriptions drop on `terminate`. */
364
+ onMessage(handler: (message: unknown) => void): Disposable;
365
+ /**
366
+ * Allocate a `SharedArrayBuffer` of `bytes` for zero-copy hand-off,
367
+ * host-budgeted against the per-bundle shared-memory ceiling. Returns
368
+ * `null` when the bundle did not declare `capabilities.workers.
369
+ * sharedMemory`, the environment is not cross-origin-isolated (SAB is
370
+ * unconstructible), or the request would exceed the budget — the
371
+ * honest, frequent answer. Pass the returned buffer through `post` to
372
+ * share it with the worker.
373
+ */
374
+ allocateShared(bytes: number): SharedArrayBuffer | null;
375
+ /** Stop the worker + drop its listeners. Idempotent; also run by the
376
+ * host on bundle dispose. */
377
+ terminate(): void;
378
+ }
379
+ /**
380
+ * The capability-gated WORKER door (K-3 / S-07 / I-02). `spawn` resolves
381
+ * a bundle-relative `module`, constructs a host-owned `Worker`, and tracks
382
+ * it for automatic teardown. Always present — when the host injects no
383
+ * `WorkerBackend`, `spawn` REJECTS honestly (no worker realm to give) and
384
+ * `supports("workers@1")` is false. Capability-gated:
385
+ * `capabilities.workers` must be declared (the host gate throws on an
386
+ * undeclared spawn); the granted worker-count cap is
387
+ * `min(declared.max, hardwareConcurrency, 8)` (read it via `concurrency`).
388
+ */
389
+ export interface WorkersSurface {
390
+ /** Spawn `opts.module` (a declared, bundle-relative path) as a
391
+ * host-owned `BundleWorker`. Rejects when the use is undeclared
392
+ * (capability gate), the host wired no backend, the count cap is
393
+ * reached, or the module fails to resolve/construct. */
394
+ spawn(opts: SpawnWorkerOptions): Promise<BundleWorker>;
395
+ /** The granted worker-count cap (`min(declared.max, hardwareConcurrency,
396
+ * 8)`, or 0 when undeclared / no backend) — a bundle sizes its pool to
397
+ * this rather than guessing. */
398
+ concurrency(): number;
399
+ }
400
+ /** The secret a `host.secrets.set` carries (D-11). v1 is a connection
401
+ * string / token / password as a UTF-8 string — opaque to the contract;
402
+ * the host stores it under the `ref` and injects it at attach/fetch time.
403
+ * This is the ONLY place a secret value crosses the door, inbound; there
404
+ * is no outbound read (no `get`). */
405
+ export type SecretMaterial = string;
406
+ /**
407
+ * The capability-gated, REFERENCE-ONLY credential store (D-11;
408
+ * rfc-credential-store). The plugin maps a source to a `credentialRef`
409
+ * string and asks the host to `set` (prompting the user), `exists`, or
410
+ * `forget` it — but it can NEVER read the secret back. `set` resolves once
411
+ * the host has stored the material (its backing decides whether to prompt;
412
+ * the editor reference backing PROMPTS — "via host UI only"). Always
413
+ * present — when the host injects no `SecretStoreBackend`, `set`/`forget`
414
+ * reject and `exists` answers `false` (the honest no-store door), and
415
+ * `supports("secrets@1")` is false. Capability-gated:
416
+ * `capabilities.secrets` must be declared (the host gate throws on an
417
+ * undeclared use).
418
+ *
419
+ * NOTE: this surface has NO `get`. That absence IS the contract (the
420
+ * trust line — secret bytes never enter the plugin realm); a `get` here
421
+ * would defeat the entire D-11 design.
422
+ */
423
+ export interface SecretsSurface {
424
+ /** Store `secret` under `ref` (the editor backing PROMPTS the user — the
425
+ * RFC's "via host UI only"). Rejects when undeclared (capability gate),
426
+ * no backend is wired, or the user declines the prompt. The plugin
427
+ * keeps only the `ref`. */
428
+ set(ref: string, secret: SecretMaterial): Promise<void>;
429
+ /** Does the host hold a secret under `ref`? `false` when none is stored
430
+ * OR no backend is wired (the honest no-store answer). A bundle uses
431
+ * this to decide whether a source still needs its credential entered. */
432
+ exists(ref: string): Promise<boolean>;
433
+ /** Forget the secret under `ref` (the source goes inert until re-entered
434
+ * — the RFC's honest degradation). Idempotent; rejects only when the
435
+ * door is undeclared (capability gate). A no-op when no backend wired. */
436
+ forget(ref: string): Promise<void>;
437
+ }
337
438
  /** Expected mutation failures are results, not throws — mirroring the
338
439
  * editor's mutate-never-throws convention. */
339
440
  export type MutationOutcome = {
@@ -765,6 +866,23 @@ export interface BundleHost {
765
866
  * Disposable and `supports("rendering.resourceProvider@1")` is false.
766
867
  * Capability-gated on `capabilities.rendering` ∋ `"resourceProvider"`. */
767
868
  readonly images: ImagesSurface;
869
+ /** The capability-gated WORKER door (K-3 / S-07 / I-02): spawn a
870
+ * host-owned, bundle-owned worker (declared-only module, no ambient
871
+ * authority) + allocate a host-budgeted `SharedArrayBuffer`. Always
872
+ * present — when the host injects no `WorkerBackend`, `spawn` rejects
873
+ * honestly, `concurrency()` is 0, and `supports("workers@1")` is false.
874
+ * Capability-gated on `capabilities.workers`. The host facade tracks
875
+ * every spawned worker for automatic teardown on bundle dispose. */
876
+ readonly workers: WorkersSurface;
877
+ /** The capability-gated, REFERENCE-ONLY CREDENTIAL STORE (D-11;
878
+ * rfc-credential-store): `set` (host-UI-prompted) / `exists` / `forget`
879
+ * a `credentialRef` — and DELIBERATELY NO `get` (secret bytes never
880
+ * enter the plugin realm; the HOST injects them at the attach/fetch
881
+ * door). Always present — when the host injects no `SecretStoreBackend`,
882
+ * `set`/`forget` reject, `exists` is false, and `supports("secrets@1")`
883
+ * is false (the honest no-store door). Capability-gated on
884
+ * `capabilities.secrets`. */
885
+ readonly secrets: SecretsSurface;
768
886
  /** The capability-gated CLIPBOARD door (K-6 / S-14): read/write the
769
887
  * SYSTEM clipboard with a rich `{ text?, tabular? }` payload (the
770
888
  * sheets grid's range copy/paste interchange). Always present — when
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
- export type { PluginId, PluginManifest, PluginCapabilities, PluginContributions, NetworkCapability, DataProvidersCapability, StorageCapability, WasmArtifact, WasmPurpose, } from "./manifest";
1
+ export type { PluginId, PluginManifest, PluginCapabilities, PluginContributions, NetworkCapability, DataProvidersCapability, StorageCapability, WasmArtifact, WasmPurpose, WorkersCapability, SecretsCapability, } from "./manifest";
2
2
  export type { BundleHandle, PagedBundle } from "./bundle";
3
- export type { BundleHost, ContributionSurface, SceneLayerSurface, ImagesSurface, ImageResourceClaimOptions, TileBytes, DocumentSurface, SelectionSurface, ViewportSurface, TextSurface, TextMetrics, FrameChainLink, OverlaySurface, ShellSurface, FilePickerOptions, PickedFile, StorageSurface, BlobSurface, BlobUsage, 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";
3
+ export type { BundleHost, ContributionSurface, SceneLayerSurface, ImagesSurface, ImageResourceClaimOptions, TileBytes, WorkersSurface, BundleWorker, SpawnWorkerOptions, SecretsSurface, SecretMaterial, DocumentSurface, SelectionSurface, ViewportSurface, TextSurface, TextMetrics, FrameChainLink, OverlaySurface, ShellSurface, FilePickerOptions, PickedFile, StorageSurface, BlobSurface, BlobUsage, 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
4
  export type { PanelSchema, PanelSchemaSection, PanelSchemaRow, SchemaPanelContribution, SchemaPanelRenderer, SchemaPanelRendererProps, WidgetValueBinding, BindingRef, SchemaGate, } from "./panel-schema";
5
5
  export type { WidgetSurface, CodeEditorProps, CodeEditorDiagnostic, CodeEditorLanguage, } from "./widgets";
6
6
  export type { AssetSurface, AssetKind, FontFaceAsset, FontFaceFormat, } from "./assets";
@@ -112,6 +112,66 @@ export interface PluginCapabilities {
112
112
  * JS. Threads/SharedArrayBuffer are OFF in v1.
113
113
  */
114
114
  wasm?: WasmArtifact[];
115
+ /**
116
+ * Worker spawn + SharedArrayBuffer reach the bundle declares (K-3 /
117
+ * S-07 / I-02). Gates `host.workers`: a bundle CANNOT spawn a worker
118
+ * without declaring it, and only modules listed under a declared path
119
+ * (bundle-relative, like the wasm artifacts) may be spawned — never an
120
+ * arbitrary URL. `max` is the worker-count ceiling the host grants
121
+ * (clamped to `min(declared, hardwareConcurrency, 8)`); `sharedMemory`
122
+ * declares `SharedArrayBuffer` use (gates `allocateShared`; absent ⇒
123
+ * message-copy only). Declaring `workers` is the prerequisite for the
124
+ * door (the host gate throws on an undeclared spawn).
125
+ *
126
+ * The worker gets NO ambient authority — no engine/DOM/network handle,
127
+ * only the bundle's already-gated JS talks to it; the SAB is a separate
128
+ * bundle-owned allocation, host-budgeted (a per-bundle shared-memory
129
+ * ceiling the host enforces, default 256 MiB, which a manifest
130
+ * `maxSharedBytes` may only TIGHTEN). v1 stance: honesty +
131
+ * accident-prevention, not a security boundary (the isolate migration
132
+ * is the real boundary). See the K-3 design note.
133
+ */
134
+ workers?: WorkersCapability;
135
+ /**
136
+ * The host CREDENTIAL-STORE door's grant (D-11; rfc-credential-store).
137
+ * Gates `host.secrets`: a bundle that does not declare `secrets` cannot
138
+ * reach the store (the host gate throws). `sources: true` is the v1
139
+ * grant — credentials for authenticated DB-attach / remote sources.
140
+ *
141
+ * The store is REFERENCE-ONLY and host-owned: a bundle holds
142
+ * `credentialRef` strings (e.g. `keychain:source-4`), NEVER secret
143
+ * material. The surface has `set` (host-UI-prompted) / `exists` /
144
+ * `forget` and DELIBERATELY NO `get` — secret bytes never enter the
145
+ * plugin realm. The plugin passes the ref to the host attach/fetch door
146
+ * and the HOST injects the connection string / Authorization header on
147
+ * its side of the wire (pairs with the D-03 consent door). See the RFC
148
+ * and DESIGN.md §16.
149
+ */
150
+ secrets?: SecretsCapability;
151
+ }
152
+ /** Credential-store declaration (D-11; rfc-credential-store). `sources`
153
+ * gates the `host.secrets` door for authenticated DB-attach / remote
154
+ * sources — the v1 (and only) grant. A closed vocabulary so the host can
155
+ * reason about it; an absent/false `sources` denies the door. */
156
+ export interface SecretsCapability {
157
+ /** Grant the credential store for data sources (DB-attach / remote). */
158
+ sources: boolean;
159
+ }
160
+ /** Worker spawn + SAB declaration (K-3 / S-07). `max` is the requested
161
+ * worker-count ceiling (the host clamps to a hard cap); `sharedMemory`
162
+ * declares `SharedArrayBuffer` use; `maxSharedBytes`, when present,
163
+ * REQUESTS a per-bundle shared-memory ceiling — the host enforces the
164
+ * stricter of it and its hard cap. */
165
+ export interface WorkersCapability {
166
+ /** Worker-count ceiling the bundle requests; the host grants
167
+ * `min(max, hardwareConcurrency, 8)`. */
168
+ max: number;
169
+ /** Declares `SharedArrayBuffer` use — gates `BundleWorker.allocateShared`.
170
+ * Absent/false ⇒ message-copy only (`allocateShared` returns `null`). */
171
+ sharedMemory?: boolean;
172
+ /** Optional per-bundle shared-memory ceiling, in bytes. Tightens —
173
+ * never widens — the host's hard cap (default 256 MiB). */
174
+ maxSharedBytes?: number;
115
175
  }
116
176
  /** Persistent binary-storage declaration (K-4 / S-08). `blob` gates the
117
177
  * OPFS-backed `host.blob` byte store; `quotaBytes` requests a ceiling
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.44.0
4
+ // Synced from @paged-media/canvas-wasm@0.44.1
5
5
  /* tslint:disable */
6
6
  /* eslint-disable */
7
7
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@paged-media/plugin-api",
3
- "version": "0.2.17-canary.0",
3
+ "version": "0.2.19",
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",
@@ -135,6 +135,42 @@
135
135
  "full"
136
136
  ]
137
137
  },
138
+ "workers": {
139
+ "type": "object",
140
+ "description": "Worker spawn + SharedArrayBuffer (K-3 / S-07 / I-02). 'max' is the worker-count ceiling requested (host clamps to min(declared, hardwareConcurrency, 8)); 'sharedMemory' declares SAB use (gates allocateShared); 'maxSharedBytes' requests a per-bundle shared-memory ceiling (host enforces the stricter of it and its 256 MiB default cap). Gates host.workers.",
141
+ "additionalProperties": false,
142
+ "required": [
143
+ "max"
144
+ ],
145
+ "properties": {
146
+ "max": {
147
+ "type": "integer",
148
+ "minimum": 1,
149
+ "maximum": 8
150
+ },
151
+ "sharedMemory": {
152
+ "type": "boolean"
153
+ },
154
+ "maxSharedBytes": {
155
+ "type": "integer",
156
+ "minimum": 1,
157
+ "maximum": 268435456
158
+ }
159
+ }
160
+ },
161
+ "secrets": {
162
+ "type": "object",
163
+ "description": "Host credential-store door (D-11; rfc-credential-store). 'sources' grants host.secrets for authenticated DB-attach / remote sources. REFERENCE-ONLY + host-owned: plugins hold credentialRef strings, never secret material; the surface has set/exists/forget and NO get. Gates host.secrets.",
164
+ "additionalProperties": false,
165
+ "required": [
166
+ "sources"
167
+ ],
168
+ "properties": {
169
+ "sources": {
170
+ "type": "boolean"
171
+ }
172
+ }
173
+ },
138
174
  "wasm": {
139
175
  "type": "array",
140
176
  "description": "Declared WebAssembly artifacts the bundle ships and loads at runtime (capability-gated, declared-only, budgeted). See docs/wasm-packaging.md.",