@turntrout/subfont 1.10.7 → 1.10.8
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/lib/FontTracerPool.d.ts +22 -27
- package/lib/FontTracerPool.d.ts.map +1 -1
- package/lib/FontTracerPool.js +51 -277
- package/lib/FontTracerPool.js.map +1 -1
- package/lib/collectTextsByPage.d.ts +2 -1
- package/lib/collectTextsByPage.d.ts.map +1 -1
- package/lib/collectTextsByPage.js +10 -3
- package/lib/collectTextsByPage.js.map +1 -1
- package/lib/fontConverter.d.ts +5 -1
- package/lib/fontConverter.d.ts.map +1 -1
- package/lib/fontConverter.js +47 -122
- package/lib/fontConverter.js.map +1 -1
- package/lib/fontConverterWorker.d.ts +14 -1
- package/lib/fontConverterWorker.d.ts.map +1 -1
- package/lib/fontConverterWorker.js +16 -16
- package/lib/fontConverterWorker.js.map +1 -1
- package/lib/fontTracerWorker.d.ts +17 -4
- package/lib/fontTracerWorker.d.ts.map +1 -1
- package/lib/fontTracerWorker.js +31 -60
- package/lib/fontTracerWorker.js.map +1 -1
- package/lib/piscinaRunWithTimeout.d.ts +18 -0
- package/lib/piscinaRunWithTimeout.d.ts.map +1 -0
- package/lib/piscinaRunWithTimeout.js +78 -0
- package/lib/piscinaRunWithTimeout.js.map +1 -0
- package/lib/subsetFonts.d.ts +2 -1
- package/lib/subsetFonts.d.ts.map +1 -1
- package/lib/subsetFonts.js +8 -4
- package/lib/subsetFonts.js.map +1 -1
- package/package.json +2 -1
package/lib/FontTracerPool.d.ts
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
interface FontTracerPoolOptions {
|
|
2
|
+
taskTimeoutMs?: number;
|
|
3
|
+
}
|
|
1
4
|
interface StylesheetWithPredicates {
|
|
2
5
|
text?: string;
|
|
3
6
|
asset?: {
|
|
@@ -5,39 +8,31 @@ interface StylesheetWithPredicates {
|
|
|
5
8
|
};
|
|
6
9
|
predicates?: Record<string, unknown>;
|
|
7
10
|
}
|
|
8
|
-
interface
|
|
9
|
-
|
|
10
|
-
|
|
11
|
+
interface TextByPropsEntry {
|
|
12
|
+
text: string;
|
|
13
|
+
props: Record<string, unknown>;
|
|
14
|
+
}
|
|
15
|
+
interface TraceOptions {
|
|
16
|
+
signal?: AbortSignal;
|
|
11
17
|
}
|
|
12
18
|
declare class FontTracerPool {
|
|
13
|
-
private
|
|
14
|
-
private _numWorkers;
|
|
19
|
+
private _pool;
|
|
15
20
|
private _taskTimeoutMs;
|
|
16
|
-
|
|
17
|
-
private _workers;
|
|
18
|
-
private _idle;
|
|
19
|
-
private _pendingTasks;
|
|
20
|
-
private _taskCallbacks;
|
|
21
|
-
private _taskTimers;
|
|
22
|
-
private _taskByWorker;
|
|
23
|
-
private _nextTaskId;
|
|
24
|
-
private _destroying;
|
|
25
|
-
private _spawning;
|
|
26
|
-
constructor(numWorkers: number, { taskTimeoutMs, respawnOnExit, }?: FontTracerPoolOptions);
|
|
27
|
-
private _spawnOne;
|
|
21
|
+
constructor(numWorkers: number, { taskTimeoutMs }?: FontTracerPoolOptions);
|
|
28
22
|
init(): Promise<void>;
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
23
|
+
trace(htmlText: string, stylesheetsWithPredicates: StylesheetWithPredicates[], { signal }?: TraceOptions): Promise<TextByPropsEntry[]>;
|
|
24
|
+
/**
|
|
25
|
+
* Number of worker threads in the underlying piscina pool. Piscina
|
|
26
|
+
* spawns up to minThreads === maxThreads at construction time, though
|
|
27
|
+
* individual workers may still be loading their module when this is
|
|
28
|
+
* read. Exposed primarily for tests.
|
|
29
|
+
*/
|
|
30
|
+
get threadCount(): number;
|
|
36
31
|
/**
|
|
37
|
-
*
|
|
38
|
-
*
|
|
32
|
+
* Number of trace tasks waiting in the piscina queue (not yet dispatched
|
|
33
|
+
* to a worker).
|
|
39
34
|
*/
|
|
40
|
-
|
|
35
|
+
get queueSize(): number;
|
|
41
36
|
destroy(): Promise<void>;
|
|
42
37
|
}
|
|
43
38
|
export = FontTracerPool;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FontTracerPool.d.ts","sourceRoot":"","sources":["../src/FontTracerPool.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"FontTracerPool.d.ts","sourceRoot":"","sources":["../src/FontTracerPool.ts"],"names":[],"mappings":"AAmBA,UAAU,qBAAqB;IAC7B,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,UAAU,wBAAwB;IAChC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAI1B,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC;AAaD,UAAU,gBAAgB;IACxB,IAAI,EAAE,MAAM,CAAC;IAGb,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAED,UAAU,YAAY;IACpB,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED,cAAM,cAAc;IAClB,OAAO,CAAC,KAAK,CAAU;IACvB,OAAO,CAAC,cAAc,CAAS;gBAG7B,UAAU,EAAE,MAAM,EAClB,EAAE,aAAuC,EAAE,GAAE,qBAA0B;IAgBnE,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAmB3B,KAAK,CACH,QAAQ,EAAE,MAAM,EAChB,yBAAyB,EAAE,wBAAwB,EAAE,EACrD,EAAE,MAAM,EAAE,GAAE,YAAiB,GAC5B,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAuB9B;;;;;OAKG;IACH,IAAI,WAAW,IAAI,MAAM,CAExB;IAED;;;OAGG;IACH,IAAI,SAAS,IAAI,MAAM,CAEtB;IAEK,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAG/B;AAED,SAAS,cAAc,CAAC"}
|
package/lib/FontTracerPool.js
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
const pathModule = require("path");
|
|
3
|
-
const
|
|
3
|
+
const piscina_1 = require("piscina");
|
|
4
|
+
const piscinaRunWithTimeout_1 = require("./piscinaRunWithTimeout");
|
|
4
5
|
/**
|
|
5
6
|
* Worker pool for running fontTracer in parallel across pages.
|
|
6
7
|
* Each worker re-parses HTML with jsdom and runs fontTracer independently.
|
|
8
|
+
*
|
|
9
|
+
* Wraps `piscina` to preserve the existing FontTracerPool surface (init,
|
|
10
|
+
* trace, destroy) while delegating worker lifecycle, queueing, and
|
|
11
|
+
* structured-clone handling to a battle-tested dependency.
|
|
7
12
|
*/
|
|
8
13
|
// Heavy pages (large blog posts with elaborate CSS) under CPU contention on
|
|
9
14
|
// CI runners can comfortably exceed a minute in jsdom + font-tracer. The
|
|
@@ -11,298 +16,67 @@ const worker_threads_1 = require("worker_threads");
|
|
|
11
16
|
// errs generous.
|
|
12
17
|
const DEFAULT_TASK_TIMEOUT_MS = 600_000;
|
|
13
18
|
class FontTracerPool {
|
|
14
|
-
|
|
15
|
-
_numWorkers;
|
|
19
|
+
_pool;
|
|
16
20
|
_taskTimeoutMs;
|
|
17
|
-
|
|
18
|
-
_workers;
|
|
19
|
-
_idle;
|
|
20
|
-
_pendingTasks;
|
|
21
|
-
_taskCallbacks;
|
|
22
|
-
_taskTimers;
|
|
23
|
-
_taskByWorker;
|
|
24
|
-
_nextTaskId;
|
|
25
|
-
_destroying;
|
|
26
|
-
_spawning;
|
|
27
|
-
constructor(numWorkers, { taskTimeoutMs = DEFAULT_TASK_TIMEOUT_MS, respawnOnExit = true, } = {}) {
|
|
28
|
-
this._workerPath = pathModule.join(__dirname, 'fontTracerWorker.js');
|
|
29
|
-
this._numWorkers = numWorkers;
|
|
21
|
+
constructor(numWorkers, { taskTimeoutMs = DEFAULT_TASK_TIMEOUT_MS } = {}) {
|
|
30
22
|
this._taskTimeoutMs = taskTimeoutMs;
|
|
31
|
-
this.
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
}
|
|
42
|
-
_spawnOne() {
|
|
43
|
-
this._spawning++;
|
|
44
|
-
return new Promise((resolve, reject) => {
|
|
45
|
-
let worker;
|
|
46
|
-
try {
|
|
47
|
-
worker = new worker_threads_1.Worker(this._workerPath);
|
|
48
|
-
}
|
|
49
|
-
catch (err) {
|
|
50
|
-
this._spawning--;
|
|
51
|
-
reject(err instanceof Error ? err : new Error(String(err)));
|
|
52
|
-
return;
|
|
53
|
-
}
|
|
54
|
-
this._workers.push(worker);
|
|
55
|
-
const detachInitHandlers = () => {
|
|
56
|
-
worker.off('message', onMessage);
|
|
57
|
-
worker.off('error', failOnInit);
|
|
58
|
-
worker.off('exit', exitDuringInit);
|
|
59
|
-
};
|
|
60
|
-
const failOnInit = (err) => {
|
|
61
|
-
detachInitHandlers();
|
|
62
|
-
const idx = this._workers.indexOf(worker);
|
|
63
|
-
if (idx !== -1)
|
|
64
|
-
this._workers.splice(idx, 1);
|
|
65
|
-
this._spawning--;
|
|
66
|
-
worker.terminate();
|
|
67
|
-
reject(err);
|
|
68
|
-
};
|
|
69
|
-
const exitDuringInit = (code) => {
|
|
70
|
-
// Worker exited before sending 'ready' (e.g. terminated by destroy()
|
|
71
|
-
// mid-spawn, or crashed during init without emitting 'error'). Settle
|
|
72
|
-
// the spawn promise so the .catch() upstream can run.
|
|
73
|
-
detachInitHandlers();
|
|
74
|
-
const idx = this._workers.indexOf(worker);
|
|
75
|
-
if (idx !== -1)
|
|
76
|
-
this._workers.splice(idx, 1);
|
|
77
|
-
this._spawning--;
|
|
78
|
-
reject(new Error(`Worker exited during init with code ${code}`));
|
|
79
|
-
};
|
|
80
|
-
const onMessage = (msg) => {
|
|
81
|
-
if (msg.type === 'ready') {
|
|
82
|
-
detachInitHandlers();
|
|
83
|
-
worker.on('message', (m) => this._onWorkerMessage(worker, m));
|
|
84
|
-
worker.on('error', (e) => this._onWorkerError(worker, e));
|
|
85
|
-
worker.on('exit', (code) => this._onWorkerExit(worker, code));
|
|
86
|
-
this._idle.push(worker);
|
|
87
|
-
this._spawning--;
|
|
88
|
-
resolve();
|
|
89
|
-
this._dispatchPending();
|
|
90
|
-
}
|
|
91
|
-
};
|
|
92
|
-
worker.on('message', onMessage);
|
|
93
|
-
worker.on('error', failOnInit);
|
|
94
|
-
worker.on('exit', exitDuringInit);
|
|
95
|
-
worker.postMessage({ type: 'init' });
|
|
23
|
+
this._pool = new piscina_1.Piscina({
|
|
24
|
+
filename: pathModule.join(__dirname, 'fontTracerWorker.js'),
|
|
25
|
+
// Pin pool size so concurrency is bounded by the caller-supplied
|
|
26
|
+
// worker count (memory and CPU contention both scale with this).
|
|
27
|
+
minThreads: numWorkers,
|
|
28
|
+
maxThreads: numWorkers,
|
|
29
|
+
concurrentTasksPerWorker: 1,
|
|
30
|
+
// Workers stay warm for the lifetime of the pool — pages on the
|
|
31
|
+
// same site share stylesheet parses through per-worker memoization.
|
|
32
|
+
idleTimeout: Infinity,
|
|
96
33
|
});
|
|
97
34
|
}
|
|
98
35
|
async init() {
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
//
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
if (taskId !== undefined) {
|
|
111
|
-
this._taskByWorker.delete(worker);
|
|
112
|
-
this._clearTaskTimer(taskId);
|
|
113
|
-
const cb = this._taskCallbacks.get(taskId);
|
|
114
|
-
if (cb) {
|
|
115
|
-
this._taskCallbacks.delete(taskId);
|
|
116
|
-
cb.reject(err);
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
_clearTaskTimer(taskId) {
|
|
121
|
-
const timer = this._taskTimers.get(taskId);
|
|
122
|
-
if (timer) {
|
|
123
|
-
clearTimeout(timer);
|
|
124
|
-
this._taskTimers.delete(taskId);
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
_onWorkerMessage(worker, msg) {
|
|
128
|
-
if (msg.type === 'ready')
|
|
129
|
-
return;
|
|
130
|
-
this._taskByWorker.delete(worker);
|
|
131
|
-
this._clearTaskTimer(msg.taskId);
|
|
132
|
-
const cb = this._taskCallbacks.get(msg.taskId);
|
|
133
|
-
if (cb) {
|
|
134
|
-
this._taskCallbacks.delete(msg.taskId);
|
|
135
|
-
if (msg.type === 'result') {
|
|
136
|
-
cb.resolve(msg.textByProps);
|
|
137
|
-
}
|
|
138
|
-
else if (msg.type === 'error') {
|
|
139
|
-
const detail = msg.stack ? `${msg.error}\n${msg.stack}` : msg.error;
|
|
140
|
-
cb.reject(new Error(`Worker error: ${detail}`));
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
// Worker is now idle, check for pending tasks
|
|
144
|
-
this._idle.push(worker);
|
|
145
|
-
this._dispatchPending();
|
|
146
|
-
}
|
|
147
|
-
_onWorkerExit(worker, code) {
|
|
148
|
-
const workerIdx = this._workers.indexOf(worker);
|
|
149
|
-
if (workerIdx !== -1) {
|
|
150
|
-
this._workers.splice(workerIdx, 1);
|
|
151
|
-
}
|
|
152
|
-
const idleIdx = this._idle.indexOf(worker);
|
|
153
|
-
if (idleIdx !== -1) {
|
|
154
|
-
this._idle.splice(idleIdx, 1);
|
|
155
|
-
}
|
|
156
|
-
// Reject any task that was in-flight on this worker. A graceful exit
|
|
157
|
-
// (code 0) mid-task still leaves the caller waiting, so don't gate on
|
|
158
|
-
// code !== 0.
|
|
159
|
-
const taskId = this._taskByWorker.get(worker);
|
|
160
|
-
this._taskByWorker.delete(worker);
|
|
161
|
-
if (taskId !== undefined) {
|
|
162
|
-
this._clearTaskTimer(taskId);
|
|
163
|
-
const cb = this._taskCallbacks.get(taskId);
|
|
164
|
-
if (cb) {
|
|
165
|
-
this._taskCallbacks.delete(taskId);
|
|
166
|
-
cb.reject(new Error(`Worker exited with code ${code}`));
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
if (this._destroying)
|
|
170
|
-
return;
|
|
171
|
-
if (this._respawnOnExit) {
|
|
172
|
-
this._spawnOne().catch((err) => {
|
|
173
|
-
// Respawn failed — fall back to draining if the pool is now empty.
|
|
174
|
-
if (this._workers.length === 0 &&
|
|
175
|
-
this._spawning === 0 &&
|
|
176
|
-
this._pendingTasks.length > 0) {
|
|
177
|
-
this._drainPendingWith(`All workers have crashed and respawn failed: ${err.message}`);
|
|
178
|
-
}
|
|
179
|
-
});
|
|
180
|
-
return;
|
|
181
|
-
}
|
|
182
|
-
if (code !== 0 && this._workers.length === 0) {
|
|
183
|
-
this._drainPendingWith('All workers have crashed, no workers available');
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
_drainPendingWith(message) {
|
|
187
|
-
for (const task of this._pendingTasks) {
|
|
188
|
-
const cb = this._taskCallbacks.get(task.message.taskId);
|
|
189
|
-
if (cb) {
|
|
190
|
-
this._taskCallbacks.delete(task.message.taskId);
|
|
191
|
-
cb.reject(new Error(message));
|
|
192
|
-
}
|
|
36
|
+
// Piscina spawns workers eagerly when minThreads === maxThreads, but
|
|
37
|
+
// each worker still pays a one-time `require('jsdom')` + `postcss` cost
|
|
38
|
+
// on its first message — hundreds of ms cold. Fire one warmup trace
|
|
39
|
+
// per worker so that cost lands in init() (where the phase tracker
|
|
40
|
+
// expects it) instead of in the first real `trace()` batch.
|
|
41
|
+
//
|
|
42
|
+
// Empty HTML produces an empty result quickly and exercises the full
|
|
43
|
+
// require chain. Tasks load-balance across all idle workers.
|
|
44
|
+
const minThreads = this._pool.options.minThreads;
|
|
45
|
+
if (minThreads > 0) {
|
|
46
|
+
await Promise.all(Array.from({ length: minThreads }, () => this._pool.run({ htmlText: '', stylesheetsWithPredicates: [] })));
|
|
193
47
|
}
|
|
194
|
-
this._pendingTasks = [];
|
|
195
48
|
}
|
|
196
|
-
|
|
197
|
-
if (this._taskTimeoutMs <= 0)
|
|
198
|
-
return;
|
|
199
|
-
const timer = setTimeout(() => {
|
|
200
|
-
this._taskTimers.delete(taskId);
|
|
201
|
-
const cb = this._taskCallbacks.get(taskId);
|
|
202
|
-
if (cb) {
|
|
203
|
-
this._taskCallbacks.delete(taskId);
|
|
204
|
-
cb.reject(new Error(`Font tracing task ${taskId} timed out after ${this._taskTimeoutMs}ms`));
|
|
205
|
-
}
|
|
206
|
-
// Terminate the hung worker so it doesn't permanently consume a pool
|
|
207
|
-
// slot. _onWorkerExit will remove it from _workers and _idle.
|
|
208
|
-
for (const [worker, tid] of this._taskByWorker) {
|
|
209
|
-
if (tid === taskId) {
|
|
210
|
-
this._taskByWorker.delete(worker);
|
|
211
|
-
worker.terminate();
|
|
212
|
-
break;
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
}, this._taskTimeoutMs);
|
|
216
|
-
timer.unref();
|
|
217
|
-
this._taskTimers.set(taskId, timer);
|
|
218
|
-
}
|
|
219
|
-
_dispatchPending() {
|
|
220
|
-
while (this._idle.length > 0 && this._pendingTasks.length > 0) {
|
|
221
|
-
const worker = this._idle.pop();
|
|
222
|
-
const task = this._pendingTasks.shift();
|
|
223
|
-
this._taskByWorker.set(worker, task.message.taskId);
|
|
224
|
-
try {
|
|
225
|
-
worker.postMessage(task.message);
|
|
226
|
-
this._startTaskTimer(task.message.taskId);
|
|
227
|
-
}
|
|
228
|
-
catch (err) {
|
|
229
|
-
// postMessage can fail synchronously (e.g. structured clone error).
|
|
230
|
-
// Return the worker to the idle pool and reject the task.
|
|
231
|
-
this._taskByWorker.delete(worker);
|
|
232
|
-
this._idle.push(worker);
|
|
233
|
-
const cb = this._taskCallbacks.get(task.message.taskId);
|
|
234
|
-
if (cb) {
|
|
235
|
-
this._taskCallbacks.delete(task.message.taskId);
|
|
236
|
-
cb.reject(err);
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
/**
|
|
242
|
-
* Run fontTracer on the given HTML text + stylesheets in a worker.
|
|
243
|
-
* Returns a promise that resolves to textByProps.
|
|
244
|
-
*/
|
|
245
|
-
// The pool is payload-agnostic; callers (subsetFonts.ts) interpret the
|
|
246
|
-
// returned textByProps according to font-tracer's contract.
|
|
247
|
-
trace(htmlText, stylesheetsWithPredicates
|
|
248
|
-
// eslint-disable-next-line no-restricted-syntax
|
|
249
|
-
) {
|
|
250
|
-
const taskId = this._nextTaskId++;
|
|
49
|
+
trace(htmlText, stylesheetsWithPredicates, { signal } = {}) {
|
|
251
50
|
// Serialize stylesheets to plain data — asset objects contain DOM/PostCSS
|
|
252
51
|
// trees that cannot be transferred via structured clone.
|
|
253
|
-
const
|
|
52
|
+
const serialized = stylesheetsWithPredicates.map((entry) => ({
|
|
254
53
|
text: entry.text || (entry.asset && entry.asset.text) || '',
|
|
255
54
|
predicates: entry.predicates || {},
|
|
256
55
|
}));
|
|
257
|
-
const
|
|
258
|
-
type: 'trace',
|
|
259
|
-
taskId,
|
|
56
|
+
const task = {
|
|
260
57
|
htmlText,
|
|
261
|
-
stylesheetsWithPredicates:
|
|
58
|
+
stylesheetsWithPredicates: serialized,
|
|
262
59
|
};
|
|
263
|
-
return
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
60
|
+
return (0, piscinaRunWithTimeout_1.runWithTimeoutAndSignal)(this._pool, task, signal, this._taskTimeoutMs, (ms) => `Font tracing task timed out after ${ms}ms`);
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Number of worker threads in the underlying piscina pool. Piscina
|
|
64
|
+
* spawns up to minThreads === maxThreads at construction time, though
|
|
65
|
+
* individual workers may still be loading their module when this is
|
|
66
|
+
* read. Exposed primarily for tests.
|
|
67
|
+
*/
|
|
68
|
+
get threadCount() {
|
|
69
|
+
return this._pool.threads.length;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Number of trace tasks waiting in the piscina queue (not yet dispatched
|
|
73
|
+
* to a worker).
|
|
74
|
+
*/
|
|
75
|
+
get queueSize() {
|
|
76
|
+
return this._pool.queueSize;
|
|
268
77
|
}
|
|
269
78
|
async destroy() {
|
|
270
|
-
this.
|
|
271
|
-
// Clear all task timers
|
|
272
|
-
for (const timer of this._taskTimers.values()) {
|
|
273
|
-
clearTimeout(timer);
|
|
274
|
-
}
|
|
275
|
-
this._taskTimers.clear();
|
|
276
|
-
// Reject any tasks still waiting in the queue
|
|
277
|
-
for (const task of this._pendingTasks) {
|
|
278
|
-
const cb = this._taskCallbacks.get(task.message.taskId);
|
|
279
|
-
if (cb) {
|
|
280
|
-
this._taskCallbacks.delete(task.message.taskId);
|
|
281
|
-
cb.reject(new Error('Worker pool destroyed'));
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
this._pendingTasks = [];
|
|
285
|
-
// Reject any in-flight tasks still assigned to workers.
|
|
286
|
-
// Clear _taskByWorker before terminate() so _onWorkerExit won't double-reject.
|
|
287
|
-
for (const [, taskId] of this._taskByWorker) {
|
|
288
|
-
const cb = this._taskCallbacks.get(taskId);
|
|
289
|
-
if (cb) {
|
|
290
|
-
this._taskCallbacks.delete(taskId);
|
|
291
|
-
cb.reject(new Error('Worker pool destroyed'));
|
|
292
|
-
}
|
|
293
|
-
}
|
|
294
|
-
this._taskByWorker.clear();
|
|
295
|
-
// Terminate workers with a 5-second timeout to prevent hanging
|
|
296
|
-
const TERMINATE_TIMEOUT_MS = 5000;
|
|
297
|
-
await Promise.all(this._workers.map((w) => Promise.race([
|
|
298
|
-
w.terminate(),
|
|
299
|
-
new Promise((resolve) => {
|
|
300
|
-
const timer = setTimeout(resolve, TERMINATE_TIMEOUT_MS);
|
|
301
|
-
timer.unref();
|
|
302
|
-
}),
|
|
303
|
-
])));
|
|
304
|
-
this._workers = [];
|
|
305
|
-
this._idle = [];
|
|
79
|
+
await this._pool.destroy();
|
|
306
80
|
}
|
|
307
81
|
}
|
|
308
82
|
module.exports = FontTracerPool;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FontTracerPool.js","sourceRoot":"","sources":["../src/FontTracerPool.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"FontTracerPool.js","sourceRoot":"","sources":["../src/FontTracerPool.ts"],"names":[],"mappings":";AAAA,mCAAoC;AACpC,qCAAkC;AAClC,mEAAkE;AAElE;;;;;;;GAOG;AAEH,4EAA4E;AAC5E,yEAAyE;AACzE,2EAA2E;AAC3E,iBAAiB;AACjB,MAAM,uBAAuB,GAAG,OAAO,CAAC;AAqCxC,MAAM,cAAc;IACV,KAAK,CAAU;IACf,cAAc,CAAS;IAE/B,YACE,UAAkB,EAClB,EAAE,aAAa,GAAG,uBAAuB,KAA4B,EAAE;QAEvE,IAAI,CAAC,cAAc,GAAG,aAAa,CAAC;QACpC,IAAI,CAAC,KAAK,GAAG,IAAI,iBAAO,CAAC;YACvB,QAAQ,EAAE,UAAU,CAAC,IAAI,CAAC,SAAS,EAAE,qBAAqB,CAAC;YAC3D,iEAAiE;YACjE,iEAAiE;YACjE,UAAU,EAAE,UAAU;YACtB,UAAU,EAAE,UAAU;YACtB,wBAAwB,EAAE,CAAC;YAC3B,gEAAgE;YAChE,oEAAoE;YACpE,WAAW,EAAE,QAAQ;SACtB,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,IAAI;QACR,qEAAqE;QACrE,wEAAwE;QACxE,oEAAoE;QACpE,mEAAmE;QACnE,4DAA4D;QAC5D,EAAE;QACF,qEAAqE;QACrE,6DAA6D;QAC7D,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC;QACjD,IAAI,UAAU,GAAG,CAAC,EAAE,CAAC;YACnB,MAAM,OAAO,CAAC,GAAG,CACf,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,EAAE,GAAG,EAAE,CACtC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,yBAAyB,EAAE,EAAE,EAAE,CAAC,CAChE,CACF,CAAC;QACJ,CAAC;IACH,CAAC;IAED,KAAK,CACH,QAAgB,EAChB,yBAAqD,EACrD,EAAE,MAAM,KAAmB,EAAE;QAE7B,0EAA0E;QAC1E,yDAAyD;QACzD,MAAM,UAAU,GAA2B,yBAAyB,CAAC,GAAG,CACtE,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;YACV,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE;YAC3D,UAAU,EAAE,KAAK,CAAC,UAAU,IAAI,EAAE;SACnC,CAAC,CACH,CAAC;QACF,MAAM,IAAI,GAAc;YACtB,QAAQ;YACR,yBAAyB,EAAE,UAAU;SACtC,CAAC;QAEF,OAAO,IAAA,+CAAuB,EAC5B,IAAI,CAAC,KAAK,EACV,IAAI,EACJ,MAAM,EACN,IAAI,CAAC,cAAc,EACnB,CAAC,EAAE,EAAE,EAAE,CAAC,qCAAqC,EAAE,IAAI,CACpD,CAAC;IACJ,CAAC;IAED;;;;;OAKG;IACH,IAAI,WAAW;QACb,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;IACnC,CAAC;IAED;;;OAGG;IACH,IAAI,SAAS;QACX,OAAO,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC;IAC9B,CAAC;IAED,KAAK,CAAC,OAAO;QACX,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;IAC7B,CAAC;CACF;AAED,iBAAS,cAAc,CAAC"}
|
|
@@ -22,12 +22,13 @@ interface CollectTextsByPageOptions {
|
|
|
22
22
|
debug?: boolean;
|
|
23
23
|
concurrency?: number;
|
|
24
24
|
chromeArgs?: string[];
|
|
25
|
+
signal?: AbortSignal;
|
|
25
26
|
}
|
|
26
27
|
interface CollectTextsByPageResult {
|
|
27
28
|
htmlOrSvgAssetTextsWithProps: AssetTextWithPropsEntry[];
|
|
28
29
|
fontFaceDeclarationsByHtmlOrSvgAsset: Map<Asset, FontFaceDeclaration[]>;
|
|
29
30
|
subTimings: Record<string, number | undefined>;
|
|
30
31
|
}
|
|
31
|
-
declare function collectTextsByPage(assetGraph: AssetGraph, htmlOrSvgAssets: Asset[], { text, console, dynamic, debug, concurrency, chromeArgs, }?: CollectTextsByPageOptions): Promise<CollectTextsByPageResult>;
|
|
32
|
+
declare function collectTextsByPage(assetGraph: AssetGraph, htmlOrSvgAssets: Asset[], { text, console, dynamic, debug, concurrency, chromeArgs, signal, }?: CollectTextsByPageOptions): Promise<CollectTextsByPageResult>;
|
|
32
33
|
export = collectTextsByPage;
|
|
33
34
|
//# sourceMappingURL=collectTextsByPage.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collectTextsByPage.d.ts","sourceRoot":"","sources":["../src/collectTextsByPage.ts"],"names":[],"mappings":"AA2BA,OAAO,EACL,mCAAmC,EAEpC,MAAM,sBAAsB,CAAC;AAE9B,OAAO,KAAK,EAAE,KAAK,EAAE,UAAU,EAAyB,MAAM,YAAY,CAAC;AAC3E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACxD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAwCtD,UAAU,gBAAgB;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAE9B,cAAc,CAAC,EAAE,KAAK,CAAC;CACxB;
|
|
1
|
+
{"version":3,"file":"collectTextsByPage.d.ts","sourceRoot":"","sources":["../src/collectTextsByPage.ts"],"names":[],"mappings":"AA2BA,OAAO,EACL,mCAAmC,EAEpC,MAAM,sBAAsB,CAAC;AAE9B,OAAO,KAAK,EAAE,KAAK,EAAE,UAAU,EAAyB,MAAM,YAAY,CAAC;AAC3E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACxD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAwCtD,UAAU,gBAAgB;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAE9B,cAAc,CAAC,EAAE,KAAK,CAAC;CACxB;AA+5BD,UAAU,uBAAuB;IAC/B,cAAc,EAAE,KAAK,CAAC;IACtB,WAAW,EAAE,gBAAgB,EAAE,CAAC;IAChC,+BAA+B,EAAE,mBAAmB,EAAE,CAAC;IACvD,+BAA+B,EAAE,UAAU,CACzC,OAAO,mCAAmC,CAC3C,CAAC;IACF,mBAAmB,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;IAK9C,UAAU,EAAE,eAAe,EAAE,CAAC;CAC/B;AA2MD,UAAU,yBAAyB;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IACzB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IAItB,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED,UAAU,wBAAwB;IAChC,4BAA4B,EAAE,uBAAuB,EAAE,CAAC;IACxD,oCAAoC,EAAE,GAAG,CAAC,KAAK,EAAE,mBAAmB,EAAE,CAAC,CAAC;IACxE,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;CAChD;AAED,iBAAe,kBAAkB,CAC/B,UAAU,EAAE,UAAU,EACtB,eAAe,EAAE,KAAK,EAAE,EACxB,EACE,IAAI,EACJ,OAAO,EACP,OAAe,EACf,KAAa,EACb,WAAW,EACX,UAAe,EACf,MAAM,GACP,GAAE,yBAA8B,GAChC,OAAO,CAAC,wBAAwB,CAAC,CAgJnC;AAED,SAAS,kBAAkB,CAAC"}
|
|
@@ -285,7 +285,7 @@ function populateGlobalFontUsages(cached, accumulatedFontFaceDeclarations, text)
|
|
|
285
285
|
// Trace fonts across the given pages. Uses a worker pool when the workload
|
|
286
286
|
// justifies the thread-startup overhead; otherwise falls back to sequential
|
|
287
287
|
// in-process tracing (required when a HeadlessBrowser is driving things).
|
|
288
|
-
async function tracePages(pagesNeedingFullTrace, { headlessBrowser, concurrency, console, memoizedGetCssRulesByProperty, debug = false, }) {
|
|
288
|
+
async function tracePages(pagesNeedingFullTrace, { headlessBrowser, concurrency, console, memoizedGetCssRulesByProperty, debug = false, signal, }) {
|
|
289
289
|
const totalPages = pagesNeedingFullTrace.length;
|
|
290
290
|
if (totalPages === 0)
|
|
291
291
|
return;
|
|
@@ -310,10 +310,15 @@ async function tracePages(pagesNeedingFullTrace, { headlessBrowser, concurrency,
|
|
|
310
310
|
await Promise.all(pagesNeedingFullTrace.map(async (pd) => {
|
|
311
311
|
const pageStart = debug ? Date.now() : 0;
|
|
312
312
|
try {
|
|
313
|
-
pd.textByProps = (await pool.trace(pd.htmlOrSvgAsset.text || '', pd.stylesheetsWithPredicates));
|
|
313
|
+
pd.textByProps = (await pool.trace(pd.htmlOrSvgAsset.text || '', pd.stylesheetsWithPredicates, { signal }));
|
|
314
314
|
}
|
|
315
315
|
catch (rawErr) {
|
|
316
316
|
const workerErr = rawErr;
|
|
317
|
+
// If the caller cancelled, surface the abort instead of running
|
|
318
|
+
// another (uncancellable) trace on the main thread.
|
|
319
|
+
if (signal?.aborted) {
|
|
320
|
+
throw workerErr;
|
|
321
|
+
}
|
|
317
322
|
fallbackCount++;
|
|
318
323
|
if (console) {
|
|
319
324
|
console.warn(`Worker fontTracer failed for ${pd.htmlOrSvgAsset.url}, falling back to main thread: ${workerErr.message}`);
|
|
@@ -793,7 +798,7 @@ function flattenTracedPagesIntoGlobal(pageData, htmlOrSvgAssetTextsWithProps, gl
|
|
|
793
798
|
});
|
|
794
799
|
}
|
|
795
800
|
}
|
|
796
|
-
async function collectTextsByPage(assetGraph, htmlOrSvgAssets, { text, console, dynamic = false, debug = false, concurrency, chromeArgs = [], } = {}) {
|
|
801
|
+
async function collectTextsByPage(assetGraph, htmlOrSvgAssets, { text, console, dynamic = false, debug = false, concurrency, chromeArgs = [], signal, } = {}) {
|
|
797
802
|
const htmlOrSvgAssetTextsWithProps = [];
|
|
798
803
|
const memoizedGetCssRulesByProperty = memoizeSync(getCssRulesByProperty);
|
|
799
804
|
const fontFaceDeclarationsByHtmlOrSvgAsset = new Map();
|
|
@@ -837,6 +842,7 @@ async function collectTextsByPage(assetGraph, htmlOrSvgAssets, { text, console,
|
|
|
837
842
|
console,
|
|
838
843
|
memoizedGetCssRulesByProperty,
|
|
839
844
|
debug,
|
|
845
|
+
signal,
|
|
840
846
|
});
|
|
841
847
|
subTimings['Full tracing'] = fullTracing.end();
|
|
842
848
|
const planPhase = trackPhase('Fast-path planning');
|
|
@@ -850,6 +856,7 @@ async function collectTextsByPage(assetGraph, htmlOrSvgAssets, { text, console,
|
|
|
850
856
|
console,
|
|
851
857
|
memoizedGetCssRulesByProperty,
|
|
852
858
|
debug,
|
|
859
|
+
signal,
|
|
853
860
|
});
|
|
854
861
|
subTimings['Fallback tracing'] = fallbackTracing.end();
|
|
855
862
|
}
|