Skip to content

Commit 4cb392a

Browse files
authored
Worker + compression cleanups (#5602)
2 parents da1ad17 + 10fa0d0 commit 4cb392a

File tree

6 files changed

+48
-39
lines changed

6 files changed

+48
-39
lines changed

src/test/fixtures/node-worker.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ function getWorkerScript(file: string): string {
2323
onmessage: function () {},
2424
DecompressionStream,
2525
CompressionStream,
26+
Response,
2627
};
2728
2829
vm.runInNewContext(scriptContent, sandbox, { filename: "${file}" });

src/test/setup.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ fetchMock.mockGlobal();
2525
(global as any).fetchMock = fetchMock;
2626

2727
// Mock the effects of the file-loader which our Webpack config defines
28-
// for JS files under res: The "default export" is the path to the file.
29-
jest.mock('firefox-profiler-res/gz-worker.js', () => './res/gz-worker.js');
28+
// for files ending in .worker.js: The "default export" is the path to the file.
29+
jest.mock('../utils/gz.worker.js', () => 'src/utils/gz.worker.js');
3030

3131
// Install a Worker class which is similar to the DOM Worker class.
3232
(global as any).Worker = NodeWorker;

src/types/globals/global.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
// Added by webpack's DefinePlugin
66
declare const AVAILABLE_STAGING_LOCALES: string[] | null;
77

8-
declare module 'firefox-profiler-res/*.js' {
8+
declare module '*.worker.js' {
99
const content: string;
1010
export default content;
1111
}

src/utils/gz.ts

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* License, v. 2.0. If a copy of the MPL was not distributed with this
33
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
44

5-
import gzWorkerPath from 'firefox-profiler-res/gz-worker.js';
5+
import gzWorkerPath from './gz.worker.js';
66

77
function runGzWorker(
88
kind: 'compress' | 'decompress',
@@ -34,12 +34,45 @@ export async function compress(
3434
// Encode the data if it's a string
3535
const arrayData =
3636
typeof data === 'string' ? new TextEncoder().encode(data) : data;
37+
38+
if (!(typeof window === 'object' && 'Worker' in window)) {
39+
// Try to fall back to Node's zlib library.
40+
const zlib = await import('zlib');
41+
return new Promise((resolve, reject) => {
42+
zlib.gzip(data, (errorOrNull, result) => {
43+
if (errorOrNull) {
44+
reject(errorOrNull);
45+
} else {
46+
resolve(new Uint8Array(result.buffer as ArrayBuffer));
47+
}
48+
});
49+
});
50+
}
51+
3752
return runGzWorker('compress', arrayData);
3853
}
3954

4055
export async function decompress(
4156
data: Uint8Array<ArrayBuffer>
4257
): Promise<Uint8Array<ArrayBuffer>> {
58+
if (!(typeof window === 'object' && 'Worker' in window)) {
59+
// Handle the case where we're not running in the browser, e.g. when
60+
// this code is used as part of a library in a Node project.
61+
// We don't get here when running Firefox profiler tests, because our
62+
// tests create a mock window with a mock Worker class.
63+
// Try to fall back to Node's zlib library.
64+
const zlib = await import('zlib');
65+
return new Promise((resolve, reject) => {
66+
zlib.gunzip(data, (errorOrNull, result) => {
67+
if (errorOrNull) {
68+
reject(errorOrNull);
69+
} else {
70+
resolve(new Uint8Array(result.buffer as ArrayBuffer));
71+
}
72+
});
73+
});
74+
}
75+
4376
return runGzWorker('decompress', data);
4477
}
4578

Lines changed: 4 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -3,35 +3,11 @@
33
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
44

55
async function readableStreamToBuffer(stream) {
6-
const reader = stream.getReader();
7-
const chunks = [];
8-
9-
try {
10-
while (true) {
11-
const { done, value } = await reader.read();
12-
if (done) break;
13-
if (value) {
14-
chunks.push(value);
15-
}
16-
}
17-
} finally {
18-
reader.releaseLock();
19-
}
20-
21-
// Calculate total length and combine chunks
22-
const totalLength = chunks.reduce((sum, chunk) => sum + chunk.length, 0);
23-
const result = new Uint8Array(totalLength);
24-
let offset = 0;
25-
for (const chunk of chunks) {
26-
result.set(chunk, offset);
27-
offset += chunk.length;
28-
}
29-
30-
return result;
6+
return new Uint8Array(await new Response(stream).arrayBuffer());
317
}
328

339
onmessage = async (e) => {
34-
let data = e.data;
10+
const data = e.data;
3511
if (data.kind === 'compress') {
3612
// Create a gzip compression stream
3713
const compressionStream = new CompressionStream('gzip');
@@ -42,7 +18,7 @@ onmessage = async (e) => {
4218
writer.close();
4319

4420
// Read the compressed data back into a buffer
45-
let result = await readableStreamToBuffer(compressionStream.readable);
21+
const result = await readableStreamToBuffer(compressionStream.readable);
4622
postMessage(result, [result.buffer]);
4723
} else if (data.kind === 'decompress') {
4824
// Create a gzip compression stream
@@ -54,7 +30,7 @@ onmessage = async (e) => {
5430
writer.close();
5531

5632
// Read the compressed data back into a buffer
57-
let result = await readableStreamToBuffer(decompressionStream.readable);
33+
const result = await readableStreamToBuffer(decompressionStream.readable);
5834
postMessage(result, [result.buffer]);
5935
} else {
6036
throw new Error('unknown message');

webpack.config.js

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,15 @@ const config = {
3232
devtool: 'source-map',
3333
module: {
3434
rules: [
35-
{
36-
test: /\.js$/,
37-
use: ['file-loader'],
38-
include: [path.join(__dirname, 'res')],
39-
},
4035
{
4136
test: /\.(js|ts|tsx)$/,
4237
use: ['babel-loader'],
43-
include: [path.join(__dirname, 'src')],
38+
include: includes,
39+
},
40+
{
41+
test: /\.worker\.js$/,
42+
use: ['file-loader'],
43+
include: includes,
4444
},
4545
{
4646
test: /\.json$/,
@@ -99,7 +99,6 @@ const config = {
9999
patterns: [
100100
'res/_headers',
101101
'res/_redirects',
102-
'res/gz-worker.js',
103102
'res/contribute.json',
104103
'res/robots.txt',
105104
'res/service-worker-compat.js',

0 commit comments

Comments
 (0)