pagespeed-quest 0.9.0 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/build/command.js +23 -3
  2. package/build/docs/assets/css/main.css +1 -0
  3. package/build/docs/assets/images/icons.png +0 -0
  4. package/build/docs/assets/images/icons@2x.png +0 -0
  5. package/build/docs/assets/images/widgets.png +0 -0
  6. package/build/docs/assets/images/widgets@2x.png +0 -0
  7. package/build/docs/assets/js/main.js +51 -0
  8. package/build/docs/classes/inventoryrepository.html +305 -0
  9. package/build/docs/classes/playbackproxy.html +524 -0
  10. package/build/docs/classes/proxy.html +474 -0
  11. package/build/docs/classes/recordingproxy.html +532 -0
  12. package/build/docs/classes/testproxy.html +497 -0
  13. package/build/docs/classes/throttle.html +425 -0
  14. package/build/docs/classes/throttlinglog.html +174 -0
  15. package/build/docs/classes/throttlingtransform.html +6297 -0
  16. package/build/docs/globals.html +1131 -0
  17. package/build/docs/index.html +348 -0
  18. package/build/docs/interfaces/beautifyresult.html +174 -0
  19. package/build/docs/interfaces/contentencodingpair.html +174 -0
  20. package/build/docs/interfaces/inventory.html +174 -0
  21. package/build/docs/interfaces/lighthouseoptions.html +230 -0
  22. package/build/docs/interfaces/playbacktransaction.html +272 -0
  23. package/build/docs/interfaces/proxyoptions.html +423 -0
  24. package/build/docs/interfaces/recordingsession.html +174 -0
  25. package/build/docs/interfaces/recordingtransaction.html +286 -0
  26. package/build/docs/interfaces/resource.html +314 -0
  27. package/build/docs/interfaces/transaction.html +258 -0
  28. package/build/docs/interfaces/withproxyoptions.html +418 -0
  29. package/build/logger.d.ts +2 -0
  30. package/build/logger.js +15 -0
  31. package/build/proxy.d.ts +35 -0
  32. package/build/proxy.js +96 -0
  33. package/build/recording.d.ts +2 -0
  34. package/build/recording.js +125 -8
  35. package/build/throttling.d.ts +33 -0
  36. package/build/throttling.js +89 -0
  37. package/package.json +4 -4
  38. package/scripts/postinstall.js +1 -1
@@ -1,11 +1,58 @@
1
- import { startRecording } from 'rust-http-playback-proxy';
1
+ import { spawn } from 'child_process';
2
+ import { createRequire } from 'module';
3
+ import Net from 'net';
4
+ import Path from 'path';
5
+ import { Proxy as RustProxy, startRecording } from 'rust-http-playback-proxy';
2
6
  import { InventoryRepository } from './inventory.js';
7
+ async function getAvailablePort() {
8
+ return new Promise((resolve, reject) => {
9
+ const server = Net.createServer();
10
+ server.listen(0, '127.0.0.1', () => {
11
+ const address = server.address();
12
+ if (address && typeof address === 'object') {
13
+ const port = address.port;
14
+ server.close(() => resolve(port));
15
+ }
16
+ else {
17
+ server.close(() => reject(new Error('Failed to get port from server address')));
18
+ }
19
+ });
20
+ server.on('error', reject);
21
+ });
22
+ }
23
+ async function waitForPort(port, timeoutMs = 60000) {
24
+ const startTime = Date.now();
25
+ let delay = 50;
26
+ while (Date.now() - startTime < timeoutMs) {
27
+ try {
28
+ await new Promise((resolve, reject) => {
29
+ const socket = Net.createConnection({ port, host: '127.0.0.1' });
30
+ socket.on('connect', () => {
31
+ socket.destroy();
32
+ resolve();
33
+ });
34
+ socket.on('error', reject);
35
+ socket.setTimeout(1000, () => {
36
+ socket.destroy();
37
+ reject(new Error('Connection timeout'));
38
+ });
39
+ });
40
+ return;
41
+ }
42
+ catch {
43
+ await new Promise((resolve) => setTimeout(resolve, delay));
44
+ delay = Math.min(delay * 1.5, 500);
45
+ }
46
+ }
47
+ throw new Error(`Timeout waiting for port ${port} to become available`);
48
+ }
3
49
  export class RecordingProxy {
4
50
  rustProxy;
5
51
  inventoryRepository;
6
52
  entryUrl;
7
53
  deviceType;
8
54
  requestedPort;
55
+ excludePatterns;
9
56
  dependency;
10
57
  constructor(options, dependency) {
11
58
  options ||= {};
@@ -18,16 +65,30 @@ export class RecordingProxy {
18
65
  this.deviceType = options.deviceType;
19
66
  // Port
20
67
  this.requestedPort = options.port;
68
+ // Exclude patterns
69
+ this.excludePatterns = options.excludePatterns;
21
70
  }
22
71
  async start() {
23
72
  this.dependency.logger?.info(`Starting recording proxy...`);
24
73
  const proxyPort = this.requestedPort || 0;
25
- this.rustProxy = await startRecording({
26
- entryUrl: this.entryUrl,
27
- deviceType: this.deviceType,
28
- inventoryDir: this.inventoryRepository.dirPath,
29
- port: proxyPort,
30
- });
74
+ if (this.excludePatterns && this.excludePatterns.length > 0) {
75
+ // Use direct binary spawn to support -x exclude patterns
76
+ this.rustProxy = await startRecordingWithExclude({
77
+ entryUrl: this.entryUrl,
78
+ deviceType: this.deviceType,
79
+ inventoryDir: this.inventoryRepository.dirPath,
80
+ port: proxyPort,
81
+ excludePatterns: this.excludePatterns,
82
+ });
83
+ }
84
+ else {
85
+ this.rustProxy = await startRecording({
86
+ entryUrl: this.entryUrl,
87
+ deviceType: this.deviceType,
88
+ inventoryDir: this.inventoryRepository.dirPath,
89
+ port: proxyPort,
90
+ });
91
+ }
31
92
  this.dependency.logger?.info(`Recording proxy started on port ${this.rustProxy.port}`);
32
93
  }
33
94
  get port() {
@@ -51,6 +112,62 @@ export class RecordingProxy {
51
112
  }
52
113
  }
53
114
  }
115
+ function getProxyBinaryPath() {
116
+ const require = createRequire(import.meta.url);
117
+ // Resolve the main entry point (which is allowed by exports) and derive package root
118
+ const mainPath = require.resolve('rust-http-playback-proxy');
119
+ // mainPath is like .../node_modules/rust-http-playback-proxy/dist/index.js
120
+ const pkgDir = Path.resolve(Path.dirname(mainPath), '..');
121
+ const platform = process.platform === 'win32' ? 'windows' : process.platform;
122
+ const arch = process.arch;
123
+ const ext = process.platform === 'win32' ? '.exe' : '';
124
+ return Path.join(pkgDir, 'bin', `${platform}-${arch}`, `http-playback-proxy${ext}`);
125
+ }
126
+ async function startRecordingWithExclude(options) {
127
+ const binaryPath = getProxyBinaryPath();
128
+ let port;
129
+ if (options.port === undefined || options.port === 0) {
130
+ port = await getAvailablePort();
131
+ }
132
+ else {
133
+ port = options.port;
134
+ }
135
+ const deviceType = options.deviceType || 'mobile';
136
+ const inventoryDir = options.inventoryDir || './inventory';
137
+ const args = ['recording'];
138
+ if (options.entryUrl) {
139
+ args.push(options.entryUrl);
140
+ }
141
+ args.push('--port', port.toString());
142
+ args.push('--device', deviceType);
143
+ args.push('--inventory', inventoryDir);
144
+ for (const pattern of options.excludePatterns) {
145
+ args.push('--exclude', pattern);
146
+ }
147
+ const proc = spawn(binaryPath, args, {
148
+ stdio: ['ignore', 'inherit', 'inherit'],
149
+ detached: false,
150
+ });
151
+ const proxy = new RustProxy('recording', port, inventoryDir, options.entryUrl, deviceType);
152
+ proxy.setProcess(proc);
153
+ let exited = false;
154
+ proc.on('exit', (code) => {
155
+ exited = true;
156
+ if (code !== 0 && code !== null) {
157
+ console.error(`Proxy process exited early with code ${code}`);
158
+ }
159
+ });
160
+ try {
161
+ await waitForPort(port, 15000);
162
+ }
163
+ catch (err) {
164
+ if (exited) {
165
+ throw new Error('Proxy process exited before port became available');
166
+ }
167
+ throw err;
168
+ }
169
+ return proxy;
170
+ }
54
171
  export async function withRecordingProxy(options, dependency, cb) {
55
172
  const proxy = new RecordingProxy(options, dependency);
56
173
  await proxy.start();
@@ -61,4 +178,4 @@ export async function withRecordingProxy(options, dependency, cb) {
61
178
  await proxy.stop();
62
179
  }
63
180
  }
64
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVjb3JkaW5nLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3JlY29yZGluZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQXNCLGNBQWMsRUFBRSxNQUFNLDBCQUEwQixDQUFBO0FBRTdFLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLGdCQUFnQixDQUFBO0FBWXBELE1BQU0sT0FBTyxjQUFjO0lBQ3pCLFNBQVMsQ0FBWTtJQUNyQixtQkFBbUIsQ0FBc0I7SUFDekMsUUFBUSxDQUFTO0lBQ2pCLFVBQVUsQ0FBYTtJQUN2QixhQUFhLENBQVM7SUFDdEIsVUFBVSxDQUEwQjtJQUVwQyxZQUFZLE9BQStCLEVBQUUsVUFBcUM7UUFDaEYsT0FBTyxLQUFLLEVBQUUsQ0FBQTtRQUNkLElBQUksQ0FBQyxVQUFVLEdBQUcsVUFBVSxJQUFJLEVBQUUsQ0FBQTtRQUVsQyx1QkFBdUI7UUFDdkIsSUFBSSxDQUFDLG1CQUFtQixHQUFHLE9BQU8sQ0FBQyxtQkFBbUIsSUFBSSxJQUFJLG1CQUFtQixDQUFDLFNBQVMsRUFBRSxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUE7UUFFN0csWUFBWTtRQUNaLElBQUksQ0FBQyxRQUFRLEdBQUcsT0FBTyxDQUFDLFFBQVEsQ0FBQTtRQUVoQyxjQUFjO1FBQ2QsSUFBSSxDQUFDLFVBQVUsR0FBRyxPQUFPLENBQUMsVUFBVSxDQUFBO1FBRXBDLE9BQU87UUFDUCxJQUFJLENBQUMsYUFBYSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUE7SUFDbkMsQ0FBQztJQUVELEtBQUssQ0FBQyxLQUFLO1FBQ1QsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLDZCQUE2QixDQUFDLENBQUE7UUFFM0QsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLGFBQWEsSUFBSSxDQUFDLENBQUE7UUFFekMsSUFBSSxDQUFDLFNBQVMsR0FBRyxNQUFNLGNBQWMsQ0FBQztZQUNwQyxRQUFRLEVBQUUsSUFBSSxDQUFDLFFBQVE7WUFDdkIsVUFBVSxFQUFFLElBQUksQ0FBQyxVQUFVO1lBQzNCLFlBQVksRUFBRSxJQUFJLENBQUMsbUJBQW1CLENBQUMsT0FBTztZQUM5QyxJQUFJLEVBQUUsU0FBUztTQUNoQixDQUFDLENBQUE7UUFFRixJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsbUNBQW1DLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQTtJQUN4RixDQUFDO0lBRUQsSUFBSSxJQUFJO1FBQ04sSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTO1lBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQyxtQkFBbUIsQ0FBQyxDQUFBO1FBQ3pELE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUE7SUFDNUIsQ0FBQztJQUVELElBQUksZ0JBQWdCO1FBQ2xCLE9BQU8sSUFBSSxDQUFDLG1CQUFtQixDQUFDLE9BQU8sQ0FBQTtJQUN6QyxDQUFDO0lBRUQsS0FBSyxDQUFDLElBQUk7UUFDUixJQUFJLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztZQUNuQixJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsNkJBQTZCLENBQUMsQ0FBQTtZQUUzRCxzRUFBc0U7WUFDdEUsNkVBQTZFO1lBQzdFLE1BQU0sSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLEVBQUUsQ0FBQTtZQUUzQiwwREFBMEQ7WUFDMUQscUVBQXFFO1lBQ3JFLE1BQU0sSUFBSSxPQUFPLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDLFVBQVUsQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQTtZQUV6RCxJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMseUJBQXlCLENBQUMsQ0FBQTtRQUN6RCxDQUFDO0lBQ0gsQ0FBQztDQUNGO0FBRUQsTUFBTSxDQUFDLEtBQUssVUFBVSxrQkFBa0IsQ0FDdEMsT0FBOEIsRUFDOUIsVUFBb0MsRUFDcEMsRUFBNEM7SUFFNUMsTUFBTSxLQUFLLEdBQUcsSUFBSSxjQUFjLENBQUMsT0FBTyxFQUFFLFVBQVUsQ0FBQyxDQUFBO0lBQ3JELE1BQU0sS0FBSyxDQUFDLEtBQUssRUFBRSxDQUFBO0lBQ25CLElBQUksQ0FBQztRQUNILE1BQU0sRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFBO0lBQ2pCLENBQUM7WUFBUyxDQUFDO1FBQ1QsTUFBTSxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUE7SUFDcEIsQ0FBQztBQUNILENBQUMifQ==
181
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVjb3JkaW5nLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3JlY29yZGluZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0sZUFBZSxDQUFBO0FBQ3JDLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxRQUFRLENBQUE7QUFDdEMsT0FBTyxHQUFHLE1BQU0sS0FBSyxDQUFBO0FBQ3JCLE9BQU8sSUFBSSxNQUFNLE1BQU0sQ0FBQTtBQUV2QixPQUFPLEVBQUUsS0FBSyxJQUFJLFNBQVMsRUFBRSxjQUFjLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQTtBQUU3RSxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQTtBQWFwRCxLQUFLLFVBQVUsZ0JBQWdCO0lBQzdCLE9BQU8sSUFBSSxPQUFPLENBQUMsQ0FBQyxPQUFPLEVBQUUsTUFBTSxFQUFFLEVBQUU7UUFDckMsTUFBTSxNQUFNLEdBQUcsR0FBRyxDQUFDLFlBQVksRUFBRSxDQUFBO1FBQ2pDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUFFLFdBQVcsRUFBRSxHQUFHLEVBQUU7WUFDakMsTUFBTSxPQUFPLEdBQUcsTUFBTSxDQUFDLE9BQU8sRUFBRSxDQUFBO1lBQ2hDLElBQUksT0FBTyxJQUFJLE9BQU8sT0FBTyxLQUFLLFFBQVEsRUFBRSxDQUFDO2dCQUMzQyxNQUFNLElBQUksR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFBO2dCQUN6QixNQUFNLENBQUMsS0FBSyxDQUFDLEdBQUcsRUFBRSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFBO1lBQ25DLENBQUM7aUJBQU0sQ0FBQztnQkFDTixNQUFNLENBQUMsS0FBSyxDQUFDLEdBQUcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEtBQUssQ0FBQyx3Q0FBd0MsQ0FBQyxDQUFDLENBQUMsQ0FBQTtZQUNqRixDQUFDO1FBQ0gsQ0FBQyxDQUFDLENBQUE7UUFD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
@@ -0,0 +1,33 @@
1
+ /// <reference types="node" />
2
+ /// <reference types="node" />
3
+ import { Transform, TransformCallback } from 'stream';
4
+ export declare class ThrottlingLog {
5
+ ms: number;
6
+ bytes: number;
7
+ }
8
+ export declare class Throttle {
9
+ flushIntervalMs: number;
10
+ limitBytes: number;
11
+ currentBytes: number;
12
+ interval?: ReturnType<typeof setInterval>;
13
+ logs: ThrottlingLog[];
14
+ constructor(limitBytes: number, flushIntervalMs?: number);
15
+ static fromMbps(mbps: number, flushIntervalMs?: number): Throttle;
16
+ computeCapacity(): {
17
+ consumed: number;
18
+ carryover: number;
19
+ };
20
+ start(): void;
21
+ stop(): void;
22
+ checkAndStack(bytes: number): boolean;
23
+ simpleReport(unitMs?: number): {
24
+ maxBytesPerUnit: number;
25
+ avgBytesPerUnit: number;
26
+ };
27
+ }
28
+ export declare class ThrottlingTransform extends Transform {
29
+ throttle: Throttle;
30
+ retryIntervalMs: number;
31
+ constructor(throttle: Throttle, retryIntervalMs: number);
32
+ _transform(chunk: string | Buffer, _: string, done: TransformCallback): void;
33
+ }
@@ -0,0 +1,89 @@
1
+ import { Transform } from 'stream';
2
+ export class ThrottlingLog {
3
+ ms;
4
+ bytes;
5
+ }
6
+ export class Throttle {
7
+ flushIntervalMs;
8
+ limitBytes;
9
+ currentBytes = 0;
10
+ interval;
11
+ logs = [];
12
+ constructor(limitBytes, flushIntervalMs) {
13
+ this.limitBytes = limitBytes;
14
+ this.flushIntervalMs = flushIntervalMs ?? 100;
15
+ }
16
+ static fromMbps(mbps, flushIntervalMs) {
17
+ const bytesPerSec = (mbps * 1024 * 1024) / 8;
18
+ const limitBytes = Math.floor((bytesPerSec * flushIntervalMs) / 1000);
19
+ return new Throttle(limitBytes, flushIntervalMs);
20
+ }
21
+ computeCapacity() {
22
+ const consumed = Math.min(this.currentBytes, this.limitBytes);
23
+ const carryover = this.currentBytes - consumed;
24
+ return { consumed, carryover };
25
+ }
26
+ start() {
27
+ this.interval = setInterval(() => {
28
+ const c = this.computeCapacity();
29
+ this.logs.push({
30
+ ms: Date.now(),
31
+ bytes: c.consumed,
32
+ });
33
+ this.currentBytes = c.carryover;
34
+ }, this.flushIntervalMs);
35
+ }
36
+ stop() {
37
+ if (this.interval)
38
+ clearInterval(this.interval);
39
+ }
40
+ checkAndStack(bytes) {
41
+ if (!this.interval)
42
+ throw new Error('Throttle is not started');
43
+ if (this.currentBytes >= this.limitBytes) {
44
+ return false;
45
+ }
46
+ this.currentBytes += bytes;
47
+ return true;
48
+ }
49
+ simpleReport(unitMs = 1000) {
50
+ const bySec = new Map();
51
+ for (const log of this.logs) {
52
+ const unit = Math.floor(log.ms / unitMs);
53
+ if (!bySec.has(unit))
54
+ bySec.set(unit, 0);
55
+ bySec.set(unit, bySec.get(unit) + log.bytes);
56
+ }
57
+ const values = Array.from(bySec.values());
58
+ const maxBytesPerUnit = Math.max(...values);
59
+ const avgBytesPerUnit = Math.floor(values.reduce((a, b) => a + b, 0) / bySec.size) / 1024 / 1024;
60
+ return {
61
+ maxBytesPerUnit,
62
+ avgBytesPerUnit,
63
+ };
64
+ }
65
+ }
66
+ export class ThrottlingTransform extends Transform {
67
+ throttle;
68
+ retryIntervalMs;
69
+ constructor(throttle, retryIntervalMs) {
70
+ super();
71
+ this.throttle = throttle;
72
+ this.retryIntervalMs = retryIntervalMs;
73
+ }
74
+ _transform(chunk, _, done) {
75
+ if (this.throttle.checkAndStack(chunk.length)) {
76
+ this.push(chunk);
77
+ done();
78
+ return;
79
+ }
80
+ const interval = setInterval(() => {
81
+ if (this.throttle.checkAndStack(chunk.length)) {
82
+ clearInterval(interval);
83
+ this.push(chunk);
84
+ done();
85
+ }
86
+ });
87
+ }
88
+ }
89
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGhyb3R0bGluZy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy90aHJvdHRsaW5nLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQXFCLE1BQU0sUUFBUSxDQUFBO0FBRXJELE1BQU0sT0FBTyxhQUFhO0lBQ3hCLEVBQUUsQ0FBUTtJQUNWLEtBQUssQ0FBUTtDQUNkO0FBRUQsTUFBTSxPQUFPLFFBQVE7SUFDbkIsZUFBZSxDQUFTO0lBQ3hCLFVBQVUsQ0FBUztJQUNuQixZQUFZLEdBQUcsQ0FBQyxDQUFBO0lBQ2hCLFFBQVEsQ0FBaUM7SUFDekMsSUFBSSxHQUFvQixFQUFFLENBQUE7SUFFMUIsWUFBWSxVQUFrQixFQUFFLGVBQXdCO1FBQ3RELElBQUksQ0FBQyxVQUFVLEdBQUcsVUFBVSxDQUFBO1FBQzVCLElBQUksQ0FBQyxlQUFlLEdBQUcsZUFBZSxJQUFJLEdBQUcsQ0FBQTtJQUMvQyxDQUFDO0lBRUQsTUFBTSxDQUFDLFFBQVEsQ0FBQyxJQUFZLEVBQUUsZUFBd0I7UUFDcEQsTUFBTSxXQUFXLEdBQUcsQ0FBQyxJQUFJLEdBQUcsSUFBSSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQTtRQUM1QyxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsV0FBVyxHQUFHLGVBQWUsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFBO1FBQ3JFLE9BQU8sSUFBSSxRQUFRLENBQUMsVUFBVSxFQUFFLGVBQWUsQ0FBQyxDQUFBO0lBQ2xELENBQUM7SUFFRCxlQUFlO1FBQ2IsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQTtRQUM3RCxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsWUFBWSxHQUFHLFFBQVEsQ0FBQTtRQUM5QyxPQUFPLEVBQUUsUUFBUSxFQUFFLFNBQVMsRUFBRSxDQUFBO0lB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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pagespeed-quest",
3
- "version": "0.9.0",
3
+ "version": "0.10.0",
4
4
  "type": "module",
5
5
  "description": "A framework for efficient web front-end speed improvement",
6
6
  "main": "build/index.js",
@@ -50,21 +50,21 @@
50
50
  "postinstall": "node scripts/postinstall.js"
51
51
  },
52
52
  "engines": {
53
- "node": ">=18"
53
+ "node": ">=22"
54
54
  },
55
55
  "dependencies": {
56
56
  "commander": "^11.1.0",
57
57
  "execa": "^9.3.1",
58
58
  "iconv-lite": "^0.6.3",
59
59
  "jschardet": "^3.0.0",
60
- "lighthouse": "^12.2.1",
60
+ "lighthouse": "^13.0.3",
61
61
  "node-html-to-image": "^5.0.0",
62
62
  "node-watch": "^0.7.4",
63
63
  "pino": "^9.4.0",
64
64
  "pino-pretty": "^11.2.2",
65
65
  "prettier": "^2.1.1",
66
66
  "puppeteer": "^24.31.0",
67
- "rust-http-playback-proxy": "^0.7.1",
67
+ "rust-http-playback-proxy": "0.9.0",
68
68
  "tmp-promise": "^3.0.3"
69
69
  },
70
70
  "devDependencies": {
@@ -10,7 +10,7 @@ import { dirname, join } from 'path'
10
10
  const __filename = fileURLToPath(import.meta.url)
11
11
  const __dirname = dirname(__filename)
12
12
 
13
- const LOADSHOW_VERSION = 'v1.4.0'
13
+ const LOADSHOW_VERSION = 'v1.5.0'
14
14
  const LOADSHOW_REPO = 'ideamans/go-loadshow'
15
15
 
16
16
  const WEBSHOT_VERSION = 'v0.2.1'