@paged-media/plugin-sdk 0.2.17-canary.0 → 0.2.19-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 +83 -2
- package/dist/index.js +196 -1
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -98,6 +98,17 @@ declare const BLOB_BUDGETS: {
|
|
|
98
98
|
/** Default per-plugin blob ceiling, in bytes (64 MiB). */
|
|
99
99
|
readonly defaultQuotaBytes: number;
|
|
100
100
|
};
|
|
101
|
+
/** Worker spawn + SAB budgets (K-3 / S-07). The host enforces the
|
|
102
|
+
* stricter of these and any manifest tightening. */
|
|
103
|
+
declare const WORKER_BUDGETS: {
|
|
104
|
+
/** Hard worker-count cap per bundle. The grant is `min(declared.max,
|
|
105
|
+
* hardwareConcurrency, maxWorkers)` — a runaway `max` can't exhaust
|
|
106
|
+
* the machine. */
|
|
107
|
+
readonly maxWorkers: 8;
|
|
108
|
+
/** Default per-bundle shared-memory ceiling, in bytes (256 MiB). A
|
|
109
|
+
* manifest's `maxSharedBytes` may only TIGHTEN this. */
|
|
110
|
+
readonly defaultSharedBytes: number;
|
|
111
|
+
};
|
|
101
112
|
/**
|
|
102
113
|
* The backend the editor injects to back `host.blob` (K-4 / S-08): a
|
|
103
114
|
* RAW per-plugin byte store (OPFS in-browser; an in-memory map in the
|
|
@@ -113,6 +124,60 @@ interface BlobStore {
|
|
|
113
124
|
/** Total bytes this plugin currently stores. */
|
|
114
125
|
used(pluginId: string): Promise<number>;
|
|
115
126
|
}
|
|
127
|
+
/**
|
|
128
|
+
* A raw spawned worker the `WorkerBackend` hands back (K-3 / S-07). The
|
|
129
|
+
* SDK adapter owns the capability gate, the count cap, the SAB budget,
|
|
130
|
+
* and teardown tracking; this backend only constructs the realm + does
|
|
131
|
+
* the raw message IO. `post` forwards to the underlying worker (optional
|
|
132
|
+
* transfer); `onMessage` subscribes (the backend fans out); `terminate`
|
|
133
|
+
* destroys the realm.
|
|
134
|
+
*/
|
|
135
|
+
interface SpawnedWorker {
|
|
136
|
+
post(message: unknown, transfer?: Transferable[]): void;
|
|
137
|
+
onMessage(handler: (message: unknown) => void): Disposable;
|
|
138
|
+
terminate(): void;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* The backend the editor injects to back `host.workers` (K-3 / S-07 /
|
|
142
|
+
* I-02): it resolves a bundle's DECLARED, bundle-relative `module` path
|
|
143
|
+
* through the bundle's own asset base (the `/@fs/`-allowed sibling-plugin
|
|
144
|
+
* path the wasm artifacts use) and constructs an ES-module `Worker`. The
|
|
145
|
+
* SDK adapter passes the plugin id + the declared module path; the
|
|
146
|
+
* backend never invents a URL. Returns a `SpawnedWorker` (or rejects when
|
|
147
|
+
* the module fails to resolve/construct). The SAB itself is allocated by
|
|
148
|
+
* the SDK adapter (a plain `new SharedArrayBuffer` under the host budget)
|
|
149
|
+
* — the backend's job is purely the worker realm. A headless host injects
|
|
150
|
+
* no backend → `spawn` rejects + `supports("workers@1")` is false.
|
|
151
|
+
*/
|
|
152
|
+
interface WorkerBackend {
|
|
153
|
+
spawn(pluginId: string, module: string, name?: string): Promise<SpawnedWorker>;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* The backend the editor injects to back `host.secrets` (D-11;
|
|
157
|
+
* rfc-credential-store): a REFERENCE-ONLY, host-owned credential store. The
|
|
158
|
+
* SDK adapter owns the capability gate + the namespacing (passes the plugin
|
|
159
|
+
* id); this backend owns the storage tier (WebCrypto-wrapped IndexedDB in
|
|
160
|
+
* the editor, an in-memory map in the headless harness) AND the user PROMPT
|
|
161
|
+
* — the RFC's "via host UI only": `set` resolves only after the host has
|
|
162
|
+
* the material (the editor backing prompts the user; the plugin's supplied
|
|
163
|
+
* `secret` is the value to STORE, never persisted silently by the adapter).
|
|
164
|
+
*
|
|
165
|
+
* The trust line is the ABSENCE of a read: there is `set`/`exists`/`forget`
|
|
166
|
+
* and NO `get` — secret bytes never leave the host realm. A headless host
|
|
167
|
+
* injects no backend → `set`/`forget` reject, `exists` is false,
|
|
168
|
+
* `supports("secrets@1")` is false. The plugin id + the (caller-supplied)
|
|
169
|
+
* `ref` together namespace the stored secret (`paged:<plugin-id>:<ref>`).
|
|
170
|
+
*/
|
|
171
|
+
interface SecretStoreBackend {
|
|
172
|
+
/** Store `secret` for `pluginId` under `ref` (the editor backing PROMPTS
|
|
173
|
+
* the user — "via host UI only"). Rejects when the user declines or the
|
|
174
|
+
* store is unavailable. */
|
|
175
|
+
set(pluginId: string, ref: string, secret: string): Promise<void>;
|
|
176
|
+
/** Whether a secret is stored for `pluginId`/`ref`. */
|
|
177
|
+
exists(pluginId: string, ref: string): Promise<boolean>;
|
|
178
|
+
/** Forget the secret for `pluginId`/`ref` (idempotent). */
|
|
179
|
+
forget(pluginId: string, ref: string): Promise<void>;
|
|
180
|
+
}
|
|
116
181
|
/**
|
|
117
182
|
* The backend the editor injects to back `host.clipboard` (K-6 / S-14): a
|
|
118
183
|
* thin read/write pair over the REAL system clipboard (`navigator.clipboard`
|
|
@@ -240,6 +305,22 @@ interface CreateBundleHostOptions {
|
|
|
240
305
|
* When absent, `read` answers `null` and `write` is a no-op (the honest
|
|
241
306
|
* no-clipboard door). */
|
|
242
307
|
clipboard?: ClipboardBackend;
|
|
308
|
+
/** Host-provided WORKER backend (K-3 / S-07 / I-02). When present,
|
|
309
|
+
* `host.workers.spawn` resolves a declared bundle-relative module +
|
|
310
|
+
* constructs a host-owned `Worker` through it (capability-gated,
|
|
311
|
+
* count-capped, SAB-budgeted, teardown-tracked) and
|
|
312
|
+
* `supports("workers@1")` answers true. When absent, `spawn` rejects
|
|
313
|
+
* honestly, `concurrency()` is 0, and the feature flag is false (the
|
|
314
|
+
* honest no-worker door). */
|
|
315
|
+
workers?: WorkerBackend;
|
|
316
|
+
/** Host-provided CREDENTIAL-STORE backend (D-11; rfc-credential-store).
|
|
317
|
+
* When present, `host.secrets.set/exists/forget` go through it
|
|
318
|
+
* (capability-gated on `capabilities.secrets`; `set` prompts the user —
|
|
319
|
+
* "via host UI only") and `supports("secrets@1")` answers true. When
|
|
320
|
+
* absent, `set`/`forget` reject and `exists` is false (the honest
|
|
321
|
+
* no-store door). REFERENCE-ONLY: there is no `get` anywhere — secret
|
|
322
|
+
* bytes never enter the plugin realm. */
|
|
323
|
+
secrets?: SecretStoreBackend;
|
|
243
324
|
/**
|
|
244
325
|
* How the host treats a declaration↔use mismatch — a bundle that
|
|
245
326
|
* USES a door (`contribute.tool`, `document.mutate`, …) it did not
|
|
@@ -334,7 +415,7 @@ interface RecordedContribution {
|
|
|
334
415
|
id: string;
|
|
335
416
|
value: ToolContribution | PanelContribution | SchemaPanelContribution | CommandContribution | KeybindingContribution | OverlayContribution | EditContextContribution | ObjectTypeContribution | ImporterContribution | ExporterContribution;
|
|
336
417
|
}
|
|
337
|
-
interface HarnessOptions extends LoadHeadlessEngineOptions, Pick<CreateBundleHostOptions, "console" | "storage" | "capabilityMode" | "assetSource" | "blobStore" | "clipboard"> {
|
|
418
|
+
interface HarnessOptions extends LoadHeadlessEngineOptions, Pick<CreateBundleHostOptions, "console" | "storage" | "capabilityMode" | "assetSource" | "blobStore" | "clipboard" | "secrets"> {
|
|
338
419
|
}
|
|
339
420
|
/** What `createHeadlessHost` resolves to: a real engine-backed host plus
|
|
340
421
|
* the conformance affordances (load an IDML, read the contribution log,
|
|
@@ -603,4 +684,4 @@ declare function contributeEditContext(host: BundleHost, contribution: EditConte
|
|
|
603
684
|
* descent. Capability-gated on `contributes.objectTypes`. */
|
|
604
685
|
declare function contributeObjectType(host: BundleHost, contribution: ObjectTypeContribution): Disposable;
|
|
605
686
|
|
|
606
|
-
export { API_VERSION, ASSET_BUDGETS, BLOB_BUDGETS, 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 PageDrag, PluginApiNotImplemented, PluginCapabilityError, type RecordableAssetSource, type RecordedContribution, type RecordedFontFaceRequest, type SeededFace, type StorageBacking, WASM_BUDGETS, beginPageDrag, commitAndSelect, contributeEditContext, contributeObjectType, contributePanel, contributeSchemaPanel, contributeTool, createBundleHost, createDataProviderRegistry, createHeadlessHost, createRecordableAssetSource, defineBundle, endLocalFor, loadBundle, loadBundleWasm, loadHeadlessEngine, makeSchemaPanelComponent, protocolFromVersion, pxToPt, readVendoredWireVersion, resolveCanvasWasm, resolveGate, satisfiesApiVersion, toDisposable };
|
|
687
|
+
export { API_VERSION, ASSET_BUDGETS, BLOB_BUDGETS, 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 PageDrag, PluginApiNotImplemented, PluginCapabilityError, type RecordableAssetSource, type RecordedContribution, type RecordedFontFaceRequest, type SecretStoreBackend, type SeededFace, type SpawnedWorker, type StorageBacking, WASM_BUDGETS, WORKER_BUDGETS, type WorkerBackend, beginPageDrag, commitAndSelect, contributeEditContext, contributeObjectType, contributePanel, contributeSchemaPanel, contributeTool, createBundleHost, createDataProviderRegistry, createHeadlessHost, createRecordableAssetSource, defineBundle, endLocalFor, loadBundle, loadBundleWasm, loadHeadlessEngine, makeSchemaPanelComponent, protocolFromVersion, pxToPt, readVendoredWireVersion, resolveCanvasWasm, resolveGate, satisfiesApiVersion, toDisposable };
|
package/dist/index.js
CHANGED
|
@@ -201,6 +201,15 @@ var BLOB_BUDGETS = {
|
|
|
201
201
|
/** Default per-plugin blob ceiling, in bytes (64 MiB). */
|
|
202
202
|
defaultQuotaBytes: 64 * 1024 * 1024
|
|
203
203
|
};
|
|
204
|
+
var WORKER_BUDGETS = {
|
|
205
|
+
/** Hard worker-count cap per bundle. The grant is `min(declared.max,
|
|
206
|
+
* hardwareConcurrency, maxWorkers)` — a runaway `max` can't exhaust
|
|
207
|
+
* the machine. */
|
|
208
|
+
maxWorkers: 8,
|
|
209
|
+
/** Default per-bundle shared-memory ceiling, in bytes (256 MiB). A
|
|
210
|
+
* manifest's `maxSharedBytes` may only TIGHTEN this. */
|
|
211
|
+
defaultSharedBytes: 256 * 1024 * 1024
|
|
212
|
+
};
|
|
204
213
|
function createDataProviderRegistry() {
|
|
205
214
|
const providers = /* @__PURE__ */ new Map();
|
|
206
215
|
const listeners = /* @__PURE__ */ new Map();
|
|
@@ -273,6 +282,8 @@ function createBundleHost(getEditor, manifest, options) {
|
|
|
273
282
|
const hasAsset = (k) => caps?.assets?.includes(k) ?? false;
|
|
274
283
|
const hasBlobStore = () => caps?.storage?.blob === true;
|
|
275
284
|
const clipboardGrant = () => caps?.clipboard === "full" ? "full" : caps?.clipboard === "vector" ? "vector" : "none";
|
|
285
|
+
const hasWorkers = () => typeof caps?.workers?.max === "number";
|
|
286
|
+
const hasSecrets = () => caps?.secrets?.sources === true;
|
|
276
287
|
const lists = (arr, id) => arr?.includes(id) ?? false;
|
|
277
288
|
const declaresType = (arr, type) => arr?.some((e) => e.type === type) ?? false;
|
|
278
289
|
const requireDeclared = (ok, door, missing) => {
|
|
@@ -1158,6 +1169,159 @@ function createBundleHost(getEditor, manifest, options) {
|
|
|
1158
1169
|
}
|
|
1159
1170
|
}
|
|
1160
1171
|
};
|
|
1172
|
+
const workerBackend = options?.workers;
|
|
1173
|
+
const declaredWorkers = caps?.workers;
|
|
1174
|
+
const hardwareConcurrency = globalThis.navigator?.hardwareConcurrency ?? 1;
|
|
1175
|
+
const workerCap = hasWorkers() && workerBackend ? Math.max(
|
|
1176
|
+
0,
|
|
1177
|
+
Math.min(
|
|
1178
|
+
declaredWorkers?.max ?? 0,
|
|
1179
|
+
hardwareConcurrency,
|
|
1180
|
+
WORKER_BUDGETS.maxWorkers
|
|
1181
|
+
)
|
|
1182
|
+
) : 0;
|
|
1183
|
+
const sharedByteBudget = Math.min(
|
|
1184
|
+
WORKER_BUDGETS.defaultSharedBytes,
|
|
1185
|
+
declaredWorkers?.maxSharedBytes ?? WORKER_BUDGETS.defaultSharedBytes
|
|
1186
|
+
);
|
|
1187
|
+
const sharedMemoryDeclared = declaredWorkers?.sharedMemory === true;
|
|
1188
|
+
const crossOriginIsolated = globalThis.crossOriginIsolated === true;
|
|
1189
|
+
let liveWorkerCount = 0;
|
|
1190
|
+
let sharedBytesUsed = 0;
|
|
1191
|
+
const makeBundleWorker = (raw) => {
|
|
1192
|
+
let terminated = false;
|
|
1193
|
+
let mySharedBytes = 0;
|
|
1194
|
+
const subs = new DisposableStore();
|
|
1195
|
+
const worker = {
|
|
1196
|
+
post(message, transfer) {
|
|
1197
|
+
if (terminated) return;
|
|
1198
|
+
raw.post(message, transfer);
|
|
1199
|
+
},
|
|
1200
|
+
onMessage(handler) {
|
|
1201
|
+
if (terminated) return toDisposable(() => {
|
|
1202
|
+
});
|
|
1203
|
+
return subs.add(raw.onMessage(handler));
|
|
1204
|
+
},
|
|
1205
|
+
allocateShared(bytes) {
|
|
1206
|
+
if (terminated) return null;
|
|
1207
|
+
if (!sharedMemoryDeclared) {
|
|
1208
|
+
log.warn(
|
|
1209
|
+
"workers.allocateShared: capabilities.workers.sharedMemory is not declared \u2014 no SharedArrayBuffer (declare it to allocate)"
|
|
1210
|
+
);
|
|
1211
|
+
return null;
|
|
1212
|
+
}
|
|
1213
|
+
if (!crossOriginIsolated) {
|
|
1214
|
+
log.warn(
|
|
1215
|
+
"workers.allocateShared: the environment is not cross-origin isolated \u2014 SharedArrayBuffer is unavailable (the host needs COOP/COEP)"
|
|
1216
|
+
);
|
|
1217
|
+
return null;
|
|
1218
|
+
}
|
|
1219
|
+
if (!Number.isInteger(bytes) || bytes <= 0) return null;
|
|
1220
|
+
if (sharedBytesUsed + bytes > sharedByteBudget) {
|
|
1221
|
+
log.warn(
|
|
1222
|
+
`workers.allocateShared(${bytes}) would exceed the ${sharedByteBudget}-byte per-bundle shared-memory budget (used ${sharedBytesUsed}) \u2014 refused`
|
|
1223
|
+
);
|
|
1224
|
+
return null;
|
|
1225
|
+
}
|
|
1226
|
+
let sab;
|
|
1227
|
+
try {
|
|
1228
|
+
sab = new SharedArrayBuffer(bytes);
|
|
1229
|
+
} catch (err) {
|
|
1230
|
+
log.warn(`workers.allocateShared(${bytes}) failed`, err);
|
|
1231
|
+
return null;
|
|
1232
|
+
}
|
|
1233
|
+
sharedBytesUsed += bytes;
|
|
1234
|
+
mySharedBytes += bytes;
|
|
1235
|
+
return sab;
|
|
1236
|
+
},
|
|
1237
|
+
terminate() {
|
|
1238
|
+
if (terminated) return;
|
|
1239
|
+
terminated = true;
|
|
1240
|
+
subs.dispose();
|
|
1241
|
+
sharedBytesUsed -= mySharedBytes;
|
|
1242
|
+
mySharedBytes = 0;
|
|
1243
|
+
liveWorkerCount = Math.max(0, liveWorkerCount - 1);
|
|
1244
|
+
try {
|
|
1245
|
+
raw.terminate();
|
|
1246
|
+
} catch (err) {
|
|
1247
|
+
log.warn("workers.terminate: backend terminate threw", err);
|
|
1248
|
+
}
|
|
1249
|
+
}
|
|
1250
|
+
};
|
|
1251
|
+
return worker;
|
|
1252
|
+
};
|
|
1253
|
+
const workers = {
|
|
1254
|
+
async spawn(opts) {
|
|
1255
|
+
requireDeclared(
|
|
1256
|
+
hasWorkers(),
|
|
1257
|
+
"workers.spawn",
|
|
1258
|
+
"capabilities.workers must be declared"
|
|
1259
|
+
);
|
|
1260
|
+
if (!workerBackend) {
|
|
1261
|
+
throw new Error(
|
|
1262
|
+
`host.workers.spawn("${opts.module}") \u2014 no worker backend wired (supports("workers@1") is false; the editor injects one)`
|
|
1263
|
+
);
|
|
1264
|
+
}
|
|
1265
|
+
if (liveWorkerCount >= workerCap) {
|
|
1266
|
+
throw new Error(
|
|
1267
|
+
`host.workers.spawn("${opts.module}") \u2014 the ${workerCap}-worker count cap is reached (declared max ${declaredWorkers?.max}, clamped to min(declared, hardwareConcurrency ${hardwareConcurrency}, ${WORKER_BUDGETS.maxWorkers})) \u2014 terminate a worker first`
|
|
1268
|
+
);
|
|
1269
|
+
}
|
|
1270
|
+
liveWorkerCount++;
|
|
1271
|
+
let raw;
|
|
1272
|
+
try {
|
|
1273
|
+
raw = await workerBackend.spawn(manifest.id, opts.module, opts.name);
|
|
1274
|
+
} catch (err) {
|
|
1275
|
+
liveWorkerCount = Math.max(0, liveWorkerCount - 1);
|
|
1276
|
+
throw err instanceof Error ? err : new Error(
|
|
1277
|
+
`host.workers.spawn("${opts.module}") failed: ${String(err)}`
|
|
1278
|
+
);
|
|
1279
|
+
}
|
|
1280
|
+
const worker = makeBundleWorker(raw);
|
|
1281
|
+
store.add(toDisposable(() => worker.terminate()));
|
|
1282
|
+
return worker;
|
|
1283
|
+
},
|
|
1284
|
+
concurrency: () => workerCap
|
|
1285
|
+
};
|
|
1286
|
+
const secretStore = options?.secrets;
|
|
1287
|
+
const secrets = {
|
|
1288
|
+
async set(ref, secret) {
|
|
1289
|
+
requireDeclared(
|
|
1290
|
+
hasSecrets(),
|
|
1291
|
+
"secrets.set",
|
|
1292
|
+
"capabilities.secrets must declare { sources: true }"
|
|
1293
|
+
);
|
|
1294
|
+
if (!secretStore) {
|
|
1295
|
+
throw new Error(
|
|
1296
|
+
`host.secrets.set("${ref}") \u2014 no secret-store backend wired (supports("secrets@1") is false; the editor injects one)`
|
|
1297
|
+
);
|
|
1298
|
+
}
|
|
1299
|
+
await secretStore.set(manifest.id, ref, secret);
|
|
1300
|
+
},
|
|
1301
|
+
async exists(ref) {
|
|
1302
|
+
requireDeclared(
|
|
1303
|
+
hasSecrets(),
|
|
1304
|
+
"secrets.exists",
|
|
1305
|
+
"capabilities.secrets must declare { sources: true }"
|
|
1306
|
+
);
|
|
1307
|
+
if (!secretStore) return false;
|
|
1308
|
+
return secretStore.exists(manifest.id, ref);
|
|
1309
|
+
},
|
|
1310
|
+
async forget(ref) {
|
|
1311
|
+
requireDeclared(
|
|
1312
|
+
hasSecrets(),
|
|
1313
|
+
"secrets.forget",
|
|
1314
|
+
"capabilities.secrets must declare { sources: true }"
|
|
1315
|
+
);
|
|
1316
|
+
if (!secretStore) {
|
|
1317
|
+
log.warn(
|
|
1318
|
+
`host.secrets.forget("${ref}") \u2014 no secret-store backend wired (supports("secrets@1") is false); nothing to forget`
|
|
1319
|
+
);
|
|
1320
|
+
return;
|
|
1321
|
+
}
|
|
1322
|
+
await secretStore.forget(manifest.id, ref);
|
|
1323
|
+
}
|
|
1324
|
+
};
|
|
1161
1325
|
const featureSet = new Set(HOST_FEATURES);
|
|
1162
1326
|
if (getEditor().text) {
|
|
1163
1327
|
featureSet.add("text.measure@1");
|
|
@@ -1196,6 +1360,12 @@ function createBundleHost(getEditor, manifest, options) {
|
|
|
1196
1360
|
if (options?.clipboard) {
|
|
1197
1361
|
featureSet.add("clipboard@1");
|
|
1198
1362
|
}
|
|
1363
|
+
if (options?.workers) {
|
|
1364
|
+
featureSet.add("workers@1");
|
|
1365
|
+
}
|
|
1366
|
+
if (options?.secrets) {
|
|
1367
|
+
featureSet.add("secrets@1");
|
|
1368
|
+
}
|
|
1199
1369
|
const host = {
|
|
1200
1370
|
manifest,
|
|
1201
1371
|
log,
|
|
@@ -1215,6 +1385,8 @@ function createBundleHost(getEditor, manifest, options) {
|
|
|
1215
1385
|
widgets,
|
|
1216
1386
|
assets,
|
|
1217
1387
|
images,
|
|
1388
|
+
workers,
|
|
1389
|
+
secrets,
|
|
1218
1390
|
clipboard,
|
|
1219
1391
|
supports: (feature) => featureSet.has(feature),
|
|
1220
1392
|
get editor() {
|
|
@@ -1408,6 +1580,25 @@ function inMemoryClipboard() {
|
|
|
1408
1580
|
}
|
|
1409
1581
|
};
|
|
1410
1582
|
}
|
|
1583
|
+
function inMemorySecretStore() {
|
|
1584
|
+
const byPlugin = /* @__PURE__ */ new Map();
|
|
1585
|
+
const dir = (id) => {
|
|
1586
|
+
let d = byPlugin.get(id);
|
|
1587
|
+
if (!d) byPlugin.set(id, d = /* @__PURE__ */ new Set());
|
|
1588
|
+
return d;
|
|
1589
|
+
};
|
|
1590
|
+
return {
|
|
1591
|
+
async set(id, ref, _secret) {
|
|
1592
|
+
dir(id).add(ref);
|
|
1593
|
+
},
|
|
1594
|
+
async exists(id, ref) {
|
|
1595
|
+
return dir(id).has(ref);
|
|
1596
|
+
},
|
|
1597
|
+
async forget(id, ref) {
|
|
1598
|
+
dir(id).delete(ref);
|
|
1599
|
+
}
|
|
1600
|
+
};
|
|
1601
|
+
}
|
|
1411
1602
|
var seqCounter = 1;
|
|
1412
1603
|
function makeEngineEditor(worker, recorder, onToolPreview) {
|
|
1413
1604
|
const protocol = worker.protocolVersion;
|
|
@@ -1571,11 +1762,13 @@ async function createHeadlessHost(options = {}) {
|
|
|
1571
1762
|
let disposed = false;
|
|
1572
1763
|
const blobStore = options.blobStore ?? inMemoryBlobStore();
|
|
1573
1764
|
const clipboard = options.clipboard ?? inMemoryClipboard();
|
|
1765
|
+
const secrets = options.secrets ?? inMemorySecretStore();
|
|
1574
1766
|
const buildHost = (manifest, mode) => createBundleHost(() => editor, manifest, {
|
|
1575
1767
|
console: options.console,
|
|
1576
1768
|
storage: options.storage,
|
|
1577
1769
|
blobStore,
|
|
1578
1770
|
clipboard,
|
|
1771
|
+
secrets,
|
|
1579
1772
|
capabilityMode: mode,
|
|
1580
1773
|
// W-06 — a recordable fake asset source the conformance harness
|
|
1581
1774
|
// can pass so a bundle's `@font-face` byte path is exercisable
|
|
@@ -1642,7 +1835,8 @@ async function createHeadlessHost(options = {}) {
|
|
|
1642
1835
|
document: { read: "broad", write: "broad" },
|
|
1643
1836
|
rendering: ["overlay", "hitTest", "sceneLayer"],
|
|
1644
1837
|
keybindings: true,
|
|
1645
|
-
storage: { blob: true }
|
|
1838
|
+
storage: { blob: true },
|
|
1839
|
+
secrets: { sources: true }
|
|
1646
1840
|
},
|
|
1647
1841
|
// Broad contribution declarations so the neutral DRIVER host (which
|
|
1648
1842
|
// registers arbitrary contributions directly in 'warn' mode) never
|
|
@@ -2000,6 +2194,7 @@ export {
|
|
|
2000
2194
|
PluginApiNotImplemented,
|
|
2001
2195
|
PluginCapabilityError,
|
|
2002
2196
|
WASM_BUDGETS,
|
|
2197
|
+
WORKER_BUDGETS,
|
|
2003
2198
|
beginPageDrag,
|
|
2004
2199
|
commitAndSelect,
|
|
2005
2200
|
contributeEditContext,
|
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.19-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.19-canary.0"
|
|
15
15
|
},
|
|
16
16
|
"peerDependencies": {
|
|
17
17
|
"react": "^18.3.0"
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
}
|
|
23
23
|
},
|
|
24
24
|
"devDependencies": {
|
|
25
|
-
"@paged-media/canvas-wasm": "0.44.
|
|
25
|
+
"@paged-media/canvas-wasm": "0.44.1",
|
|
26
26
|
"@types/node": "20.19.39",
|
|
27
27
|
"@types/react": "^18.3.12",
|
|
28
28
|
"react": "^18.3.0",
|