@arcblock/did-connect-service 4.1.57 → 4.1.59

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 (46) hide show
  1. package/assets/fonts/subset-v1/noto-sans-sc-regular.otf +0 -0
  2. package/dist/_generated/asset-bytes.js +1 -1
  3. package/dist/_generated/asset-manifest.js +2 -2
  4. package/dist/_generated/login-bundle-string.d.ts +1 -1
  5. package/dist/_generated/login-bundle-string.d.ts.map +1 -1
  6. package/dist/_generated/login-bundle-string.js +1 -1
  7. package/dist/_generated/login-bundle-string.js.map +1 -1
  8. package/dist/assets/{admin-extra.918f91ce.js → admin-extra.35313406.js} +18 -1
  9. package/dist/assets/{login.de8082af.js → login.02c19607.js} +78 -78
  10. package/dist/ga4-measurement-id.d.ts +12 -2
  11. package/dist/ga4-measurement-id.d.ts.map +1 -1
  12. package/dist/ga4-measurement-id.js +26 -6
  13. package/dist/ga4-measurement-id.js.map +1 -1
  14. package/dist/handlers/blocklet-js-handler.d.ts.map +1 -1
  15. package/dist/handlers/blocklet-js-handler.js +3 -1
  16. package/dist/handlers/blocklet-js-handler.js.map +1 -1
  17. package/dist/handlers/branding-handler.d.ts.map +1 -1
  18. package/dist/handlers/branding-handler.js +10 -1
  19. package/dist/handlers/branding-handler.js.map +1 -1
  20. package/dist/og/font-subset.d.ts +56 -0
  21. package/dist/og/font-subset.d.ts.map +1 -0
  22. package/dist/og/font-subset.js +266 -0
  23. package/dist/og/font-subset.js.map +1 -0
  24. package/dist/og/generator.d.ts +2 -0
  25. package/dist/og/generator.d.ts.map +1 -1
  26. package/dist/og/generator.js +2 -1
  27. package/dist/og/generator.js.map +1 -1
  28. package/dist/og/subset-fonts.generated.d.ts +70 -0
  29. package/dist/og/subset-fonts.generated.d.ts.map +1 -0
  30. package/dist/og/subset-fonts.generated.js +41 -0
  31. package/dist/og/subset-fonts.generated.js.map +1 -0
  32. package/dist/og/tree-node.d.ts +17 -1
  33. package/dist/og/tree-node.d.ts.map +1 -1
  34. package/dist/og/tree-node.js +144 -9
  35. package/dist/og/tree-node.js.map +1 -1
  36. package/dist/og/worker.d.ts +25 -3
  37. package/dist/og/worker.d.ts.map +1 -1
  38. package/dist/og/worker.js +123 -49
  39. package/dist/og/worker.js.map +1 -1
  40. package/dist/pages/admin/i18n.d.ts.map +1 -1
  41. package/dist/pages/admin/i18n.js +28 -0
  42. package/dist/pages/admin/i18n.js.map +1 -1
  43. package/dist/pages/admin/tab-branding.d.ts.map +1 -1
  44. package/dist/pages/admin/tab-branding.js +29 -2
  45. package/dist/pages/admin/tab-branding.js.map +1 -1
  46. package/package.json +3 -3
@@ -19,6 +19,14 @@
19
19
  * - Missing Bold renders 700 with Regular (`boldFallback: true` on the event).
20
20
  * Only a success, "not configured", or a missing DERIVED file is cached; a
21
21
  * failure of an explicitly configured URL is retried on the next render.
22
+ * - Subsets (ArcBlock/arc#8800): next to each font, `subset-v1/<same name>`
23
+ * (the bundled face ships `assets/fonts/subset-v1/noto-sans-sc-regular.otf`;
24
+ * for a URL, the sibling `…/subset-v1/NotoSansSC-Regular.otf`). When every
25
+ * character of the tree is covered and the subset file exists with the
26
+ * build's sha256, it is used instead of the full face (same pixels, a
27
+ * fraction of the parse). A Bold subset is needed only when a full Bold
28
+ * exists. Otherwise — unknown font, missing file, uncovered text — the full
29
+ * fonts, as before (`fontSubset` on the event says which).
22
30
  *
23
31
  * No wall-clock guard around satori/resvg here (`Resvg.render()` is one
24
32
  * synchronous wasm call; a timer cannot interrupt it). Render cost is bounded
@@ -29,14 +37,15 @@
29
37
  * (ArcBlock/arc#8746) if still wanted.
30
38
  */
31
39
  import { createHash } from "node:crypto";
32
- import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
40
+ import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
33
41
  import { readFile } from "node:fs/promises";
34
42
  import { createRequire } from "node:module";
35
43
  import { tmpdir } from "node:os";
36
44
  import { dirname, join } from "node:path";
37
- import { fileURLToPath } from "node:url";
45
+ import { fileURLToPath, pathToFileURL } from "node:url";
38
46
  import { consoleLogger } from "../logger.js";
39
- import { FONT_FETCH_TIMEOUT_MS, loadFont } from "./generator.js";
47
+ import { OG_SUBSET_PREFIX, ogFontSha256, ogSubsetFontSets, ogTreeCoveredBySubset, } from "./font-subset.js";
48
+ import { FONT_FETCH_TIMEOUT_MS, FONT_PATH, loadFont } from "./generator.js";
40
49
  import { resolveNodeOgConfig } from "./node-config.js";
41
50
  import { rasterizeSvgToPngWithWasm } from "./node-wasm-fallback.js";
42
51
  import { createSerialQueue, OG_RENDER_UNAVAILABLE_CODES, OG_TREE_ERROR_CODES, OgRenderUnavailableError, OgTreeRenderError, prepareOgTree, wantsBold, withTimeout, } from "./tree.js";
@@ -118,10 +127,101 @@ async function loadBold(explicitUrl, regularUrl, fontCacheDir, fetchImpl, logger
118
127
  return null;
119
128
  }
120
129
  }
121
- /** Test isolation: forget cached Bold bytes and re-arm the missing-Bold warning. */
130
+ // ---------------------------------------------------------------------------
131
+ // Subset fonts (ArcBlock/arc#8800)
132
+ // ---------------------------------------------------------------------------
133
+ const SUBSET_DIR = OG_SUBSET_PREFIX.slice(OG_SUBSET_PREFIX.lastIndexOf("/") + 1);
134
+ /** `…/NotoSansSC-Regular.otf` → `…/subset-v1/NotoSansSC-Regular.otf` (and the file name). */
135
+ export function deriveSubsetFontUrl(url) {
136
+ if (!url)
137
+ return undefined;
138
+ let parsed;
139
+ try {
140
+ parsed = new URL(url);
141
+ }
142
+ catch {
143
+ return undefined;
144
+ }
145
+ const slash = parsed.pathname.lastIndexOf("/");
146
+ const name = parsed.pathname.slice(slash + 1);
147
+ if (!name)
148
+ return undefined;
149
+ parsed.pathname = `${parsed.pathname.slice(0, slash + 1)}${SUBSET_DIR}/${name}`;
150
+ let file;
151
+ try {
152
+ file = decodeURIComponent(name);
153
+ }
154
+ catch {
155
+ return undefined;
156
+ }
157
+ return { url: parsed.href, file };
158
+ }
159
+ /** Subset file bytes by URL; `null` = missing or not the build's bytes (cached). Errors are not cached. */
160
+ const subsetFiles = new Map();
161
+ let subsetMissingWarned = false;
162
+ async function readSubsetFile(url, fontCacheDir, fetchImpl) {
163
+ if (url.startsWith("file:")) {
164
+ try {
165
+ return await readFile(fileURLToPath(url));
166
+ }
167
+ catch (err) {
168
+ if (err.code === "ENOENT")
169
+ return null;
170
+ throw err;
171
+ }
172
+ }
173
+ const diskPath = join(fontCacheDir, `${md5(url)}.font`);
174
+ if (existsSync(diskPath))
175
+ return readFile(diskPath);
176
+ const res = await fetchImpl(url, { signal: AbortSignal.timeout(FONT_FETCH_TIMEOUT_MS) });
177
+ if (res.status === 404 || res.status === 403)
178
+ return null;
179
+ if (!res.ok)
180
+ throw new Error(`subset font fetch failed: ${res.status}`);
181
+ const buf = Buffer.from(await res.arrayBuffer());
182
+ mkdirSync(dirname(diskPath), { recursive: true });
183
+ writeFileSync(diskPath, buf);
184
+ return buf;
185
+ }
186
+ function loadSubsetFile(url, sha256, fontCacheDir, fetchImpl, logger) {
187
+ let entry = subsetFiles.get(url);
188
+ if (!entry) {
189
+ const created = readSubsetFile(url, fontCacheDir, fetchImpl).then(async (bytes) => {
190
+ const reason = !bytes ? "missing" : (await ogFontSha256(bytes)) !== sha256 ? "sha256 mismatch" : undefined;
191
+ if (!reason)
192
+ return bytes;
193
+ // A stale / corrupt download must not stay on disk for the next process.
194
+ if (bytes && !url.startsWith("file:"))
195
+ rmSync(join(fontCacheDir, `${md5(url)}.font`), { force: true });
196
+ if (!subsetMissingWarned) {
197
+ subsetMissingWarned = true;
198
+ logger.warn({ message: `[og] subset font ${reason}; rendering with the full font`, mod: "og" });
199
+ }
200
+ return null;
201
+ });
202
+ created.catch(() => {
203
+ if (subsetFiles.get(url) === created)
204
+ subsetFiles.delete(url);
205
+ });
206
+ subsetFiles.set(url, created);
207
+ entry = created;
208
+ }
209
+ return entry;
210
+ }
211
+ /** The subset set built from the Regular font at `regularUrl` (the bundled face when unset). */
212
+ function subsetPlanFor(regularUrl) {
213
+ const derived = deriveSubsetFontUrl(regularUrl ?? pathToFileURL(FONT_PATH).href);
214
+ if (!derived)
215
+ return undefined;
216
+ const set = Object.values(ogSubsetFontSets()).find((candidate) => candidate.regular.file === derived.file);
217
+ return set ? { set, url: derived.url } : undefined;
218
+ }
219
+ /** Test isolation: forget cached Bold / subset bytes and re-arm the warnings. */
122
220
  export function resetOgNodeTreeFontsForTesting() {
123
221
  boldSlot = undefined;
124
222
  boldMissingWarned = false;
223
+ subsetFiles.clear();
224
+ subsetMissingWarned = false;
125
225
  }
126
226
  /**
127
227
  * Renders a caller-built satori tree to PNG bytes. Rejects with an
@@ -138,15 +238,49 @@ export async function renderOgTree(options) {
138
238
  const fontCacheDir = options.fontCacheDir ?? join(tmpdir(), "og-fonts");
139
239
  const fontTimeout = options.fontReadTimeoutMs ?? FONT_FETCH_TIMEOUT_MS;
140
240
  const regularUrl = options.fontUrl ?? config.fontUrl;
241
+ const explicitBoldUrl = options.boldFontUrl ?? config.boldFontUrl;
141
242
  const timeoutError = () => new OgRenderUnavailableError(OG_RENDER_UNAVAILABLE_CODES.fontTimeout, `font load exceeded ${fontTimeout}ms`);
142
- const { png, queueMs, fontReadMs, boldFallback } = await serialRender(async ({ queueMs }) => {
243
+ const boldWanted = wantsBold(options.weights);
244
+ const plan = subsetPlanFor(regularUrl);
245
+ const covered = plan ? ogTreeCoveredBySubset(plan.set, tree) : false;
246
+ /** Full Bold (cached), bounded by the font deadline. */
247
+ const fullBold = () => withTimeout(loadBold(explicitBoldUrl, regularUrl, fontCacheDir, fetchImpl, logger), fontTimeout, timeoutError);
248
+ /** Subset Regular (+ Bold), or null when the full fonts must be used. Errors ⇒ null for this render. */
249
+ async function subsetFonts() {
250
+ if (!plan || !covered)
251
+ return null;
252
+ try {
253
+ const load = (url, sha256) => withTimeout(loadSubsetFile(url, sha256, fontCacheDir, fetchImpl, logger), fontTimeout, timeoutError);
254
+ const regular = await load(plan.url, plan.set.regular.sha256);
255
+ if (!regular)
256
+ return null;
257
+ if (!boldWanted)
258
+ return { regular, bold: null };
259
+ const boldSubset = deriveSubsetFontUrl(explicitBoldUrl ?? deriveBoldFontUrl(regularUrl ?? pathToFileURL(FONT_PATH).href));
260
+ if (plan.set.bold && boldSubset?.file === plan.set.bold.file) {
261
+ const bold = await load(boldSubset.url, plan.set.bold.sha256);
262
+ if (bold)
263
+ return { regular, bold };
264
+ }
265
+ // No Bold subset: still a hit when there is no full Bold either (700 is
266
+ // drawn with Regular both ways); otherwise the full fonts.
267
+ return (await fullBold()) ? null : { regular, bold: null };
268
+ }
269
+ catch (err) {
270
+ logger.warn({ message: "[og] subset font load failed; rendering with the full font", mod: "og", err });
271
+ return null;
272
+ }
273
+ }
274
+ const { png, queueMs, fontReadMs, boldFallback, fontSubset } = await serialRender(async ({ queueMs }) => {
143
275
  const satori = await loadSatori();
144
276
  const fontStart = performance.now();
145
- const regular = await withTimeout(loadFont({ fontUrl: regularUrl, fontCacheDir, fetchImpl, logger, timeoutMs: fontTimeout }), fontTimeout, timeoutError);
277
+ const subset = await subsetFonts();
278
+ const fontSubset = subset ? "hit" : plan && !covered ? "miss" : "absent";
279
+ const regular = subset?.regular ??
280
+ (await withTimeout(loadFont({ fontUrl: regularUrl, fontCacheDir, fetchImpl, logger, timeoutMs: fontTimeout }), fontTimeout, timeoutError));
146
281
  let bold = null;
147
- const boldWanted = wantsBold(options.weights);
148
282
  if (boldWanted) {
149
- bold = await withTimeout(loadBold(options.boldFontUrl ?? config.boldFontUrl, regularUrl, fontCacheDir, fetchImpl, logger), fontTimeout, timeoutError);
283
+ bold = subset ? subset.bold : await fullBold();
150
284
  if (!bold && !boldMissingWarned) {
151
285
  boldMissingWarned = true;
152
286
  logger.warn({ message: "[og] bold font missing; rendering weight 700 with the regular face", mod: "og" });
@@ -176,7 +310,7 @@ export async function renderOgTree(options) {
176
310
  // satori/resvg messages can quote the input; report a generic 400.
177
311
  throw new OgTreeRenderError(OG_TREE_ERROR_CODES.renderFailed, "the tree could not be rendered");
178
312
  }
179
- return { png, queueMs, fontReadMs, boldFallback: boldWanted && !bold };
313
+ return { png, queueMs, fontReadMs, boldFallback: boldWanted && !bold, fontSubset };
180
314
  }, { maxWaitMs: options.queueMaxWaitMs ?? OG_NODE_QUEUE_MAX_WAIT_MS });
181
315
  options.observer?.({
182
316
  locale: options.locale,
@@ -184,6 +318,7 @@ export async function renderOgTree(options) {
184
318
  durationMs: performance.now() - startedAt,
185
319
  queueMs,
186
320
  fontReadMs,
321
+ fontSubset,
187
322
  template: "tree",
188
323
  ...(boldFallback ? { boldFallback: true } : {}),
189
324
  });
@@ -1 +1 @@
1
- {"version":3,"file":"tree-node.js","sourceRoot":"","sources":["../../src/og/tree-node.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tree-node.js","sourceRoot":"","sources":["../../src/og/tree-node.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,9 @@
1
1
  import { type Logger } from "../logger.js";
2
+ import { type OgFontSubsetStatus } from "./font-subset.js";
2
3
  import { type OgTreeRenderOptions } from "./tree.js";
3
4
  import type { OgGenerateOptions } from "./types.js";
5
+ export type { OgFontSubsetStatus } from "./font-subset.js";
6
+ export { OG_SUBSET_FONTS, OG_SUBSET_PREFIX } from "./font-subset.js";
4
7
  export type { OgImageInspection, OgImageKind, OgRenderUnavailableCode, OgTreeErrorCode, OgTreeImageStats, OgTreeNode, OgTreeRenderOptions, OgTreeWeight, } from "./tree.js";
5
8
  export { inspectOgImage, OG_RENDER_UNAVAILABLE_CODES, OG_TREE_ERROR_CODES, OG_TREE_FONT_FAMILY, OG_TREE_LIMITS, OgRenderUnavailableError, OgTreeRenderError, sniffOgImageKind, validateOgTree, } from "./tree.js";
6
9
  /** Default deadline for one font object read from the bucket. */
@@ -48,12 +51,21 @@ export interface OgWorkerLogoAsset {
48
51
  export interface OgWorkerRenderEvent {
49
52
  locale: OgWorkerLocale;
50
53
  cacheStatus: OgWorkerCacheStatus;
51
- /** Wall time of the whole call, INCLUDING `queueMs` and `fontReadMs`. */
54
+ /**
55
+ * `performance.now()` delta over the whole call, INCLUDING `queueMs` and
56
+ * `fontReadMs`. On Cloudflare Workers that clock only advances across I/O —
57
+ * it stands still during CPU work (satori, resvg, PNG encoding) — so there
58
+ * this is ≈ queue + font I/O, NOT the render's wall or CPU time. Use the
59
+ * platform's per-invocation `wallTimeMs` / `cpuTimeMs` for those. On Node it
60
+ * is the real wall time.
61
+ */
52
62
  durationMs: number;
53
63
  /** Time spent waiting in the isolate render queue (renders only, not cache HITs). */
54
64
  queueMs?: number;
55
- /** Time spent loading fonts (≈0 when the raw-font slot already held them; includes first wasm init on a cold isolate). */
65
+ /** Time spent loading fonts — I/O (≈0 when the raw-font slot already held them; includes first wasm init on a cold isolate). */
56
66
  fontReadMs?: number;
67
+ /** Subset fonts used (`"hit"`), not covering the text (`"miss"`), or unavailable (`"absent"`) — renders only. See {@link OgFontSubsetStatus}. */
68
+ fontSubset?: OgFontSubsetStatus;
57
69
  /** Weight 700 was requested but the Bold object is missing — drawn with Regular. */
58
70
  boldFallback?: boolean;
59
71
  /** `"tree"` for {@link OgWorkerRenderer.renderTree}; the template name for og.png renders. */
@@ -114,11 +126,17 @@ export declare function normalizeOgLocale(locale: string | undefined): OgWorkerL
114
126
  export declare function resetOgWorkerWasmForTesting(): void;
115
127
  /** Test isolation: drop the raw font slot and re-arm the Bold warning. */
116
128
  export declare function resetOgWorkerFontCacheForTesting(): void;
117
- /** Introspection for tests/benchmarks: which locale's raw fonts are resident, and how many bytes. */
129
+ /**
130
+ * Introspection for tests/benchmarks: which locale's raw fonts are resident,
131
+ * and how many bytes (`regularBytes` / `boldBytes`: full fonts; `subset*`: the
132
+ * subset objects).
133
+ */
118
134
  export declare function getOgWorkerFontCacheStats(): Promise<{
119
135
  locale?: OgWorkerLocale;
120
136
  regularBytes: number;
121
137
  boldBytes: number;
138
+ subsetRegularBytes: number;
139
+ subsetBoldBytes: number;
122
140
  }>;
123
141
  /**
124
142
  * Resolves a stored branding-logo asset to a satori/resvg-compatible data
@@ -137,6 +155,10 @@ export declare function resolveOgWorkerLogoDataUri(asset: OgWorkerLogoAsset | nu
137
155
  * render with an `OgTreeRenderError` and nothing is fetched.
138
156
  * - Fonts come from `fontBucket` by locale: Regular always, Bold when
139
157
  * `weights` includes 700 (missing Bold ⇒ Regular + one warning per isolate).
158
+ * When every character of the tree is covered by the locale's subset fonts
159
+ * (`fonts/subset-v1/…`, ArcBlock/arc#8800) those are used instead — same
160
+ * pixels, a fraction of the parse; otherwise, or when the subset object is
161
+ * missing (one warning per isolate), the full fonts.
140
162
  * - Runs inside the isolate-wide serial queue, so concurrent calls never
141
163
  * parse fonts or grow the wasm heap in parallel.
142
164
  * - No cache: callers version and cache the result themselves.
@@ -1 +1 @@
1
- {"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../../src/og/worker.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../../src/og/worker.ts"],"names":[],"mappings":"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"}
package/dist/og/worker.js CHANGED
@@ -1,10 +1,12 @@
1
1
  import stringify from "fast-json-stable-stringify";
2
2
  import satori from "satori/standalone";
3
3
  import { consoleLogger } from "../logger.js";
4
+ import { ogFontSha256, ogSubsetFontKey, ogSubsetFontSets, ogTreeCoveredBySubset, } from "./font-subset.js";
4
5
  import { initializeRendererWasm, Resvg } from "./resvg-runtime.js";
5
6
  import { prepareOgRender } from "./shared.js";
6
7
  import { getTemplate } from "./templates.js";
7
8
  import { createSerialQueue, OG_RENDER_UNAVAILABLE_CODES, OG_TREE_ERROR_CODES, OgRenderUnavailableError, OgTreeRenderError, ogImageMime, prepareOgTree, sniffOgImageKind, wantsBold, withTimeout, } from "./tree.js";
9
+ export { OG_SUBSET_FONTS, OG_SUBSET_PREFIX } from "./font-subset.js";
8
10
  export { inspectOgImage, OG_RENDER_UNAVAILABLE_CODES, OG_TREE_ERROR_CODES, OG_TREE_FONT_FAMILY, OG_TREE_LIMITS, OgRenderUnavailableError, OgTreeRenderError, sniffOgImageKind, validateOgTree, } from "./tree.js";
9
11
  /** Default deadline for one font object read from the bucket. */
10
12
  export const OG_FONT_READ_TIMEOUT_MS = 10_000;
@@ -34,6 +36,7 @@ const CACHE_ORIGIN = "https://og-cache.invalid";
34
36
  let wasmInitialization;
35
37
  let fontSlot;
36
38
  let boldMissingWarned = false;
39
+ let subsetMissingWarned = false;
37
40
  /** Every satori + resvg pass in this isolate runs through this FIFO queue. */
38
41
  const serialRender = createSerialQueue();
39
42
  export function normalizeOgLocale(locale) {
@@ -67,68 +70,130 @@ export function resetOgWorkerWasmForTesting() {
67
70
  function readFontObject(bucket, key, timeoutMs) {
68
71
  return withTimeout(bucket.get(key).then(async (object) => (object ? new Uint8Array(await object.arrayBuffer()) : null)), timeoutMs, () => new OgRenderUnavailableError(OG_RENDER_UNAVAILABLE_CODES.fontTimeout, `font read exceeded ${timeoutMs}ms`));
69
72
  }
70
- function slotFor(bucket, locale, timeoutMs) {
73
+ function slotFor(bucket, locale) {
71
74
  if (fontSlot && fontSlot.bucket === bucket && fontSlot.locale === locale)
72
75
  return fontSlot;
73
- const key = OG_WORKER_FONT_KEYS[locale];
74
- const slot = {
75
- bucket,
76
- locale,
77
- regular: readFontObject(bucket, key, timeoutMs).then((bytes) => {
78
- if (!bytes)
79
- throw new Error(`OG font unavailable: ${key}`);
80
- return bytes;
81
- }),
82
- };
83
- // A failed read must not poison the slot: the next render retries.
84
- slot.regular.catch(() => {
85
- if (fontSlot === slot)
86
- fontSlot = undefined;
87
- });
88
- fontSlot = slot;
89
- return slot;
76
+ fontSlot = { bucket, locale };
77
+ return fontSlot;
78
+ }
79
+ /** Caches `load()` in `slot[field]`; a rejection clears it so the next render retries. */
80
+ function memo(slot, field, load) {
81
+ let pending = slot[field];
82
+ if (!pending) {
83
+ const created = load();
84
+ created.catch(() => {
85
+ if (slot[field] === created)
86
+ slot[field] = undefined;
87
+ });
88
+ slot[field] = created;
89
+ pending = created;
90
+ }
91
+ return pending;
90
92
  }
91
- /** Regular bytes for `locale`, from the single-locale slot. */
93
+ /** Full Regular bytes for `locale`, from the single-locale slot. */
92
94
  function loadRegularFont(bucket, locale, timeoutMs) {
93
- return slotFor(bucket, locale, timeoutMs).regular;
95
+ const key = OG_WORKER_FONT_KEYS[locale];
96
+ return memo(slotFor(bucket, locale), "regular", () => readFontObject(bucket, key, timeoutMs).then((bytes) => {
97
+ if (!bytes)
98
+ throw new Error(`OG font unavailable: ${key}`);
99
+ return bytes;
100
+ }));
94
101
  }
95
- /** Bold bytes for `locale`, or `null` (warned once per isolate) when the object is missing. */
102
+ /** Full Bold bytes for `locale`, or `null` (warned once per isolate) when the object is missing. */
96
103
  async function loadBoldFont(bucket, locale, logger, timeoutMs) {
97
- const slot = slotFor(bucket, locale, timeoutMs);
98
- if (!slot.bold) {
99
- const key = OG_WORKER_BOLD_FONT_KEYS[locale];
100
- const bold = readFontObject(bucket, key, timeoutMs);
101
- bold.catch(() => {
102
- if (slot.bold === bold)
103
- slot.bold = undefined;
104
- });
105
- slot.bold = bold;
106
- }
107
- const bytes = await slot.bold;
104
+ const key = OG_WORKER_BOLD_FONT_KEYS[locale];
105
+ const bytes = await memo(slotFor(bucket, locale), "bold", () => readFontObject(bucket, key, timeoutMs));
108
106
  if (!bytes && !boldMissingWarned) {
109
107
  boldMissingWarned = true;
110
108
  logger.warn({
111
109
  message: "[og] bold font missing; rendering weight 700 with the regular face",
112
110
  mod: "og",
113
- key: OG_WORKER_BOLD_FONT_KEYS[locale],
111
+ key,
114
112
  locale,
115
113
  });
116
114
  }
117
115
  return bytes;
118
116
  }
117
+ /** One subset object, or `null` when it is missing or not the build's bytes (warned once per isolate). */
118
+ async function readSubsetObject(bucket, file, locale, logger, timeoutMs) {
119
+ const key = ogSubsetFontKey(file.file);
120
+ const bytes = await readFontObject(bucket, key, timeoutMs);
121
+ const reason = !bytes ? "missing" : (await ogFontSha256(bytes)) !== file.sha256 ? "sha256 mismatch" : undefined;
122
+ if (!reason)
123
+ return bytes;
124
+ if (!subsetMissingWarned) {
125
+ subsetMissingWarned = true;
126
+ logger.warn({ message: `[og] subset font ${reason}; rendering with the full font`, mod: "og", key, locale });
127
+ }
128
+ return null;
129
+ }
130
+ /**
131
+ * Subset Regular (+ Bold when `bold`) for `locale`, or `null` when this locale
132
+ * has no usable subset — every requested weight must be present, else the
133
+ * render uses the full fonts. A read error / timeout rejects like a full-font
134
+ * read (503), and the slot retries on the next render.
135
+ */
136
+ async function loadSubsetFonts(bucket, locale, bold, logger, timeoutMs) {
137
+ const set = ogSubsetFontSets()[locale];
138
+ if (!set || (bold && !set.bold))
139
+ return null;
140
+ const slot = slotFor(bucket, locale);
141
+ const regular = await memo(slot, "subsetRegular", () => readSubsetObject(bucket, set.regular, locale, logger, timeoutMs));
142
+ if (!regular)
143
+ return null;
144
+ if (!bold)
145
+ return { regular, bold: null };
146
+ const boldBytes = await memo(slot, "subsetBold", () => readSubsetObject(bucket, set.bold, locale, logger, timeoutMs));
147
+ return boldBytes ? { regular, bold: boldBytes } : null;
148
+ }
149
+ /**
150
+ * Whether `tree`'s text is covered by `locale`'s subset. A locale without a
151
+ * subset counts as covered, so the render reports `"absent"`, not `"miss"`.
152
+ */
153
+ function treeCoveredForLocale(locale, tree) {
154
+ const set = ogSubsetFontSets()[locale];
155
+ return !set || ogTreeCoveredBySubset(set, tree);
156
+ }
157
+ /**
158
+ * The fonts for one render: the locale's subset when `covered` and available,
159
+ * else the full fonts (Bold only when `bold`).
160
+ */
161
+ async function loadRenderFonts(bucket, locale, covered, bold, logger, timeoutMs) {
162
+ if (covered) {
163
+ const subset = await loadSubsetFonts(bucket, locale, bold, logger, timeoutMs);
164
+ if (subset)
165
+ return { ...subset, fontSubset: "hit" };
166
+ }
167
+ const [regular, boldBytes] = await Promise.all([
168
+ loadRegularFont(bucket, locale, timeoutMs),
169
+ bold ? loadBoldFont(bucket, locale, logger, timeoutMs) : Promise.resolve(null),
170
+ ]);
171
+ return { regular, bold: boldBytes, fontSubset: covered ? "absent" : "miss" };
172
+ }
119
173
  /** Test isolation: drop the raw font slot and re-arm the Bold warning. */
120
174
  export function resetOgWorkerFontCacheForTesting() {
121
175
  fontSlot = undefined;
122
176
  boldMissingWarned = false;
177
+ subsetMissingWarned = false;
123
178
  }
124
- /** Introspection for tests/benchmarks: which locale's raw fonts are resident, and how many bytes. */
179
+ /**
180
+ * Introspection for tests/benchmarks: which locale's raw fonts are resident,
181
+ * and how many bytes (`regularBytes` / `boldBytes`: full fonts; `subset*`: the
182
+ * subset objects).
183
+ */
125
184
  export async function getOgWorkerFontCacheStats() {
126
185
  const slot = fontSlot;
186
+ const empty = { regularBytes: 0, boldBytes: 0, subsetRegularBytes: 0, subsetBoldBytes: 0 };
127
187
  if (!slot)
128
- return { regularBytes: 0, boldBytes: 0 };
129
- const regular = await slot.regular.catch(() => null);
130
- const bold = slot.bold ? await slot.bold.catch(() => null) : null;
131
- return { locale: slot.locale, regularBytes: regular?.byteLength ?? 0, boldBytes: bold?.byteLength ?? 0 };
188
+ return empty;
189
+ const size = async (p) => (p ? ((await p.catch(() => null))?.byteLength ?? 0) : 0);
190
+ return {
191
+ locale: slot.locale,
192
+ regularBytes: await size(slot.regular),
193
+ boldBytes: await size(slot.bold),
194
+ subsetRegularBytes: await size(slot.subsetRegular),
195
+ subsetBoldBytes: await size(slot.subsetBold),
196
+ };
132
197
  }
133
198
  async function sha256(value) {
134
199
  const bytes = new TextEncoder().encode(value);
@@ -175,7 +240,7 @@ export function resolveOgWorkerLogoDataUri(asset) {
175
240
  }
176
241
  /**
177
242
  * satori → resvg for one tree. Callers hold the {@link serialRender} queue.
178
- * `regular` is copied per render (`slice()`), so satori's parse of it is
243
+ * The fonts are copied per render (`slice()`), so satori's parse of them is
179
244
  * garbage once this returns — only the raw bytes stay in {@link fontSlot}.
180
245
  * resvg gets the Regular face only (for text inside embedded SVG images; satori
181
246
  * already turns tree text into paths).
@@ -210,6 +275,10 @@ async function rasterizeTree(tree, width, height, regular, bold) {
210
275
  * render with an `OgTreeRenderError` and nothing is fetched.
211
276
  * - Fonts come from `fontBucket` by locale: Regular always, Bold when
212
277
  * `weights` includes 700 (missing Bold ⇒ Regular + one warning per isolate).
278
+ * When every character of the tree is covered by the locale's subset fonts
279
+ * (`fonts/subset-v1/…`, ArcBlock/arc#8800) those are used instead — same
280
+ * pixels, a fraction of the parse; otherwise, or when the subset object is
281
+ * missing (one warning per isolate), the full fonts.
213
282
  * - Runs inside the isolate-wide serial queue, so concurrent calls never
214
283
  * parse fonts or grow the wasm heap in parallel.
215
284
  * - No cache: callers version and cache the result themselves.
@@ -221,23 +290,23 @@ export async function renderOgTree(options) {
221
290
  const logger = options.logger ?? consoleLogger;
222
291
  const fontTimeout = options.fontReadTimeoutMs ?? OG_FONT_READ_TIMEOUT_MS;
223
292
  const bold = wantsBold(options.weights);
224
- const { body, queueMs, fontReadMs, boldBytes } = await serialRender(async ({ queueMs }) => {
293
+ const covered = treeCoveredForLocale(locale, tree);
294
+ const { body, queueMs, fontReadMs, boldBytes, fontSubset } = await serialRender(async ({ queueMs }) => {
225
295
  const fontStart = performance.now();
226
- const [regular, boldBytes] = await Promise.all([
227
- loadRegularFont(options.fontBucket, locale, fontTimeout),
228
- bold ? loadBoldFont(options.fontBucket, locale, logger, fontTimeout) : Promise.resolve(null),
296
+ const [fonts] = await Promise.all([
297
+ loadRenderFonts(options.fontBucket, locale, covered, bold, logger, fontTimeout),
229
298
  ensureWasm(),
230
299
  ]);
231
300
  const fontReadMs = performance.now() - fontStart;
232
301
  let body;
233
302
  try {
234
- body = await rasterizeTree(tree, options.width, options.height, regular, boldBytes);
303
+ body = await rasterizeTree(tree, options.width, options.height, fonts.regular, fonts.bold);
235
304
  }
236
305
  catch {
237
306
  // satori/resvg messages can quote the input; report a generic 400.
238
307
  throw new OgTreeRenderError(OG_TREE_ERROR_CODES.renderFailed, "the tree could not be rendered");
239
308
  }
240
- return { body, queueMs, fontReadMs, boldBytes };
309
+ return { body, queueMs, fontReadMs, boldBytes: fonts.bold, fontSubset: fonts.fontSubset };
241
310
  }, { maxWaitMs: options.queueMaxWaitMs ?? OG_QUEUE_MAX_WAIT_MS });
242
311
  options.observer?.({
243
312
  locale,
@@ -245,6 +314,7 @@ export async function renderOgTree(options) {
245
314
  durationMs: performance.now() - startedAt,
246
315
  queueMs,
247
316
  fontReadMs,
317
+ fontSubset,
248
318
  template: "tree",
249
319
  ...(bold && !boldBytes ? { boldFallback: true } : {}),
250
320
  });
@@ -317,14 +387,17 @@ export function createOgWorkerRenderer(options) {
317
387
  const { dataUri: logoDataUri, skipped: logoSkipped } = resolveOgWorkerLogoDataUri(logoAsset ?? undefined);
318
388
  params.logo = logoDataUri ?? TRANSPARENT_PNG_DATA_URI;
319
389
  const tree = await getTemplate(params);
320
- const { body, queueMs, fontReadMs } = await serialRender(async ({ queueMs }) => {
390
+ const covered = treeCoveredForLocale(locale, tree);
391
+ const logger = options.logger ?? consoleLogger;
392
+ const { body, queueMs, fontReadMs, fontSubset } = await serialRender(async ({ queueMs }) => {
321
393
  const fontStart = performance.now();
322
- const [font] = await Promise.all([
323
- loadRegularFont(options.fontBucket, locale, options.fontReadTimeoutMs ?? OG_FONT_READ_TIMEOUT_MS),
394
+ const [fonts] = await Promise.all([
395
+ loadRenderFonts(options.fontBucket, locale, covered, false, logger, options.fontReadTimeoutMs ?? OG_FONT_READ_TIMEOUT_MS),
324
396
  ensureWasm(),
325
397
  ]);
326
398
  const fontReadMs = performance.now() - fontStart;
327
- return { body: await rasterizeTree(tree, params.width, params.height, font, null), queueMs, fontReadMs };
399
+ const body = await rasterizeTree(tree, params.width, params.height, fonts.regular, null);
400
+ return { body, queueMs, fontReadMs, fontSubset: fonts.fontSubset };
328
401
  }, { maxWaitMs: options.queueMaxWaitMs ?? OG_QUEUE_MAX_WAIT_MS });
329
402
  const responseBody = body.slice().buffer;
330
403
  const response = new Response(responseBody, {
@@ -345,6 +418,7 @@ export function createOgWorkerRenderer(options) {
345
418
  durationMs: performance.now() - startedAt,
346
419
  queueMs,
347
420
  fontReadMs,
421
+ fontSubset,
348
422
  template: params.template,
349
423
  ...(logoSkipped ? { logoSkipped } : {}),
350
424
  });