@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.
- package/assets/fonts/subset-v1/noto-sans-sc-regular.otf +0 -0
- package/dist/_generated/asset-bytes.js +1 -1
- package/dist/_generated/asset-manifest.js +2 -2
- package/dist/_generated/login-bundle-string.d.ts +1 -1
- package/dist/_generated/login-bundle-string.d.ts.map +1 -1
- package/dist/_generated/login-bundle-string.js +1 -1
- package/dist/_generated/login-bundle-string.js.map +1 -1
- package/dist/assets/{admin-extra.918f91ce.js → admin-extra.35313406.js} +18 -1
- package/dist/assets/{login.de8082af.js → login.02c19607.js} +78 -78
- package/dist/ga4-measurement-id.d.ts +12 -2
- package/dist/ga4-measurement-id.d.ts.map +1 -1
- package/dist/ga4-measurement-id.js +26 -6
- package/dist/ga4-measurement-id.js.map +1 -1
- package/dist/handlers/blocklet-js-handler.d.ts.map +1 -1
- package/dist/handlers/blocklet-js-handler.js +3 -1
- package/dist/handlers/blocklet-js-handler.js.map +1 -1
- package/dist/handlers/branding-handler.d.ts.map +1 -1
- package/dist/handlers/branding-handler.js +10 -1
- package/dist/handlers/branding-handler.js.map +1 -1
- package/dist/og/font-subset.d.ts +56 -0
- package/dist/og/font-subset.d.ts.map +1 -0
- package/dist/og/font-subset.js +266 -0
- package/dist/og/font-subset.js.map +1 -0
- package/dist/og/generator.d.ts +2 -0
- package/dist/og/generator.d.ts.map +1 -1
- package/dist/og/generator.js +2 -1
- package/dist/og/generator.js.map +1 -1
- package/dist/og/subset-fonts.generated.d.ts +70 -0
- package/dist/og/subset-fonts.generated.d.ts.map +1 -0
- package/dist/og/subset-fonts.generated.js +41 -0
- package/dist/og/subset-fonts.generated.js.map +1 -0
- package/dist/og/tree-node.d.ts +17 -1
- package/dist/og/tree-node.d.ts.map +1 -1
- package/dist/og/tree-node.js +144 -9
- package/dist/og/tree-node.js.map +1 -1
- package/dist/og/worker.d.ts +25 -3
- package/dist/og/worker.d.ts.map +1 -1
- package/dist/og/worker.js +123 -49
- package/dist/og/worker.js.map +1 -1
- package/dist/pages/admin/i18n.d.ts.map +1 -1
- package/dist/pages/admin/i18n.js +28 -0
- package/dist/pages/admin/i18n.js.map +1 -1
- package/dist/pages/admin/tab-branding.d.ts.map +1 -1
- package/dist/pages/admin/tab-branding.js +29 -2
- package/dist/pages/admin/tab-branding.js.map +1 -1
- package/package.json +3 -3
package/dist/og/tree-node.js
CHANGED
|
@@ -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 {
|
|
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
|
-
|
|
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
|
|
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
|
|
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 =
|
|
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
|
});
|
package/dist/og/tree-node.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tree-node.js","sourceRoot":"","sources":["../../src/og/tree-node.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,aAAa,EAAe,MAAM,cAAc,CAAC;AAC1D,OAAO,EAAE,qBAAqB,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AACjE,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AACpE,OAAO,EACL,iBAAiB,EACjB,2BAA2B,EAC3B,mBAAmB,EACnB,wBAAwB,EACxB,iBAAiB,EAEjB,aAAa,EACb,SAAS,EACT,WAAW,GACZ,MAAM,WAAW,CAAC;AAEnB,gEAAgE;AAChE,MAAM,CAAC,MAAM,yBAAyB,GAAG,MAAM,CAAC;AA+BhD,MAAM,YAAY,GAAG,iBAAiB,EAAE,CAAC;AACzC,IAAI,WAA4E,CAAC;AAEjF,gGAAgG;AAChG,IAAI,QAA2D,CAAC;AAChE,IAAI,iBAAiB,GAAG,KAAK,CAAC;AAE9B;;;;GAIG;AACH,SAAS,UAAU;IACjB,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,WAAW,GAAG,CAAC,KAAK,IAAI,EAAE;YACxB,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,MAAM,CAAC,mBAAmB,CAAC,CAAC;YACpE,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAC/C,MAAM,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC;YAC9D,OAAO,MAAM,CAAC;QAChB,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;YAC5B,WAAW,GAAG,SAAS,CAAC;YACxB,MAAM,KAAK,CAAC;QACd,CAAC,CAAC,CAAC;IACL,CAAC;IACD,OAAO,WAAW,CAAC;AACrB,CAAC;AAED,SAAS,GAAG,CAAC,CAAS;IACpB,OAAO,UAAU,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACnD,CAAC;AAED,sGAAsG;AACtG,MAAM,UAAU,iBAAiB,CAAC,UAA8B;IAC9D,IAAI,CAAC,UAAU;QAAE,OAAO,SAAS,CAAC;IAClC,MAAM,KAAK,GAAG,UAAU,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IAC1C,MAAM,IAAI,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC;IAC5C,MAAM,IAAI,GAAG,UAAU,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;IACzC,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IACxE,OAAO,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,GAAG,IAAI,CAAC;AACjD,CAAC;AAED,KAAK,UAAU,cAAc,CAAC,GAAW,EAAE,YAAoB,EAAE,SAAuB;IACtF,IAAI,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC;QAAE,OAAO,QAAQ,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC;IACjE,MAAM,QAAQ,GAAG,IAAI,CAAC,YAAY,EAAE,GAAG,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IACxD,IAAI,UAAU,CAAC,QAAQ,CAAC;QAAE,OAAO,QAAQ,CAAC,QAAQ,CAAC,CAAC;IACpD,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,qBAAqB,CAAC,EAAE,CAAC,CAAC;IACzF,IAAI,CAAC,GAAG,CAAC,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,sBAAsB,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;IACjE,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC;IACjD,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAClD,aAAa,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;IAC7B,OAAO,GAAG,CAAC;AACb,CAAC;AAED,KAAK,UAAU,QAAQ,CACrB,WAA+B,EAC/B,UAA8B,EAC9B,YAAoB,EACpB,SAAuB,EACvB,MAAc;IAEd,MAAM,GAAG,GAAG,WAAW,IAAI,iBAAiB,CAAC,UAAU,CAAC,CAAC;IACzD,MAAM,GAAG,GAAG,GAAG,IAAI,kBAAkB,CAAC;IACtC,IAAI,QAAQ,EAAE,GAAG,KAAK,GAAG;QAAE,OAAO,QAAQ,CAAC,KAAK,CAAC;IACjD,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,QAAQ,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;QAChC,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,cAAc,CAAC,GAAG,EAAE,YAAY,EAAE,SAAS,CAAC,CAAC;QACjE,QAAQ,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC;QAC1B,OAAO,KAAK,CAAC;IACf,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,4EAA4E;YAC5E,QAAQ,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;YAChC,OAAO,IAAI,CAAC;QACd,CAAC;QACD,wEAAwE;QACxE,MAAM,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,wEAAwE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC;QACnH,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,oFAAoF;AACpF,MAAM,UAAU,8BAA8B;IAC5C,QAAQ,GAAG,SAAS,CAAC;IACrB,iBAAiB,GAAG,KAAK,CAAC;AAC5B,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,OAAgC;IACjE,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;IACpC,MAAM,IAAI,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;IACpC,MAAM,MAAM,GAAG,mBAAmB,EAAE,CAAC;IACrC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,aAAa,CAAC;IAC/C,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,KAAK,CAAC;IAC7C,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,IAAI,IAAI,CAAC,MAAM,EAAE,EAAE,UAAU,CAAC,CAAC;IACxE,MAAM,WAAW,GAAG,OAAO,CAAC,iBAAiB,IAAI,qBAAqB,CAAC;IACvE,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,IAAI,MAAM,CAAC,OAAO,CAAC;IACrD,MAAM,YAAY,GAAG,GAAG,EAAE,CACxB,IAAI,wBAAwB,CAAC,2BAA2B,CAAC,WAAW,EAAE,sBAAsB,WAAW,IAAI,CAAC,CAAC;IAE/G,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,GAAG,MAAM,YAAY,CACnE,KAAK,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;QACpB,MAAM,MAAM,GAAG,MAAM,UAAU,EAAE,CAAC;QAClC,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;QACpC,MAAM,OAAO,GAAG,MAAM,WAAW,CAC/B,QAAQ,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,CAAC,EAC1F,WAAW,EACX,YAAY,CACb,CAAC;QACF,IAAI,IAAI,GAAkB,IAAI,CAAC;QAC/B,MAAM,UAAU,GAAG,SAAS,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAC9C,IAAI,UAAU,EAAE,CAAC;YACf,IAAI,GAAG,MAAM,WAAW,CACtB,QAAQ,CAAC,OAAO,CAAC,WAAW,IAAI,MAAM,CAAC,WAAW,EAAE,UAAU,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,CAAC,EAChG,WAAW,EACX,YAAY,CACb,CAAC;YACF,IAAI,CAAC,IAAI,IAAI,CAAC,iBAAiB,EAAE,CAAC;gBAChC,iBAAiB,GAAG,IAAI,CAAC;gBACzB,MAAM,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,oEAAoE,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC;YAC5G,CAAC;QACH,CAAC;QACD,MAAM,UAAU,GAAG,WAAW,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;QACjD,wEAAwE;QACxE,uEAAuE;QACvE,MAAM,IAAI,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,UAAU,CAAgB,CAAC;QACrG,MAAM,KAAK,GAAmF;YAC5F,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE;SACpE,CAAC;QACF,IAAI,IAAI;YAAE,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;QACvF,IAAI,GAAW,CAAC;QAChB,IAAI,CAAC;YACH,0EAA0E;YAC1E,6DAA6D;YAC7D,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,IAAoC,EAAE;gBAC7D,KAAK,EAAE,OAAO,CAAC,KAAK;gBACpB,MAAM,EAAE,OAAO,CAAC,MAAM;gBACtB,KAAK;aACN,CAAC,CAAC;YACH,GAAG,GAAG,MAAM,yBAAyB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QACtD,CAAC;QAAC,MAAM,CAAC;YACP,mEAAmE;YACnE,MAAM,IAAI,iBAAiB,CAAC,mBAAmB,CAAC,YAAY,EAAE,gCAAgC,CAAC,CAAC;QAClG,CAAC;QACD,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,UAAU,IAAI,CAAC,IAAI,EAAE,CAAC;IACzE,CAAC,EACD,EAAE,SAAS,EAAE,OAAO,CAAC,cAAc,IAAI,yBAAyB,EAAE,CACnE,CAAC;IACF,OAAO,CAAC,QAAQ,EAAE,CAAC;QACjB,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,WAAW,EAAE,QAAQ;QACrB,UAAU,EAAE,WAAW,CAAC,GAAG,EAAE,GAAG,SAAS;QACzC,OAAO;QACP,UAAU;QACV,QAAQ,EAAE,MAAM;QAChB,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAChD,CAAC,CAAC;IACH,OAAO,IAAI,UAAU,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,UAAU,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC;AACpE,CAAC"}
|
|
1
|
+
{"version":3,"file":"tree-node.js","sourceRoot":"","sources":["../../src/og/tree-node.ts"],"names":[],"mappings":"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"}
|
package/dist/og/worker.d.ts
CHANGED
|
@@ -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
|
-
/**
|
|
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
|
-
/**
|
|
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.
|
package/dist/og/worker.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../../src/og/worker.ts"],"names":[],"mappings":"AAEA,OAAO,EAAiB,KAAK,MAAM,EAAE,MAAM,cAAc,CAAC;
|
|
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
|
|
73
|
+
function slotFor(bucket, locale) {
|
|
71
74
|
if (fontSlot && fontSlot.bucket === bucket && fontSlot.locale === locale)
|
|
72
75
|
return fontSlot;
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
}
|
|
88
|
-
|
|
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
|
-
|
|
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
|
|
98
|
-
|
|
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
|
|
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
|
-
/**
|
|
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
|
|
129
|
-
const
|
|
130
|
-
|
|
131
|
-
|
|
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
|
-
*
|
|
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
|
|
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 [
|
|
227
|
-
|
|
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,
|
|
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
|
|
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 [
|
|
323
|
-
|
|
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
|
-
|
|
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
|
});
|