aboutsummaryrefslogtreecommitdiffstats
path: root/packages/excalidraw/subset/woff2/woff2-loader.ts
diff options
context:
space:
mode:
authorkj_sh6042026-03-15 16:19:35 -0400
committerkj_sh6042026-03-15 16:19:35 -0400
commit6ec259a0e71174651bae95d4628138bf6fd68742 (patch)
tree5e33c6a5ec091ecabfcb257fdc7b6a88ed8754ac /packages/excalidraw/subset/woff2/woff2-loader.ts
parent16c8578b15c727f22921f8a80a56ee4d4e7f2272 (diff)
refactor: packages/
Diffstat (limited to 'packages/excalidraw/subset/woff2/woff2-loader.ts')
-rw-r--r--packages/excalidraw/subset/woff2/woff2-loader.ts76
1 files changed, 76 insertions, 0 deletions
diff --git a/packages/excalidraw/subset/woff2/woff2-loader.ts b/packages/excalidraw/subset/woff2/woff2-loader.ts
new file mode 100644
index 0000000..446dc9f
--- /dev/null
+++ b/packages/excalidraw/subset/woff2/woff2-loader.ts
@@ -0,0 +1,76 @@
+/**
+ * DON'T depend on anything from the outside like `promiseTry`, as this module is part of a separate lazy-loaded chunk.
+ *
+ * Including anything from the main chunk would include the whole chunk by default.
+ * Even it it would be tree-shaken during build, it won't be tree-shaken in dev.
+ *
+ * In the future consider separating common utils into a separate shared chunk.
+ */
+
+import binary from "./woff2-wasm";
+import bindings from "./woff2-bindings";
+
+/**
+ * Lazy loads wasm and respective bindings for woff2 compression and decompression.
+ */
+type Vector = any;
+
+let loadedWasm: ReturnType<typeof load> | null = null;
+
+// re-map from internal vector into byte array
+function convertFromVecToUint8Array(vector: Vector): Uint8Array {
+ const arr = [];
+ for (let i = 0, l = vector.size(); i < l; i++) {
+ arr.push(vector.get(i));
+ }
+
+ return new Uint8Array(arr);
+}
+
+// TODO: consider adding support for fetching the wasm from an URL (external CDN, data URL, etc.)
+const load = (): Promise<{
+ compress: (buffer: ArrayBuffer) => Uint8Array;
+ decompress: (buffer: ArrayBuffer) => Uint8Array;
+}> => {
+ return new Promise((resolve, reject) => {
+ try {
+ // initializing the module manually, so that we could pass in the wasm binary
+ // note that the `bindings.then` is not not promise/A+ compliant, hence the need for another explicit try/catch
+ bindings({ wasmBinary: binary }).then(
+ (module: {
+ woff2Enc: (buffer: ArrayBuffer, byteLength: number) => Vector;
+ woff2Dec: (buffer: ArrayBuffer, byteLength: number) => Vector;
+ }) => {
+ try {
+ // re-exporting only compress and decompress functions (also avoids infinite loop inside emscripten bindings)
+ const woff2 = {
+ compress: (buffer: ArrayBuffer) =>
+ convertFromVecToUint8Array(
+ module.woff2Enc(buffer, buffer.byteLength),
+ ),
+ decompress: (buffer: ArrayBuffer) =>
+ convertFromVecToUint8Array(
+ module.woff2Dec(buffer, buffer.byteLength),
+ ),
+ };
+
+ resolve(woff2);
+ } catch (e) {
+ reject(e);
+ }
+ },
+ );
+ } catch (e) {
+ reject(e);
+ }
+ });
+};
+
+// lazy loaded default export
+export default (): ReturnType<typeof load> => {
+ if (!loadedWasm) {
+ loadedWasm = load();
+ }
+
+ return loadedWasm;
+};