@paged-media/plugin-sdk 0.2.53-canary.0 → 0.2.55-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.
Files changed (2) hide show
  1. package/dist/index.js +116 -10
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -393,6 +393,28 @@ async function planCoreDelete(a, swatchId, pageId, protocol) {
393
393
  }
394
394
  }
395
395
 
396
+ // src/document-change.ts
397
+ function documentChangeOf(msg) {
398
+ switch (msg.kind) {
399
+ case "mutationApplied": {
400
+ const reflow = msg.payload.reflow;
401
+ return {
402
+ kind: msg.kind,
403
+ pageIds: [...msg.payload.pageIds ?? []],
404
+ ...reflow ? { reflow: { frameId: reflow.frameId, contentBox: reflow.contentBox } } : {}
405
+ };
406
+ }
407
+ case "undoApplied":
408
+ case "redoApplied":
409
+ case "gestureCommitted":
410
+ return { kind: msg.kind, pageIds: [...msg.payload.pageIds ?? []] };
411
+ case "scriptResult":
412
+ return { kind: msg.kind, pageIds: [], pagesUnknown: true };
413
+ default:
414
+ return null;
415
+ }
416
+ }
417
+
396
418
  // ../plugin-api/src/catalog.json
397
419
  var pathAliases = [
398
420
  {
@@ -11663,7 +11685,7 @@ function createCoreObjectsV70(getEditor) {
11663
11685
  subscribed = true;
11664
11686
  try {
11665
11687
  unsubscribe = client().subscribe((msg) => {
11666
- if (msg.kind === "mutationApplied" || msg.kind === "undoApplied" || msg.kind === "redoApplied" || msg.kind === "documentLoaded") {
11688
+ if (documentChangeOf(msg) !== null || msg.kind === "documentLoaded") {
11667
11689
  generation++;
11668
11690
  for (const l of listeners) l();
11669
11691
  }
@@ -14165,6 +14187,12 @@ var HOST_FEATURES = [
14165
14187
  // needed — DESIGN.md §4.3d).
14166
14188
  "document.parentOf@1",
14167
14189
  "document.onDidChange@1",
14190
+ // ADR 327 — `onDidChange` reports EVERY committed change: a canvas
14191
+ // gesture's commit (`gestureCommitted`) and a script run (`scriptResult`,
14192
+ // `pagesUnknown`) as well as mutations, undos and redos. STATIC: the
14193
+ // editor's client hands every reply to its subscribers, and the headless
14194
+ // harness does the same for these.
14195
+ "document.onDidChange@2",
14168
14196
  // W-22 — the document-opened event. STATIC: it is the client's
14169
14197
  // `documentLoaded` broadcast filtered, and every host posts that on
14170
14198
  // every load (File ▸ Open, File ▸ New, a native-document open).
@@ -14188,6 +14216,11 @@ var HOST_FEATURES = [
14188
14216
  // like the channel's own `overlay.toolPreview@1`. The headless harness
14189
14217
  // records the shape verbatim.
14190
14218
  "overlay.text@1",
14219
+ // ADR 328 — the document-face door. STATIC like `assets.images@1`: the
14220
+ // engine's document registry answers it (protocol 70's `scope`), no
14221
+ // injected source is involved, and the worker handshake refuses an engine
14222
+ // older than the pin. Fill-only; a refusal comes back as an outcome.
14223
+ "assets.documentFont@1",
14191
14224
  // C-5 / I-04 (core v42): the placed-image bytes read is engine-served
14192
14225
  // through the wire (no injected source), so it is unconditionally
14193
14226
  // implemented at the pinned canvas-wasm — unlike assets.fonts@1, which
@@ -14287,6 +14320,16 @@ function sceneFaceLedger(provider) {
14287
14320
  }
14288
14321
  return ledger;
14289
14322
  }
14323
+ var documentFaceQueues = /* @__PURE__ */ new WeakMap();
14324
+ function faceContainer(bytes) {
14325
+ if (bytes.byteLength < 4) return null;
14326
+ const magic = String.fromCharCode(bytes[0], bytes[1], bytes[2], bytes[3]);
14327
+ if (magic === "\0\0\0" || magic === "true" || magic === "OTTO" || magic === "ttcf") {
14328
+ return "sfnt";
14329
+ }
14330
+ if (magic === "wOFF" || magic === "wOF2") return "woff";
14331
+ return null;
14332
+ }
14290
14333
  var BLOB_BUDGETS = {
14291
14334
  /** Default per-plugin blob ceiling, in bytes (64 MiB). */
14292
14335
  defaultQuotaBytes: 64 * 1024 * 1024
@@ -15333,7 +15376,7 @@ function createBundleHost(getEditor, manifest, options) {
15333
15376
  if (!parentIndexWired) {
15334
15377
  parentIndexWired = true;
15335
15378
  const off = getEditor().client.subscribe((msg) => {
15336
- if (msg.kind === "mutationApplied" || msg.kind === "undoApplied" || msg.kind === "redoApplied" || // A newly opened document invalidates everything; the kind
15379
+ if (documentChangeOf(msg) !== null || // A newly opened document invalidates everything; the kind
15337
15380
  // is matched defensively (not every host posts it).
15338
15381
  msg.kind === "documentLoaded") {
15339
15382
  parentIndex = null;
@@ -15425,14 +15468,8 @@ function createBundleHost(getEditor, manifest, options) {
15425
15468
  onDidChange(listener) {
15426
15469
  requireDocRead("document.onDidChange");
15427
15470
  const off = getEditor().client.subscribe((msg) => {
15428
- if (msg.kind === "mutationApplied" || msg.kind === "undoApplied" || msg.kind === "redoApplied") {
15429
- const reflow = msg.kind === "mutationApplied" ? msg.payload.reflow : void 0;
15430
- listener({
15431
- kind: msg.kind,
15432
- pageIds: msg.payload.pageIds,
15433
- ...reflow ? { reflow: { frameId: reflow.frameId, contentBox: reflow.contentBox } } : {}
15434
- });
15435
- }
15471
+ const change = documentChangeOf(msg);
15472
+ if (change) listener(change);
15436
15473
  });
15437
15474
  return store.add(toDisposable(off));
15438
15475
  },
@@ -15490,6 +15527,12 @@ function createBundleHost(getEditor, manifest, options) {
15490
15527
  const editor = getEditor();
15491
15528
  const applied = await editor.client.setElementSelection(ids, mode);
15492
15529
  editor.selection.setElementSelection(applied);
15530
+ try {
15531
+ editor.selection.setElementGeometry(
15532
+ await editor.client.elementGeometry(applied)
15533
+ );
15534
+ } catch {
15535
+ }
15493
15536
  return applied;
15494
15537
  },
15495
15538
  onDidChange(listener) {
@@ -16022,6 +16065,68 @@ function createBundleHost(getEditor, manifest, options) {
16022
16065
  })
16023
16066
  );
16024
16067
  },
16068
+ // ADR 328 — a face for the DOCUMENT where it holds none. Engine-served
16069
+ // like `getPlacedImage` (no injected provider): the document registry
16070
+ // is the engine's. Fill-only — the engine is asked first whether it
16071
+ // holds the face, and a held face is never sent again — so a bundle
16072
+ // cannot change how text that already resolves is drawn.
16073
+ async registerDocumentFont(bytes, family, style) {
16074
+ requireDeclared(
16075
+ hasAsset("fonts"),
16076
+ "assets.registerDocumentFont",
16077
+ 'capabilities.assets must include "fonts"'
16078
+ );
16079
+ const label = `assets.registerDocumentFont("${family}"${style ? `, "${style}"` : ""})`;
16080
+ const refuse3 = (reason) => {
16081
+ log.warn(`${label} refused: ${reason}`);
16082
+ return { status: "refused", reason };
16083
+ };
16084
+ const denied = denyWrite(hasDoc("write"), "assets.registerDocumentFont", "capabilities.document.write");
16085
+ if (denied !== null) return refuse3(denied);
16086
+ if (family.trim() === "") return refuse3("the family is empty");
16087
+ if (bytes.byteLength > ASSET_BUDGETS.maxFontFaceBytes) {
16088
+ return refuse3(
16089
+ `${bytes.byteLength} bytes is over the ${ASSET_BUDGETS.maxFontFaceBytes}-byte per-face cap`
16090
+ );
16091
+ }
16092
+ const container = faceContainer(bytes);
16093
+ if (container !== "sfnt") {
16094
+ return refuse3(
16095
+ container === "woff" ? "a WOFF or WOFF2 face \u2014 the canvas reads TrueType and OpenType only" : "the bytes are not a TrueType or OpenType face"
16096
+ );
16097
+ }
16098
+ const face = Array.from(bytes);
16099
+ let client;
16100
+ try {
16101
+ client = getEditor().client;
16102
+ } catch (err) {
16103
+ return refuse3(`no engine to give the face to (${String(err)})`);
16104
+ }
16105
+ const run = async () => {
16106
+ try {
16107
+ const held = await client.send({
16108
+ kind: "requestFontFaceBytes",
16109
+ payload: { family, style: style ?? null }
16110
+ });
16111
+ if (held.kind === "fontFaceBytes" && held.payload.found && (style === void 0 || held.payload.style === style)) {
16112
+ return { status: "held" };
16113
+ }
16114
+ const reply = await client.send({
16115
+ kind: "registerFont",
16116
+ payload: { family, style: style ?? null, bytes: face, scope: "document" }
16117
+ });
16118
+ if (reply.kind !== "fontRegistered") {
16119
+ return refuse3(`the engine answered ${reply.kind}`);
16120
+ }
16121
+ return { status: "registered", pageIds: [...reply.payload.pageIds ?? []] };
16122
+ } catch (err) {
16123
+ return refuse3(`the engine could not be reached (${String(err)})`);
16124
+ }
16125
+ };
16126
+ const queued = (documentFaceQueues.get(client) ?? Promise.resolve()).then(run, run);
16127
+ documentFaceQueues.set(client, queued);
16128
+ return queued;
16129
+ },
16025
16130
  // C-5 / I-04 (core v42): a placed DOCUMENT image's ORIGINAL bytes,
16026
16131
  // straight from the engine's resolver/parse cache through the
16027
16132
  // `requestPlacedAssetBytes` wire query — no injected source needed
@@ -17221,6 +17326,7 @@ function makeEngineEditor(worker, recorder, onToolPreview, onToolPreviews, overl
17221
17326
  async send(message) {
17222
17327
  const m = message;
17223
17328
  const reply = dispatch(m.kind, m.payload);
17329
+ if (documentChangeOf(reply) !== null) fanOut(reply);
17224
17330
  return reply;
17225
17331
  },
17226
17332
  subscribe(listener) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@paged-media/plugin-sdk",
3
- "version": "0.2.53-canary.0",
3
+ "version": "0.2.55-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.53-canary.0"
14
+ "@paged-media/plugin-api": "0.2.55-canary.0"
15
15
  },
16
16
  "peerDependencies": {
17
17
  "react": "^18.3.0"