|
1 | | -const Base64Url = { |
2 | | - from(b64: string) { |
3 | | - return b64.replace(/=+/g, "").replace(/\+/g, "-").replace(/\//g, "_"); |
4 | | - }, |
5 | | - toBase64(b64Url: string) { |
6 | | - return b64Url.replace(/-/g, "+").replace(/_/g, "/"); |
7 | | - }, |
8 | | -}; |
9 | | - |
10 | | -const blobToBase64 = (blob: Blob): Promise<string> => { |
11 | | - const reader = new FileReader(); |
12 | | - reader.readAsDataURL(blob); |
13 | | - return new Promise(resolve => { |
14 | | - reader.onloadend = () => { |
15 | | - const dataUrl = reader.result as string; |
16 | | - resolve(dataUrl.substring(dataUrl.indexOf(";") + 1).replace(/^base64,/, "")); |
17 | | - }; |
18 | | - }); |
19 | | -}; |
20 | | - |
21 | | -const base64ToUint8Array = (base64: string) => { |
22 | | - base64 = base64.replace(/[\s\t\n]/g, ""); |
23 | | - if (base64.length % 4 !== 0) { |
24 | | - base64 = base64 + "=".repeat(4 - (base64.length % 4)); |
25 | | - } |
26 | | - const bytesString = atob(base64); |
27 | | - const length = bytesString.length; |
28 | | - const bytes = new Uint8Array(length); |
29 | | - for (let i = 0; i < length; i++) { |
30 | | - bytes[i] = bytesString.charCodeAt(i); |
31 | | - } |
32 | | - return bytes; |
33 | | -}; |
| 1 | +import { decode, encode } from "./Base64"; |
34 | 2 |
|
35 | 3 | class JSONGzip { |
36 | 4 | public static async compress( |
37 | 5 | value: string, |
38 | 6 | format: "base64" | "base64url" = "base64", |
39 | 7 | valueType: "string" | "json" = "json", |
40 | 8 | ) { |
41 | | - const stream = new Blob([valueType === "string" ? value : JSON.stringify(value)], { |
42 | | - type: "application/json", |
43 | | - }).stream(); |
44 | | - const compressedStream = stream.pipeThrough(new CompressionStream("gzip")); |
45 | | - const response = new Response(compressedStream); |
46 | | - const blob = await response.blob(); |
47 | | - const base64 = await blobToBase64(blob); |
48 | | - // const buffer = await response.blob().then(blob => blob.arrayBuffer()); |
49 | | - // const base64 = btoa(String.fromCharCode(...new Uint8Array(buffer))); |
50 | | - if (format === "base64url") { |
51 | | - return Base64Url.from(base64); |
52 | | - } |
53 | | - return base64; |
| 9 | + const input = valueType === "string" ? value : JSON.stringify(value); |
| 10 | + const compressionStream = new Blob([input], { type: "application/json" }) |
| 11 | + .stream() |
| 12 | + .pipeThrough(new CompressionStream("gzip")); |
| 13 | + return new Response(compressionStream).arrayBuffer().then(buffer => encode(buffer, format === "base64url")); |
54 | 14 | } |
55 | 15 |
|
56 | 16 | public static async decompress(compressed: string, format: "base64" | "base64url" = "base64") { |
57 | | - const base64Input = format === "base64url" ? Base64Url.toBase64(compressed) : compressed; |
58 | | - const buffer = base64ToUint8Array(base64Input); |
59 | | - const stream = new Blob([buffer], { type: "text/plain" }).stream(); |
60 | | - const decompressedStream = stream.pipeThrough(new DecompressionStream("gzip")); |
61 | | - const response = new Response(decompressedStream); |
62 | | - return response |
| 17 | + const buffer = decode(compressed, format === "base64url"); |
| 18 | + const decompressionStream = new Blob([buffer], { type: "application/json" }) |
| 19 | + .stream() |
| 20 | + .pipeThrough(new DecompressionStream("gzip")); |
| 21 | + return new Response(decompressionStream) |
63 | 22 | .blob() |
64 | 23 | .then(blob => blob.text()) |
65 | 24 | .then(text => JSON.parse(text)); |
|
0 commit comments