diff --git a/docz/docs/02-getting-started/01-installation/07-bun.md b/docz/docs/02-getting-started/01-installation/07-bun.md
index b5f74bc..2a247e6 100644
--- a/docz/docs/02-getting-started/01-installation/07-bun.md
+++ b/docz/docs/02-getting-started/01-installation/07-bun.md
@@ -121,11 +121,11 @@ This demo was last tested in the following deployments:
| Architecture | BunJS | Date |
|:-------------|:---------|:-----------|
-| `darwin-x64` | `1.2.8` | 2025-03-31 |
-| `darwin-arm` | `1.2.7` | 2025-03-30 |
+| `darwin-x64` | `1.3.6` | 2026-01-20 |
+| `darwin-arm` | `1.3.6` | 2026-01-19 |
| `win11-x64` | `1.2.8` | 2025-04-17 |
| `win11-arm` | `1.2.3` | 2025-02-23 |
-| `linux-x64` | `1.2.10` | 2025-04-21 |
+| `linux-x64` | `1.3.6` | 2026-01-18 |
| `linux-arm` | `1.2.2` | 2025-02-16 |
BunJS on Windows on ARM uses the X64 compatibility layer.
diff --git a/docz/docs/02-getting-started/02-examples/06-loader.md b/docz/docs/02-getting-started/02-examples/06-loader.md
index 79861b6..616c05a 100644
--- a/docz/docs/02-getting-started/02-examples/06-loader.md
+++ b/docz/docs/02-getting-started/02-examples/06-loader.md
@@ -39,15 +39,17 @@ This demo was tested in the following configurations:
| NVIDIA RTX PRO 6000 (96 GB VRAM) + Ryzen Z2 Go (32 GB RAM) | `linux-x64` | 2025-11-15 |
| NVIDIA RTX 5090 (32 GB VRAM) + Ryzen Z2 Go (32 GB RAM) | `win11-x64` | 2025-11-15 |
| NVIDIA RTX 5090 (32 GB VRAM) + Ryzen Z2 Go (32 GB RAM) | `linux-x64` | 2025-11-15 |
+| AMD AI PRO R9700 (32 GB VRAM) + Ryzen Z1 Extreme (16 GB RAM) | `win11-x64` | 2026-01-17 |
+| AMD AI PRO R9700 (32 GB VRAM) + Ryzen Z1 Extreme (16 GB RAM) | `linux-x64` | 2026-01-17 |
+| AMD RX 9070 XT (16 GB VRAM) + Ryzen Z2 Go (32 GB RAM) | `win11-x64` | 2026-01-17 |
+| AMD RX 9070 XT (16 GB VRAM) + Ryzen Z2 Go (32 GB RAM) | `linux-x64` | 2026-01-17 |
| AMD RX 7900 XTX (24 GB VRAM) + Ryzen Z1 Extreme (16 GB RAM) | `win11-x64` | 2025-11-15 |
| AMD RX 7900 XTX (24 GB VRAM) + Ryzen Z1 Extreme (16 GB RAM) | `linux-x64` | 2025-11-15 |
-| AMD RYZEN AI MAX+ 395 + Radeon 8060S (128 GB unified memory) | `linux-x64` | 2025-11-15 |
-| AMD RYZEN AI MAX+ 395 + Radeon 8060S (128 GB unified memory) | `win11-x64` | 2025-11-15 |
| Intel Arc B580 (12 GB VRAM) + Ryzen Z1 Extreme (24 GB RAM) | `win11-x64` | 2025-11-15 |
| Intel Arc B580 (12 GB VRAM) + Ryzen Z1 Extreme (16 GB RAM) | `linux-x64` | 2025-11-15 |
+| AMD RYZEN AI MAX+ 395 + Radeon 8060S (128 GB unified memory) | `linux-x64` | 2025-11-15 |
+| AMD RYZEN AI MAX+ 395 + Radeon 8060S (128 GB unified memory) | `win11-x64` | 2025-11-15 |
| Apple M4 Max 16-Core CPU + 40-Core GPU (48 GB unified memory) | `darwin-arm` | 2025-11-15 |
-| Apple M3 Ultra 28-Core CPU + 60-Core GPU (96 GB unified memory) | `darwin-arm` | 2025-11-15 |
-| Apple M2 Max 12-Core CPU + 30-Core GPU (32 GB unified memory) | `darwin-arm` | 2025-11-15 |
SheetJS users have verified this demo in other configurations:
@@ -75,6 +77,8 @@ SheetJS users have verified this demo in other configurations:
| NVIDIA GTX 1070 (8 GB VRAM) + Ryzen 7 7700x (32 GB RAM) | `win11-x64` | LangChainJS |
| AMD RX 6800 XT (16 GB VRAM) + Ryzen Z1 Extreme (16 GB RAM) | `win11-x64` | LangChainJS |
| Apple M4 10-Core CPU + 10-Core GPU (24 GB unified memory) | `darwin-arm` | LangChainJS |
+| Apple M3 Ultra 28-Core CPU + 60-Core GPU (96 GB unified memory) | `darwin-arm` | LangChainJS |
+| Apple M2 Max 12-Core CPU + 30-Core GPU (32 GB unified memory) | `darwin-arm` | LangChainJS |
@@ -386,7 +390,7 @@ includes one header row and a number of data rows.
```js title="loadofsheet.mjs"
import { Document } from "@langchain/core/documents";
-import { BufferLoader } from "langchain/document_loaders/fs/buffer";
+import { BufferLoader } from "@langchain/classic/document_loaders/fs/buffer";
import { read, utils } from "xlsx";
/**
@@ -525,7 +529,7 @@ export class CSVLoader extends TextLoader {
The SheetJS `read` method supports NodeJS Buffer objects directly[^6]:
```js title="Parsing a workbook in a BufferLoader"
-import { BufferLoader } from "langchain/document_loaders/fs/buffer";
+import { BufferLoader } from "@langchain/classic/document_loaders/fs/buffer";
import { read, utils } from "xlsx";
export default class LoadOfSheet extends BufferLoader {
@@ -836,6 +840,62 @@ D) Run the `start-ollama.sh` script from the extracted folder.
:::
+:::caution pass
+
+AMD GPUs may require special ROCm / HIP libraries.
+
+
+ AMD Instructions on Windows (click to show)
+
+[`ollama-for-amd`](https://github.com/likelovewant/ollama-for-amd) is a
+community fork that provides support for many AMD GPUs.
+
+[Installers](https://github.com/ByronLeeeee/Ollama-For-AMD-Installer/releases)
+are also provided by the community.
+
+There are separate drivers for each GPU family. The following GPUs were tested:
+
+| Name | GPU | Identifier |
+|:-----------------|:--------|:-----------|
+| AMD AI PRO R9700 | Navi 48 | `gfx1200` |
+| AMD RX 9070 XT | Navi 48 | `gfx1201` |
+| AND RX 7900 XTX | Navi 31 | `gfx1100` |
+
+When this demo was last tested, the installer claimed `gfx1200` corresponded to
+Navi 48. `gfx1200` should be used for the PRO R9700, while `gfx1201` should be
+used for the 9070 XT.
+
+
+
+
+ AMD Instructions on Linux (click to show)
+
+The official Ollama release is compatible with AMD cards. However, in some test
+runs, Ollama will try to use the CPU. Some environment variables were required:
+
+```bash
+export OLLAMA_USE_ROCM=1
+export OLLAMA_GPU_LAYERS=999
+export OLLAMA_VULKAN=1
+```
+
+In addition, `HSA_OVERRIDE_GFX_VERSION` must be set to a specific version based
+on the card, which may not match the official version:
+
+| Name | Value | Command |
+|:-----------------|:---------|:-------------------------------------------|
+| AMD AI PRO R9700 | `12.0.0` | `export HSA_OVERRIDE_GFX_VERSION="12.0.0"` |
+| AMD RX 9070 XT | `12.0.0` | `export HSA_OVERRIDE_GFX_VERSION="12.0.0"` |
+| AND RX 7900 XTX | `11.0.0` | `export HSA_OVERRIDE_GFX_VERSION="11.0.0"` |
+
+These environment variables may not be used by the Ollama service, so it is
+strongly recommended to stop the default service and run `ollama serve` in a
+separate terminal window.
+
+
+
+:::
+
After installing dependencies, start a new terminal session.
1) Create a new project:
@@ -882,7 +942,7 @@ npm i --save https://sheet.lol/balls/xlsx-${current}.tgz`}
4) Install dependencies:
```bash
-npm i --save @langchain/core@0.3.78 langchain@0.3.36 @langchain/ollama@0.2.4 peggy@3.0.2
+npm i --save @langchain/core@1.1.15 langchain@1.2.10 @langchain/classic@1.0.9 @langchain/ollama@1.2.0 peggy@5.0.6
```
:::note pass
@@ -891,7 +951,7 @@ In some test runs, there were error messages relating to dependency and peer
dependency versions. The `--force` flag will suppress version mismatch errors:
```bash
-npm i --save @langchain/core@0.3.78 langchain@0.3.36 @langchain/ollama@0.2.4 peggy@3.0.2 --force
+npm i --save @langchain/core@1.1.15 langchain@1.2.10 @langchain/classic@1.0.9 @langchain/ollama@1.2.0 peggy@5.0.6 --force
```
:::
diff --git a/docz/docs/03-demos/20-cli/03-nexe.md b/docz/docs/03-demos/20-cli/03-nexe.md
index bb2766b..5fc3be9 100644
--- a/docz/docs/03-demos/20-cli/03-nexe.md
+++ b/docz/docs/03-demos/20-cli/03-nexe.md
@@ -41,7 +41,7 @@ This demo was tested in the following deployments:
| `darwin-arm` | `5.0.0-beta.4` | `22.14.0` | Compiled | 2025-06-18 |
| `win11-x64` | `5.0.0-beta.4` | `14.15.3` | Pre-built | 2025-05-07 |
| `win11-arm` | `4.0.0-rc.6` | `22.14.0` | Compiled | 2025-02-23 |
-| `linux-x64` | `5.0.0-beta.4` | `14.15.3` | Pre-built | 2025-04-21 |
+| `linux-x64` | `5.0.0-beta.4` | `14.15.3` | Pre-built | 2026-01-18 |
| `linux-arm` | `4.0.0-rc.6` | `22.13.0` | Compiled | 2025-02-15 |
:::
diff --git a/docz/docs/03-demos/20-cli/05-pkg.md b/docz/docs/03-demos/20-cli/05-pkg.md
index fbfbee5..b728f89 100644
--- a/docz/docs/03-demos/20-cli/05-pkg.md
+++ b/docz/docs/03-demos/20-cli/05-pkg.md
@@ -41,7 +41,7 @@ This demo was tested in the following deployments:
| `darwin-arm` | `5.8.1` | `18.5.0` | 2025-06-18 |
| `win11-x64` | `5.8.1` | `18.5.0` | 2025-05-07 |
| `win11-arm` | `5.8.1` | `18.5.0` | 2025-02-23 |
-| `linux-x64` | `5.8.1` | `18.5.0` | 2025-04-21 |
+| `linux-x64` | `5.8.1` | `18.5.0` | 2026-01-18 |
| `linux-arm` | `5.8.1` | `18.5.0` | 2025-02-15 |
:::
diff --git a/docz/docs/03-demos/20-cli/08-boxednode.md b/docz/docs/03-demos/20-cli/08-boxednode.md
index 2a9c211..ec17d6c 100644
--- a/docz/docs/03-demos/20-cli/08-boxednode.md
+++ b/docz/docs/03-demos/20-cli/08-boxednode.md
@@ -91,7 +91,7 @@ yarn add https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz exit-on-epi
```bash
-npx -y boxednode@2.4.4 -s xlsx-cli.js -t xlsx-cli
+npx -y boxednode@3.0.0 -s xlsx-cli.js -t xlsx-cli
```
:::note pass
diff --git a/docz/docs/03-demos/20-cli/21-txiki.md b/docz/docs/03-demos/20-cli/21-txiki.md
index d07cdb0..4db1c26 100644
--- a/docz/docs/03-demos/20-cli/21-txiki.md
+++ b/docz/docs/03-demos/20-cli/21-txiki.md
@@ -88,14 +88,14 @@ console.log(csv);
This demo was tested in the following deployments:
-| Architecture | TxikiJS | Date |
-|:-------------|:----------|:-----------|
-| `darwin-x64` | `24.12.0` | 2025-04-19 |
-| `darwin-arm` | `24.12.0` | 2025-04-19 |
-| `win11-x64` | `24.12.0` | 2025-04-19 |
-| `win11-arm` | `24.12.0` | 2025-04-19 |
-| `linux-x64` | `24.12.0` | 2025-04-19 |
-| `linux-arm` | `24.12.0` | 2025-04-19 |
+| Architecture | Version | Commit | Date |
+|:-------------|:----------|:----------|:-----------|
+| `darwin-x64` | `24.12.0` | | 2025-04-19 |
+| `darwin-arm` | `24.12.0` | `793dd9d` | 2026-01-18 |
+| `win11-x64` | `24.12.0` | | 2025-04-19 |
+| `win11-arm` | `24.12.0` | | 2025-04-19 |
+| `linux-x64` | `24.12.0` | `65e5595` | 2026-01-18 |
+| `linux-arm` | `24.12.0` | | 2025-04-19 |
:::
@@ -133,6 +133,40 @@ cp build/tjs ../
cd ..
```
+:::caution pass
+
+In some `linux-x64` test runs, the `make` step failed:
+
+```
+make[5]: *** No rule to make target 'all-configured'. Stop.
+```
+
+After re-running `make`, the `[ 0%]` line identifies the root cause:
+
+```text
+// highlight-next-line
+[ 0%] Performing build step for 'libffi'
+[ 1%] Built target sqlite3
+[ 2%] Built target ffi-test
+...
+[ 61%] Built target sqlite-test
+MAKE x86_64-pc-linux-gnu : 0 * all-configured
+// highlight-next-line
+make[5]: *** No rule to make target 'all-configured'. Stop.
+```
+
+If the root cause is `libffi`, it is possible to use the system `libffi`. The
+following commands should be run in the `txiki.js` folder:
+
+```bash
+rm -rf build
+cmake -B build -DCMAKE_BUILD_TYPE=Release -DUSE_EXTERNAL_FFI=ON
+cmake --build build -j 32
+cp build/tjs ../
+```
+
+:::
+
diff --git a/docz/docs/03-demos/42-engines/01-duktape.md b/docz/docs/03-demos/42-engines/01-duktape.md
index 34a1788..7ec2198 100644
--- a/docz/docs/03-demos/42-engines/01-duktape.md
+++ b/docz/docs/03-demos/42-engines/01-duktape.md
@@ -784,8 +784,8 @@ This demo was tested in the following deployments:
| Architecture | Version | Zig | Date |
|:-------------|:--------|:---------|:-----------|
-| `darwin-x64` | `2.7.0` | `0.14.0` | 2025-03-31 |
-| `darwin-arm` | `2.7.0` | `0.13.0` | 2025-02-13 |
+| `darwin-x64` | `2.7.0` | `0.15.2` | 2026-01-20 |
+| `darwin-arm` | `2.7.0` | `0.15.2` | 2026-01-20 |
| `win11-x64` | `2.7.0` | `0.14.0` | 2025-04-28 |
| `win11-arm` | `2.7.0` | `0.13.0` | 2025-02-23 |
| `linux-x64` | `2.7.0` | `0.14.0` | 2025-04-21 |
@@ -812,15 +812,15 @@ the project folder.
For X64 Mac:
```bash
-curl -LO https://ziglang.org/download/0.14.0/zig-macos-x86_64-0.14.0.tar.xz
-tar -xzf zig-macos-*.tar.xz
+curl -LO https://ziglang.org/download/0.15.2/zig-x86_64-macos-0.15.2.tar.xz
+tar -xzf zig-*.tar.xz
```
For ARM64 Mac:
```bash
-curl -LO https://ziglang.org/download/0.13.0/zig-macos-aarch64-0.13.0.tar.xz
-tar -xzf zig-macos-*.tar.xz
+curl -LO https://ziglang.org/download/0.15.2/zig-aarch64-macos-0.15.2.tar.xz
+tar -xzf zig-*.tar.xz
```
diff --git a/docz/docs/03-demos/42-engines/20-chakra.md b/docz/docs/03-demos/42-engines/20-chakra.md
index c9ed9b8..e15da43 100644
--- a/docz/docs/03-demos/42-engines/20-chakra.md
+++ b/docz/docs/03-demos/42-engines/20-chakra.md
@@ -131,8 +131,8 @@ This demo was tested in the following deployments:
| Architecture | Git Commit | Date |
|:-------------|:-----------|:-----------|
-| `darwin-x64` | `36becec` | 2025-03-31 |
-| `darwin-arm` | `36becec` | 2025-09-03 |
+| `darwin-x64` | `792ee76` | 2026-01-20 |
+| `darwin-arm` | `792ee76` | 2026-01-20 |
| `win11-x64` | `36becec` | 2025-04-28 |
| `win11-arm` | `e26c81f` | 2025-02-23 |
| `linux-x64` | `36becec` | 2025-06-18 |
@@ -215,7 +215,7 @@ cd ..
```bash
cd ChakraCore
-./build.sh --static --icu=/usr/local/opt/icu4c/include --test-build -j=8 --system-icu --no-jit
+./build.sh --static --icu=/usr/local/opt/icu4c/include --test-build -j=8 --no-jit
cd ..
```
@@ -233,6 +233,7 @@ This was fixed with a local symlink to the `icu4c` folder before the build step:
cd ChakraCore
mkdir -p usr/local/opt
ln -s /opt/homebrew/opt/icu4c usr/local/opt/icu4c
+./build.sh --static --icu=/usr/local/opt/icu4c/include --test-build -j=8 --system-icu --no-jit
cd ..
```
@@ -291,12 +292,10 @@ When the demo was last tested, ChakraCore JIT was not supported.
```bash
cd ChakraCore
-export PATH="$(brew --prefix cmake3)/bin:${PATH}"
-./build.sh --static --icu=$(brew --prefix)/opt/icu4c/include --test-build -j=8 --no-jit
+./build.sh --static --icu=/usr/local/opt/icu4c/include --test-build -j=8 --no-jit
cd ..
```
-:::
:::caution Troubleshooting
diff --git a/docz/docs/03-demos/42-engines/25-mujs.md b/docz/docs/03-demos/42-engines/25-mujs.md
index b9e3677..03126d6 100644
--- a/docz/docs/03-demos/42-engines/25-mujs.md
+++ b/docz/docs/03-demos/42-engines/25-mujs.md
@@ -322,8 +322,8 @@ This demo was tested in the following deployments:
| Architecture | Version | Date |
|:-------------|:--------|:-----------|
-| `darwin-x64` | `1.3.6` | 2025-03-31 |
-| `darwin-arm` | `1.3.6` | 2025-09-03 |
+| `darwin-x64` | `1.3.8` | 2026-01-20 |
+| `darwin-arm` | `1.3.8` | 2026-01-20 |
| `win11-x64` | `1.3.6` | 2025-04-23 |
| `win11-arm` | `1.3.5` | 2025-02-23 |
| `linux-x64` | `1.3.6` | 2025-06-16 |
diff --git a/docz/docs/07-csf/07-features/02-formulae.md b/docz/docs/07-csf/07-features/02-formulae.md
index f473751..9bb6da1 100644
--- a/docz/docs/07-csf/07-features/02-formulae.md
+++ b/docz/docs/07-csf/07-features/02-formulae.md
@@ -33,110 +33,34 @@ to mark a dynamic array formula in the XLS file format.
SheetJS supports reading and writing formulae for a number of file formats. When
supported, formulae will always be exported.
-By default, formulae are not always imported. To ensure formula parsing, the
-option `cellFormula: true` should be passed to the parser.
+The ["A1-Style"](/docs/csf/general#a1-style) formula string is stored in the `f`
+field of the cell object. The SheetJS formula string closely matches the text
+representation in spreadsheet file formats.
-
-
+:::caution pass
-Typically file data will be available as an `ArrayBuffer`, either downloaded
-with `fetch` / `XMLHttpRequest` or user-submitted with a File Input element.
-`cellFormula: true` should be added to the second options argument:
+**SheetJS formula strings do not always match Excel or other spreadsheets!**
-```js
-/* using read in the browser, `cellFormula` is in the second argument */
-const ab = await (await fetch("test.xlsx")).arrayBuffer();
-const workbook = XLSX.read(ab, { cellFormula: true });
-// ------------------------------^^^^^^^^^^^^^^^^^
-```
+- Spreadsheet software typically represent formulae with a leading `=` sign, but
+ SheetJS formulae omit the `=`.
-
-
+- Spreadsheet software [localize formulae](#localization), but SheetJS formulae
+ always use the `en-US` form.
-Typically file data will be available as a `Buffer` from a network request / API
-or stored in the file system. `cellFormula: true` should be added to the second
-options argument to `read` or `readFile`:
+- Spreadsheet software may display formulae in RC notation, but SheetJS formulae
+ always use A1-Style.
-**`XLSX.read`**
+- Spreadsheet software will hide [prefixes](#prefixed-future-functions). SheetJS
+ parsers provide options to replicate that behavior.
-```js
-/* using read in NodeJS, `cellFormula` is in the second argument */
-const ab = await (await fetch("test.xlsx")).arrayBuffer();
-const workbook = XLSX.read(ab, { cellFormula: true });
-// ------------------------------^^^^^^^^^^^^^^^^^
-```
+When building new exports, it is strongly recommended to create a sample file in
+Excel, parse with the SheetJS library, and inspect the formula string.
-**`XLSX.readFile`**
+:::
-```js
-/* using readFile in NodeJS, add `cellFormula` to the second argument */
-const workbook = XLSX.readFile("test.xlsx", { cellFormula: true });
-// -------------------------------------------^^^^^^^^^^^^^^^^^
-```
+## Live Demo
-
-
-
-Typically file data will be available as a `Uint8Array` from a network request
-or stored in the file system. `cellFormula: true` should be set in the options
-argument to `read` or `readFile`:
-
-**`XLSX.read`**
-
-```js
-/* using read in Bun, `cellFormula` is in the second argument */
-const ab = await (await fetch("test.xlsx")).arrayBuffer();
-const workbook = XLSX.read(ab, { cellFormula: true });
-// ------------------------------^^^^^^^^^^^^^^^^^
-```
-
-**`XLSX.readFile`**
-
-```js
-/* using readFile in Bun, add `cellFormula` to the second argument */
-const workbook = XLSX.readFile("test.xlsx", { cellFormula: true });
-// -------------------------------------------^^^^^^^^^^^^^^^^^
-```
-
-
-
-
-Typically file data will be available as a `Uint8Array` or `ArrayBuffer` from
-API or stored in the file system. `cellFormula: true` should be set in the
-options argument to `read` or `readFile`:
-
-**`XLSX.read`**
-
-```js
-/* using read in Deno, `cellFormula` is in the second argument */
-const ab = await (await fetch("test.xlsx")).arrayBuffer();
-const workbook = XLSX.read(ab, { cellFormula: true });
-// ------------------------------^^^^^^^^^^^^^^^^^
-```
-
-**`XLSX.readFile`**
-
-```js
-/* using readFile in Deno, add `cellFormula` to the second argument */
-const workbook = XLSX.readFile("test.xlsx", { cellFormula: true });
-// -------------------------------------------^^^^^^^^^^^^^^^^^
-```
-
-
-
-
-## A1-Style Formulae
-
-The A1-Style formula string is stored in the `f` field of the cell object.
-Spreadsheet software typically represent formulae with a leading `=` sign, but
-SheetJS formulae omit the `=`.
-
-["A1-Style"](/docs/csf/general#a1-style) describes A1-Style in more detail.
-
-
- Live Example (click to hide)
-
-For example, consider [this test file](pathname:///files/concat.xlsx):
+[This test file](pathname:///files/concat.xlsx) includes a formula in cell `D1`:

@@ -144,7 +68,7 @@ The following code block fetches the file, parses and prints info on cell `D1`:
```jsx live
/* The live editor requires this function wrapper */
-function ConcatFormula(props) {
+function InspectCellFormula(props) {
const [ws, setWS] = React.useState({"!ref":"A1"});
const [addr, setAddr] = React.useState("D1");
const setaddr = React.useCallback((evt)=>{ setAddr(evt.target.value) });
@@ -163,7 +87,8 @@ function ConcatFormula(props) {
process_ab(await e.target.files[0].arrayBuffer());
};
return ( <>
-
+ Select a file to inspect cell formulae
+
Cell:
{!ws[addr] ? ( Cell {addr} not found ) : (
Formula
{ws[addr].f}
@@ -174,9 +99,9 @@ function ConcatFormula(props) {
}
```
-
+## Storage
-## Single-Cell Formulae
+### Single-Cell Formulae
For simple formulae, the `f` key of the desired cell can be set to the actual
formula text. This worksheet represents `A1=1`, `A2=2`, and `A3=A1+A2`:
@@ -250,7 +175,7 @@ values and dependent cells, and refreshing entire workbooks.
:::
-## Array Formulae
+### Array Formulae
_Assign an array formula_
@@ -393,20 +318,129 @@ function ExportDynamicArrayFormulae(props) {
+## Functions
+
+#### Reading Files
+
+[`read` and `readFile`](/docs/api/parse-options) accept an options argument. The
+`cellFormula` option should be set to `true` to expose cell formulae:
+
+
+
+
+Typically file data will be available as an `ArrayBuffer`, either downloaded
+with `fetch` / `XMLHttpRequest` or user-submitted with a File Input element.
+`cellFormula: true` should be added to the second options argument:
+
+```js
+/* using read in the browser, `cellFormula` is in the second argument */
+const ab = await (await fetch("test.xlsx")).arrayBuffer();
+const workbook = XLSX.read(ab, { cellFormula: true });
+// ------------------------------^^^^^^^^^^^^^^^^^
+```
+
+
+
+
+Typically file data will be available as a `Buffer` from a network request / API
+or stored in the file system. `cellFormula: true` should be added to the second
+options argument to `read` or `readFile`:
+
+**`XLSX.read`**
+
+```js
+/* using read in NodeJS, `cellFormula` is in the second argument */
+const ab = await (await fetch("test.xlsx")).arrayBuffer();
+const workbook = XLSX.read(ab, { cellFormula: true });
+// ------------------------------^^^^^^^^^^^^^^^^^
+```
+
+**`XLSX.readFile`**
+
+```js
+/* using readFile in NodeJS, add `cellFormula` to the second argument */
+const workbook = XLSX.readFile("test.xlsx", { cellFormula: true });
+// -------------------------------------------^^^^^^^^^^^^^^^^^
+```
+
+
+
+
+Typically file data will be available as a `Uint8Array` from a network request
+or stored in the file system. `cellFormula: true` should be set in the options
+argument to `read` or `readFile`:
+
+**`XLSX.read`**
+
+```js
+/* using read in Bun, `cellFormula` is in the second argument */
+const ab = await (await fetch("test.xlsx")).arrayBuffer();
+const workbook = XLSX.read(ab, { cellFormula: true });
+// ------------------------------^^^^^^^^^^^^^^^^^
+```
+
+**`XLSX.readFile`**
+
+```js
+/* using readFile in Bun, add `cellFormula` to the second argument */
+const workbook = XLSX.readFile("test.xlsx", { cellFormula: true });
+// -------------------------------------------^^^^^^^^^^^^^^^^^
+```
+
+
+
+
+Typically file data will be available as a `Uint8Array` or `ArrayBuffer` from
+API or stored in the file system. `cellFormula: true` should be set in the
+options argument to `read` or `readFile`:
+
+**`XLSX.read`**
+
+```js
+/* using read in Deno, `cellFormula` is in the second argument */
+const ab = await (await fetch("test.xlsx")).arrayBuffer();
+const workbook = XLSX.read(ab, { cellFormula: true });
+// ------------------------------^^^^^^^^^^^^^^^^^
+```
+
+**`XLSX.readFile`**
+
+```js
+/* using readFile in Deno, add `cellFormula` to the second argument */
+const workbook = XLSX.readFile("test.xlsx", { cellFormula: true });
+// -------------------------------------------^^^^^^^^^^^^^^^^^
+```
+
+
+
+
## Localization
-SheetJS operates at the file level. Excel stores formula expressions using the
-English (United States) function names. For non-English users, Excel uses a
-localized set of function names.
+Excel and other spreadsheet software will display different formula strings in
+different countries and locales.
+
+SheetJS parsers and writers do not attempt locale-specific changes.
+
+For example, the Spanish Excel formula `=CONTAR(A1:C3;B4:D6)` is equivalent to
+the SheetJS formula string `COUNT(A1:A3,B4:D6)` .
+
+### Grammar
+
+SheetJS formula function arguments are always separated with commas (`,`).
+
+| SheetJS | `en-US` Excel | `es-ES` Excel |
+|:-------------|:--------------|:--------------|
+| `ATAN2(1,1)` | `=ATAN2(1,1)` | `=ATAN2(1;1)` |
+
+### Function Names
+
+Excel stores formula expressions using the English (United States) function
+names. For non-English users, Excel uses a localized set of function names.
For example, when the computer language and region is set to Spanish, Excel
interprets `=CONTAR(A1:C3)` as if `CONTAR` is the `COUNT` function. However,
in the actual file, Excel stores `COUNT(A1:C3)`.
-Function arguments are separated with commas. For example, the Spanish Excel
-formula `=CONTAR(A1:C3;B4:D6)` is equivalent to the SheetJS formula string
-`COUNT(A1:A3,B4:D6)`
-
[JSON Translation table](https://docs.sheetjs.com/fmla/table.json).
diff --git a/docz/static/loadofsheet/loadofsheet.mjs b/docz/static/loadofsheet/loadofsheet.mjs
index 23612be..e20d7c3 100644
--- a/docz/static/loadofsheet/loadofsheet.mjs
+++ b/docz/static/loadofsheet/loadofsheet.mjs
@@ -1,5 +1,5 @@
import { Document } from "@langchain/core/documents";
-import { BufferLoader } from "langchain/document_loaders/fs/buffer";
+import { BufferLoader } from "@langchain/classic/document_loaders/fs/buffer";
import { read, utils } from "xlsx";
/**
diff --git a/docz/static/loadofsheet/query.mjs b/docz/static/loadofsheet/query.mjs
index 97202b1..4e4bf89 100644
--- a/docz/static/loadofsheet/query.mjs
+++ b/docz/static/loadofsheet/query.mjs
@@ -1,6 +1,6 @@
import { ChatOllama, OllamaEmbeddings } from "@langchain/ollama";
-import { MemoryVectorStore } from "langchain/vectorstores/memory";
-import { SelfQueryRetriever } from "langchain/retrievers/self_query";
+import { MemoryVectorStore } from "@langchain/classic/vectorstores/memory";
+import { SelfQueryRetriever } from "@langchain/classic/retrievers/self_query";
import { FunctionalTranslator } from "@langchain/core/structured_query";
import LoadOfSheet from "./loadofsheet.mjs";
diff --git a/tests/cli/txiki.sh b/tests/cli/txiki.sh
new file mode 100755
index 0000000..8c0fa1a
--- /dev/null
+++ b/tests/cli/txiki.sh
@@ -0,0 +1,39 @@
+#!/bin/bash
+# https://docs.sheetjs.com/docs/demos/cli/txiki
+cd /tmp
+rm -rf sheetjs-txiki
+mkdir sheetjs-txiki
+cd sheetjs-txiki
+
+curl -o pres.numbers https://docs.sheetjs.com/pres.numbers
+
+cat >sheet2csv.js <<'EOF'
+const XLSX = require("./xlsx.full.min");
+
+/* tjs.args[1] is the first argument to the script */
+const filename = tjs.args[1];
+
+/* read and parse file */
+const data = await tjs.readFile(filename);
+const wb = XLSX.read(data);
+
+/* generate CSV of first sheet */
+const ws = wb.Sheets[wb.SheetNames[0]];
+const csv = XLSX.utils.sheet_to_csv(ws);
+
+/* print to terminal */
+console.log(csv);
+EOF
+
+curl -LO https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min.js
+
+## NOTE: these steps are for darwin
+curl -LO https://github.com/saghul/txiki.js/releases/download/v24.12.0/txiki-macos.zip
+unzip txiki-macos.zip
+mv txiki-macos/tjs .
+chmod +x tjs
+
+npx -y esbuild sheet2csv.js --bundle --outfile=bundle.js --platform=neutral
+
+./tjs compile bundle.js sheet2csv
+./sheet2csv pres.numbers
diff --git a/tests/engines/chakracore.sh b/tests/engines/chakracore.sh
index 66bfdab..46e2817 100755
--- a/tests/engines/chakracore.sh
+++ b/tests/engines/chakracore.sh
@@ -9,54 +9,10 @@ cd sheetjs-chakra
git clone https://github.com/chakra-core/ChakraCore.git
cd ChakraCore
-git checkout e26c81f
+git checkout 792ee76
cd ..
cd ChakraCore
-
-## in commit e26c81f in macOS 15.2, the build fails with the following error:
-##
-##/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX15.2.sdk/usr/include/c++/v1/new:279:66: error: redefinition of 'operator new'
-## 279 | _LIBCPP_NODISCARD_AFTER_CXX17 inline _LIBCPP_HIDE_FROM_ABI void* operator new(std::size_t, void* __p) _NOEXCEPT {
-## | ^
-##/tmp/sheetjs-chakra/ChakraCore/lib/Common/Memory/Allocator.h:457:1: note: previous definition is here
-## 457 | operator new(
-## | ^
-##
-## This patch avoids the issues
-cat <sheetjs.patch
-diff --git a/lib/Common/Memory/Allocator.h b/lib/Common/Memory/Allocator.h
-index 5a3a099bc..e05a7390f 100644
---- a/lib/Common/Memory/Allocator.h
-+++ b/lib/Common/Memory/Allocator.h
-@@ -452,24 +452,7 @@ void AssertValue(void * mem, T value, uint byteCount)
- #ifndef __PLACEMENT_NEW_INLINE
- #define __PLACEMENT_NEW_INLINE
-
--_Ret_notnull_
--NO_EXPORT(inline void *) __cdecl
--operator new(
--DECLSPEC_GUARD_OVERFLOW size_t byteSize,
--_In_ void * previousAllocation) throw()
--{
-- return previousAllocation;
--}
--
--
--NO_EXPORT(inline void) __cdecl
--operator delete(
--void * allocationToFree, // Allocation to free
--void * previousAllocation // Previously allocated memory
--) throw()
--{
--
--}
-+#include
-
- #endif
-
-EOF
-git apply sheetjs.patch
./build.sh --static --icu=/usr/local/opt/icu4c/include --test-build -j=8 --no-jit
cd ..
@@ -66,7 +22,6 @@ curl -L -O https://docs.sheetjs.com/chakra/Makefile
make
curl -L -O https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min.js
-curl -L -O https://cdn.sheetjs.com/xlsx-latest/package/dist/shim.min.js
curl -L -O https://docs.sheetjs.com/pres.numbers
./sheetjs.ch pres.numbers
diff --git a/tests/engines/duktape-zig.sh b/tests/engines/duktape-zig.sh
new file mode 100755
index 0000000..17cc795
--- /dev/null
+++ b/tests/engines/duktape-zig.sh
@@ -0,0 +1,38 @@
+#!/bin/bash
+# https://docs.sheetjs.com/docs/demos/engines/duktape#zig-demo
+
+cd /tmp
+rm -rf sheetjs-zig
+mkdir -p sheetjs-zig
+cd sheetjs-zig
+
+## NOTE: these steps are for darwin
+case "$(uname -m)" in
+ arm64) curl -LO https://ziglang.org/download/0.15.2/zig-aarch64-macos-0.15.2.tar.xz ;;
+ x86_64) curl -LO https://ziglang.org/download/0.15.2/zig-x86_64-macos-0.15.2.tar.xz ;;
+ *) echo "unsupported arch $(uname -m)"; exit 1 ;;
+esac
+tar -xzf zig-*.tar.xz
+
+./zig-*/zig init
+
+curl -LO https://duktape.org/duktape-2.7.0.tar.xz
+tar -xJf duktape-2.7.0.tar.xz
+
+curl -LO https://cdn.sheetjs.com/xlsx-latest/package/dist/shim.min.js
+curl -LO https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min.js
+curl -LO https://docs.sheetjs.com/pres.numbers
+
+mv *.js src
+
+curl -L -o src/main.zig https://docs.sheetjs.com/duk/main.zig
+
+sed -i '' '/b.installArtifact(exe);/ i\
+ exe.addCSourceFile(.{ .file = b.path("duktape-2.7.0/src/duktape.c"), .flags = &.{ "-std=c99", "-fno-sanitize=undefined" } });\
+ exe.addIncludePath(b.path("duktape-2.7.0/src"));\
+ exe.linkSystemLibrary("c");\
+ exe.linkSystemLibrary("m");' build.zig
+
+./zig-*/zig build run -- pres.numbers; echo $?
+
+npx -y xlsx-cli sheetjs.zig.xlsx
diff --git a/tests/engines/mujs.sh b/tests/engines/mujs.sh
index 92cd75c..6111a56 100755
--- a/tests/engines/mujs.sh
+++ b/tests/engines/mujs.sh
@@ -7,7 +7,7 @@ rm -rf sheetjs-mu
mkdir sheetjs-mu
cd sheetjs-mu
-curl -LO https://mujs.com/downloads/mujs-1.3.6.zip
+curl -LO https://mujs.com/downloads/mujs-1.3.8.zip
unzip mujs-*.zip
rm mujs-*.zip
cd mujs-*