@paged-media/plugin-sdk 0.2.32-canary.0 → 0.2.34-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/index.d.ts +30 -3
- package/dist/index.js +109 -1
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { PagedBundle, BindingProvider, Disposable, ActiveBindingProvider, BindingPropertyRequest, BindingReadResult, BindingPropertyWrite, BindingWriteResult, BindingCollectionRequest, BindingCollectionResult, MutationInput, FontFaceAsset, BundleHost, ClipboardPayload, ConsentResult, DataProviderRegistration, DataProviderHandle, DataProviderInfo, DataProviderSnapshot, ShellSurface, WidgetSurface, SchemaPanelRenderer, SchemaPanelContribution, EditContextContribution, ObjectTypeContribution, Diagnostic, TextCaret, PagedEditor, PluginManifest, ToolContribution, PanelContribution, CommandContribution, KeybindingContribution, OverlayContribution, ImporterContribution, ExporterContribution, ToolPreviewShape, BindingsSurface, PanelProps, SchemaGate, WasmArtifact, CanvasPointerEvent, Mutation, MutationOutcome, BindingProviderHandle } from '@paged-media/plugin-api';
|
|
1
|
+
import { PagedBundle, BindingProvider, Disposable, ActiveBindingProvider, BindingPropertyRequest, BindingReadResult, BindingPropertyWrite, BindingWriteResult, BindingCollectionRequest, BindingCollectionResult, MutationInput, FontFaceAsset, BundleHost, ClipboardPayload, ConsentResult, DataProviderRegistration, DataProviderHandle, DataProviderInfo, DataProviderSnapshot, JournalRecord, ShellSurface, WidgetSurface, SchemaPanelRenderer, SchemaPanelContribution, EditContextContribution, ObjectTypeContribution, Diagnostic, TextCaret, PagedEditor, PluginManifest, ToolContribution, PanelContribution, CommandContribution, KeybindingContribution, OverlayContribution, ImporterContribution, ExporterContribution, ToolPreviewShape, BindingsSurface, PanelProps, SchemaGate, WasmArtifact, CanvasPointerEvent, Mutation, MutationOutcome, BindingProviderHandle } from '@paged-media/plugin-api';
|
|
2
2
|
import { ComponentType } from 'react';
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -68,6 +68,20 @@ interface DiagnosticsSink {
|
|
|
68
68
|
publish(bundleId: string, key: string, diagnostics: Diagnostic[]): void;
|
|
69
69
|
clear(bundleId: string, key?: string): void;
|
|
70
70
|
}
|
|
71
|
+
/**
|
|
72
|
+
* ADR 025 — the host's journal buffer, injected the same way `DiagnosticsSink`
|
|
73
|
+
* is, and for the same reason: the ring lives in the app (one per session,
|
|
74
|
+
* created outside any bundle), and every loaded bundle fans INTO it with its
|
|
75
|
+
* own id stamped by the host.
|
|
76
|
+
*
|
|
77
|
+
* Structurally identical to the diagnostics fan-out on purpose: `manifest`,
|
|
78
|
+
* `storage`, `diagnostics`, `supports` and `log` are the members DESIGN.md §6
|
|
79
|
+
* already lists as "trivial proxy" across the future isolate boundary, and a
|
|
80
|
+
* plain-JSON, bundleId-keyed sink joins them without adding a new problem.
|
|
81
|
+
*/
|
|
82
|
+
interface JournalSink {
|
|
83
|
+
record(bundleId: string, entry: JournalRecord): void;
|
|
84
|
+
}
|
|
71
85
|
/** Asset-store budgets (W-06). The per-face cap mirrors the wasm lane's
|
|
72
86
|
* per-artifact ceiling (DESIGN.md §10/§13.3) — a bundle can never be
|
|
73
87
|
* handed an unbounded face buffer. The host facade refuses an
|
|
@@ -349,8 +363,17 @@ interface CreateBundleHostOptions {
|
|
|
349
363
|
* (nothing would ever consult the provider) and
|
|
350
364
|
* `supports("bindings.provider@1")` is false. */
|
|
351
365
|
bindingProviders?: BindingProviderBackend;
|
|
352
|
-
/** Console sink override
|
|
366
|
+
/** Console sink override.
|
|
367
|
+
*
|
|
368
|
+
* Originally a test hook, and now ALSO the production capture point: the
|
|
369
|
+
* editor passes a sink that censuses every `host.log` line (severity + a
|
|
370
|
+
* hash of the message) into the journal while forwarding the real text to
|
|
371
|
+
* the real console. See ADR 025 §5 — a census, not a mirror, because
|
|
372
|
+
* `host.log` is free text across ~900 call sites. */
|
|
353
373
|
console?: Pick<Console, "debug" | "info" | "warn" | "error">;
|
|
374
|
+
/** ADR 025 — where `host.journal` entries go. Absent = the surface is
|
|
375
|
+
* inert and `supports("journal@1")` is false. */
|
|
376
|
+
journal?: JournalSink;
|
|
354
377
|
/** Shell actions the HOST APP owns (the cockpit's panel placement).
|
|
355
378
|
* When absent, `host.shell` warns and no-ops, and
|
|
356
379
|
* `supports("shell.openPanel@1")` answers false. Typed as
|
|
@@ -690,6 +713,10 @@ declare function makeSchemaPanelComponent(contribution: SchemaPanelContribution,
|
|
|
690
713
|
interface LoadedBundle {
|
|
691
714
|
readonly id: string;
|
|
692
715
|
readonly active: boolean;
|
|
716
|
+
/** Set when `activate()` threw. `active` is then false and this bundle
|
|
717
|
+
* contributed nothing — the host can surface the reason rather than
|
|
718
|
+
* discovering an inert plugin by its absence. */
|
|
719
|
+
readonly activationError?: unknown;
|
|
693
720
|
dispose(): void;
|
|
694
721
|
}
|
|
695
722
|
declare function loadBundle(getEditor: () => PagedEditor, bundle: PagedBundle, options?: CreateBundleHostOptions): LoadedBundle;
|
|
@@ -855,4 +882,4 @@ declare function contributeObjectType(host: BundleHost, contribution: ObjectType
|
|
|
855
882
|
*/
|
|
856
883
|
declare function contributeBindingProvider(host: BundleHost, contextType: string, provider: BindingProvider): BindingProviderHandle;
|
|
857
884
|
|
|
858
|
-
export { API_VERSION, ASSET_BUDGETS, BLOB_BUDGETS, type BindingProviderBackend, type BlobStore, type BundleAssetProvider, type BundleAssetSource, type BundleHostHandle, type BundleTrust, CANVAS_WASM_PKG, CLICK_DRAG_THRESHOLD_PX, type ClipboardBackend, type ConsentBackend, type CreateBundleHostOptions, type DataProviderBackend, type DiagnosticsSink, DisposableStore, FALLBACK_WIDGETS, HOST_FEATURES, type HarnessOptions, type HeadlessCanvasWorker, type HeadlessHost, type HeadlessHostHandle, type LoadBundleWasmOptions, type LoadHeadlessEngineOptions, type LoadedBundle, type LoadedBundleWasm, type LoadedEngine, type NativeDocumentBackend, type PageDrag, PluginApiNotImplemented, PluginCapabilityError, type RecordableAssetSource, type RecordedContribution, type RecordedFontFaceRequest, type RegisteredBindingProvider, type SecretStoreBackend, type SeededFace, type ShellBackend, type SpawnedWorker, type StorageBacking, type TextCaretBackend, WASM_BUDGETS, WORKER_BUDGETS, type WorkerBackend, beginPageDrag, commitAndSelect, contributeBindingProvider, contributeEditContext, contributeObjectType, contributePanel, contributeSchemaPanel, contributeTool, createBindingProviderRegistry, createBundleHost, createDataProviderRegistry, createHeadlessHost, createRecordableAssetSource, defineBundle, endLocalFor, loadBundle, loadBundleWasm, loadHeadlessEngine, makeSchemaPanelComponent, protocolFromVersion, pxToPt, readVendoredWireVersion, resolveCanvasWasm, resolveGate, satisfiesApiVersion, toDisposable };
|
|
885
|
+
export { API_VERSION, ASSET_BUDGETS, BLOB_BUDGETS, type BindingProviderBackend, type BlobStore, type BundleAssetProvider, type BundleAssetSource, type BundleHostHandle, type BundleTrust, CANVAS_WASM_PKG, CLICK_DRAG_THRESHOLD_PX, type ClipboardBackend, type ConsentBackend, type CreateBundleHostOptions, type DataProviderBackend, type DiagnosticsSink, DisposableStore, FALLBACK_WIDGETS, HOST_FEATURES, type HarnessOptions, type HeadlessCanvasWorker, type HeadlessHost, type HeadlessHostHandle, type JournalSink, type LoadBundleWasmOptions, type LoadHeadlessEngineOptions, type LoadedBundle, type LoadedBundleWasm, type LoadedEngine, type NativeDocumentBackend, type PageDrag, PluginApiNotImplemented, PluginCapabilityError, type RecordableAssetSource, type RecordedContribution, type RecordedFontFaceRequest, type RegisteredBindingProvider, type SecretStoreBackend, type SeededFace, type ShellBackend, type SpawnedWorker, type StorageBacking, type TextCaretBackend, WASM_BUDGETS, WORKER_BUDGETS, type WorkerBackend, beginPageDrag, commitAndSelect, contributeBindingProvider, contributeEditContext, contributeObjectType, contributePanel, contributeSchemaPanel, contributeTool, createBindingProviderRegistry, createBundleHost, createDataProviderRegistry, createHeadlessHost, createRecordableAssetSource, defineBundle, endLocalFor, loadBundle, loadBundleWasm, loadHeadlessEngine, makeSchemaPanelComponent, protocolFromVersion, pxToPt, readVendoredWireVersion, resolveCanvasWasm, resolveGate, satisfiesApiVersion, toDisposable };
|
package/dist/index.js
CHANGED
|
@@ -478,6 +478,34 @@ function createBundleHost(getEditor, manifest, options) {
|
|
|
478
478
|
warn: (m, ...a) => sink.warn(`${tag} ${m}`, ...a),
|
|
479
479
|
error: (m, ...a) => sink.error(`${tag} ${m}`, ...a)
|
|
480
480
|
};
|
|
481
|
+
const journalSink = options?.journal;
|
|
482
|
+
const journal = {
|
|
483
|
+
record(entry) {
|
|
484
|
+
if (!journalSink) return;
|
|
485
|
+
try {
|
|
486
|
+
assertNamespaced(entry.code, "journal");
|
|
487
|
+
journalSink.record(manifest.id, entry);
|
|
488
|
+
} catch (err) {
|
|
489
|
+
log.warn(`journal.record refused: ${String(err)}`);
|
|
490
|
+
}
|
|
491
|
+
},
|
|
492
|
+
async time(code, fn) {
|
|
493
|
+
const t0 = Date.now();
|
|
494
|
+
try {
|
|
495
|
+
const out = await fn();
|
|
496
|
+
journal.record({ code, durMs: Date.now() - t0, data: { ok: true } });
|
|
497
|
+
return out;
|
|
498
|
+
} catch (err) {
|
|
499
|
+
journal.record({
|
|
500
|
+
code,
|
|
501
|
+
severity: "error",
|
|
502
|
+
durMs: Date.now() - t0,
|
|
503
|
+
data: { ok: false }
|
|
504
|
+
});
|
|
505
|
+
throw err;
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
};
|
|
481
509
|
const capabilityMode = options?.capabilityMode ?? "enforce";
|
|
482
510
|
const caps = manifest.capabilities;
|
|
483
511
|
const declared = manifest.contributes;
|
|
@@ -624,6 +652,42 @@ function createBundleHost(getEditor, manifest, options) {
|
|
|
624
652
|
);
|
|
625
653
|
return store.add(getEditor().registries.keybindings.register(c));
|
|
626
654
|
},
|
|
655
|
+
menu(c) {
|
|
656
|
+
assertNamespaced(c.command, "menu");
|
|
657
|
+
requireDeclared(
|
|
658
|
+
lists(declared?.commands, c.command),
|
|
659
|
+
"contribute.menu",
|
|
660
|
+
`contributes.commands[] must include "${c.command}" before a menu entry can invoke it`
|
|
661
|
+
);
|
|
662
|
+
const scope = c.scope ?? "document";
|
|
663
|
+
const editContext = typeof scope === "object" ? scope.editContext : null;
|
|
664
|
+
const menus = getEditor().registries.menus;
|
|
665
|
+
if (!menus) {
|
|
666
|
+
return { dispose() {
|
|
667
|
+
} };
|
|
668
|
+
}
|
|
669
|
+
return store.add(
|
|
670
|
+
menus.register({
|
|
671
|
+
path: c.path,
|
|
672
|
+
command: c.command,
|
|
673
|
+
order: c.order,
|
|
674
|
+
group: c.group,
|
|
675
|
+
// The scope becomes a `when` predicate, which is the host's
|
|
676
|
+
// existing vocabulary for "does this apply where you are
|
|
677
|
+
// standing" — the same field the Insert items and the Window
|
|
678
|
+
// menu already use. A context-scoped entry is simply one whose
|
|
679
|
+
// predicate asks what context is active.
|
|
680
|
+
when: (state2) => {
|
|
681
|
+
const st = state2;
|
|
682
|
+
if (!st?.document?.handle || (st.document.handle.pageCount ?? 0) === 0) {
|
|
683
|
+
return false;
|
|
684
|
+
}
|
|
685
|
+
if (editContext === null) return true;
|
|
686
|
+
return st.editContext?.type === editContext;
|
|
687
|
+
}
|
|
688
|
+
})
|
|
689
|
+
);
|
|
690
|
+
},
|
|
627
691
|
overlay(c) {
|
|
628
692
|
assertNamespaced(c.id, "overlay");
|
|
629
693
|
requireDeclared(
|
|
@@ -1879,6 +1943,9 @@ function createBundleHost(getEditor, manifest, options) {
|
|
|
1879
1943
|
}
|
|
1880
1944
|
};
|
|
1881
1945
|
const featureSet = new Set(HOST_FEATURES);
|
|
1946
|
+
if (options?.journal) {
|
|
1947
|
+
featureSet.add("journal@1");
|
|
1948
|
+
}
|
|
1882
1949
|
if (getEditor().text) {
|
|
1883
1950
|
featureSet.add("text.measure@1");
|
|
1884
1951
|
}
|
|
@@ -1958,6 +2025,7 @@ function createBundleHost(getEditor, manifest, options) {
|
|
|
1958
2025
|
network,
|
|
1959
2026
|
dataProviders,
|
|
1960
2027
|
diagnostics,
|
|
2028
|
+
journal,
|
|
1961
2029
|
bindings,
|
|
1962
2030
|
widgets,
|
|
1963
2031
|
assets,
|
|
@@ -2604,7 +2672,31 @@ function loadBundle(getEditor, bundle, options) {
|
|
|
2604
2672
|
manifest,
|
|
2605
2673
|
options
|
|
2606
2674
|
);
|
|
2607
|
-
|
|
2675
|
+
let handle;
|
|
2676
|
+
try {
|
|
2677
|
+
handle = bundle.activate(host);
|
|
2678
|
+
} catch (err) {
|
|
2679
|
+
options?.journal?.record(manifest.id, {
|
|
2680
|
+
code: `${manifest.id}.activate`,
|
|
2681
|
+
severity: "error",
|
|
2682
|
+
// Only the error KIND crosses: an activation throw routinely carries a
|
|
2683
|
+
// module path or a bundler message in its text.
|
|
2684
|
+
data: { ok: false, error: errorKind(err) }
|
|
2685
|
+
});
|
|
2686
|
+
options?.diagnosticsSink?.publish(manifest.id, "activation", [
|
|
2687
|
+
{
|
|
2688
|
+
severity: "error",
|
|
2689
|
+
message: `${manifest.id} failed to activate: ${String(err)}`,
|
|
2690
|
+
source: "loadBundle"
|
|
2691
|
+
}
|
|
2692
|
+
]);
|
|
2693
|
+
disposeHost();
|
|
2694
|
+
return inertBundle(manifest.id, err);
|
|
2695
|
+
}
|
|
2696
|
+
options?.journal?.record(manifest.id, {
|
|
2697
|
+
code: `${manifest.id}.activate`,
|
|
2698
|
+
data: { ok: true }
|
|
2699
|
+
});
|
|
2608
2700
|
let active = true;
|
|
2609
2701
|
return {
|
|
2610
2702
|
id: manifest.id,
|
|
@@ -2622,6 +2714,22 @@ function loadBundle(getEditor, bundle, options) {
|
|
|
2622
2714
|
}
|
|
2623
2715
|
};
|
|
2624
2716
|
}
|
|
2717
|
+
function errorKind(err) {
|
|
2718
|
+
const raw = err && typeof err === "object" && typeof err.constructor?.name === "string" ? err.constructor.name : typeof err;
|
|
2719
|
+
const lowered = raw.toLowerCase();
|
|
2720
|
+
return /^[a-z0-9][a-z0-9._:-]{0,63}$/.test(lowered) ? lowered : "unknown";
|
|
2721
|
+
}
|
|
2722
|
+
function inertBundle(id, error) {
|
|
2723
|
+
return {
|
|
2724
|
+
id,
|
|
2725
|
+
get active() {
|
|
2726
|
+
return false;
|
|
2727
|
+
},
|
|
2728
|
+
activationError: error,
|
|
2729
|
+
dispose() {
|
|
2730
|
+
}
|
|
2731
|
+
};
|
|
2732
|
+
}
|
|
2625
2733
|
|
|
2626
2734
|
// src/wasm-bundle-loader.ts
|
|
2627
2735
|
var WASM_BUDGETS = {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@paged-media/plugin-sdk",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.34-canary.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
}
|
|
12
12
|
},
|
|
13
13
|
"dependencies": {
|
|
14
|
-
"@paged-media/plugin-api": "0.2.
|
|
14
|
+
"@paged-media/plugin-api": "0.2.34-canary.0"
|
|
15
15
|
},
|
|
16
16
|
"peerDependencies": {
|
|
17
17
|
"react": "^18.3.0"
|