diff options
Diffstat (limited to 'packages/excalidraw/subset/woff2/woff2-loader.ts')
| -rw-r--r-- | packages/excalidraw/subset/woff2/woff2-loader.ts | 76 |
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; +}; |
