@extend-ai/react-xlsx 0.10.2 → 0.10.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -24,6 +24,69 @@ pnpm add @extend-ai/react-xlsx react react-dom
24
24
 
25
25
  `react` and `react-dom` are peer dependencies.
26
26
 
27
+ ## WebAssembly Asset
28
+
29
+ Workbook parsing and calculation run through the `@dukelib/sheets-wasm` WebAssembly module. The module loads lazily, on the first workbook parse.
30
+
31
+ Most apps can use the default loader. If your bundler or deployment needs to host the WASM binary somewhere explicit, configure it before the first parse:
32
+
33
+ ```ts
34
+ import { setWasmSource } from "@extend-ai/react-xlsx";
35
+
36
+ setWasmSource("https://cdn.example.com/duke_sheets_wasm_bg.wasm");
37
+ // or pass a URL, Request, Response, ArrayBuffer/TypedArray, or compiled WebAssembly.Module
38
+ ```
39
+
40
+ The Duke WASM binary is also exposed as a package subpath:
41
+
42
+ ```ts
43
+ import wasmUrl from "@extend-ai/react-xlsx/duke_sheets_wasm_bg.wasm?url";
44
+ import { setWasmSource } from "@extend-ai/react-xlsx";
45
+
46
+ setWasmSource(wasmUrl);
47
+ ```
48
+
49
+ ### Next.js Turbopack
50
+
51
+ Turbopack may try to treat `.wasm?url` imports as WebAssembly modules during static analysis. For Turbopack apps, use a plain public or CDN URL instead of importing the WASM file with `?url`.
52
+
53
+ Copy the WASM file into your app's `public/` directory:
54
+
55
+ ```bash
56
+ cp node_modules/@extend-ai/react-xlsx/dist/duke_sheets_wasm_bg.wasm public/duke_sheets_wasm_bg.wasm
57
+ ```
58
+
59
+ Then configure the source from a shared client module before any workbook is parsed:
60
+
61
+ ```ts
62
+ // app/xlsx-wasm.ts
63
+ "use client";
64
+
65
+ import { setWasmSource } from "@extend-ai/react-xlsx";
66
+
67
+ setWasmSource("/duke_sheets_wasm_bg.wasm");
68
+ ```
69
+
70
+ Import that setup module before rendering any XLSX viewer, provider, or controller:
71
+
72
+ ```tsx
73
+ // app/workbook-preview.tsx
74
+ "use client";
75
+
76
+ import "./xlsx-wasm";
77
+ import { XlsxViewer } from "@extend-ai/react-xlsx";
78
+
79
+ export function WorkbookPreview({ file }: { file: ArrayBuffer }) {
80
+ return <XlsxViewer file={file} height={600} />;
81
+ }
82
+ ```
83
+
84
+ If several routes use the viewer, import the same setup module from a shared client boundary such as `app/providers.tsx`. Calling `setWasmSource()` more than once with the same source is fine before initialization, but the source must not change after the first parse because the WASM module is initialized once per JavaScript context.
85
+
86
+ Configured string, URL, Request URL, bytes, and `WebAssembly.Module` sources are forwarded into the XLSX worker. `Response` sources are supported on the main thread; worker-backed parsing is skipped for that source type.
87
+
88
+ You can also call `initWasm()` (optionally with a source) ahead of time to warm the module before the first workbook is opened.
89
+
27
90
  ## Main Entry Points
28
91
 
29
92
  The package exports three useful levels of API:
Binary file
package/dist/index.cjs CHANGED
@@ -34,6 +34,8 @@ __export(index_exports, {
34
34
  XlsxFileSizeLimitExceededError: () => XlsxFileSizeLimitExceededError,
35
35
  XlsxViewer: () => XlsxViewer,
36
36
  XlsxViewerProvider: () => XlsxViewerProvider,
37
+ initWasm: () => initWasm,
38
+ setWasmSource: () => setWasmSource,
37
39
  useXlsxViewer: () => useXlsxViewer,
38
40
  useXlsxViewerCharts: () => useXlsxViewerCharts,
39
41
  useXlsxViewerController: () => useXlsxViewerController,
@@ -6421,13 +6423,58 @@ function tryRecalculate(workbook) {
6421
6423
 
6422
6424
  // src/wasm.ts
6423
6425
  var wasmModulePromise = null;
6426
+ var hasConfiguredWasmSource = false;
6427
+ var configuredWasmSource;
6428
+ var configuredWorkerWasmSource;
6429
+ function bufferSourceToArrayBuffer(source) {
6430
+ if (source instanceof ArrayBuffer) {
6431
+ return source.slice(0);
6432
+ }
6433
+ const bytes = new Uint8Array(source.buffer, source.byteOffset, source.byteLength);
6434
+ const copy = new Uint8Array(bytes);
6435
+ return copy.buffer;
6436
+ }
6437
+ function sourceToWorkerSource(source) {
6438
+ if (typeof source === "string") {
6439
+ return source;
6440
+ }
6441
+ if (typeof URL !== "undefined" && source instanceof URL) {
6442
+ return source.href;
6443
+ }
6444
+ if (typeof Request !== "undefined" && source instanceof Request) {
6445
+ return source.url;
6446
+ }
6447
+ if (source instanceof ArrayBuffer || ArrayBuffer.isView(source)) {
6448
+ return bufferSourceToArrayBuffer(source);
6449
+ }
6450
+ if (typeof WebAssembly !== "undefined" && source instanceof WebAssembly.Module) {
6451
+ return source;
6452
+ }
6453
+ return void 0;
6454
+ }
6455
+ function setWasmSource(source) {
6456
+ hasConfiguredWasmSource = true;
6457
+ configuredWasmSource = source;
6458
+ configuredWorkerWasmSource = sourceToWorkerSource(source);
6459
+ }
6460
+ function initWasm(source) {
6461
+ if (source !== void 0) {
6462
+ setWasmSource(source);
6463
+ }
6464
+ return getSheetsWasmModule();
6465
+ }
6466
+ function canUseConfiguredWasmSourceInWorker() {
6467
+ return !hasConfiguredWasmSource || configuredWorkerWasmSource !== void 0;
6468
+ }
6469
+ function getConfiguredWorkerWasmSource() {
6470
+ return configuredWorkerWasmSource;
6471
+ }
6424
6472
  function getSheetsWasmModule() {
6425
6473
  if (!wasmModulePromise) {
6426
6474
  wasmModulePromise = import("@dukelib/sheets-wasm").then(async (mod) => {
6427
- try {
6428
- const wasmAsset = await import("@dukelib/sheets-wasm/duke_sheets_wasm_bg.wasm?url");
6429
- await mod.default(wasmAsset.default);
6430
- } catch {
6475
+ if (configuredWasmSource !== void 0) {
6476
+ await mod.default(configuredWasmSource);
6477
+ } else {
6431
6478
  await mod.default();
6432
6479
  }
6433
6480
  return mod;
@@ -6477,7 +6524,8 @@ var XlsxWorkerClient = class {
6477
6524
  payload: {
6478
6525
  buffer: workerBuffer,
6479
6526
  showHiddenSheets,
6480
- skipXmlParsing
6527
+ skipXmlParsing,
6528
+ wasmSource: getConfiguredWorkerWasmSource()
6481
6529
  },
6482
6530
  type: "load"
6483
6531
  }, [workerBuffer]);
@@ -6496,7 +6544,8 @@ var XlsxWorkerClient = class {
6496
6544
  payload: {
6497
6545
  buffer: workerBuffer,
6498
6546
  showHiddenSheets,
6499
- skipXmlParsing
6547
+ skipXmlParsing,
6548
+ wasmSource: getConfiguredWorkerWasmSource()
6500
6549
  },
6501
6550
  type: "parseCharts"
6502
6551
  }, [workerBuffer]);
@@ -7843,7 +7892,7 @@ function useXlsxViewerController(options) {
7843
7892
  const shouldDeferLoading = deferLoadingAboveBytes > 0;
7844
7893
  const readOnly = requestedReadOnly || forcedReadOnly;
7845
7894
  const canResizeReadOnly = requestedReadOnly && allowResizeInReadOnly && !forcedReadOnly;
7846
- const workerSupported = useWorker && typeof Worker !== "undefined";
7895
+ const workerSupported = useWorker && typeof Worker !== "undefined" && canUseConfiguredWasmSourceInWorker();
7847
7896
  const shouldUseWorker = workerSupported && forcedReadOnly;
7848
7897
  const shouldForceReadOnlyForBuffer = React.useCallback((bufferByteLength) => !requestedReadOnly && readOnlyAboveBytes > 0 && bufferByteLength > readOnlyAboveBytes, [readOnlyAboveBytes, requestedReadOnly]);
7849
7898
  const disposeWorkerClient = React.useCallback(() => {
@@ -29773,6 +29822,8 @@ function DefaultXlsxToolbar() {
29773
29822
  XlsxFileSizeLimitExceededError,
29774
29823
  XlsxViewer,
29775
29824
  XlsxViewerProvider,
29825
+ initWasm,
29826
+ setWasmSource,
29776
29827
  useXlsxViewer,
29777
29828
  useXlsxViewerCharts,
29778
29829
  useXlsxViewerController,