@spinajs/templates-puppeteer 2.0.481 → 2.0.482
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/README.md +35 -0
- package/lib/cjs/asset-server.d.ts +32 -0
- package/lib/cjs/asset-server.d.ts.map +1 -0
- package/lib/cjs/asset-server.js +125 -0
- package/lib/cjs/asset-server.js.map +1 -0
- package/lib/cjs/browser-pool.d.ts +31 -0
- package/lib/cjs/browser-pool.d.ts.map +1 -0
- package/lib/cjs/browser-pool.js +83 -0
- package/lib/cjs/browser-pool.js.map +1 -0
- package/lib/cjs/index.d.ts +84 -19
- package/lib/cjs/index.d.ts.map +1 -1
- package/lib/cjs/index.js +203 -182
- package/lib/cjs/index.js.map +1 -1
- package/lib/cjs/progress.d.ts +41 -0
- package/lib/cjs/progress.d.ts.map +1 -0
- package/lib/cjs/progress.js +179 -0
- package/lib/cjs/progress.js.map +1 -0
- package/lib/mjs/asset-server.d.ts +32 -0
- package/lib/mjs/asset-server.d.ts.map +1 -0
- package/lib/mjs/asset-server.js +118 -0
- package/lib/mjs/asset-server.js.map +1 -0
- package/lib/mjs/browser-pool.d.ts +31 -0
- package/lib/mjs/browser-pool.d.ts.map +1 -0
- package/lib/mjs/browser-pool.js +76 -0
- package/lib/mjs/browser-pool.js.map +1 -0
- package/lib/mjs/index.d.ts +84 -19
- package/lib/mjs/index.d.ts.map +1 -1
- package/lib/mjs/index.js +190 -180
- package/lib/mjs/index.js.map +1 -1
- package/lib/mjs/progress.d.ts +41 -0
- package/lib/mjs/progress.d.ts.map +1 -0
- package/lib/mjs/progress.js +175 -0
- package/lib/mjs/progress.js.map +1 -0
- package/lib/tsconfig.cjs.tsbuildinfo +1 -1
- package/lib/tsconfig.mjs.tsbuildinfo +1 -1
- package/package.json +8 -7
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import { RenderPhase } from '@spinajs/templates';
|
|
2
|
+
/** Minimum gap between resource-driven emissions (ms). */
|
|
3
|
+
const THROTTLE_MS = 150;
|
|
4
|
+
/** Re-emit interval during long phases so the bar moves even when nothing changes (ms). */
|
|
5
|
+
const HEARTBEAT_MS = 750;
|
|
6
|
+
/** Percent band [start, end] each phase occupies. */
|
|
7
|
+
const PHASE_BANDS = {
|
|
8
|
+
[RenderPhase.Starting]: [0, 10],
|
|
9
|
+
[RenderPhase.Preparing]: [10, 15],
|
|
10
|
+
[RenderPhase.Loading]: [15, 80],
|
|
11
|
+
[RenderPhase.Rendering]: [80, 95],
|
|
12
|
+
[RenderPhase.Done]: [100, 100],
|
|
13
|
+
[RenderPhase.Failed]: [0, 0],
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Tracks a single puppeteer render and delivers throttled {@link IRenderProgress}
|
|
17
|
+
* snapshots to a callback. Resource counts come from the page's request lifecycle
|
|
18
|
+
* events; the percentage is phase-weighted (see {@link PHASE_BANDS}), and a
|
|
19
|
+
* heartbeat keeps it ticking during the long Loading/Rendering phases.
|
|
20
|
+
*
|
|
21
|
+
* When constructed without a callback it is entirely inert - no listeners, no
|
|
22
|
+
* timers, no allocations on the hot path - so callers can always create one.
|
|
23
|
+
*/
|
|
24
|
+
export class RenderProgressReporter {
|
|
25
|
+
constructor(filePath, callback) {
|
|
26
|
+
this.filePath = filePath;
|
|
27
|
+
this.startedAt = Date.now();
|
|
28
|
+
this.phaseNow = RenderPhase.Starting;
|
|
29
|
+
this.loaded = 0;
|
|
30
|
+
this.pending = 0;
|
|
31
|
+
this.failed = 0;
|
|
32
|
+
this.lastEmitAt = 0;
|
|
33
|
+
this.lastPercent = 0;
|
|
34
|
+
this.heartbeat = null;
|
|
35
|
+
this.page = null;
|
|
36
|
+
// pre-bound so add/remove reference the same function identities
|
|
37
|
+
this.onRequest = () => {
|
|
38
|
+
this.pending++;
|
|
39
|
+
};
|
|
40
|
+
this.onRequestFinished = () => {
|
|
41
|
+
this.pending = Math.max(0, this.pending - 1);
|
|
42
|
+
this.loaded++;
|
|
43
|
+
this.emit();
|
|
44
|
+
};
|
|
45
|
+
this.onRequestFailed = () => {
|
|
46
|
+
this.pending = Math.max(0, this.pending - 1);
|
|
47
|
+
this.failed++;
|
|
48
|
+
this.emit();
|
|
49
|
+
};
|
|
50
|
+
this.enabled = !!callback;
|
|
51
|
+
this.callback = callback ?? (() => undefined);
|
|
52
|
+
}
|
|
53
|
+
/** Attach resource-lifecycle counters to the page. Call once, after newPage(). */
|
|
54
|
+
attach(page) {
|
|
55
|
+
if (!this.enabled) {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
this.page = page;
|
|
59
|
+
page.on('request', this.onRequest);
|
|
60
|
+
page.on('requestfinished', this.onRequestFinished);
|
|
61
|
+
page.on('requestfailed', this.onRequestFailed);
|
|
62
|
+
}
|
|
63
|
+
/** Transition to a new phase and emit immediately (bypassing the throttle). */
|
|
64
|
+
phase(phase, message) {
|
|
65
|
+
if (!this.enabled) {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
this.phaseNow = phase;
|
|
69
|
+
// Heartbeat only during the phases that can take a long time.
|
|
70
|
+
if (phase === RenderPhase.Loading || phase === RenderPhase.Rendering) {
|
|
71
|
+
this.startHeartbeat();
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
this.stopHeartbeat();
|
|
75
|
+
}
|
|
76
|
+
this.emit(message, true);
|
|
77
|
+
}
|
|
78
|
+
/** Stop the heartbeat and detach page listeners. Safe to call multiple times. */
|
|
79
|
+
dispose() {
|
|
80
|
+
this.stopHeartbeat();
|
|
81
|
+
if (this.page) {
|
|
82
|
+
this.page.off('request', this.onRequest);
|
|
83
|
+
this.page.off('requestfinished', this.onRequestFinished);
|
|
84
|
+
this.page.off('requestfailed', this.onRequestFailed);
|
|
85
|
+
this.page = null;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
startHeartbeat() {
|
|
89
|
+
if (this.heartbeat) {
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
this.heartbeat = setInterval(() => this.emit(), HEARTBEAT_MS);
|
|
93
|
+
// never keep the process alive just to tick progress
|
|
94
|
+
this.heartbeat.unref?.();
|
|
95
|
+
}
|
|
96
|
+
stopHeartbeat() {
|
|
97
|
+
if (this.heartbeat) {
|
|
98
|
+
clearInterval(this.heartbeat);
|
|
99
|
+
this.heartbeat = null;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
computePercent() {
|
|
103
|
+
if (this.phaseNow === RenderPhase.Failed) {
|
|
104
|
+
return this.lastPercent;
|
|
105
|
+
}
|
|
106
|
+
const [start, end] = PHASE_BANDS[this.phaseNow];
|
|
107
|
+
if (this.phaseNow === RenderPhase.Loading) {
|
|
108
|
+
// total is unknown up front; approximate with completed / seen-so-far
|
|
109
|
+
const seen = this.loaded + this.pending;
|
|
110
|
+
const ratio = seen > 0 ? this.loaded / seen : 0;
|
|
111
|
+
return Math.max(this.lastPercent, Math.min(end, Math.round(start + (end - start) * ratio)));
|
|
112
|
+
}
|
|
113
|
+
// milestone phases sit at their band start (Done -> 100); never regress
|
|
114
|
+
return Math.max(this.lastPercent, start);
|
|
115
|
+
}
|
|
116
|
+
emit(message, force = false) {
|
|
117
|
+
if (!this.enabled) {
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
const now = Date.now();
|
|
121
|
+
if (!force && now - this.lastEmitAt < THROTTLE_MS) {
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
this.lastEmitAt = now;
|
|
125
|
+
const percent = this.computePercent();
|
|
126
|
+
this.lastPercent = percent;
|
|
127
|
+
const progress = {
|
|
128
|
+
phase: this.phaseNow,
|
|
129
|
+
percent,
|
|
130
|
+
resourcesLoaded: this.loaded,
|
|
131
|
+
resourcesPending: this.pending,
|
|
132
|
+
resourcesFailed: this.failed,
|
|
133
|
+
elapsedMs: now - this.startedAt,
|
|
134
|
+
filePath: this.filePath,
|
|
135
|
+
message: message ?? this.defaultMessage(),
|
|
136
|
+
};
|
|
137
|
+
// progress must never stall or break a render: don't await, swallow errors
|
|
138
|
+
try {
|
|
139
|
+
const result = this.callback(progress);
|
|
140
|
+
if (result && typeof result.then === 'function') {
|
|
141
|
+
result.catch(() => {
|
|
142
|
+
/* swallow async listener errors */
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
catch {
|
|
147
|
+
/* swallow sync listener errors */
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
defaultMessage() {
|
|
151
|
+
switch (this.phaseNow) {
|
|
152
|
+
case RenderPhase.Starting:
|
|
153
|
+
return 'Starting renderer';
|
|
154
|
+
case RenderPhase.Preparing:
|
|
155
|
+
return 'Preparing HTML';
|
|
156
|
+
case RenderPhase.Loading: {
|
|
157
|
+
const extra = [`${this.loaded} done`];
|
|
158
|
+
if (this.pending)
|
|
159
|
+
extra.push(`${this.pending} pending`);
|
|
160
|
+
if (this.failed)
|
|
161
|
+
extra.push(`${this.failed} failed`);
|
|
162
|
+
return `Loading resources (${extra.join(', ')})`;
|
|
163
|
+
}
|
|
164
|
+
case RenderPhase.Rendering:
|
|
165
|
+
return 'Generating output';
|
|
166
|
+
case RenderPhase.Done:
|
|
167
|
+
return 'Done';
|
|
168
|
+
case RenderPhase.Failed:
|
|
169
|
+
return 'Failed';
|
|
170
|
+
default:
|
|
171
|
+
return '';
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
//# sourceMappingURL=progress.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"progress.js","sourceRoot":"","sources":["../../src/progress.ts"],"names":[],"mappings":"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"}
|