Skip to content

Commit 998bd9c

Browse files
authored
Replace zee-worker.js with compression streams API (#5584)
2 parents 3a1777b + 60c4e4c commit 998bd9c

File tree

7 files changed

+67
-177
lines changed

7 files changed

+67
-177
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: 62 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -2,107 +2,80 @@
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<ArrayBuffer>>
7+
): Promise<Uint8Array<ArrayBuffer>> {
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+
try {
12+
while (true) {
13+
const { done, value } = await reader.read();
14+
if (done) break;
15+
if (value) {
16+
chunks.push(value);
17+
}
18+
}
19+
} finally {
20+
reader.releaseLock();
21+
}
1122

12-
type ZeeWorkerData = {
13-
callbackID: number;
14-
type: 'success' | 'error';
15-
data: any;
16-
};
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;
30+
}
1731

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;
25-
}
26-
};
32+
return result;
2733
}
2834

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-
});
35+
// The Streams API doesn't support SAB, and so we need to copy from these to
36+
// use these API's.
37+
function copyBufferIfShared(buffer: Uint8Array): Uint8Array<ArrayBuffer> {
38+
// Check if the buffer is a view into a larger ArrayBuffer (shared)
39+
if (buffer.buffer instanceof SharedArrayBuffer) {
40+
// Create a new buffer with its own ArrayBuffer
41+
return new Uint8Array(buffer);
4642
}
43+
// Return the original buffer if it's not shared
44+
return buffer as Uint8Array<ArrayBuffer>;
45+
}
4746

48-
const zeeWorker = new Worker(zeeWorkerPath);
49-
workerOnMessage(zeeWorker);
50-
47+
export async function compress(
48+
data: string | Uint8Array
49+
): Promise<Uint8Array<ArrayBuffer>> {
50+
// Encode the data if it's a string
5151
const arrayData =
5252
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-
});
53+
54+
// Create a gzip compression stream
55+
const compressionStream = new CompressionStream('gzip');
56+
57+
// Write the data to the compression stream
58+
const writer = compressionStream.writable.getWriter();
59+
writer.write(copyBufferIfShared(arrayData));
60+
writer.close();
61+
62+
// Read the compressed data back into a buffer
63+
return readableStreamToBuffer(compressionStream.readable);
6864
}
6965

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-
}
66+
export async function decompress(
67+
data: Uint8Array
68+
): Promise<Uint8Array<ArrayBuffer>> {
69+
// Create a gzip compression stream
70+
const decompressionStream = new DecompressionStream('gzip');
71+
72+
// Write the data to the compression stream
73+
const writer = decompressionStream.writable.getWriter();
74+
writer.write(copyBufferIfShared(data));
75+
writer.close();
8976

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-
});
77+
// Read the compressed data back into a buffer
78+
return readableStreamToBuffer(decompressionStream.readable);
10679
}
10780

10881
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)