pagespeed-quest 0.5.0 → 0.6.2

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/build/adhoc.js CHANGED
@@ -27,5 +27,5 @@ export async function playback() {
27
27
  await execLighthouse({ url: proxy.entryUrl, proxyPort: proxy.port, headless: false, timeout: 60000 }, dependency);
28
28
  });
29
29
  }
30
- playback();
31
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWRob2MuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvYWRob2MudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxHQUFHLE1BQU0sYUFBYSxDQUFBO0FBRTdCLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQTtBQUM1QyxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQTtBQUNwRCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0saUJBQWlCLENBQUE7QUFDaEQsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sZUFBZSxDQUFBO0FBQ2pELE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLGdCQUFnQixDQUFBO0FBRW5ELE1BQU0sVUFBVSxHQUFHLElBQUksVUFBVSxFQUFFLENBQUE7QUFFbkMsTUFBTSxDQUFDLEtBQUssVUFBVSxTQUFTO0lBQzdCLE1BQU0sU0FBUyxHQUFHLCtCQUErQixDQUFBO0lBQ2pELGlEQUFpRDtJQUVqRCxNQUFNLEdBQUcsQ0FBQyxLQUFLLENBQUMsT0FBTyxFQUFFLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUE7SUFDN0MsTUFBTSxtQkFBbUIsR0FBRyxJQUFJLG1CQUFtQixDQUFDLE9BQU8sRUFBRSxVQUFVLENBQUMsQ0FBQTtJQUN4RSxNQUFNLGtCQUFrQixDQUN0QjtRQUNFLG1CQUFtQjtLQUNwQixFQUNELFVBQVUsRUFDVixLQUFLLEVBQUUsS0FBSyxFQUFFLEVBQUU7UUFDZCxLQUFLLENBQUMsUUFBUSxHQUFHLFNBQVMsQ0FBQTtRQUMxQixNQUFNLGNBQWMsQ0FBQyxFQUFFLEdBQUcsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLEtBQUssQ0FBQyxJQUFJLEVBQUUsUUFBUSxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLEVBQUUsVUFBVSxDQUFDLENBQUE7SUFDOUcsQ0FBQyxDQUNGLENBQUE7QUFDSCxDQUFDO0FBRUQsTUFBTSxDQUFDLEtBQUssVUFBVSxRQUFRO0lBQzVCLE1BQU0sbUJBQW1CLEdBQUcsSUFBSSxtQkFBbUIsQ0FBQyxPQUFPLEVBQUUsVUFBVSxDQUFDLENBQUE7SUFDeEUsTUFBTSxpQkFBaUIsQ0FDckI7UUFDRSxtQkFBbUI7S0FDcEIsRUFDRCxVQUFVLEVBQ1YsS0FBSyxFQUFFLEtBQUssRUFBRSxFQUFFO1FBQ2QsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRO1lBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQyx5QkFBeUIsQ0FBQyxDQUFBO1FBQy9ELE1BQU0sY0FBYyxDQUFDLEVBQUUsR0FBRyxFQUFFLEtBQUssQ0FBQyxRQUFRLEVBQUUsU0FBUyxFQUFFLEtBQUssQ0FBQyxJQUFJLEVBQUUsUUFBUSxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLEVBQUUsVUFBVSxDQUFDLENBQUE7SUFDbkgsQ0FBQyxDQUNGLENBQUE7QUFDSCxDQUFDO0FBRUQsUUFBUSxFQUFFLENBQUEifQ==
30
+ recording().then(playback);
31
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWRob2MuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvYWRob2MudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxHQUFHLE1BQU0sYUFBYSxDQUFBO0FBRTdCLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQTtBQUM1QyxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQTtBQUNwRCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0saUJBQWlCLENBQUE7QUFDaEQsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sZUFBZSxDQUFBO0FBQ2pELE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLGdCQUFnQixDQUFBO0FBRW5ELE1BQU0sVUFBVSxHQUFHLElBQUksVUFBVSxFQUFFLENBQUE7QUFFbkMsTUFBTSxDQUFDLEtBQUssVUFBVSxTQUFTO0lBQzdCLE1BQU0sU0FBUyxHQUFHLCtCQUErQixDQUFBO0lBQ2pELGlEQUFpRDtJQUVqRCxNQUFNLEdBQUcsQ0FBQyxLQUFLLENBQUMsT0FBTyxFQUFFLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUE7SUFDN0MsTUFBTSxtQkFBbUIsR0FBRyxJQUFJLG1CQUFtQixDQUFDLE9BQU8sRUFBRSxVQUFVLENBQUMsQ0FBQTtJQUN4RSxNQUFNLGtCQUFrQixDQUN0QjtRQUNFLG1CQUFtQjtLQUNwQixFQUNELFVBQVUsRUFDVixLQUFLLEVBQUUsS0FBSyxFQUFFLEVBQUU7UUFDZCxLQUFLLENBQUMsUUFBUSxHQUFHLFNBQVMsQ0FBQTtRQUMxQixNQUFNLGNBQWMsQ0FBQyxFQUFFLEdBQUcsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLEtBQUssQ0FBQyxJQUFJLEVBQUUsUUFBUSxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLEVBQUUsVUFBVSxDQUFDLENBQUE7SUFDOUcsQ0FBQyxDQUNGLENBQUE7QUFDSCxDQUFDO0FBRUQsTUFBTSxDQUFDLEtBQUssVUFBVSxRQUFRO0lBQzVCLE1BQU0sbUJBQW1CLEdBQUcsSUFBSSxtQkFBbUIsQ0FBQyxPQUFPLEVBQUUsVUFBVSxDQUFDLENBQUE7SUFDeEUsTUFBTSxpQkFBaUIsQ0FDckI7UUFDRSxtQkFBbUI7S0FDcEIsRUFDRCxVQUFVLEVBQ1YsS0FBSyxFQUFFLEtBQUssRUFBRSxFQUFFO1FBQ2QsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRO1lBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQyx5QkFBeUIsQ0FBQyxDQUFBO1FBQy9ELE1BQU0sY0FBYyxDQUFDLEVBQUUsR0FBRyxFQUFFLEtBQUssQ0FBQyxRQUFRLEVBQUUsU0FBUyxFQUFFLEtBQUssQ0FBQyxJQUFJLEVBQUUsUUFBUSxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLEVBQUUsVUFBVSxDQUFDLENBQUE7SUFDbkgsQ0FBQyxDQUNGLENBQUE7QUFDSCxDQUFDO0FBRUQsU0FBUyxFQUFFLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFBIn0=
package/build/command.js CHANGED
@@ -33,7 +33,6 @@ function registerLighthouseCommands(main) {
33
33
  url,
34
34
  proxyPort: proxy.port,
35
35
  deviceType,
36
- noThrottling: true,
37
36
  view: false,
38
37
  artifactsDir,
39
38
  headless: quiet,
@@ -88,10 +87,8 @@ function registerLoadshowCommands(main) {
88
87
  });
89
88
  const playback = loadshow.command('playback');
90
89
  playback.description('Playback contents for loadshow');
91
- playback.option('-l, --lighthouse', 'Loadshow with lighthouse throttling');
92
90
  playback.action(async () => {
93
91
  const inventoryRepository = new InventoryRepository(main.opts().inventory || './inventory');
94
- const lighthouse = playback.opts().lighthouse;
95
92
  const artifactsDir = loadshow.opts().artifacts || './artifacts';
96
93
  const credit = loadshow.opts().credit || '';
97
94
  const timeout = Number(loadshow.opts().timeout || '30000');
@@ -102,7 +99,6 @@ function registerLoadshowCommands(main) {
102
99
  url: proxy.entryUrl,
103
100
  proxyPort: proxy.port,
104
101
  deviceType: proxy.deviceType,
105
- syncLighthouseSpec: lighthouse,
106
102
  artifactsDir,
107
103
  credit,
108
104
  timeout,
@@ -117,18 +113,15 @@ function registerProxyCommands(main) {
117
113
  proxy.option('-r, --record <url>', 'Recording URL to start the proxy as recording mode', '');
118
114
  proxy.action(async () => {
119
115
  const inventoryRepository = new InventoryRepository(main.opts().inventory || './inventory');
120
- const proxyOptions = {
121
- inventoryRepository,
122
- port: Number(proxy.opts().port || '8080'),
123
- };
116
+ const port = Number(proxy.opts().port || '8080');
124
117
  if (proxy.opts().record) {
125
118
  const url = proxy.opts().record;
126
119
  if (!url) {
127
120
  throw new Error('Recording URL must be specified with --record option.');
128
121
  }
129
122
  // Recordingモード
130
- await withRecordingProxy({ ...proxyOptions, entryUrl: url }, dependency, async () => {
131
- dependency.logger?.info(`Recording proxy started on port ${proxyOptions.port}. Press Ctrl+C to stop.`);
123
+ await withRecordingProxy({ inventoryRepository, port, entryUrl: url }, dependency, async () => {
124
+ dependency.logger?.info(`Recording proxy started on port ${port}. Press Ctrl+C to stop.`);
132
125
  // Wait for Ctrl+C signal
133
126
  return new Promise((resolve) => {
134
127
  process.on('SIGINT', () => {
@@ -142,7 +135,7 @@ function registerProxyCommands(main) {
142
135
  // Playbackモード
143
136
  // eslint-disable-next-line no-constant-condition
144
137
  while (true) {
145
- await withPlaybackProxy(proxyOptions, dependency, async () => {
138
+ await withPlaybackProxy({ inventoryRepository, port }, dependency, async () => {
146
139
  const watcher = Watch(inventoryRepository.dirPath, { recursive: true });
147
140
  return new Promise((ok) => {
148
141
  watcher.on('change', () => {
@@ -160,4 +153,4 @@ registerLighthouseCommands(main);
160
153
  registerLoadshowCommands(main);
161
154
  registerProxyCommands(main);
162
155
  main.parse(process.argv);
163
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tbWFuZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9jb21tYW5kLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFFQSxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sV0FBVyxDQUFBO0FBQ25DLE9BQU8sS0FBSyxNQUFNLFlBQVksQ0FBQTtBQUU5QixPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0saUJBQWlCLENBQUE7QUFDNUMsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLGlCQUFpQixDQUFBO0FBQ2hELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxlQUFlLENBQUE7QUFHNUMsT0FBTyxFQUFFLG1CQUFtQixFQUFnQixpQkFBaUIsRUFBRSxrQkFBa0IsRUFBRSxNQUFNLFlBQVksQ0FBQTtBQUVyRyxNQUFNLFVBQVUsR0FBRyxJQUFJLFVBQVUsRUFBRSxDQUFBO0FBRW5DLE1BQU0sSUFBSSxHQUFHLElBQUksT0FBTyxFQUFFLENBQUE7QUFDMUIsSUFBSSxDQUFDLE1BQU0sQ0FBQyx1QkFBdUIsRUFBRSxxQkFBcUIsRUFBRSxhQUFhLENBQUMsQ0FBQTtBQUUxRSxTQUFTLDBCQUEwQixDQUFDLElBQWE7SUFDL0MsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsQ0FBQTtJQUM3QyxVQUFVLENBQUMsV0FBVyxDQUFDLG1EQUFtRCxDQUFDLENBQUE7SUFDM0UsVUFBVSxDQUFDLE1BQU0sQ0FBQyx1QkFBdUIsRUFBRSxxQkFBcUIsRUFBRSxhQUFhLENBQUMsQ0FBQTtJQUNoRixVQUFVLENBQUMsTUFBTSxDQUFDLGFBQWEsRUFBRSxjQUFjLEVBQUUsS0FBSyxDQUFDLENBQUE7SUFDdkQsVUFBVSxDQUFDLE1BQU0sQ0FBQyxvQkFBb0IsRUFBRSxzQkFBc0IsRUFBRSxPQUFPLENBQUMsQ0FBQTtJQUV4RSxNQUFNLFNBQVMsR0FBRyxVQUFVLENBQUMsT0FBTyxDQUFDLFdBQVcsQ0FBQyxDQUFBO0lBQ2pELFNB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
156
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tbWFuZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9jb21tYW5kLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFFQSxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sV0FBVyxDQUFBO0FBQ25DLE9BQU8sS0FBSyxNQUFNLFlBQVksQ0FBQTtBQUU5QixPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0saUJBQWlCLENBQUE7QUFDNUMsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLGlCQUFpQixDQUFBO0FBQ2hELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxlQUFlLENBQUE7QUFHNUMsT0FBTyxFQUFFLG1CQUFtQixFQUFFLGlCQUFpQixFQUFFLGtCQUFrQixFQUFFLE1BQU0sWUFBWSxDQUFBO0FBRXZGLE1BQU0sVUFBVSxHQUFHLElBQUksVUFBVSxFQUFFLENBQUE7QUFFbkMsTUFBTSxJQUFJLEdBQUcsSUFBSSxPQUFPLEVBQUUsQ0FBQTtBQUMxQixJQUFJLENBQUMsTUFBTSxDQUFDLHVCQUF1QixFQUFFLHFCQUFxQixFQUFFLGFBQWEsQ0FBQyxDQUFBO0FBRTFFLFNBQVMsMEJBQTBCLENBQUMsSUFBYTtJQUMvQyxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLFlBQVksQ0FBQyxDQUFBO0lBQzdDLFVBQVUsQ0FBQyxXQUFXLENBQUMsbURBQW1ELENBQUMsQ0FBQTtJQUMzRSxVQUFVLENBQUMsTUFBTSxDQUFDLHVCQUF1QixFQUFFLHFCQUFxQixFQUFFLGFBQWEsQ0FBQyxDQUFBO0lBQ2hGLFVBQVUsQ0FBQyxNQUFNLENBQUMsYUFBYSxFQUFFLGNBQWMsRUFBRSxLQUFLLENBQUMsQ0FBQTtJQUN2RCxVQUFVLENBQUMsTUFBTSxDQUFDLG9CQUFvQixFQUFFLHNCQUFzQixFQUFFLE9BQU8sQ0FBQyxDQUFBO0lBRXhFLE1BQU0sU0FBUyxHQUFHLFVBQVUsQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLENBQUE7SUFDakQsU0FB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
package/build/index.d.ts CHANGED
@@ -4,9 +4,8 @@ export * from './formatting.js';
4
4
  export * from './http.js';
5
5
  export * from './inventory.js';
6
6
  export * from './playback.js';
7
- export * from './proxy.js';
8
7
  export * from './recording.js';
9
- export * from './throttling.js';
10
8
  export * from './types.js';
11
9
  export * from './lighthouse.js';
10
+ export * from './lighthouse-digest.js';
12
11
  export * from './loadshow.js';
package/build/index.js CHANGED
@@ -4,10 +4,9 @@ export * from './formatting.js';
4
4
  export * from './http.js';
5
5
  export * from './inventory.js';
6
6
  export * from './playback.js';
7
- export * from './proxy.js';
8
7
  export * from './recording.js';
9
- export * from './throttling.js';
10
8
  export * from './types.js';
11
9
  export * from './lighthouse.js';
10
+ export * from './lighthouse-digest.js';
12
11
  export * from './loadshow.js';
13
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsY0FBYyxpQkFBaUIsQ0FBQTtBQUMvQixjQUFjLGVBQWUsQ0FBQTtBQUM3QixjQUFjLGlCQUFpQixDQUFBO0FBQy9CLGNBQWMsV0FBVyxDQUFBO0FBQ3pCLGNBQWMsZ0JBQWdCLENBQUE7QUFDOUIsY0FBYyxlQUFlLENBQUE7QUFDN0IsY0FBYyxZQUFZLENBQUE7QUFDMUIsY0FBYyxnQkFBZ0IsQ0FBQTtBQUM5QixjQUFjLGlCQUFpQixDQUFBO0FBQy9CLGNBQWMsWUFBWSxDQUFBO0FBQzFCLGNBQWMsaUJBQWlCLENBQUE7QUFDL0IsY0FBYyxlQUFlLENBQUEifQ==
12
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsY0FBYyxpQkFBaUIsQ0FBQTtBQUMvQixjQUFjLGVBQWUsQ0FBQTtBQUM3QixjQUFjLGlCQUFpQixDQUFBO0FBQy9CLGNBQWMsV0FBVyxDQUFBO0FBQ3pCLGNBQWMsZ0JBQWdCLENBQUE7QUFDOUIsY0FBYyxlQUFlLENBQUE7QUFDN0IsY0FBYyxnQkFBZ0IsQ0FBQTtBQUM5QixjQUFjLFlBQVksQ0FBQTtBQUMxQixjQUFjLGlCQUFpQixDQUFBO0FBQy9CLGNBQWMsd0JBQXdCLENBQUE7QUFDdEMsY0FBYyxlQUFlLENBQUEifQ==
@@ -6,6 +6,7 @@ import { convertEditableText, isText } from './formatting.js';
6
6
  import { parseContentTypeHeader, requestContentFilePath, stringifyContentTypeHeader } from './http.js';
7
7
  const InventoryDir = 'inventory';
8
8
  const IndexFile = 'index.json';
9
+ const InventoryFile = 'inventory.json'; // Rust proxy uses this name
9
10
  export class InventoryRepository {
10
11
  dirPath;
11
12
  dependency;
@@ -16,12 +17,25 @@ export class InventoryRepository {
16
17
  async saveInventory(inventory) {
17
18
  const inventoryJson = JSON.stringify(inventory, null, 2);
18
19
  await Fsp.mkdir(this.dirPath, { recursive: true });
20
+ // Save as both index.json (legacy) and inventory.json (Rust proxy)
19
21
  await Fsp.writeFile(Path.join(this.dirPath, IndexFile), inventoryJson);
22
+ await Fsp.writeFile(Path.join(this.dirPath, InventoryFile), inventoryJson);
20
23
  }
21
24
  async loadInventory() {
22
- const inventoryJson = await Fsp.readFile(Path.join(this.dirPath, IndexFile), 'utf8');
23
- const inventory = JSON.parse(inventoryJson);
24
- return inventory;
25
+ // Try inventory.json first (Rust proxy), fallback to index.json (legacy)
26
+ let inventoryPath = Path.join(this.dirPath, InventoryFile);
27
+ try {
28
+ const inventoryJson = await Fsp.readFile(inventoryPath, 'utf8');
29
+ const inventory = JSON.parse(inventoryJson);
30
+ return inventory;
31
+ }
32
+ catch {
33
+ // Fallback to index.json
34
+ inventoryPath = Path.join(this.dirPath, IndexFile);
35
+ const inventoryJson = await Fsp.readFile(inventoryPath, 'utf8');
36
+ const inventory = JSON.parse(inventoryJson);
37
+ return inventory;
38
+ }
25
39
  }
26
40
  async saveTransactions(transactions) {
27
41
  // To keep transactions order in Promise.all,
@@ -172,4 +186,4 @@ export class InventoryRepository {
172
186
  return transactions;
173
187
  }
174
188
  }
175
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW52ZW50b3J5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2ludmVudG9yeS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsTUFBTSxJQUFJLENBQUE7QUFDbkIsT0FBTyxHQUFHLE1BQU0sYUFBYSxDQUFBO0FBQzdCLE9BQU8sSUFBSSxNQUFNLE1BQU0sQ0FBQTtBQUV2QixPQUFPLEVBQUUsUUFBUSxFQUF1QixVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUE7QUFDekUsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sRUFBRSxNQUFNLGlCQUFpQixDQUFBO0FBQzdELE9BQU8sRUFBZSxzQkFBc0IsRUFBRSxzQkFBc0IsRUFBRSwwQkFBMEIsRUFBRSxNQUFNLFdBQVcsQ0FBQTtBQUduSCxNQUFNLFlBQVksR0FBRyxXQUFXLENBQUE7QUFDaEMsTUFBTSxTQUFTLEdBQUcsWUFBWSxDQUFBO0FBc0M5QixNQUFNLE9BQU8sbUJBQW1CO0lBQzlCLE9BQU8sQ0FBUztJQUNoQixVQUFVLENBQStCO0lBRXpDLFlBQVksT0FBZ0IsRUFBRSxVQUEwQztRQUN0RSxJQUFJLENBQUMsT0FBTyxHQUFHLE9BQU8sSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUUsRUFBRSxZQUFZLENBQUMsQ0FBQTtRQUNoRSxJQUFJLENBQUMsVUFBVSxHQUFHLFVBQVUsSUFBSSxFQUFFLENBQUE7SUFDcEMsQ0FBQztJQUVELEtBQUssQ0FBQyxhQUFhLENBQUMsU0FBb0I7UUFDdEMsTUFBTSxhQUFhLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxTQUFTLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFBO1FBQ3hELE1BQU0sR0FBRyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUE7UUFDbEQsTUFBTSxHQUFHLENBQUMsU0FBUyxDQUFDLElB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
189
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW52ZW50b3J5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2ludmVudG9yeS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsTUFBTSxJQUFJLENBQUE7QUFDbkIsT0FBTyxHQUFHLE1BQU0sYUFBYSxDQUFBO0FBQzdCLE9BQU8sSUFBSSxNQUFNLE1BQU0sQ0FBQTtBQUV2QixPQUFPLEVBQUUsUUFBUSxFQUF1QixVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUE7QUFDekUsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sRUFBRSxNQUFNLGlCQUFpQixDQUFBO0FBQzdELE9BQU8sRUFBZSxzQkFBc0IsRUFBRSxzQkFBc0IsRUFBRSwwQkFBMEIsRUFBRSxNQUFNLFdBQVcsQ0FBQTtBQUduSCxNQUFNLFlBQVksR0FBRyxXQUFXLENBQUE7QUFDaEMsTUFBTSxTQUFTLEdBQUcsWUFBWSxDQUFBO0FBQzlCLE1BQU0sYUFBYSxHQUFHLGdCQUFnQixDQUFBLENBQUMsNEJBQTRCO0FBc0NuRSxNQUFNLE9BQU8sbUJBQW1CO0lBQzlCLE9BQU8sQ0FBUztJQUNoQixVQUFVLENBQStCO0lBRXpDLFlBQVksT0FBZ0IsRUFBRSxVQUEwQztRQUN0RSxJQUFJLENBQUMsT0FBTyxHQUFHLE9BQU8sSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUUsRUFBRSxZQUFZLENBQUMsQ0FBQTtRQUNoRSxJQUFJLENBQUMsVUFBVSxHQUFHLFVBQVUsSUFBSSxFQUFFLENBQUE7SUFDcEMsQ0FBQztJQUVELEtBQUssQ0FBQyxhQUFhLENBQUMsU0FBb0I7UUFDdEMsTUFBTSxhQUFhLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxTQUFTLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFBO1FBQ3hELE1BQU0sR0FBRyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLEVBQUUsU0FBUyxFQUFFLElBQUksRUFB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
@@ -0,0 +1,12 @@
1
+ import { DependencyInterface } from './types.js';
2
+ export interface CaptureLighthouseDigestInput {
3
+ htmlPath: string;
4
+ outputPath: string;
5
+ }
6
+ /**
7
+ * Captures a digest screenshot of the Lighthouse report.
8
+ * This function captures two specific sections:
9
+ * 1. The final screenshot header (lh-category-header__finalscreenshot)
10
+ * 2. The metrics audit group (lh-audit-group--metrics)
11
+ */
12
+ export declare function captureLighthouseDigest(opts: CaptureLighthouseDigestInput, dependency: Pick<DependencyInterface, 'logger' | 'mkdirp'>): Promise<void>;
@@ -0,0 +1,69 @@
1
+ import Path from 'path';
2
+ import puppeteer from 'puppeteer';
3
+ /**
4
+ * Captures a digest screenshot of the Lighthouse report.
5
+ * This function captures two specific sections:
6
+ * 1. The final screenshot header (lh-category-header__finalscreenshot)
7
+ * 2. The metrics audit group (lh-audit-group--metrics)
8
+ */
9
+ export async function captureLighthouseDigest(opts, dependency) {
10
+ const browser = await puppeteer.launch({
11
+ headless: true,
12
+ args: ['--no-sandbox', '--disable-setuid-sandbox'],
13
+ });
14
+ try {
15
+ const page = await browser.newPage();
16
+ // Load the HTML file
17
+ const fileUrl = `file://${Path.resolve(opts.htmlPath)}`;
18
+ await page.goto(fileUrl, { waitUntil: 'networkidle0' });
19
+ // Check if the required elements exist
20
+ const elementsExist = await page.evaluate(() => {
21
+ const finalScreenshot = document.querySelector('.lh-category-header__finalscreenshot');
22
+ const metrics = document.querySelector('.lh-audit-group--metrics');
23
+ return finalScreenshot !== null && metrics !== null;
24
+ });
25
+ if (!elementsExist) {
26
+ throw new Error('Required elements not found in the Lighthouse report');
27
+ }
28
+ // Get the bounding boxes of both elements
29
+ const finalScreenshotElement = await page.$('.lh-category-header__finalscreenshot');
30
+ const metricsElement = await page.$('.lh-audit-group--metrics');
31
+ if (!finalScreenshotElement || !metricsElement) {
32
+ throw new Error('Required elements not found in the Lighthouse report');
33
+ }
34
+ const finalScreenshotBox = await finalScreenshotElement.boundingBox();
35
+ const metricsBox = await metricsElement.boundingBox();
36
+ if (!finalScreenshotBox || !metricsBox) {
37
+ throw new Error('Could not get bounding box of required elements');
38
+ }
39
+ // Calculate the bounding box that encompasses both elements
40
+ const minX = Math.min(finalScreenshotBox.x, metricsBox.x);
41
+ const minY = Math.min(finalScreenshotBox.y, metricsBox.y);
42
+ const maxX = Math.max(finalScreenshotBox.x + finalScreenshotBox.width, metricsBox.x + metricsBox.width);
43
+ const maxY = Math.max(finalScreenshotBox.y + finalScreenshotBox.height, metricsBox.y + metricsBox.height);
44
+ const boundingBox = {
45
+ x: minX,
46
+ y: minY,
47
+ width: maxX - minX,
48
+ height: maxY - minY,
49
+ };
50
+ // Ensure output directory exists
51
+ const outputDir = Path.dirname(opts.outputPath);
52
+ await dependency.mkdirp(outputDir);
53
+ // Capture the screenshot
54
+ await page.screenshot({
55
+ path: opts.outputPath,
56
+ clip: {
57
+ x: boundingBox.x,
58
+ y: boundingBox.y,
59
+ width: boundingBox.width,
60
+ height: boundingBox.height,
61
+ },
62
+ });
63
+ dependency.logger?.info(`Lighthouse digest screenshot saved to ${opts.outputPath}`);
64
+ }
65
+ finally {
66
+ await browser.close();
67
+ }
68
+ }
69
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGlnaHRob3VzZS1kaWdlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvbGlnaHRob3VzZS1kaWdlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxJQUFJLE1BQU0sTUFBTSxDQUFBO0FBRXZCLE9BQU8sU0FBUyxNQUFNLFdBQVcsQ0FBQTtBQVNqQzs7Ozs7R0FLRztBQUNILE1BQU0sQ0FBQyxLQUFLLFVBQVUsdUJBQXVCLENBQzNDLElBQWtDLEVBQ2xDLFVBQTBEO0lBRTFELE1BQU0sT0FBTyxHQUFHLE1BQU0sU0FBUyxDQUFDLE1BQU0sQ0FBQztRQUNyQyxRQUFRLEVBQUUsSUFBSTtRQUNkLElBQUksRUFBRSxDQUFDLGNBQWMsRUFBRSwwQkFBMEIsQ0FBQztLQUNuRCxDQUFDLENBQUE7SUFFRixJQUFJO1FBQ0YsTUFBTSxJQUFJLEdBQUcsTUFBTSxPQUFPLENBQUMsT0FBTyxFQUFFLENBQUE7UUFFcEMscUJBQXFCO1FBQ3JCLE1BQU0sT0FBTyxHQUFHLFVBQVUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQTtRQUN2RCxNQUFNLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLEVBQUUsU0FBUyxFQUFFLGNBQWMsRUFBRSxDQUFDLENBQUE7UUFFdkQsdUNBQXVDO1FBQ3ZDLE1BQU0sYUFBYSxHQUFHLE1BQU0sSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLEVBQUU7WUFDN0MsTUFBTSxlQUFlLEdBQUcsUUFBUSxDQUFDLGFBQWEsQ0FBQyxzQ0FBc0MsQ0FBQyxDQUFBO1lBQ3RGLE1BQU0sT0FBTyxHQUFHLFFBQVEsQ0FBQyxhQUFhLENBQUMsMEJBQTBCLENBQUMsQ0FBQTtZQUNsRSxPQUFPLGVBQWUsS0FBSyxJQUFJLElBQUksT0FBTyxLQUFLLElBQUksQ0FBQTtRQUNyRCxDQUFDLENBQUMsQ0FBQTtRQUVGLElBQUksQ0FBQyxhQUFhLEVBQUU7WUFDbEIsTUFBTSxJ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
@@ -3,11 +3,10 @@ export interface ExecLighthouseInput {
3
3
  url: string;
4
4
  proxyPort: number;
5
5
  deviceType?: DeviceType;
6
- cpuMultiplier?: string;
7
- noThrottling?: boolean;
8
6
  view?: boolean;
9
7
  artifactsDir?: string;
10
8
  headless: boolean;
11
9
  timeout: number;
10
+ captureScoreAndMetrics?: boolean;
12
11
  }
13
- export declare function execLighthouse(opts: ExecLighthouseInput, dependency: Pick<DependencyInterface, 'mkdirp' | 'executeLighthouse'>): Promise<void>;
12
+ export declare function execLighthouse(opts: ExecLighthouseInput, dependency: Pick<DependencyInterface, 'mkdirp' | 'executeLighthouse' | 'logger'>): Promise<void>;
@@ -1,4 +1,5 @@
1
1
  import Path from 'path';
2
+ import { captureLighthouseDigest } from './lighthouse-digest.js';
2
3
  export async function execLighthouse(opts, dependency) {
3
4
  const artifactsDir = opts.artifactsDir || './artifacts';
4
5
  await dependency.mkdirp(artifactsDir);
@@ -11,12 +12,15 @@ export async function execLighthouse(opts, dependency) {
11
12
  `--output-path=${outputPath}`,
12
13
  '--only-categories=performance',
13
14
  `--form-factor=${deviceType}`,
15
+ // Set screen emulation to match form factor
16
+ `--screenEmulation.mobile=${deviceType === 'mobile' ? 'true' : 'false'}`,
17
+ // Disable throttling as Rust proxy handles timing accurately
18
+ '--throttling.rttMs=0',
19
+ '--throttling.throughputKbps=0',
20
+ '--throttling.downloadThroughputKbps=0',
21
+ '--throttling.uploadThroughputKbps=0',
22
+ '--throttling.cpuSlowdownMultiplier=1',
14
23
  ];
15
- if (opts.noThrottling) {
16
- args.push('--throttling.rttMs=0', '--throttling.throughputKbps=0', '--throttling.downloadThroughputKbps=0', '--throttling.uploadThroughputKbps=0', '--throttling.cpuSlowdownMultiplier=1');
17
- }
18
- else if (opts.cpuMultiplier)
19
- args.push(`--throttling.cpuSlowdownMultiplier=${opts.cpuMultiplier}`);
20
24
  args.push(`--max-wait-for-load=${opts.timeout}`);
21
25
  const chromeFlags = ['--ignore-certificate-errors', `--proxy-server=http://localhost:${opts.proxyPort}`];
22
26
  if (opts.headless)
@@ -25,5 +29,19 @@ export async function execLighthouse(opts, dependency) {
25
29
  if (opts.view)
26
30
  args.push('--view');
27
31
  await dependency.executeLighthouse(args);
32
+ // Capture score and metrics screenshot if requested
33
+ if (opts.captureScoreAndMetrics !== false) {
34
+ const htmlPath = `${outputPath}.report.html`;
35
+ const digestPath = Path.join(artifactsDir, 'lighthouse.digest.png');
36
+ try {
37
+ await captureLighthouseDigest({
38
+ htmlPath,
39
+ outputPath: digestPath,
40
+ }, dependency);
41
+ }
42
+ catch (error) {
43
+ dependency.logger?.warn(`Failed to capture Lighthouse score and metrics: ${error}`);
44
+ }
45
+ }
28
46
  }
29
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGlnaHRob3VzZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9saWdodGhvdXNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sSUFBSSxNQUFNLE1BQU0sQ0FBQTtBQWdCdkIsTUFBTSxDQUFDLEtBQUssVUFBVSxjQUFjLENBQ2xDLElBQXlCLEVBQ3pCLFVBQXFFO0lBRXJFLE1BQU0sWUFBWSxHQUFHLElBQUksQ0FBQyxZQUFZLElBQUksYUFBYSxDQUFBO0lBQ3ZELE1BQU0sVUFBVSxDQUFDLE1BQU0sQ0FBQyxZQUFZLENBQUMsQ0FBQTtJQUVyQyxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsVUFBVSxJQUFJLFFBQVEsQ0FBQTtJQUM5QyxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLFlBQVksRUFBRSxZQUFZLENBQUMsQ0FBQTtJQUN4RCxNQUFNLElBQUksR0FBYTtRQUNyQixJQUFJLENBQUMsR0FBRztRQUNSLGVBQWU7UUFDZixvQkFBb0I7UUFDcEIsaUJBQWlCLFVBQVUsRUFBRTtRQUM3QiwrQkFBK0I7UUFDL0IsaUJBQWlCLFVBQVUsRUFBRTtLQUM5QixDQUFBO0lBRUQsSUFBSSxJQUFJLENBQUMsWUFBWSxFQUFFO1FBQ3JCLElBQUksQ0FBQyxJQUFJLENBQ1Asc0JBQXNCLEVBQ3RCLCtCQUErQixFQUMvQix1Q0FBdUMsRUFDdkMscUNBQXFDLEVBQ3JDLHNDQUFzQyxDQUN2QyxDQUFBO0tBQ0Y7U0FBTSxJQUFJLElBQUksQ0FBQyxhQUFhO1FBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxzQ0FBc0MsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDLENBQUE7SUFFcEcsSUFBSSxDQUFDLElBQUksQ0FBQyx1QkFBdUIsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUE7SUFFaEQsTUFBTSxXQUFXLEdBQWEsQ0FBQyw2QkFBNkIsRUFBRSxtQ0FBbUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUE7SUFDbEgsSUFBSSxJQUFJLENBQUMsUUFBUTtRQUFFLFdBQVcsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUE7SUFDakQsSUFBSSxDQUFDLElBQUksQ0FBQyxtQkFBbUIsV0FBVyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUE7SUFFdEQsSUFBSSxJQUFJLENBQUMsSUFBSTtRQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUE7SUFFbEMsTUFBTSxVQUFVLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLENBQUE7QUFDMUMsQ0FBQyJ9
47
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGlnaHRob3VzZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9saWdodGhvdXNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sSUFBSSxNQUFNLE1BQU0sQ0FBQTtBQUV2QixPQUFPLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQTtBQWNoRSxNQUFNLENBQUMsS0FBSyxVQUFVLGNBQWMsQ0FDbEMsSUFBeUIsRUFDekIsVUFBZ0Y7SUFFaEYsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLFlBQVksSUFBSSxhQUFhLENBQUE7SUFDdkQsTUFBTSxVQUFVLENBQUMsTUFBTSxDQUFDLFlBQVksQ0FBQyxDQUFBO0lBRXJDLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxVQUFVLElBQUksUUFBUSxDQUFBO0lBQzlDLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFLFlBQVksQ0FBQyxDQUFBO0lBQ3hELE1BQU0sSUFBSSxHQUFhO1FBQ3JCLElBQUksQ0FBQyxHQUFHO1FBQ1IsZUFBZTtRQUNmLG9CQUFvQjtRQUNwQixpQkFBaUIsVUFBVSxFQUFFO1FBQzdCLCtCQUErQjtRQUMvQixpQkFBaUIsVUFBVSxFQUFFO1FBQzdCLDRDQUE0QztRQUM1Qyw0QkFBNEIsVUFBVSxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxPQUFPLEVBQUU7UUFDeEUsNkRBQTZEO1FBQzdELHNCQUFzQjtRQUN0QiwrQkFBK0I7UUFDL0IsdUNBQXVDO1FBQ3ZDLHFDQUFxQztRQUNyQyxzQ0FBc0M7S0FDdkMsQ0FBQTtJQUVELElBQUksQ0FBQyxJQUFJLENBQUMsdUJBQXVCLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFBO0lBRWhELE1BQU0sV0FBVyxHQUFhLENBQUMsNkJBQTZCLEVBQUUsbUNBQW1DLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQyxDQUFBO0lBQ2xILElBQUksSUFBSSxDQUFDLFFBQVE7UUFBRSxXQUFXLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFBO0lBQ2pELElBQUksQ0FBQyxJQUFJLENBQUMsbUJBQW1CLFdBQVcsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFBO0lBRXRELElBQUksSUFBSSxDQUFDLElBQUk7UUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFBO0lBRWxDLE1BQU0sVUFBVSxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxDQUFBO0lBRXhDLG9EQUFvRDtJQUNwRCxJQUFJLElBQUksQ0FBQyxzQkFBc0IsS0FBSyxLQUFLLEVBQUU7UUFDekMsTUFBTSxRQUFRLEdBQUcsR0FBRyxVQUFVLGNBQWMsQ0FBQTtRQUM1QyxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLFlBQVksRUFBRSx1QkFBdUIsQ0FBQyxDQUFBO1FBRW5FLElBQUk7WUFDRixNQUFNLHVCQUF1QixDQUMzQjtnQkFDRSxRQUFRO2dCQUNSLFVBQVUsRUFBRSxVQUFVO2FBQ3ZCLEVBQ0QsVUFBVSxDQUNYLENBQUE7U0FDRjtRQUFDLE9BQU8sS0FBSyxFQUFFO1lBQ2QsVUFBVSxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsbURBQW1ELEtBQUssRUFBRSxDQUFDLENBQUE7U0FDcEY7S0FDRjtBQUNILENBQUMifQ==
@@ -3,8 +3,6 @@ export interface ExecLoadshowInput {
3
3
  url: string;
4
4
  proxyPort: number;
5
5
  deviceType?: DeviceType;
6
- noThrottling?: boolean;
7
- syncLighthouseSpec?: boolean;
8
6
  artifactsDir?: string;
9
7
  timeout: number;
10
8
  credit?: string;
@@ -13,8 +11,6 @@ export interface ExecLoadshowSpec {
13
11
  viewportWidth?: number;
14
12
  columns?: number;
15
13
  cpuThrottling?: number;
16
- networkLatencyMs?: number;
17
- networkThroughputMbps?: number;
18
14
  timeoutMs?: number;
19
15
  userAgent?: string;
20
16
  proxyPort?: number;
package/build/loadshow.js CHANGED
@@ -10,12 +10,6 @@ function execSpecToCommandArgs(spec) {
10
10
  args.push('-u', `recording.viewportWidth=${spec.viewportWidth}`);
11
11
  if (spec.cpuThrottling !== undefined)
12
12
  args.push('-u', `recording.cpuThrottling=${spec.cpuThrottling}`);
13
- if (spec.networkLatencyMs !== undefined)
14
- args.push('-u', `recording.network.latencyMs=${spec.networkLatencyMs}`);
15
- if (spec.networkThroughputMbps !== undefined) {
16
- args.push('-u', `recording.network.uploadThroughputMbps=${spec.networkThroughputMbps}`);
17
- args.push('-u', `recording.network.downloadThroughputMbps=${spec.networkThroughputMbps}`);
18
- }
19
13
  if (spec.timeoutMs !== undefined)
20
14
  args.push('-u', `recording.timeoutMs=${spec.timeoutMs}`);
21
15
  if (spec.userAgent !== undefined)
@@ -48,21 +42,8 @@ export async function execLoadshow(input, dependency) {
48
42
  cpuThrottling: lighthouseByDevice.settings?.throttling?.cpuSlowdownMultiplier,
49
43
  userAgent: typeof userAgent === 'string' ? userAgent : undefined,
50
44
  timeoutMs: input.timeout,
45
+ credit: input.credit,
51
46
  };
52
- // Sync network conditions with Lighthouse
53
- if (input.syncLighthouseSpec) {
54
- if (lighthouseByDevice.settings?.throttling?.rttMs)
55
- spec.networkLatencyMs = lighthouseByDevice.settings?.throttling?.rttMs;
56
- if (lighthouseByDevice.settings?.throttling?.throughputKbps)
57
- spec.networkThroughputMbps = lighthouseByDevice.settings?.throttling?.throughputKbps / 1024;
58
- }
59
- // No throttling
60
- if (input.noThrottling) {
61
- spec.networkLatencyMs = 0;
62
- spec.networkThroughputMbps = 999999;
63
- }
64
- // Credit
65
- spec.credit = input.credit;
66
47
  const args = [];
67
48
  args.push('record');
68
49
  args.push('-a', loadshowDir);
@@ -70,4 +51,4 @@ export async function execLoadshow(input, dependency) {
70
51
  args.push(input.url, outputPath);
71
52
  await dependency.executeLoadshow(args);
72
53
  }
73
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9hZHNob3cuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvbG9hZHNob3cudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxJQUFJLE1BQU0sTUFBTSxDQUFBO0FBRXZCLE9BQU8sRUFBRSxhQUFhLEVBQUUsYUFBYSxFQUFFLE1BQU0sWUFBWSxDQUFBO0FBMkJ6RCxTQUFTLHFCQUFxQixDQUFDLElBQXNCO0lBQ25ELE1BQU0sSUFBSSxHQUFhLEVBQUUsQ0FBQTtJQUV6QixTQUFTO0lBQ1QsSUFBSSxJQUFJLENBQUMsT0FBTyxLQUFLLFNBQVM7UUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxrQkFBa0IsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUE7SUFFakYsWUFBWTtJQUNaLElBQUksSUFBSSxDQUFDLGFBQWEsS0FBSyxTQUFTO1FBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsMkJBQTJCLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQyxDQUFBO0lBQ3RHLElBQUksSUFBSSxDQUFDLGFBQWEsS0FBSyxTQUFTO1FBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsMkJBQTJCLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQyxDQUFBO0lBQ3RHLElBQUksSUFBSSxDQUFDLGdCQUFnQixLQUFLLFNBQVM7UUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSwrQkFBK0IsSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUMsQ0FBQTtJQUNoSCxJQUFJLElBQUksQ0FBQyxxQkFBcUIsS0FBSyxTQUFTLEVBQUU7UUFDNUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsMENBQTBDLElBQUksQ0FBQyxxQkFBcUIsRUFBRSxDQUFDLENBQUE7UUFDdkYsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsNENBQTRDLElBQUksQ0FBQyxxQkFBcUIsRUFBRSxDQUFDLENBQUE7S0FD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
54
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9hZHNob3cuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvbG9hZHNob3cudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxJQUFJLE1BQU0sTUFBTSxDQUFBO0FBRXZCLE9BQU8sRUFBRSxhQUFhLEVBQUUsYUFBYSxFQUFFLE1BQU0sWUFBWSxDQUFBO0FBdUJ6RCxTQUFTLHFCQUFxQixDQUFDLElBQXNCO0lBQ25ELE1BQU0sSUFBSSxHQUFhLEVBQUUsQ0FBQTtJQUV6QixTQUFTO0lBQ1QsSUFBSSxJQUFJLENBQUMsT0FBTyxLQUFLLFNBQVM7UUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxrQkFBa0IsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUE7SUFFakYsWUFBWTtJQUNaLElBQUksSUFBSSxDQUFDLGFBQWEsS0FBSyxTQUFTO1FBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsMkJBQTJCLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQyxDQUFBO0lBQ3RHLElBQUksSUFBSSxDQUFDLGFBQWEsS0FBSyxTQUFTO1FBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsMkJBQTJCLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQyxDQUFBO0lBQ3RHLElBQUksSUFBSSxDQUFDLFNBQVMsS0FBSyxTQUFTO1FBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsdUJBQXVCLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQyxDQUFBO0lBQzFGLElBQUksSUFBSSxDQUFDLFNBQVMsS0FBSyxTQUFTO1FBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsZ0NBQWdDLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQyxDQUFBO0lBRW5HLHNCQUFzQjtJQUN0QixNQUFNLFVBQVUsR0FBYSxDQUFDLDZCQUE2QixDQUFDLENBQUE7SUFDNUQsSUFBSSxJQUFJLENBQUMsU0FBUyxLQUFLLFNBQVMs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
@@ -1,23 +1,22 @@
1
- /// <reference types="node" />
2
- import { HttpHeaders } from './http.js';
3
- import { Inventory, Transaction } from './inventory.js';
4
- import { Proxy, ProxyDependency, ProxyOptions } from './proxy.js';
5
- export interface PlaybackTransaction {
6
- method: string;
7
- url: string;
8
- ttfbMs: number;
9
- statusCode?: number;
10
- err?: Error;
11
- rawHeaders?: HttpHeaders;
12
- contentChunks: Buffer[];
13
- contentLength: number;
14
- durationMs: number;
1
+ import { Proxy as RustProxy } from 'rust-http-playback-proxy';
2
+ import { InventoryRepository } from './inventory.js';
3
+ import { DependencyInterface, DeviceType } from './types.js';
4
+ export interface PlaybackProxyOptions {
5
+ inventoryRepository?: InventoryRepository;
6
+ port?: number;
15
7
  }
16
- export declare class PlaybackProxy extends Proxy {
17
- transactions: Transaction[];
18
- transactionsMap: Map<string, Map<string, PlaybackTransaction>>;
19
- loadTransactions(inventory: Inventory): Promise<void>;
20
- setup(): Promise<void>;
21
- shutdown(): Promise<void>;
8
+ export type PlaybackProxyDependency = Pick<DependencyInterface, 'logger'>;
9
+ export declare class PlaybackProxy {
10
+ rustProxy?: RustProxy;
11
+ inventoryRepository: InventoryRepository;
12
+ entryUrl?: string;
13
+ deviceType?: DeviceType;
14
+ requestedPort?: number;
15
+ dependency: PlaybackProxyDependency;
16
+ constructor(options?: PlaybackProxyOptions, dependency?: PlaybackProxyDependency);
17
+ start(): Promise<void>;
18
+ get port(): number;
19
+ get inventoryDirPath(): string;
20
+ stop(): Promise<void>;
22
21
  }
23
- export declare function withPlaybackProxy(options: ProxyOptions, dependency: ProxyDependency, cb: (proxy: PlaybackProxy) => Promise<void>): Promise<void>;
22
+ export declare function withPlaybackProxy(options: PlaybackProxyOptions, dependency: PlaybackProxyDependency, cb: (proxy: PlaybackProxy) => Promise<void>): Promise<void>;
package/build/playback.js CHANGED
@@ -1,110 +1,56 @@
1
- import { Proxy } from './proxy.js';
2
- const ChunkSize = 1024 * 16;
3
- export class PlaybackProxy extends Proxy {
4
- transactions = [];
5
- transactionsMap = new Map();
6
- async loadTransactions(inventory) {
7
- this.transactions = await this.inventoryRepository.loadTransactions(inventory.resources);
8
- for (const transaction of this.transactions) {
9
- const playbackTransaction = {
10
- method: transaction.method,
11
- url: transaction.url,
12
- ttfbMs: transaction.ttfbMs,
13
- statusCode: transaction.statusCode,
14
- err: transaction.errorMessage ? new Error(transaction.errorMessage) : undefined,
15
- rawHeaders: transaction.rawHeaders || {},
16
- contentChunks: [],
17
- contentLength: 0,
18
- durationMs: transaction.durationMs || 0,
19
- };
20
- if (transaction.content) {
21
- const maxChunks = 10;
22
- const minInterval = 10;
23
- const chunks = Math.min(maxChunks, Math.floor(playbackTransaction.durationMs / minInterval));
24
- playbackTransaction.contentChunks = [];
25
- const chunkSize = Math.max(ChunkSize, Math.ceil(transaction.content.length / chunks));
26
- for (let i = 0; i <= transaction.content.length; i += chunkSize) {
27
- playbackTransaction.contentChunks.push(transaction.content.subarray(i, i + chunkSize));
28
- }
29
- }
30
- if (!this.transactionsMap.has(transaction.method)) {
31
- this.transactionsMap.set(transaction.method, new Map());
32
- }
33
- this.transactionsMap.get(transaction.method).set(transaction.url, playbackTransaction);
34
- }
1
+ import { startPlayback } from 'rust-http-playback-proxy';
2
+ import { InventoryRepository } from './inventory.js';
3
+ export class PlaybackProxy {
4
+ rustProxy;
5
+ inventoryRepository;
6
+ entryUrl;
7
+ deviceType;
8
+ requestedPort;
9
+ dependency;
10
+ constructor(options, dependency) {
11
+ options ||= {};
12
+ this.dependency = dependency || {};
13
+ // Inventory repository
14
+ this.inventoryRepository = options.inventoryRepository ?? new InventoryRepository(undefined, this.dependency);
15
+ // Port
16
+ this.requestedPort = options.port;
35
17
  }
36
- async setup() {
18
+ async start() {
19
+ this.dependency.logger?.info(`Starting playback proxy...`);
20
+ // Load inventory to get entryUrl and deviceType
37
21
  const inventory = await this.inventoryRepository.loadInventory();
38
- await this.loadTransactions(inventory);
39
- if (inventory.entryUrl)
40
- this.entryUrl = inventory.entryUrl;
41
- let requestNumber = 1;
42
- this.proxy.onRequest((ctx, onRequestComplete) => {
43
- const number = requestNumber++;
44
- // Skip websocket
45
- if (ctx.clientToProxyRequest.headers?.upgrade === 'websocket') {
46
- this.dependency.logger?.warn({ number }, `Request #${number} ${ctx.clientToProxyRequest.url} skipped (websocket)`);
47
- return;
48
- }
49
- const identifier = Proxy.contextRequest(ctx);
50
- const transaction = this.transactionsMap.get(identifier.method)?.get(identifier.url);
51
- if (!transaction) {
52
- this.dependency.logger?.warn({ number, identifier }, `Request #${number} ${identifier.url} (${identifier.method}) not found in inventory`);
53
- return;
54
- }
55
- const contentStream = this.createThrottlingTransform() || ctx.proxyToClientResponse;
56
- if (contentStream !== ctx.proxyToClientResponse) {
57
- contentStream.pipe(ctx.proxyToClientResponse);
58
- }
59
- this.dependency.logger?.debug({ number, identifier }, `Request #${number} ${transaction.url} started`);
60
- ctx.onError((_, err) => {
61
- this.dependency.logger?.warn({ number, identifier, err }, `Request #${number} ${transaction.url} failed: ${err.message}`);
62
- });
63
- setTimeout(() => {
64
- // Error
65
- if (transaction.err) {
66
- return onRequestComplete(transaction.err);
67
- }
68
- // Status code
69
- ctx.proxyToClientResponse.statusCode = transaction.statusCode || 500;
70
- // Headers
71
- if (transaction.rawHeaders) {
72
- for (const [key, value] of Object.entries(transaction.rawHeaders)) {
73
- if (ctx.proxyToClientResponse.headersSent)
74
- break;
75
- ctx.proxyToClientResponse.setHeader(key, value);
76
- }
77
- }
78
- // Empty content body
79
- if (!transaction.contentChunks || transaction.contentChunks.length === 0) {
80
- contentStream.end();
81
- return;
82
- }
83
- // Content body
84
- const chunks = [...transaction.contentChunks];
85
- const intervalMs = transaction.durationMs / transaction.contentChunks.length;
86
- const interval = setInterval(() => {
87
- const chunk = chunks.shift();
88
- if (chunk) {
89
- contentStream.write(chunk);
90
- }
91
- if (chunks.length === 0) {
92
- clearInterval(interval);
93
- contentStream.end();
94
- this.dependency.logger?.debug({ number, identifier }, `Request #${number} ${transaction.url} completed`);
95
- }
96
- }, intervalMs);
97
- }, transaction.ttfbMs);
22
+ this.entryUrl = inventory.entryUrl;
23
+ this.deviceType = inventory.deviceType;
24
+ this.rustProxy = await startPlayback({
25
+ inventoryDir: this.inventoryRepository.dirPath,
26
+ port: this.requestedPort || 0,
98
27
  });
28
+ this.dependency.logger?.info(`Playback proxy started on port ${this.rustProxy.port}`);
29
+ }
30
+ get port() {
31
+ if (!this.rustProxy)
32
+ throw new Error('Proxy not started');
33
+ return this.rustProxy.port;
34
+ }
35
+ get inventoryDirPath() {
36
+ return this.inventoryRepository.dirPath;
99
37
  }
100
- async shutdown() {
101
- // nothing to do
38
+ async stop() {
39
+ if (this.rustProxy) {
40
+ this.dependency.logger?.info(`Stopping playback proxy...`);
41
+ await this.rustProxy.stop();
42
+ this.dependency.logger?.info(`Playback proxy stopped`);
43
+ }
102
44
  }
103
45
  }
104
46
  export async function withPlaybackProxy(options, dependency, cb) {
105
47
  const proxy = new PlaybackProxy(options, dependency);
106
48
  await proxy.start();
107
- await cb(proxy);
108
- await proxy.stop();
49
+ try {
50
+ await cb(proxy);
51
+ }
52
+ finally {
53
+ await proxy.stop();
54
+ }
109
55
  }
110
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGxheWJhY2suanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvcGxheWJhY2sudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBRUEsT0FBTyxFQUFFLEtBQUssRUFBaUMsTUFBTSxZQUFZLENBQUE7QUFFakUsTUFBTSxTQUFTLEdBQUcsSUFBSSxHQUFHLEVBQUUsQ0FBQTtBQWMzQixNQUFNLE9BQU8sYUFBYyxTQUFRLEtBQUs7SUFDdEMsWUFBWSxHQUFrQixFQUFFLENBQUE7SUFDaEMsZUFBZSxHQUFrRCxJQUFJLEdBQUcsRUFBRSxDQUFBO0lBRTFFLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQyxTQUFvQjtRQUN6QyxJQUFJLENBQUMsWUFBWSxHQUFHLE1BQU0sSUFBSSxDQUFDLG1CQUFtQixDQUFDLGdCQUFnQixDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUMsQ0FBQTtRQUV4RixLQUFLLE1BQU0sV0FBVyxJQUFJLElBQUksQ0FBQyxZQUFZLEVBQUU7WUFDM0MsTUFBTSxtQkFBbUIsR0FBd0I7Z0JBQy9DLE1BQU0sRUFBRSxXQUFXLENBQUMsTUFBTTtnQkFDMUIsR0FBRyxFQUFFLFdBQVcsQ0FBQyxHQUFHO2dCQUNwQixNQUFNLEVBQUUsV0FBVyxDQUFDLE1BQU07Z0JBQzFCLFVBQVUsRUFBRSxXQUFXLENBQUMsVUFBVTtnQkFDbEMsR0FBRyxFQUFFLFdBQVcsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLElBQUksS0FBSyxDQUFDLFdBQVcsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUztnQkFDL0UsVUFBVSxFQUFFLFdBQVcsQ0FBQyxVQUFVLElBQUksRUFBRTtnQkFDeEMsYUFBYSxFQUFFLEVBQUU7Z0JBQ2pCLGFBQWEsRUFBRSxDQUFDO2dCQUNoQixVQUFVLEVBQUUsV0FBVyxDQUFDLFVBQVUsSUFBSSxDQUFDO2FBQ3hDLENBQUE7WUFFRCxJQUFJLFdBQVcsQ0FBQyxPQUFPLEVBQUU7Z0JBQ3ZCLE1BQU0sU0FBUyxHQUFHLEVB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
56
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGxheWJhY2suanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvcGxheWJhY2sudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFzQixhQUFhLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQTtBQUU1RSxPQUFPLEVBQWEsbUJBQW1CLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQTtBQVUvRCxNQUFNLE9BQU8sYUFBYTtJQUN4QixTQUFTLENBQVk7SUFDckIsbUJBQW1CLENBQXNCO0lBQ3pDLFFBQVEsQ0FBUztJQUNqQixVQUFVLENBQWE7SUFDdkIsYUFBYSxDQUFTO0lBQ3RCLFVBQVUsQ0FBeUI7SUFFbkMsWUFBWSxPQUE4QixFQUFFLFVBQW9DO1FBQzlFLE9BQU8sS0FBSyxFQUFFLENBQUE7UUFDZCxJQUFJLENBQUMsVUFBVSxHQUFHLFVBQVUsSUFBSSxFQUFFLENBQUE7UUFFbEMsdUJBQXVCO1FBQ3ZCLElBQUksQ0FBQyxtQkFBbUIsR0FBRyxPQUFPLENBQUMsbUJBQW1CLElBQUksSUFBSSxtQkFBbUIsQ0FBQyxTQUFTLEVBQUUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFBO1FBRTdHLE9BQU87UUFDUCxJQUFJLENBQUMsYUFBYSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUE7SUFDbkMsQ0FBQztJQUVELEtBQUssQ0FBQyxLQUFLO1FBQ1QsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLDRCQUE0QixDQUFDLENBQUE7UUFFMUQsZ0RBQWdEO1FBQ2hELE1BQU0sU0FBUyxHQUFjLE1BQU0sSUFBSSxDQUFDLG1CQUFtQixDQUFDLGFBQWEsRUFBRSxDQUFBO1FBQzNFLElBQUksQ0FBQyxRQUFRLEdBQUcsU0FBUyxDQUFDLFFBQVEsQ0FBQTtRQUNsQyxJQUFJLENBQUMsVUFBVSxHQUFHLFNBQVMsQ0FBQyxVQUFVLENBQUE7UUFFdEMsSUFBSSxDQUFDLFNBQVMsR0FBRyxNQUFNLGFBQWEsQ0FBQztZQUNuQyxZQUFZLEVBQUUsSUFBSSxDQUFDLG1CQUFtQixDQUFDLE9BQU87WUFDOUMsSUFBSSxFQUFFLElBQUksQ0FBQyxhQUFhLElBQUksQ0FBQztTQUM5QixDQUFDLENBQUE7UUFFRixJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsa0NBQWtDLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQTtJQUN2RixDQUFDO0lBRUQsSUFBSSxJQUFJO1FBQ04sSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTO1lBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQyxtQkFBbUIsQ0FBQyxDQUFBO1FBQ3pELE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUE7SUFDNUIsQ0FBQztJQUVELElBQUksZ0JBQWdCO1FBQ2xCLE9BQU8sSUFBSSxDQUFDLG1CQUFtQixDQUFDLE9BQU8sQ0FBQTtJQUN6QyxDQUFDO0lBRUQsS0FBSyxDQUFDLElBQUk7UUFDUixJQUFJLElBQUksQ0FBQyxTQUFTLEVBQUU7WUFDbEIsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLDRCQUE0QixDQUFDLENBQUE7WUFDMUQsTUFBTSxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksRUFBRSxDQUFBO1lBQzNCLElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxDQUFBO1NBQ3ZEO0lBQ0gsQ0FBQztDQUNGO0FBRUQsTUFBTSxDQUFDLEtBQUssVUFBVSxpQkFBaUIsQ0FDckMsT0FBNkIsRUFDN0IsVUFBbUMsRUFDbkMsRUFBMkM7SUFFM0MsTUFBTSxLQUFLLEdBQUcsSUFBSSxhQUFhLENBQUMsT0FBTyxFQUFFLFVBQVUsQ0FBQyxDQUFBO0lBQ3BELE1BQU0sS0FBSyxDQUFDLEtBQUssRUFBRSxDQUFBO0lBQ25CLElBQUk7UUFDRixNQUFNLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQTtLQUNoQjtZQUFTO1FBQ1IsTUFBTSxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUE7S0FDbkI7QUFDSCxDQUFDIn0=
@@ -1,28 +1,24 @@
1
- /// <reference types="node" />
2
- /// <reference types="node" />
3
- import { IncomingHttpHeaders } from 'http';
4
- import { Proxy, ProxyDependency, ProxyOptions } from './proxy.js';
5
- export interface RecordingTransaction {
6
- startedAt?: Date;
7
- responseStartedAt?: Date;
8
- responseEndedAt?: Date;
9
- method: string;
10
- url: string;
11
- statusCode?: number;
12
- incomingHttpHeaders?: IncomingHttpHeaders;
13
- contentChunks: Buffer[];
14
- err?: Error;
15
- errKind?: string;
1
+ import { Proxy as RustProxy } from 'rust-http-playback-proxy';
2
+ import { InventoryRepository } from './inventory.js';
3
+ import { DependencyInterface, DeviceType } from './types.js';
4
+ export interface RecordingProxyOptions {
5
+ inventoryRepository?: InventoryRepository;
6
+ entryUrl?: string;
7
+ deviceType?: DeviceType;
8
+ port?: number;
16
9
  }
17
- export interface RecordingSession {
18
- startedAt?: Date;
19
- transactions: RecordingTransaction[];
10
+ export type RecordingProxyDependency = Pick<DependencyInterface, 'logger'>;
11
+ export declare class RecordingProxy {
12
+ rustProxy?: RustProxy;
13
+ inventoryRepository: InventoryRepository;
14
+ entryUrl?: string;
15
+ deviceType?: DeviceType;
16
+ requestedPort?: number;
17
+ dependency: RecordingProxyDependency;
18
+ constructor(options?: RecordingProxyOptions, dependency?: RecordingProxyDependency);
19
+ start(): Promise<void>;
20
+ get port(): number;
21
+ get inventoryDirPath(): string;
22
+ stop(): Promise<void>;
20
23
  }
21
- export declare class RecordingProxy extends Proxy {
22
- startedAt?: Date;
23
- transactions: RecordingTransaction[];
24
- setup(): Promise<void>;
25
- saveInventory(): Promise<void>;
26
- shutdown(): Promise<void>;
27
- }
28
- export declare function withRecordingProxy(options: ProxyOptions, dependency: ProxyDependency, cb: (proxy: RecordingProxy) => Promise<void>): Promise<void>;
24
+ export declare function withRecordingProxy(options: RecordingProxyOptions, dependency: RecordingProxyDependency, cb: (proxy: RecordingProxy) => Promise<void>): Promise<void>;
@@ -1,99 +1,64 @@
1
- import { Proxy } from './proxy.js';
2
- export class RecordingProxy extends Proxy {
3
- startedAt;
4
- transactions = [];
5
- async setup() {
6
- this.startedAt = new Date();
7
- let requestNumber = 1;
8
- this.proxy.onRequest((ctx, onRequestComplete) => {
9
- const number = requestNumber++;
10
- // Skip websocket
11
- if (ctx.clientToProxyRequest.headers?.upgrade === 'websocket') {
12
- this.dependency.logger?.warn({ number }, `Request #${number} ${ctx.clientToProxyRequest.url} skipped (websocket)`);
13
- return;
14
- }
15
- // Throttling
16
- const filter = this.createThrottlingTransform();
17
- if (filter)
18
- ctx.addResponseFilter(filter);
19
- const identifier = Proxy.contextRequest(ctx);
20
- const transaction = {
21
- startedAt: new Date(),
22
- ...identifier,
23
- contentChunks: [],
24
- };
25
- this.dependency.logger?.debug({ number, identifier }, `Request #${number} ${transaction.url} started`);
26
- ctx.onError((_, err, errKind) => {
27
- transaction.responseStartedAt = new Date();
28
- transaction.err = err;
29
- transaction.errKind = errKind;
30
- this.dependency.logger?.warn({ number, identifier, err }, `Request #${number} ${transaction.url} failed: ${err.message}`);
31
- });
32
- ctx.onResponse((_, onResponseComplete) => {
33
- transaction.responseStartedAt = new Date();
34
- transaction.statusCode = ctx.serverToProxyResponse.statusCode;
35
- transaction.incomingHttpHeaders = ctx.serverToProxyResponse.headers;
36
- this.dependency.logger?.debug({ number, identifier }, `Request #${number} ${transaction.url} responded`);
37
- onResponseComplete();
38
- });
39
- ctx.onResponseData((_, chunk, onResponseDataComplete) => {
40
- transaction.contentChunks.push(chunk);
41
- onResponseDataComplete(null, chunk);
42
- });
43
- ctx.onResponseEnd((_, onResponseEndComplete) => {
44
- transaction.responseEndedAt = new Date();
45
- this.transactions.push(transaction);
46
- this.dependency.logger?.debug({ number, identifier }, `Request #${number} ${transaction.url} completed`);
47
- onResponseEndComplete();
48
- });
49
- onRequestComplete();
1
+ import { startRecording } from 'rust-http-playback-proxy';
2
+ import { InventoryRepository } from './inventory.js';
3
+ export class RecordingProxy {
4
+ rustProxy;
5
+ inventoryRepository;
6
+ entryUrl;
7
+ deviceType;
8
+ requestedPort;
9
+ dependency;
10
+ constructor(options, dependency) {
11
+ options ||= {};
12
+ this.dependency = dependency || {};
13
+ // Inventory repository
14
+ this.inventoryRepository = options.inventoryRepository ?? new InventoryRepository(undefined, this.dependency);
15
+ // Entry URL
16
+ this.entryUrl = options.entryUrl;
17
+ // Device type
18
+ this.deviceType = options.deviceType;
19
+ // Port
20
+ this.requestedPort = options.port;
21
+ }
22
+ async start() {
23
+ this.dependency.logger?.info(`Starting recording proxy...`);
24
+ 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,
50
30
  });
31
+ this.dependency.logger?.info(`Recording proxy started on port ${this.rustProxy.port}`);
51
32
  }
52
- async saveInventory() {
53
- const transactions = [];
54
- for (const requestTransaction of this.transactions) {
55
- const transaction = {
56
- method: requestTransaction.method,
57
- url: requestTransaction.url,
58
- ttfbMs: 0,
59
- content: Buffer.concat(requestTransaction.contentChunks),
60
- };
61
- // ttfb and duration
62
- if (requestTransaction.responseStartedAt) {
63
- transaction.ttfbMs = +requestTransaction.responseStartedAt - +requestTransaction.startedAt;
64
- if (requestTransaction.responseEndedAt) {
65
- transaction.durationMs = +requestTransaction.responseEndedAt - +requestTransaction.responseStartedAt;
66
- }
67
- }
68
- // error
69
- if (requestTransaction.err) {
70
- transaction.errorMessage = requestTransaction.err.message;
71
- }
72
- // status code
73
- if (requestTransaction.statusCode) {
74
- transaction.statusCode = requestTransaction.statusCode;
75
- }
76
- // headers
77
- if (requestTransaction.incomingHttpHeaders) {
78
- transaction.rawHeaders = {};
79
- for (const [key, value] of Object.entries(requestTransaction.incomingHttpHeaders)) {
80
- transaction.rawHeaders[key.toLowerCase()] = value.toString();
81
- }
82
- }
83
- transactions.push(transaction);
84
- }
85
- const resources = await this.inventoryRepository.saveTransactions(transactions);
86
- const inventory = { entryUrl: this.entryUrl, deviceType: this.deviceType, resources };
87
- await this.inventoryRepository.saveInventory(inventory);
33
+ get port() {
34
+ if (!this.rustProxy)
35
+ throw new Error('Proxy not started');
36
+ return this.rustProxy.port;
37
+ }
38
+ get inventoryDirPath() {
39
+ return this.inventoryRepository.dirPath;
88
40
  }
89
- async shutdown() {
90
- await this.saveInventory();
41
+ async stop() {
42
+ if (this.rustProxy) {
43
+ this.dependency.logger?.info(`Stopping recording proxy...`);
44
+ // Stop the proxy (this triggers graceful shutdown via SIGTERM signal)
45
+ // The Rust proxy will save index.json automatically during graceful shutdown
46
+ await this.rustProxy.stop();
47
+ // Wait for the Rust proxy to finish writing files to disk
48
+ // The Rust proxy needs time to process resources and save index.json
49
+ await new Promise((resolve) => setTimeout(resolve, 2000));
50
+ this.dependency.logger?.info(`Recording proxy stopped`);
51
+ }
91
52
  }
92
53
  }
93
54
  export async function withRecordingProxy(options, dependency, cb) {
94
55
  const proxy = new RecordingProxy(options, dependency);
95
56
  await proxy.start();
96
- await cb(proxy);
97
- await proxy.stop();
57
+ try {
58
+ await cb(proxy);
59
+ }
60
+ finally {
61
+ await proxy.stop();
62
+ }
98
63
  }
99
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVjb3JkaW5nLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3JlY29yZGluZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFHQSxPQUFPLEVBQUUsS0FBSyxFQUFpQyxNQUFNLFlBQVksQ0FBQTtBQW9CakUsTUFBTSxPQUFPLGNBQWUsU0FBUSxLQUFLO0lBQ3ZDLFNBQVMsQ0FBTztJQUNoQixZQUFZLEdBQTJCLEVBQUUsQ0FBQTtJQUV6QyxLQUFLLENBQUMsS0FBSztRQUNULElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxJQUFJLEVBQUUsQ0FBQTtRQUUzQixJQUFJLGFBQWEsR0FBRyxDQUFDLENBQUE7UUFDckIsSUFBSSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQyxHQUFHLEVBQUUsaUJBQWlCLEVBQUUsRUFBRTtZQUM5QyxNQUFNLE1BQU0sR0FBRyxhQUFhLEVBQUUsQ0FBQTtZQUU5QixpQkFBaUI7WUFDakIsSUFBSSxHQUFHLENBQUMsb0JBQW9CLENBQUMsT0FBTyxFQUFFLE9BQU8sS0FBSyxXQUFXLEVBQUU7Z0JBQzdELElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxFQUFFLElBQUksQ0FDMUIsRUFBRSxNQUFNLEVBQUUsRUFDVixZQUFZLE1BQU0sSUFBSSxHQUFHLENBQUMsb0JBQW9CLENBQUMsR0FBRyxzQkFBc0IsQ0FDekUsQ0FBQTtnQkFDRCxPQUFNO2FBQ1A7WUFFRCxhQUFhO1lBQ2IsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLHlCQUF5QixFQUFFLENBQUE7WUFDL0MsSUFBSSxNQUFNO2dCQUFFLEdBQUcsQ0FBQyxpQkFBaUIsQ0FBQyxNQUFNLENBQUMsQ0FBQTtZQUV6QyxNQUFNLFVBQVUsR0FBRyxLQUFLLENBQUMsY0FBYyxDQUFDLEdBQUcsQ0FBQyxDQUFBO1lBQzVDLE1BQU0sV0FBVyxHQUF5QjtnQkFDeEMsU0FBUyxFQUFFLElBQUksSUFBSSxFQUFFO2dCQUNyQixHQUFHLFVBQVU7Z0JBQ2IsYUFBYSxF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
64
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVjb3JkaW5nLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3JlY29yZGluZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQXNCLGNBQWMsRUFBRSxNQUFNLDBCQUEwQixDQUFBO0FBRTdFLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLGdCQUFnQixDQUFBO0FBWXBELE1BQU0sT0FBTyxjQUFjO0lBQ3pCLFNBQVMsQ0FBWTtJQUNyQixtQkFBbUIsQ0FBc0I7SUFDekMsUUFBUSxDQUFTO0lBQ2pCLFVBQVUsQ0FBYTtJQUN2QixhQUFhLENBQVM7SUFDdEIsVUFBVSxDQUEwQjtJQUVwQyxZQUFZLE9BQStCLEVBQUUsVUFBcUM7UUFDaEYsT0FBTyxLQUFLLEVBQUUsQ0FBQTtRQUNkLElBQUksQ0FBQyxVQUFVLEdBQUcsVUFBVSxJQUFJLEVBQUUsQ0FBQTtRQUVsQyx1QkFBdUI7UUFDdkIsSUFBSSxDQUFDLG1CQUFtQixHQUFHLE9BQU8sQ0FBQyxtQkFBbUIsSUFBSSxJQUFJLG1CQUFtQixDQUFDLFNBQVMsRUFBRSxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUE7UUFFN0csWUFBWTtRQUNaLElBQUksQ0FBQyxRQUFRLEdBQUcsT0FBTyxDQUFDLFFBQVEsQ0FBQTtRQUVoQyxjQUFjO1FBQ2QsSUFBSSxDQUFDLFVBQVUsR0FBRyxPQUFPLENBQUMsVUFBVSxDQUFBO1FBRXBDLE9BQU87UUFDUCxJQUFJLENBQUMsYUFBYSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUE7SUFDbkMsQ0FBQztJQUVELEtBQUssQ0FBQyxLQUFLO1FBQ1QsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLDZCQUE2QixDQUFDLENBQUE7UUFFM0QsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLGFBQWEsSUFBSSxDQUFDLENBQUE7UUFFekMsSUFBSSxDQUFDLFNBQVMsR0FBRyxNQUFNLGNBQWMsQ0FBQztZQUNwQyxRQUFRLEVBQUUsSUFBSSxDQUFDLFFBQVE7WUFDdkIsVUFBVSxFQUFFLElBQUksQ0FBQyxVQUFVO1lBQzNCLFlBQVksRUFBRSxJQUFJLENBQUMsbUJBQW1CLENBQUMsT0FBTztZQUM5QyxJQUFJLEVBQUUsU0FBUztTQUNoQixDQUFDLENBQUE7UUFFRixJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsbUNBQW1DLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQTtJQUN4RixDQUFDO0lBRUQsSUFBSSxJQUFJO1FBQ04sSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTO1lBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQyxtQkFBbUIsQ0FBQyxDQUFBO1FBQ3pELE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUE7SUFDNUIsQ0FBQztJQUVELElBQUksZ0JBQWdCO1FBQ2xCLE9BQU8sSUFBSSxDQUFDLG1CQUFtQixDQUFDLE9BQU8sQ0FBQTtJQUN6QyxDQUFDO0lBRUQsS0FBSyxDQUFDLElBQUk7UUFDUixJQUFJLElBQUksQ0FBQyxTQUFTLEVBQUU7WUFDbEIsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLDZCQUE2QixDQUFDLENBQUE7WUFFM0Qsc0VBQXNFO1lBQ3RFLDZFQUE2RTtZQUM3RSxNQUFNLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxFQUFFLENBQUE7WUFFM0IsMERBQTBEO1lBQzFELHFFQUFxRTtZQUNyRSxNQUFNLElBQUksT0FBTyxDQUFDLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQyxVQUFVLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUE7WUFFekQsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLHlCQUF5QixDQUFDLENBQUE7U0FDeEQ7SUFDSCxDQUFDO0NBQ0Y7QUFFRCxNQUFNLENBQUMsS0FBSyxVQUFVLGtCQUFrQixDQUN0QyxPQUE4QixFQUM5QixVQUFvQyxFQUNwQyxFQUE0QztJQUU1QyxNQUFNLEtBQUssR0FBRyxJQUFJLGNBQWMsQ0FBQyxPQUFPLEVBQUUsVUFBVSxDQUFDLENBQUE7SUFDckQsTUFBTSxLQUFLLENBQUMsS0FBSyxFQUFFLENBQUE7SUFDbkIsSUFBSTtRQUNGLE1BQU0sRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFBO0tBQ2hCO1lBQVM7UUFDUixNQUFNLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQTtLQUNuQjtBQUNILENBQUMifQ==
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pagespeed-quest",
3
- "version": "0.5.0",
3
+ "version": "0.6.2",
4
4
  "type": "module",
5
5
  "description": "A framework for efficient web front-end speed improvement",
6
6
  "main": "build/index.js",
@@ -52,19 +52,19 @@
52
52
  "node": ">=18"
53
53
  },
54
54
  "dependencies": {
55
- "@bitauth/libauth": "^1.17.1",
56
55
  "commander": "^11.1.0",
57
56
  "execa": "^9.3.1",
58
- "get-port": "^7.1.0",
59
- "http-mitm-proxy": "^0.9.0",
60
57
  "iconv-lite": "^0.6.3",
61
58
  "jschardet": "^3.0.0",
62
59
  "lighthouse": "^12.2.1",
63
- "loadshow": "^1.0.9",
60
+ "loadshow": "1.2.0",
61
+ "node-html-to-image": "^5.0.0",
64
62
  "node-watch": "^0.7.4",
65
63
  "pino": "^9.4.0",
66
64
  "pino-pretty": "^11.2.2",
67
65
  "prettier": "^2.1.1",
66
+ "puppeteer": "^24.31.0",
67
+ "rust-http-playback-proxy": "0.4.2",
68
68
  "tmp-promise": "^3.0.3"
69
69
  },
70
70
  "devDependencies": {
package/build/proxy.d.ts DELETED
@@ -1,35 +0,0 @@
1
- import HttpMitmProxy from 'http-mitm-proxy';
2
- import { InventoryRepository } from './inventory.js';
3
- import { Throttle, ThrottlingTransform } from './throttling.js';
4
- import { DependencyInterface, DeviceType } from './types.js';
5
- export interface ProxyOptions extends HttpMitmProxy.IProxyOptions {
6
- inventoryRepository?: InventoryRepository;
7
- throttle?: Throttle;
8
- throttlingRetryIntervalMs?: number;
9
- entryUrl?: string;
10
- deviceType?: DeviceType;
11
- }
12
- export type ProxyDependency = Pick<DependencyInterface, 'logger'>;
13
- export declare abstract class Proxy {
14
- proxyOptions: HttpMitmProxy.IProxyOptions;
15
- proxy: HttpMitmProxy.IProxy;
16
- inventoryRepository: InventoryRepository;
17
- throttle?: Throttle;
18
- throttlingRetryIntervalMs: number;
19
- entryUrl?: string;
20
- deviceType?: DeviceType;
21
- dependency: ProxyDependency;
22
- constructor(options?: ProxyOptions, dependency?: ProxyDependency);
23
- static contextRequest(ctx: HttpMitmProxy.IContext): {
24
- method: string;
25
- url: string;
26
- };
27
- createThrottlingTransform(): ThrottlingTransform | void;
28
- abstract setup(): Promise<void>;
29
- abstract shutdown(): Promise<void>;
30
- start(): Promise<void>;
31
- get port(): number;
32
- get inventoryDirPath(): string;
33
- stop(): Promise<void>;
34
- }
35
- export declare function withProxy<ProxyType extends Proxy>(proxy: ProxyType, fn: (proxy: ProxyType) => Promise<void>): Promise<void>;
package/build/proxy.js DELETED
@@ -1,96 +0,0 @@
1
- import Crypto from 'crypto';
2
- import Fsp from 'fs/promises';
3
- import Http from 'http';
4
- import Https from 'https';
5
- import Os from 'os';
6
- import Path from 'path';
7
- import GetPort from 'get-port';
8
- import HttpMitmProxy from 'http-mitm-proxy';
9
- import { InventoryRepository } from './inventory.js';
10
- import { ThrottlingTransform } from './throttling.js';
11
- export class Proxy {
12
- proxyOptions;
13
- proxy;
14
- inventoryRepository;
15
- throttle;
16
- throttlingRetryIntervalMs;
17
- entryUrl;
18
- deviceType;
19
- dependency;
20
- constructor(options, dependency) {
21
- options ||= {};
22
- this.dependency = dependency || {};
23
- // Proxy
24
- this.proxyOptions = options;
25
- this.proxy = HttpMitmProxy();
26
- // Inventory repository
27
- this.inventoryRepository = options.inventoryRepository ?? new InventoryRepository(undefined, this.dependency);
28
- // Throttle
29
- if (options.throttle)
30
- this.throttle = options.throttle;
31
- this.throttlingRetryIntervalMs = options.throttlingRetryIntervalMs || 10;
32
- // Entry URL
33
- this.entryUrl = options.entryUrl;
34
- // Device type
35
- this.deviceType = options.deviceType;
36
- }
37
- static contextRequest(ctx) {
38
- if (!ctx.clientToProxyRequest.headers.host)
39
- throw new Error('ctx.clientToProxyRequest.headers.host is empty');
40
- const url = [
41
- ctx.isSSL ? 'https://' : 'http://',
42
- ctx.clientToProxyRequest.headers.host,
43
- ctx.clientToProxyRequest.url,
44
- ].join('');
45
- const method = (ctx.clientToProxyRequest.method || 'get').toLowerCase();
46
- return {
47
- method,
48
- url,
49
- };
50
- }
51
- createThrottlingTransform() {
52
- if (this.throttle) {
53
- return new ThrottlingTransform(this.throttle, this.throttlingRetryIntervalMs);
54
- }
55
- }
56
- async start() {
57
- if (this.throttle)
58
- this.throttle.start();
59
- const sslCaDir = this.proxyOptions.sslCaDir || process.env.SSL_CA_DIR || Path.join(Os.homedir(), '.pagespeed-quest/ca');
60
- const port = Number(this.proxyOptions.port || process.env.PORT || (await GetPort()));
61
- const options = {
62
- port,
63
- sslCaDir,
64
- httpAgent: new Http.Agent({
65
- keepAlive: true,
66
- }),
67
- httpsAgent: new Https.Agent({
68
- keepAlive: true,
69
- secureOptions: Crypto.constants.SSL_OP_LEGACY_SERVER_CONNECT,
70
- }),
71
- };
72
- await this.setup();
73
- await Fsp.mkdir(options.sslCaDir, { recursive: true });
74
- await new Promise((resolve, reject) => this.proxy.listen(options, (error) => (error ? reject(error) : resolve())));
75
- this.dependency.logger?.info(`Proxy started to listening on port ${this.port}`);
76
- }
77
- get port() {
78
- return this.proxy.httpPort;
79
- }
80
- get inventoryDirPath() {
81
- return this.inventoryRepository.dirPath;
82
- }
83
- async stop() {
84
- this.proxy.close();
85
- await this.shutdown();
86
- if (this.throttle)
87
- this.throttle.stop();
88
- this.dependency.logger?.info(`Proxy stopped`);
89
- }
90
- }
91
- export async function withProxy(proxy, fn) {
92
- await proxy.start();
93
- await fn(proxy);
94
- await proxy.stop();
95
- }
96
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJveHkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvcHJveHkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxNQUFNLE1BQU0sUUFBUSxDQUFBO0FBQzNCLE9BQU8sR0FBRyxNQUFNLGFBQWEsQ0FBQTtBQUM3QixPQUFPLElBQUksTUFBTSxNQUFNLENBQUE7QUFDdkIsT0FBTyxLQUFLLE1BQU0sT0FBTyxDQUFBO0FBQ3pCLE9BQU8sRUFBRSxNQUFNLElBQUksQ0FBQTtBQUNuQixPQUFPLElBQUksTUFBTSxNQUFNLENBQUE7QUFFdkIsT0FBTyxPQUFPLE1BQU0sVUFBVSxDQUFBO0FBQzlCLE9BQU8sYUFBYSxNQUFNLGlCQUFpQixDQUFBO0FBRTNDLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLGdCQUFnQixDQUFBO0FBQ3BELE9BQU8sRUFBWSxtQkFBbUIsRUFBRSxNQUFNLGlCQUFpQixDQUFBO0FBYS9ELE1BQU0sT0FBZ0IsS0FBSztJQUN6QixZQUFZLENBQThCO0lBQzFDLEtBQUssQ0FBdUI7SUFDNUIsbUJBQW1CLENBQXNCO0lBQ3pDLFFBQVEsQ0FBVztJQUNuQix5QkFBeUIsQ0FBUztJQUNsQyxRQUFRLENBQVM7SUFDakIsVUFBVSxDQUFhO0lBQ3ZCLFVBQVUsQ0FBaUI7SUFFM0IsWUFBWSxPQUFzQixFQUFFLFVBQTRCO1FBQzlELE9BQU8sS0FBSyxFQUFFLENBQUE7UUFDZCxJQUFJLENBQUMsVUFBVSxHQUFHLFVBQVUsSUFBSSxFQUFFLENBQUE7UUFFbEMsUUFBUTtRQUNSLElBQUksQ0FBQyxZQUFZLEdBQUcsT0FBTyxDQUFBO1FBQzNCLElBQUksQ0FBQyxLQUFLLEdBQUcsYUFBYSxFQUFFLENBQUE7UUFFNUIsdUJBQXVCO1FBQ3ZCLElBQUksQ0FBQyxtQkFBbUIsR0FBRyxPQUFPLENBQUMsbUJBQW1CLElBQUksSUFBSSxtQkFBbUIsQ0FBQyxTQUFTLEVBQUUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFBO1FB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
@@ -1,33 +0,0 @@
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
- }
@@ -1,89 +0,0 @@
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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