Skip to content

Commit c3806dd

Browse files
committed
Replace zee-worker.js with compression streams API
1 parent 48c7847 commit c3806dd

File tree

7 files changed

+56
-178
lines changed

7 files changed

+56
-178
lines changed

.prettierignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ src/types/libdef/npm
33
docs-user/js
44
docs-user/css
55
src/test/fixtures/upgrades
6-
res/zee-worker.js
76
dist
87
coverage
98
taskcluster/

res/zee-worker.js

Lines changed: 0 additions & 80 deletions
This file was deleted.

src/test/components/__snapshots__/MenuButtons.test.tsx.snap

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2211,7 +2211,7 @@ exports[`app/MenuButtons <Publish> matches the snapshot for the menu buttons and
22112211
class="menuButtonsDownloadSize"
22122212
>
22132213
(
2214-
1.58 kB
2214+
1.56 kB
22152215
)
22162216
</span>
22172217
</a>
@@ -2329,7 +2329,7 @@ exports[`app/MenuButtons <Publish> matches the snapshot for the opened panel for
23292329
class="menuButtonsDownloadSize"
23302330
>
23312331
(
2332-
1.56 kB
2332+
1.54 kB
23332333
)
23342334
</span>
23352335
</a>
@@ -2442,7 +2442,7 @@ exports[`app/MenuButtons <Publish> matches the snapshot for the opened panel for
24422442
class="menuButtonsDownloadSize"
24432443
>
24442444
(
2445-
1.58 kB
2445+
1.56 kB
24462446
)
24472447
</span>
24482448
</a>

src/test/custom-environment.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,5 +39,7 @@ export default class CustomTestEnvironment extends TestEnvironment {
3939
this.global.Request = Request;
4040
this.global.Response = Response;
4141
this.global.ReadableStream = ReadableStream;
42+
this.global.CompressionStream = CompressionStream;
43+
this.global.DecompressionStream = DecompressionStream;
4244
}
4345
}

src/test/setup.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,6 @@ if (process.env.TZ !== 'UTC') {
2424
fetchMock.mockGlobal();
2525
(global as any).fetchMock = fetchMock;
2626

27-
// 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/zee-worker.js', () => './res/zee-worker.js');
3027
// Install a Worker class which is similar to the DOM Worker class.
3128
(global as any).Worker = NodeWorker;
3229

src/utils/gz.ts

Lines changed: 51 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -2,107 +2,68 @@
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 zeeWorkerPath from 'firefox-profiler-res/zee-worker.js';
5+
async function readableStreamToBuffer(
6+
stream: ReadableStream<Uint8Array>
7+
): Promise<Uint8Array> {
8+
const reader = stream.getReader();
9+
const chunks: Uint8Array[] = [];
610

7-
const zeeCallbacks: Array<{
8-
success: (data: any) => void;
9-
error: (error: any) => void;
10-
} | null> = [];
11-
12-
type ZeeWorkerData = {
13-
callbackID: number;
14-
type: 'success' | 'error';
15-
data: any;
16-
};
17-
18-
function workerOnMessage(zeeWorker: Worker) {
19-
zeeWorker.onmessage = function (msg: MessageEvent) {
20-
const data = msg.data as ZeeWorkerData;
21-
const callbacks = zeeCallbacks[data.callbackID];
22-
if (callbacks) {
23-
callbacks[data.type](data.data);
24-
zeeCallbacks[data.callbackID] = null;
11+
try {
12+
while (true) {
13+
const { done, value } = await reader.read();
14+
if (done) break;
15+
if (value) {
16+
chunks.push(value);
17+
}
2518
}
26-
};
27-
}
19+
} finally {
20+
reader.releaseLock();
21+
}
2822

29-
// Neuters data's buffer, if data is a typed array.
30-
export async function compress(
31-
data: string | Uint8Array,
32-
compressionLevel?: number
33-
): Promise<Uint8Array<ArrayBuffer>> {
34-
if (!(typeof window === 'object' && 'Worker' in window)) {
35-
// Try to fall back to Node's zlib library.
36-
const zlib = await import('zlib');
37-
return new Promise((resolve, reject) => {
38-
zlib.gzip(data, (errorOrNull, result) => {
39-
if (errorOrNull) {
40-
reject(errorOrNull);
41-
} else {
42-
resolve(new Uint8Array(result.buffer as ArrayBuffer));
43-
}
44-
});
45-
});
23+
// Calculate total length and combine chunks
24+
const totalLength = chunks.reduce((sum, chunk) => sum + chunk.length, 0);
25+
const result = new Uint8Array(totalLength);
26+
let offset = 0;
27+
for (const chunk of chunks) {
28+
result.set(chunk, offset);
29+
offset += chunk.length;
4630
}
4731

48-
const zeeWorker = new Worker(zeeWorkerPath);
49-
workerOnMessage(zeeWorker);
32+
return result;
33+
}
5034

35+
export async function compress(
36+
data: string | Uint8Array<ArrayBuffer>
37+
): Promise<Uint8Array> {
38+
// Encode the data if it's a string
5139
const arrayData =
5240
typeof data === 'string' ? new TextEncoder().encode(data) : data;
53-
return new Promise(function (resolve, reject) {
54-
zeeWorker.postMessage(
55-
{
56-
request: 'compress',
57-
data: arrayData,
58-
compressionLevel: compressionLevel,
59-
callbackID: zeeCallbacks.length,
60-
},
61-
[arrayData.buffer]
62-
);
63-
zeeCallbacks.push({
64-
success: resolve,
65-
error: reject,
66-
});
67-
});
41+
42+
// Create a gzip compression stream
43+
const compressionStream = new CompressionStream('gzip');
44+
45+
// Write the data to the compression stream
46+
const writer = compressionStream.writable.getWriter();
47+
writer.write(arrayData);
48+
writer.close();
49+
50+
// Read the compressed data back into a buffer
51+
return readableStreamToBuffer(compressionStream.readable);
6852
}
6953

70-
// Neuters data's buffer, if data is a typed array.
71-
export async function decompress(data: Uint8Array): Promise<Uint8Array> {
72-
if (!(typeof window === 'object' && 'Worker' in window)) {
73-
// Handle the case where we're not running in the browser, e.g. when
74-
// this code is used as part of a library in a Node project.
75-
// We don't get here when running Firefox profiler tests, because our
76-
// tests create a mock window with a mock Worker class.
77-
// Try to fall back to Node's zlib library.
78-
const zlib = await import('zlib');
79-
return new Promise((resolve, reject) => {
80-
zlib.gunzip(data, (errorOrNull, result) => {
81-
if (errorOrNull) {
82-
reject(errorOrNull);
83-
} else {
84-
resolve(new Uint8Array(result.buffer as ArrayBuffer));
85-
}
86-
});
87-
});
88-
}
54+
export async function decompress(
55+
data: Uint8Array<ArrayBuffer>
56+
): Promise<Uint8Array> {
57+
// Create a gzip compression stream
58+
const decompressionStream = new DecompressionStream('gzip');
59+
60+
// Write the data to the compression stream
61+
const writer = decompressionStream.writable.getWriter();
62+
writer.write(data);
63+
writer.close();
8964

90-
const zeeWorker = new Worker(zeeWorkerPath);
91-
return new Promise(function (resolve, reject) {
92-
workerOnMessage(zeeWorker);
93-
zeeWorker.postMessage(
94-
{
95-
request: 'decompress',
96-
data: data,
97-
callbackID: zeeCallbacks.length,
98-
},
99-
[data.buffer]
100-
);
101-
zeeCallbacks.push({
102-
success: resolve,
103-
error: reject,
104-
});
105-
});
65+
// Read the compressed data back into a buffer
66+
return readableStreamToBuffer(decompressionStream.readable);
10667
}
10768

10869
export function isGzip(data: Uint8Array): boolean {

webpack.config.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,6 @@ const config = {
9999
patterns: [
100100
'res/_headers',
101101
'res/_redirects',
102-
'res/zee-worker.js',
103102
'res/contribute.json',
104103
'res/robots.txt',
105104
'res/service-worker-compat.js',

0 commit comments

Comments
 (0)