.
https://cdn.sheetjs.com/xlsx-{current}/xlsx-{current}.tgz is the URL for version {current}
@@ -23,7 +25,7 @@ be reported to the Bun project for further diagnosis.
## Installation
-Tarballs can be directly installed with `bun install`[^1]:
+Tarballs can be directly installed with `bun install`:
{`\
bun install https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`}
@@ -37,15 +39,27 @@ new versions are released!
:::
-:::warning pass
+### Vendoring
-At the time of writing `bun install` does not support vendored tarballs[^2].
+For general stability, "vendoring" modules is the recommended approach:
-:::
+1) Download the tarball (xlsx-{current}.tgz
) for the desired version. The current
+ version is available at https://cdn.sheetjs.com/xlsx-{current}/xlsx-{current}.tgz
+
+2) Create a `vendor` subfolder at the root of your project and move the tarball
+ to that folder. Add it to your project repository.
+
+3) Install the tarball:
+
+{`\
+bun install file:vendor/xlsx-${current}.tgz`}
+
+
+The package will be installed and accessible as `xlsx`.
## Usage
-Bun supports both "CommonJS" and "ESM" modules.
+The package supports CommonJS `require` and ESM `import` module systems.
:::info pass
@@ -53,7 +67,7 @@ Bun supports both "CommonJS" and "ESM" modules.
:::
-#### CommonJS `require`
+### CommonJS `require`
By default, the module supports `require` and it will automatically add support
for streams and file system access:
@@ -63,7 +77,13 @@ const { readFile } = require("xlsx");
const wb = readFile("pres.numbers"); // works!
```
-#### ESM `import`
+:::caution pass
+
+In the BunJS REPL, `require` incorrectly loads the ESM build.
+
+:::
+
+### ESM `import`
When importing the library using ESM `import` statements, the native NodeJS
modules are not loaded. They must be added manually:
@@ -91,7 +111,7 @@ builder requires a proper `package.json` that includes the SheetJS dependency.
:::note Tested Deployments
-This example was last tested on 2023 November 05 against BunJS 1.0.8.
+This example was last tested on 2024-02-21 against BunJS 1.0.28 on macOS 14.3.1.
:::
@@ -100,7 +120,7 @@ This example was last tested on 2023 November 05 against BunJS 1.0.8.
```bash
mkdir sheetjs-bun-dle
cd sheetjs-bun-dle
-echo "{}" >> package.json
+echo "{}" > package.json
```
1) Install the library:
@@ -109,9 +129,9 @@ echo "{}" >> package.json
bun install https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`}
-2) Save the following script to `bun.js`:
+2) Save the following script to `SheetJSBun.js`:
-```js title="bun.js"
+```js title="SheetJSBun.js"
// highlight-next-line
import * as XLSX from 'xlsx';
// highlight-next-line
@@ -155,18 +175,20 @@ XLSX.writeFile(workbook, "Presidents.xlsx");
3) Bundle the script with `bun build`:
```bash
-bun build --target=bun bun.js --outfile=app.js
+bun build --target=bun SheetJSBun.js --outfile=app.js
```
This procedure will generate `app.js`.
-4) Remove the `node_modules` directory and `package.json` file:
+4) Remove the module artifacts and original script:
```bash
-rm package.json
+rm package.json bun.lockb SheetJSBun.js
rm -rf ./node_modules
```
+At this point, `app.js` will be the only file in the project folder.
+
5) Run the script:
```bash
@@ -175,6 +197,3 @@ bun app.js
If the script succeeded, the file `Presidents.xlsx` will be created. That file
can be opened in a spreadsheet editor.
-
-[^1]: Bun releases before the official 1.0.0 release did not support tarball dependencies. If a pre-1.0.0 release must be used, the [ES Module script can be vendored](/docs/getting-started/installation/standalone#ecmascript-module-imports) or the [NodeJS module can be installed with a NodeJS-compatible package manager](/docs/getting-started/installation/nodejs).
-[^2]: See [the relevant issue in the Bun issue tracker](https://github.com/oven-sh/bun/issues/101)
\ No newline at end of file
diff --git a/docz/docs/02-getting-started/01-installation/index.md b/docz/docs/02-getting-started/01-installation/index.md
index 9b7d9f0..d2b5ca9 100644
--- a/docz/docs/02-getting-started/01-installation/index.md
+++ b/docz/docs/02-getting-started/01-installation/index.md
@@ -3,7 +3,7 @@ pagination_prev: getting-started/index
pagination_next: getting-started/examples/index
hide_table_of_contents: true
title: Installation
-------
+---
import DocCardList from '@theme/DocCardList';
import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
diff --git a/docz/docs/03-demos/01-math/21-pandas.md b/docz/docs/03-demos/01-math/21-pandas.md
index 77ca364..efe033b 100644
--- a/docz/docs/03-demos/01-math/21-pandas.md
+++ b/docz/docs/03-demos/01-math/21-pandas.md
@@ -41,6 +41,7 @@ This demo was tested in the following deployments:
| Architecture | JS Engine | Pandas | Python | Date |
|:-------------|:----------------|:-------|:-------|:-----------|
| `darwin-x64` | Duktape `2.7.0` | 2.0.3 | 3.11.7 | 2024-01-29 |
+| `darwin-arm` | Duktape `2.7.0` | 2.0.3 | 3.11.7 | 2024-02-13 |
| `linux-x64` | Duktape `2.7.0` | 1.5.3 | 3.11.3 | 2024-01-29 |
:::
@@ -358,6 +359,7 @@ This demo was tested in the following deployments:
| Architecture | JS Engine | Polars | Python | Date |
|:-------------|:----------------|:-------|:-------|:-----------|
| `darwin-x64` | Duktape `2.7.0` | 0.20.6 | 3.11.7 | 2024-01-30 |
+| `darwin-arm` | Duktape `2.7.0` | 0.20.7 | 3.11.7 | 2024-02-13 |
| `linux-x64` | Duktape `2.7.0` | 0.20.6 | 3.11.3 | 2024-01-30 |
:::
diff --git a/docz/docs/03-demos/02-frontend/19-bundler/11-requirejs.md b/docz/docs/03-demos/02-frontend/19-bundler/11-requirejs.md
index af5bdcd..fc937f4 100644
--- a/docz/docs/03-demos/02-frontend/19-bundler/11-requirejs.md
+++ b/docz/docs/03-demos/02-frontend/19-bundler/11-requirejs.md
@@ -40,7 +40,7 @@ This demo was tested in the following environments:
| RequireJS | Date |
|:----------|:-----------|
-| `2.3.6` | 2023-12-04 |
+| `2.3.6` | 2024-03-01 |
| `2.1.22` | 2023-12-04 |
:::
@@ -201,7 +201,7 @@ require(["xlsx"], function(XLSX) {
The `r.js` optimizer does not handle `async` functions or ES6 arrow functions.
-To demonstrate compatibility with older versions of Webpack, `SheetJSRequire.js`
+To demonstrate compatibility with older RequireJS releases, `SheetJSRequire.js`
uses normal functions and traditional Promise chains.
:::
diff --git a/docz/docs/03-demos/03-net/02-upload/index.mdx b/docz/docs/03-demos/03-net/02-upload/index.mdx
index 079d037..4c64a45 100644
--- a/docz/docs/03-demos/03-net/02-upload/index.mdx
+++ b/docz/docs/03-demos/03-net/02-upload/index.mdx
@@ -108,7 +108,7 @@ Each browser demo was tested in the following environments:
| Browser | Date |
|:------------|:-----------|
| Chrome 120 | 2024-01-15 |
-| Safari 17.2 | 2023-01-15 |
+| Safari 17.3 | 2024-02-21 |
:::
diff --git a/docz/docs/03-demos/03-net/03-server/01-express.md b/docz/docs/03-demos/03-net/03-server/01-express.md
index 74aa1af..9801fab 100644
--- a/docz/docs/03-demos/03-net/03-server/01-express.md
+++ b/docz/docs/03-demos/03-net/03-server/01-express.md
@@ -20,10 +20,10 @@ with downloadable spreadsheets.
The ["Complete Example"](#complete-example) section includes a complete server.
-:::note
+:::note Tested Deployments
-This demo was tested on 2023 October 16 using `express-formidable@1.2.0` and
-ExpressJS `4.18.2`
+This demo was tested on 2024 March 11 using `express-formidable@1.2.0` and
+ExpressJS `4.18.3`
:::
@@ -142,7 +142,7 @@ app.listen(+process.env.PORT||3000);
2) Install dependencies:
{`\
-npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz express@4.18.2 express-formidable@1.2.0`}
+npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz express@4.18.3 express-formidable@1.2.0`}
3) Start server (note: it will not print anything to console when running)
@@ -151,7 +151,8 @@ npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz express
node SheetJSExpressCSV.js
```
-4) Test POST requests using :
+4) Test POST requests using . The following
+commands should be run in a new terminal window:
```bash
curl -LO https://sheetjs.com/pres.numbers
diff --git a/docz/docs/03-demos/03-net/03-server/04-drash.md b/docz/docs/03-demos/03-net/03-server/04-drash.md
index 0ebddee..3b3fc40 100644
--- a/docz/docs/03-demos/03-net/03-server/04-drash.md
+++ b/docz/docs/03-demos/03-net/03-server/04-drash.md
@@ -20,9 +20,9 @@ downloadable spreadsheets.
The ["Complete Example"](#complete-example) section includes a complete server.
-:::note
+:::note Tested Deployments
-This demo was last tested on 2023 October 16 against Drash 2.8.1 and Deno 1.37.2.
+This demo was last tested on 2024 March 11 against Drash 2.8.1 and Deno 1.41.2.
:::
diff --git a/docz/docs/03-demos/03-net/03-server/09-elysia.md b/docz/docs/03-demos/03-net/03-server/09-elysia.md
index 549ace4..9844fec 100644
--- a/docz/docs/03-demos/03-net/03-server/09-elysia.md
+++ b/docz/docs/03-demos/03-net/03-server/09-elysia.md
@@ -19,9 +19,9 @@ downloadable spreadsheets.
The ["Complete Example"](#complete-example) section includes a complete server.
-:::note
+:::note Tested Deployments
-This demo was last tested on 2023 October 17 against ElysiaJS 0.7.17 and BunJS 1.0.6.
+This demo was last tested on 2024 March 11 with ElysiaJS 0.8.17 and BunJS 1.0.30.
:::
@@ -151,7 +151,8 @@ app.listen(3000);
bun run src/SheetJSElysia.ts
```
-5) Test POST requests using :
+5) Test POST requests using . The following
+commands should be run in a new terminal window:
```bash
curl -LO https://sheetjs.com/pres.numbers
diff --git a/docz/docs/03-demos/03-net/03-server/11-nestjs.md b/docz/docs/03-demos/03-net/03-server/11-nestjs.md
index b34bb8b..6abc811 100644
--- a/docz/docs/03-demos/03-net/03-server/11-nestjs.md
+++ b/docz/docs/03-demos/03-net/03-server/11-nestjs.md
@@ -20,9 +20,9 @@ downloadable spreadsheets.
The ["Complete Example"](#complete-example) section includes a complete server.
-:::note
+:::note Tested Deployments
-This demo was tested on 2023 October 15 using NestJS `10.2.7`.
+This demo was tested on 2024 March 11 using NestJS `10.3.3`.
:::
@@ -150,7 +150,7 @@ npx @nestjs/cli generate controller sheetjs
6) Replace `src/sheetjs/sheetjs.controller.ts` with the following code block:
-```ts title="src/sheetjs/sheetjs.controller.js"
+```ts title="src/sheetjs/sheetjs.controller.ts"
import { Controller, Get, Header, Post, StreamableFile, UploadedFile, UseInterceptors } from '@nestjs/common';
import { FileInterceptor } from '@nestjs/platform-express';
import { read, utils, write } from 'xlsx';
@@ -204,11 +204,13 @@ The recommended fix is to install `@types/multer` again:
```bash
npm i --save-dev @types/multer
+npx @nestjs/cli start
```
:::
-8) Test POST requests in the terminal with :
+8) Test POST requests using . The following
+commands should be run in a new terminal window:
```bash
curl -LO https://sheetjs.com/pres.numbers
diff --git a/docz/docs/03-demos/03-net/03-server/19-fastify.md b/docz/docs/03-demos/03-net/03-server/19-fastify.md
index 2eb92c4..6895ed6 100644
--- a/docz/docs/03-demos/03-net/03-server/19-fastify.md
+++ b/docz/docs/03-demos/03-net/03-server/19-fastify.md
@@ -19,9 +19,9 @@ with downloadable spreadsheets.
The ["Complete Example"](#complete-example) section includes a complete server.
-:::note
+:::note Tested Deployments
-This demo was verified on 2023 October 16 using `fastify@4.24.2`
+This demo was verified on 2024 March 11 using `fastify@4.26.2`
:::
@@ -157,7 +157,7 @@ fastify.listen({port: process.env.PORT || 3000}, (err, addr) => { if(err) throw
1) Install dependencies:
{`\
-npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz fastify@4.24.2 @fastify/multipart@8.0.0`}
+npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz fastify@4.26.2 @fastify/multipart@8.1.0`}
2) Start server
@@ -166,7 +166,8 @@ npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz fastify
node SheetJSFastify.js
```
-3) Test POST requests using :
+3) Test POST requests using . The following
+commands should be run in a new terminal window:
```bash
curl -LO https://sheetjs.com/pres.numbers
diff --git a/docz/docs/03-demos/03-net/03-server/index.md b/docz/docs/03-demos/03-net/03-server/index.md
index 6637097..1735e9d 100644
--- a/docz/docs/03-demos/03-net/03-server/index.md
+++ b/docz/docs/03-demos/03-net/03-server/index.md
@@ -122,23 +122,29 @@ That approach is not explored in this demo.
Complete Example (click to show)
-:::note
+:::note Tested Deployments
-This demo was last tested on 2023 August 27 with NodeJS 20.5.1 + ExpressJS
-4.18.2 + Formidable 2.1.1
+This demo was tested in the following environments:
+
+| NodeJS | Date | Dependencies |
+|:----------|:-----------|:------------------------------------|
+| `18.19.1` | 2024-02-23 | ExpressJS 4.18.2 + Formidable 2.1.2 |
+| `20.11.1` | 2024-02-23 | ExpressJS 4.18.2 + Formidable 2.1.2 |
:::
-0) Create a simple ECMAScript-Module-enabled `package.json`:
+0) Create a new project with a ESM-enabled `package.json`:
-```json title="package.json"
-{ "type": "module" }
+```bash
+mkdir sheetjs-worker
+cd sheetjs-worker
+echo '{ "type": "module" }' > package.json
```
1) Install the dependencies:
{`\
-npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz express@4.18.2 formidable@2.1.1`}
+npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz express@4.18.2 formidable@2.1.2`}
2) Create a worker script `worker.js` that listens for messages. When a message
@@ -221,7 +227,10 @@ app.listen(7262, () => { console.log(`Example app listening on port 7262`); });
node main.mjs
```
-Test with the [`pres.numbers` sample file](https://sheetjs.com/pres.numbers):
+Keep the server process running during the test.
+
+6) Test with the [`pres.numbers` sample file](https://sheetjs.com/pres.numbers).
+The following commands should be run in a new terminal window:
```bash
curl -LO https://sheetjs.com/pres.numbers
diff --git a/docz/docs/03-demos/03-net/04-email/11-pst.md b/docz/docs/03-demos/03-net/04-email/11-pst.md
index 224bee7..333c017 100644
--- a/docz/docs/03-demos/03-net/04-email/11-pst.md
+++ b/docz/docs/03-demos/03-net/04-email/11-pst.md
@@ -32,9 +32,9 @@ and generate HTML and CSV views of the underlying data.
The ["Live Demo"](#live-demo) reads PST files. Individual spreadsheets within
the file can be downloaded or previewed in the browser.
-:::note
+:::note Tested Deployments
-This demo was last tested on 2023 October 22 against `pst-extractor` 1.9.0
+This demo was last tested on 2024 March 11 against `pst-extractor` 1.9.0
:::
@@ -197,6 +197,12 @@ This demo will fetch a [test PST](pathnamme:///pst/enron.pst) and extract all
embedded spreadsheets. The script can be adapted to read local PST files or pull
PST files from a different URL.
+:::caution pass
+
+The demo uses `fetch` and requires NodeJS 18 or later.
+
+:::
+
0) Initialize a new project:
```bash
diff --git a/docz/docs/03-demos/03-net/04-email/index.md b/docz/docs/03-demos/03-net/04-email/index.md
index 5175afd..57b603b 100644
--- a/docz/docs/03-demos/03-net/04-email/index.md
+++ b/docz/docs/03-demos/03-net/04-email/index.md
@@ -37,17 +37,18 @@ or ban from Google services.
:::
-### Email Details
-
-#### App Passwords
+### App Passwords
Many email providers (including Fastmail, GMail, and Yahoo Mail) require "app
passwords" or passwords for "less secure apps". Attempting to connect and send
using the account password will throw errors.
-#### Test Account
+### Test Account
It is strongly recommended to first test with an independent service provider.
+
+#### Fastmail
+
This demo will start with a free 30-day trial of Fastmail. At the time the demo
was last tested, no payment details were required.
@@ -74,6 +75,38 @@ the second drop-down, select "Mail (IMAP/POP/SMTP)". Click "Generate password".
A new password will be displayed. This is the app password that will be used in
the demo script. **Copy the displayed password or write it down.**
+#### Gmail
+
+This demo will start with a free Gmail account. At the time the demo was last
+tested, no payment details were required.
+
+:::caution pass
+
+A valid phone number (for SMS verification and 2FA) was required.
+
+:::
+
+0) Create a new Gmail email account and verify with a mobile number.
+
+_Create App Password_
+
+1) Click the icon in the top-right corner and click "Manage your Google Account"
+
+2) Click "Security" in the left column
+
+3) Enable 2-Step Verification (if it is not currently enabled)
+
+4) Click "2-Step Verification"
+
+5) Click the right arrow (`>`) next to "App passwords".
+
+6) Type a name ("SheetJS Test") and click "Create".
+
+A new password will be displayed. This is the app password that will be used in
+the demo script. **Copy the displayed password or write it down.**
+
+## Operations
+
### Sending Mail
Many SheetJS users deploy the `nodemailer` module in production.
@@ -113,14 +146,14 @@ includes a table showing the file extension required for each supported type.
#### Send Demo
-:::note
+:::note Tested Deployments
This demo was tested in the following deployments:
-| Email Provider | Date | Library | Version |
-|:---------------|:-----------|:-------------|:--------|
-| `gmail.com` | 2023-06-03 | `nodemailer` | `6.9.3` |
-| `fastmail.com` | 2023-06-03 | `nodemailer` | `6.9.3` |
+| Email Provider | Date | Library | Version |
+|:---------------|:-----------|:-------------|:---------|
+| `gmail.com` | 2024-03-11 | `nodemailer` | `6.9.12` |
+| `fastmail.com` | 2024-03-11 | `nodemailer` | `6.9.12` |
:::
@@ -131,7 +164,7 @@ This demo was tested in the following deployments:
{`\
mkdir sheetjs-send
cd sheetjs-send
-npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz nodemailer@6.9.3`}
+npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz nodemailer@6.9.12`}
2) Save the following script to `SheetJSend.js`:
@@ -141,6 +174,7 @@ const XLSX = require('xlsx');
const nodemailer = require('nodemailer');
const transporter = nodemailer.createTransport({
+// highlight-next-line
service: 'fastmail',
auth: {
// highlight-start
@@ -176,6 +210,7 @@ transporter.sendMail(mailOptions, function (err, info) {
3) Edit `SheetJSend.js` and replace the highlighted lines:
+- `service: 'fastmail',` the value should be one of the supported providers[^1]
- `user: "**",` the value should be the sender email address
- `pass: "**"` the value should be the app password from earlier
- `from: "**",` the value should be the sender email address
@@ -259,13 +294,14 @@ function process_buf(buf, name) {
#### Receive Demo
-:::note
+:::note Tested Deployments
This demo was tested in the following deployments:
| Email Provider | Date | Library | Version |
|:---------------|:-----------|:-----------|:----------|
-| `fastmail.com` | 2023-06-03 | `imapflow` | `1.0.128` |
+| `gmail.com` | 2024-03-11 | `imapflow` | `1.0.156` |
+| `fastmail.com` | 2024-03-11 | `imapflow` | `1.0.156` |
:::
@@ -276,7 +312,7 @@ This demo was tested in the following deployments:
{`\
mkdir sheetjs-recv
cd sheetjs-recv
-npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz imapflow@1.0.128`}
+npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz imapflow@1.0.156`}
2) Save the following script to `SheetJSIMAP.js`:
@@ -286,7 +322,9 @@ const XLSX = require('xlsx');
const { ImapFlow } = require('imapflow');
const client = new ImapFlow({
- host: 'imap.fastmail.com', port: 993, secure: true, logger: false,
+// highlight-next-line
+ host: 'imap.fastmail.com',
+ port: 993, secure: true, logger: false,
auth: {
// highlight-start
user: '**',
@@ -333,6 +371,12 @@ const concat_RS = (stream) => new Promise((res, rej) => {
- `user: "**",` the value should be the account address
- `pass: "**"` the value should be the app password from earlier
+- `host: 'imap.fastmail.com',` the value should be the host name:
+
+| Service | `host` value |
+|:---------------|:--------------------|
+| `gmail.com` | `imap.gmail.com` |
+| `fastmail.com` | `imap.fastmail.com` |
4) Download . Using a different account, send
an email to the test account and attach the file. At the end of this step, the
@@ -364,3 +408,5 @@ proprietary mail and email account file formats.
### PST
**[The exposition has been moved to a separate page.](/docs/demos/net/email/pst)**
+
+[^1]: The list of services can be found in [`lib/well-known/services.json`](https://github.com/nodemailer/nodemailer/blob/master/lib/well-known/services.json) in the NodeMailer project.
diff --git a/docz/docs/03-demos/03-net/08-headless.md b/docz/docs/03-demos/03-net/08-headless.md
index 8c49653..dd5fbc7 100644
--- a/docz/docs/03-demos/03-net/08-headless.md
+++ b/docz/docs/03-demos/03-net/08-headless.md
@@ -400,7 +400,12 @@ strongly recommended to add verbose logging and to lint scripts before use.
:::note Tested Deployments
-This demo was last tested on 2023 September 14 against PhantomJS 2.1.1
+This demo was tested in the following environments:
+
+| Architecture | PhantomJS | Date |
+|:-------------|:----------|:-----------|
+| `darwin-x64` | `2.1.1` | 2024-02-23 |
+| `win10-x64` | `2.1.1` | 2024-02-23 |
:::
diff --git a/docz/docs/03-demos/17-mobile/01-reactnative.md b/docz/docs/03-demos/17-mobile/01-reactnative.md
index ddb4a3a..0b8752d 100644
--- a/docz/docs/03-demos/17-mobile/01-reactnative.md
+++ b/docz/docs/03-demos/17-mobile/01-reactnative.md
@@ -219,9 +219,9 @@ This demo was tested in the following environments:
| OS | Type | Device | RN | Date |
|:-----------|:-----|:--------------------|:---------|:-----------|
-| Android 34 | Sim | Pixel 3a | `0.73.1` | 2023-12-21 |
+| Android 34 | Sim | Pixel 3a | `0.73.5` | 2024-03-05 |
| iOS 17.2 | Sim | iPhone 15 Pro Max | `0.73.1` | 2023-12-21 |
-| Android 29 | Real | NVIDIA Shield | `0.73.1` | 2023-12-21 |
+| Android 29 | Real | NVIDIA Shield | `0.73.5` | 2024-03-05 |
| iOS 15.1 | Real | iPad Pro | `0.73.1` | 2023-12-21 |
:::
diff --git a/docz/docs/03-demos/19-desktop/01-electron.md b/docz/docs/03-demos/19-desktop/01-electron.md
index 93f8699..a10cd21 100644
--- a/docz/docs/03-demos/19-desktop/01-electron.md
+++ b/docz/docs/03-demos/19-desktop/01-electron.md
@@ -190,7 +190,7 @@ This demo was tested in the following environments:
|:---------------|:-------------|:---------|:-----------|
| macOS 13.5.1 | `darwin-x64` | `27.1.3` | 2023-12-09 |
| macOS 14.1.2 | `darwin-arm` | `27.1.3` | 2023-12-01 |
-| Windows 10 | `win10-x64` | `27.1.3` | 2023-12-09 |
+| Windows 10 | `win10-x64` | `28.2.0` | 2024-03-04 |
| Windows 11 | `win11-arm` | `27.1.3` | 2023-12-01 |
| Linux (HoloOS) | `linux-x64` | `28.2.0` | 2024-01-26 |
| Linux (Debian) | `linux-arm` | `27.1.3` | 2023-12-01 |
diff --git a/docz/docs/03-demos/19-desktop/02-nwjs.md b/docz/docs/03-demos/19-desktop/02-nwjs.md
index f8dd493..c2d19c2 100644
--- a/docz/docs/03-demos/19-desktop/02-nwjs.md
+++ b/docz/docs/03-demos/19-desktop/02-nwjs.md
@@ -115,7 +115,7 @@ This demo was tested in the following environments:
|:---------------|:-------------|:---------|:-----------|
| macOS 13.5.2 | `darwin-x64` | `0.78.1` | 2023-09-27 |
| macOS 14.1.2 | `darwin-arm` | `0.82.0` | 2023-12-01 |
-| Windows 10 | `win10-x64` | `0.82.0` | 2023-12-09 |
+| Windows 10 | `win10-x64` | `0.83.0` | 2024-03-04 |
| Windows 11 | `win11-arm` | `0.82.0` | 2023-12-01 |
| Linux (HoloOS) | `linux-x64` | `0.83.0` | 2024-01-26 |
diff --git a/docz/docs/03-demos/19-desktop/03-wails.md b/docz/docs/03-demos/19-desktop/03-wails.md
index c4bb330..66344ba 100644
--- a/docz/docs/03-demos/19-desktop/03-wails.md
+++ b/docz/docs/03-demos/19-desktop/03-wails.md
@@ -299,7 +299,7 @@ This demo was tested in the following environments:
|:---------------|:-------------|:---------|:-----------|
| macOS 13.6 | `darwin-x64` | `v2.6.0` | 2023-11-05 |
| macOS 14.1.2 | `darwin-arm` | `v2.6.0` | 2023-12-01 |
-| Windows 10 | `win10-x64` | `v2.6.0` | 2023-12-09 |
+| Windows 10 | `win10-x64` | `v2.8.0` | 2024-03-10 |
| Windows 11 | `win11-arm` | `v2.6.0` | 2023-12-01 |
| Linux (HoloOS) | `linux-x64` | `v2.7.1` | 2024-01-22 |
| Linux (Debian) | `linux-arm` | `v2.6.0` | 2023-12-01 |
@@ -402,7 +402,7 @@ curl -o frontend/src/App.svelte https://docs.sheetjs.com/wails/App.svelte
wails build
```
-At the end, it will print the path to the generated program.
+It will print the path to the generated program (typically in `build/bin/`).
6) Run the generated application.
diff --git a/docz/docs/03-demos/19-desktop/04-tauri.md b/docz/docs/03-demos/19-desktop/04-tauri.md
index 79ca192..41439a7 100644
--- a/docz/docs/03-demos/19-desktop/04-tauri.md
+++ b/docz/docs/03-demos/19-desktop/04-tauri.md
@@ -434,7 +434,7 @@ During the last Linux x64 test, the build failed with the error message:
'openssl/opensslv.h' file not found
```
-This error was resolved installing OpenSSL. On Arch Linux and HoloOS:
+OpenSSL must be installed. On Arch Linux and HoloOS (Steam Deck):
```bash
sudo pacman -S openssl
diff --git a/docz/docs/03-demos/19-desktop/09-cli.md b/docz/docs/03-demos/19-desktop/09-cli.md
index e043d35..b8404a6 100644
--- a/docz/docs/03-demos/19-desktop/09-cli.md
+++ b/docz/docs/03-demos/19-desktop/09-cli.md
@@ -53,7 +53,7 @@ This demo was tested in the following deployments:
|:-------------|:-------------|:----------|:----------|:-----------|
| `darwin-x64` | `4.0.0-rc.2` | `14.15.3` | Pre-built | 2023-10-10 |
| `darwin-arm` | `4.0.0-rc.2` | `18.18.0` | Compiled | 2023-12-01 |
-| `win10-x64` | `4.0.0-rc.2` | `14.15.3` | Pre-built | 2023-10-09 |
+| `win10-x64` | `4.0.0-rc.4` | `14.15.3` | Pre-built | 2024-03-04 |
| `win11-arm` | `4.0.0-rc.2` | `20.10.0` | Compiled | 2023-12-01 |
| `linux-x64` | `4.0.0-rc.4` | `14.15.3` | Pre-built | 2024-01-26 |
| `linux-arm` | `4.0.0-rc.2` | `20.10.0` | Compiled | 2023-12-01 |
diff --git a/docz/docs/03-demos/23-data/29-pouchdb.md b/docz/docs/03-demos/23-data/29-pouchdb.md
index 55480cb..472906f 100644
--- a/docz/docs/03-demos/23-data/29-pouchdb.md
+++ b/docz/docs/03-demos/23-data/29-pouchdb.md
@@ -62,7 +62,7 @@ async function push_first_sheet_to_pouchdb(db, wb, _id_) {
/* get first worksheet */
const ws = wb.Sheets[wb.SheetNames[0]];
- /* generate array of arrays */
+ /* generate array of objects */
const aoo = XLSX.utils.sheet_to_json(ws);
/* if a prefix is specified, add a unique _id to each row based on index */
diff --git a/docz/docs/03-demos/27-local/02-websql.md b/docz/docs/03-demos/27-local/02-websql.md
index 5212e69..08274ab 100644
--- a/docz/docs/03-demos/27-local/02-websql.md
+++ b/docz/docs/03-demos/27-local/02-websql.md
@@ -9,22 +9,22 @@ sidebar_custom_props:
import CodeBlock from '@theme/CodeBlock';
+:::warning pass
+
+WebSQL is no longer enabled by default in Chrome. Chrome 123 will officially
+remove support. For SQL in the browser, there are a few alternatives:
+
+- [SQL.js](/docs/demos/data/sqlite#browser) is a compiled version of SQLite
+- [AlaSQL](/docs/demos/data/alasql) is a pure-JS SQL engine backed by IndexedDB
+
+:::
+
WebSQL (formally "Web SQL Database") is a popular SQL-based in-browser database
available in Chromium and related browsers including Google Chrome. In practice,
it is powered by SQLite. Many SQLite-compatible queries work as-is in WebSQL.
The public demo generates a database from workbook.
-:::caution pass
-
-WebSQL is only supported in Chromium-based browsers including Chrome.
-
-Safari historically supported WebSQL but Safari 13 dropped support.
-
-Legacy browsers including Internet Explorer and Firefox never added support.
-
-:::
-
:::info pass
WebSQL is not commonly available on server-side platforms. Typically scripts
@@ -150,14 +150,15 @@ This browser demo was tested in the following environments:
| Browser | Date |
|:------------|:-----------|
-| Chrome 119 | 2023-11-30 |
+| Chrome 118 | 2024-02-11 |
-Some lesser-used browsers do not support WebSQL:
+Browsers that do not support WebSQL will throw errors:
-| Browser | Date | Support |
-|:------------|:-----------|:------------------------------------|
-| Safari 17.0 | 2023-10-13 | Error `Web SQL is deprecated` |
-| Firefox 118 | 2023-10-13 | Error `openDatabase is not defined` |
+| Browser | Date | Error Message |
+|:------------|:-----------|:------------------------------|
+| Chrome 120 | 2024-02-11 | `openDatabase is not defined` |
+| Safari 17.3 | 2024-02-11 | `Web SQL is deprecated` |
+| Firefox 118 | 2023-10-13 | `openDatabase is not defined` |
:::
diff --git a/docz/docs/03-demos/27-local/05-clipboard.md b/docz/docs/03-demos/27-local/05-clipboard.md
index 7b2a0a0..f05140f 100644
--- a/docz/docs/03-demos/27-local/05-clipboard.md
+++ b/docz/docs/03-demos/27-local/05-clipboard.md
@@ -20,11 +20,11 @@ Not all Clipboard APIs offer access to all clipboard types.
Each browser demo was tested in the following environments:
-| Browser | Date |
-|:------------|:-----------|
-| Chrome 119 | 2023-11-30 |
-| Safari 16.6 | 2023-09-01 |
-| Brave 1.57 | 2023-09-01 |
+| Browser | Date | Notes
+|:------------|:-----------|:-------------------------|
+| Chrome 121 | 2024-02-21 | |
+| Safari 17.3 | 2024-02-21 | `text/rtf` not supported |
+| Brave 1.59 | 2024-02-21 | |
:::
diff --git a/docz/docs/03-demos/32-extensions/01-extendscript.md b/docz/docs/03-demos/32-extensions/01-extendscript.md
index 4a67798..712d373 100644
--- a/docz/docs/03-demos/32-extensions/01-extendscript.md
+++ b/docz/docs/03-demos/32-extensions/01-extendscript.md
@@ -33,7 +33,7 @@ versions of Photoshop and InDesign:
- ["Unified Extensibility Platform" (UXP)](#uxp): This platform supports modern
JavaScript but has limited support (Photoshop 2021+ and InDesign 2022+)
-:::note
+:::note Tested Deployments
This demo was verified in the following deployments:
@@ -42,7 +42,7 @@ This demo was verified in the following deployments:
| Photoshop | ExtendScript | 2023-09-24 |
| InDesign | ExtendScript | 2023-09-24 |
| InDesign | CEP | 2023-09-24 |
-| InDesign | UXP | 2023-09-24 |
+| InDesign | UXP | 2024-03-11 |
:::
diff --git a/docz/docs/03-demos/32-extensions/02-chromium.md b/docz/docs/03-demos/32-extensions/02-chromium.md
index c15f66c..b8989b5 100644
--- a/docz/docs/03-demos/32-extensions/02-chromium.md
+++ b/docz/docs/03-demos/32-extensions/02-chromium.md
@@ -4,14 +4,6 @@ pagination_prev: demos/cloud/index
pagination_next: demos/bigdata/index
---
-:::note pass
-
-This demo showcases Manifest V2 and Manifest V3 extensions. Chrome Web Store
-will not accept new V2 extensions, but these can be sideloaded using the
-"Load unpacked" extension option in Developer mode.
-
-:::
-
The [SheetJS Standalone scripts](/docs/getting-started/installation/standalone)
can be integrated in a Chromium extension.
@@ -20,9 +12,20 @@ tables with a content script and a background script.
[The demo](#demo) includes unpacked extensions for Manifest V2 and Manifest V3.
-:::note
+:::note Tested Deployments
-This demo was last tested on 2023 October 14 against Chrome 117.
+This demo was last tested on 2024 March 11 against Chrome 122.
+
+:::
+
+:::caution pass
+
+This demo showcases Manifest V2 and Manifest V3 extensions.
+
+Chrome Web Store will not accept new V2 extensions, but these can be sideloaded
+using the "Load unpacked" extension option in Developer mode.
+
+**New Chrome and Chromium Extensions should use Manifest V3!**
:::
diff --git a/docz/docs/03-demos/32-extensions/03-excelapi.md b/docz/docs/03-demos/32-extensions/03-excelapi.md
index 6ca68a9..6169354 100644
--- a/docz/docs/03-demos/32-extensions/03-excelapi.md
+++ b/docz/docs/03-demos/32-extensions/03-excelapi.md
@@ -14,23 +14,24 @@ writing Excel files, [other demos](/docs/demos/) cover a wide variety of use cas
:::
+[SheetJS](https://sheetjs.com) is a JavaScript library for reading and writing
+data from spreadsheets.
+
Office 2016 introduced a JavaScript API for interacting with the application.
It offers solutions for custom functions as well as task panes.
Excel currently does not provide support for working with Apple Numbers files
-and some legacy file formats. SheetJS fills the gap.
+and some legacy file formats. SheetJS fills the gap.
-This demo creates a new custom function `SHEETJS.EXTERN()` which tries to fetch
-an external spreadsheet and insert the data into the worksheet.
+In the ["Complete Demo"](#complete-demo), we'll create a new custom function
+`SHEETJS.EXTERN()` which tries to fetch an external spreadsheet and insert the
+data into the worksheet.
![`SHEETJS.EXTERN` output](pathname:///xlapi/xlfetch.png)
-This demo focuses on the basic mechanics. Advanced topics like Excel Custom
-Function parameters are covered in the official Office JavaScript API docs.
+:::note Tested Deployments
-:::note
-
-This demo was last tested on 2023 September 03 against Excel 365 (version 2308)
+This demo was last tested on 2024 March 04 against Excel 365 (version 2402).
:::
@@ -42,10 +43,26 @@ Excel 365 before running the demo.
:::
+:::warning Telemetry
+
+The Office Add-in CLI collects telemetry by default. It can be disabled:
+
+```js
+npx office-addin-usage-data off
+```
+
+The setting can be verified by running:
+
+```js
+npx office-addin-usage-data list
+```
+
+:::
+
## Integration Details
-The [NodeJS module](/docs/getting-started/installation/nodejs) can be imported
-in an Excel Custom Functions project.
+The [SheetJS NodeJS module](/docs/getting-started/installation/nodejs) can be
+imported from scripts in an Excel Custom Functions project.
The [`sheet_to_json`](/docs/api/utilities#json) helper function can generate
arrays of arrays of values based on the worksheet data. Excel custom functions
@@ -62,7 +79,7 @@ var XLSX = require("xlsx");
* @param {string} url URL to fetch and parse
* @returns {any[][]} Worksheet data
*/
-async function extern(url) {
+export async function extern(url) {
try {
/* Fetch Data */
const res = await fetch(url);
@@ -101,7 +118,15 @@ after testing is finished.
1) Install [NodeJS LTS](https://nodejs.org/en/download/).
-2) Install dependencies in a new PowerShell window:
+2) After installing NodeJS, launch a new PowerShell window.
+
+3) Disable telemetry:
+
+```bash
+npx office-addin-usage-data off
+```
+
+4) Install dependencies:
```bash
npm i -g yo bower generator-office
@@ -109,7 +134,13 @@ npm i -g yo bower generator-office
### Creating a new Add-in
-3) Run `yo office` from the command line. It will ask a few questions:
+5) Run the generator:
+
+```bash
+npx yo office
+```
+
+The generator will ask a few questions:
- "Choose a project type": "Excel Custom Functions using a Shared Runtime"
@@ -117,7 +148,9 @@ npm i -g yo bower generator-office
- "What do you want to name your add-in?": "SheetJSImport"
-4) Start the dev process:
+The generator will create the project and install dependencies.
+
+6) Start the development process:
```bash
cd SheetJSImport
@@ -125,13 +158,34 @@ npm run build
npm start
```
-Running `npm start` will open up a terminal window and a new Excel window with
-the loaded add-in. Keep the terminal window open.
+If prompted to `Allow localhost loopback for Microsoft Edge WebView`, type "N"
+and press Enter.
-5) In `manifest.xml` , search for `Functions.NameSpace` . There will be an XML
+If prompted to install "Developer CA for Microsoft Office Add-ins" certificate,
+select "Yes"
+
+If Windows Firewall prompts to allow Node.js on private networks, select "Yes"
+A new terminal window running NodeJS will be created. Keep the window open.
+
+A new Excel window with the loaded add-in will launch.
+
+:::caution pass
+
+In some tests, the taskpane showed an error:
+
+```
+Script error.
+```
+
+[Webview2](https://developer.microsoft.com/en-us/microsoft-edge/webview2/)
+should be installed manually.
+
+:::
+
+7) In `manifest.xml` , search for `Functions.Namespace` . There will be an XML
element with name `bt:String`. Change the `DefaultValue` attribute to `SHEETJS`:
-```xml title="manifest.xml"
+```xml title="manifest.xml (change highlighted line)"
// highlight-next-line
@@ -139,17 +193,23 @@ element with name `bt:String`. Change the `DefaultValue` attribute to `SHEETJS`:
```
-6) Close the Excel window and the terminal window, then run `npm start` again.
+8) Close the Excel window and the terminal window. Do not save the XLSX file.
+
+9) In the PowerShell window, start the development process again:
+
+```bash
+npm start
+```
### Integrating the SheetJS Library
-7) Install the SheetJS library in the project
+10) Install the SheetJS library in the project
{`\
npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`}
-8) Replace `src\functions\functions.js` with the following:
+11) Replace `src\functions\functions.js` with the following:
```js title="src\functions\functions.js"
var XLSX = require("xlsx");
@@ -159,15 +219,20 @@ var XLSX = require("xlsx");
* @customfunction
* @returns {string[][]} The SheetJS Library Version.
*/
-function version() {
+export function version() {
return [[XLSX.version]];
}
```
-9) After making the change, save the files. Close the terminal window and the
-Excel window (do not save the Excel file). Re-run `npm start`.
+12) Close the terminal window and the Excel window. Do not save the Excel file.
-10) In the new Excel window, enter the formula `=SHEETJS.VERSION()` in cell
+13) In the PowerShell window, start the development process again:
+
+```bash
+npm start
+```
+
+14) In the new Excel window, enter the formula `=SHEETJS.VERSION()` in cell
`D1`. You should see something similar to the following screenshot:
![`SHEETJS.VERSION` output](pathname:///xlapi/xlvers.png)
@@ -176,7 +241,7 @@ This indicates that the SheetJS library has been loaded.
### Fetching Files from the Internet
-11) Add the following code snippet to `src\functions\functions.js`:
+15) Add the following code snippet to `src\functions\functions.js`:
```js title="src\functions\functions.js (add to end)"
/**
@@ -185,7 +250,7 @@ This indicates that the SheetJS library has been loaded.
* @param {string} url URL to fetch and parse
* @returns {any[][]} Worksheet data
*/
-async function extern(url) {
+export async function extern(url) {
try {
/* Fetch Data */
const res = await fetch(url);
@@ -204,12 +269,14 @@ async function extern(url) {
}
```
-12) After making the change, save the files. Close the terminal window and the
+16) After making the change, save the files. Close the terminal window and the
Excel window (do not save the Excel file). Re-run `npm start`.
-13) Enter the text `https://sheetjs.com/pres.numbers` in cell `D1`. Enter the
-formula `=SHEETJS.EXTERN(D1)` in cell `D2` and press Enter. Excel should pull
-in the data and generate a dynamic array.
+17) Enter the text `https://sheetjs.com/pres.numbers` in cell `D1`. Enter the
+formula `=SHEETJS.EXTERN(D1)` in cell `D2` and press Enter.
+
+Excel should pull in the data and generate a dynamic array. The worksheet should
+match the screenshot at the top of this page.
:::tip pass
diff --git a/docz/docs/03-demos/32-extensions/04-gsheet.md b/docz/docs/03-demos/32-extensions/04-gsheet.md
index e75ce80..f170d26 100644
--- a/docz/docs/03-demos/32-extensions/04-gsheet.md
+++ b/docz/docs/03-demos/32-extensions/04-gsheet.md
@@ -27,9 +27,9 @@ remote file, parses the contents, and writes data to the sheet:
![Screenshot of final result](pathname:///gsheet/udf.png)
-:::note
+:::note Tested Deployments
-This demo was last tested on 2023 September 16.
+This demo was last tested on 2024 March 11.
:::
diff --git a/docz/docs/03-demos/32-extensions/06-osa.md b/docz/docs/03-demos/32-extensions/06-osa.md
index 1b4abb1..3f12ab2 100644
--- a/docz/docs/03-demos/32-extensions/06-osa.md
+++ b/docz/docs/03-demos/32-extensions/06-osa.md
@@ -9,23 +9,30 @@ import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
import CodeBlock from '@theme/CodeBlock';
-Open Scripting Architecture (OSA), a built-in feature in macOS introduced in
-1993, enables users to communicate with applications with a standardized
-language and grammar. macOS releases starting from Yosemite (OSX 10.10) include
-native support for scripting with JavaScript.
+Open Scripting Architecture (OSA)[^1] enables macOS app automation with scripts.
+OSA originally supported the "AppleScript" language. Modern macOS releases
+(OSX 10.10 and later) natively support JavaScript scripts using "JXA"[^2].
-The [SheetJS Standalone scripts](/docs/getting-started/installation/standalone)
-can be parsed and evaluated from the JS engine. Once evaluated, the `XLSX`
-global will be defined. A JS stub can expose methods from AppleScript scripts.
+[SheetJS](https://sheetjs.com) is a JavaScript library for reading and writing
+data from spreadsheets.
-:::note
+:::note Tested Environments
-This demo was last tested on 2023-09-03 in macOS Ventura.
+This demo was tested in the following environments:
+
+| macOS | Language | Date |
+|:---------|:------------------|:-----------|
+| `14.3.1` | AppleScript (OSA) | 2024-02-21 |
+| `14.3.1` | JavaScript (JXA) | 2024-02-21 |
:::
## Integration details
+The [SheetJS Standalone scripts](/docs/getting-started/installation/standalone)
+can be parsed and evaluated from the JS engine. Once evaluated, the `XLSX`
+global will be defined. A JS stub can expose methods from AppleScript scripts.
+
@@ -252,4 +259,7 @@ chmod +x sheetosa.scpt
```
-
\ No newline at end of file
+
+
+[^1]: See ["Introduction to AppleScript Overview"](https://developer.apple.com/library/archive/documentation/AppleScript/Conceptual/AppleScriptX/AppleScriptX.html) in the Apple Developer documentation for more details.
+[^2]: See ["Introduction to JavaScript for Automation Release Notes"](https://developer.apple.com/library/archive/releasenotes/InterapplicationCommunication/RN-JavaScriptForAutomation/Articles/Introduction.html) in the Apple Developer documentation for more details.
diff --git a/docz/docs/03-demos/37-bigdata/01-stream.md b/docz/docs/03-demos/37-bigdata/01-stream.md
index 5efcaee..599cb0d 100644
--- a/docz/docs/03-demos/37-bigdata/01-stream.md
+++ b/docz/docs/03-demos/37-bigdata/01-stream.md
@@ -137,22 +137,23 @@ XLSX.stream.to_json(ws, {raw: true}).pipe(conv).pipe(process.stdout);
**Demo**
-:::note
+:::note Tested Deployments
-This demo was last tested in the following deployments:
+This demo was tested in the following deployments:
| Node Version | Date | Node Status when tested |
|:-------------|:-----------|:------------------------|
-| `0.12.18` | 2023-09-02 | End-of-Life |
-| `4.9.1` | 2023-09-02 | End-of-Life |
-| `6.17.1` | 2023-09-02 | End-of-Life |
-| `8.17.0` | 2023-09-02 | End-of-Life |
-| `10.24.1` | 2023-09-02 | End-of-Life |
-| `12.22.12` | 2023-09-02 | End-of-Life |
-| `14.21.3` | 2023-09-02 | End-of-Life |
-| `16.20.0` | 2023-09-02 | Maintenance LTS |
-| `18.17.1` | 2023-09-02 | Active LTS |
-| `20.5.1` | 2023-09-02 | Current |
+| `0.12.18` | 2024-02-23 | End-of-Life |
+| `4.9.1` | 2024-02-23 | End-of-Life |
+| `6.17.1` | 2024-02-23 | End-of-Life |
+| `8.17.0` | 2024-02-23 | End-of-Life |
+| `10.24.1` | 2024-02-23 | End-of-Life |
+| `12.22.12` | 2024-02-23 | End-of-Life |
+| `14.21.3` | 2024-02-23 | End-of-Life |
+| `16.20.2` | 2024-02-23 | End-of-Life |
+| `18.19.1` | 2024-02-23 | Maintenance LTS |
+| `20.11.1` | 2024-02-23 | Active LTS |
+| `21.6.2` | 2024-02-23 | Current |
While streaming methods work in End-of-Life versions of NodeJS, production
deployments should upgrade to a Current or LTS version of NodeJS.
@@ -210,9 +211,14 @@ Joseph Biden,46
### Browser
-:::note
+:::note Tested Deployments
-The live demo was last tested on 2023-09-02 in Chromium 116.
+Each browser demo was tested in the following environments:
+
+| Browser | Date |
+|:------------|:-----------|
+| Chrome 121 | 2024-02-23 |
+| Safari 17.3 | 2024-02-23 |
:::
@@ -441,9 +447,9 @@ const ws = workbook.Sheets[workbook.SheetNames[0]];
stream.to_csv(wb.Sheets[wb.SheetNames[0]]).resume();`}
-:::note
+:::note Tested Deployments
-This demo was last tested on 2023-09-02 against Deno `1.36.4`
+This demo was last tested on 2024-02-23 against Deno `1.41.0`.
:::
@@ -451,4 +457,11 @@ This demo was last tested on 2023-09-02 against Deno `1.36.4`
example script that downloads and prints
CSV row objects.
-1) Run `deno run -A https://docs.sheetjs.com/stream/SheetJSDenoStream.ts`
+1) Run the script:
+
+```bash
+deno run -A https://docs.sheetjs.com/stream/SheetJSDenoStream.ts
+```
+
+This script will fetch [`pres.numbers`](https://sheetjs.com/pres.numbers) and
+generate CSV rows. The result will be printed to the terminal window.
\ No newline at end of file
diff --git a/docz/docs/03-demos/37-bigdata/02-worker.md b/docz/docs/03-demos/37-bigdata/02-worker.md
index d9fdef9..151fd82 100644
--- a/docz/docs/03-demos/37-bigdata/02-worker.md
+++ b/docz/docs/03-demos/37-bigdata/02-worker.md
@@ -184,13 +184,13 @@ const worker = new Worker(
## Live Demos
-:::note
+:::note Tested Deployments
Each browser demo was tested in the following environments:
| Browser | Date | Comments |
|:------------|:-----------|:----------------------------------------|
-| Chrome 116 | 2023-09-02 | |
+| Chrome 121 | 2024-02-25 | |
| Edge 116 | 2023-09-02 | |
| Safari 16.6 | 2023-09-02 | File System Access API is not supported |
| Brave 1.57 | 2023-09-02 | File System Access API is not supported |
diff --git a/docz/docs/03-demos/42-engines/01-duktape.md b/docz/docs/03-demos/42-engines/01-duktape.md
index d6c2832..a2114d1 100644
--- a/docz/docs/03-demos/42-engines/01-duktape.md
+++ b/docz/docs/03-demos/42-engines/01-duktape.md
@@ -98,7 +98,7 @@ duk_config_buffer(ctx, -1, buf, len);
duk_put_global_string(ctx, "buf");
/* parse with SheetJS */
-duk_eval_string_noresult("workbook = XLSX.read(buf.slice(0, buf.length), {type:'buffer'});");
+duk_eval_string_noresult(ctx, "workbook = XLSX.read(buf.slice(0, buf.length), {type:'buffer'});");
```
`workbook` will be a variable in the JS environment that can be inspected using
@@ -347,11 +347,57 @@ sequenceDiagram
Bindings exist for many languages. As these bindings require "native" code, they
may not work on every platform.
+The Duktape source distribution includes a separate Makefile for building a
+shared library. This library can be loaded in other programs.
+
+#### Blingos
+
+Duktape includes a number of "blingos" (function-like macros) which will not be
+included in the shared library. The macros must be manually expanded.
+
+For example, `duk_create_heap_default` is defined as follows:
+
+```c
+#define duk_create_heap_default() \
+ duk_create_heap(NULL, NULL, NULL, NULL, NULL)
+```
+
+The `duk_create_heap_default` blingo will not be defined in the shared library.
+Instead, `duk_create_heap` must be called directly. Using PHP FFI:
+
+```php
+/* create new FFI object */
+$ffi = FFI::cdef(/* ... arguments */);
+
+/* call duk_create_heap directly */
+// highlight-next-line
+$context = $ffi->duk_create_heap(null, null, null, null, null);
+```
+
+#### Null Pointers
+
+The C `NULL` pointer must be used in some functions. Some FFI implementations
+have special values distinct from the language-native null value. Using Python,
+return type hints are specified with the `restype` property:
+
+```py
+from ctypes import CDLL, c_void_p
+
+duk = CDLL("libduktape.so")
+
+# highlight-next-line
+duk.duk_create_heap.restype = c_void_p
+context = duk.duk_create_heap(None, None, None, None, None)
+```
+
### PHP
There is no official PHP binding to the Duktape library. Instead, this demo uses
the raw `FFI` interface[^1] to the Duktape shared library.
+The [`SheetJSDuk.php`](pathname:///duk/SheetJSDuk.php) demo script parses a
+file, prints CSV rows from the first worksheet, and creates a XLSB workbook.
+
#### PHP Demo
:::note Tested Deployments
@@ -361,6 +407,7 @@ This demo was tested in the following deployments:
| Architecture | Version | PHP Version | Date |
|:-------------|:--------|:------------|:-----------|
| `darwin-x64` | `2.7.0` | `8.3.2` | 2024-01-26 |
+| `darwin-arm` | `2.7.0` | `8.3.2` | 2024-02-13 |
| `linux-x64` | `2.7.0` | `8.2.7` | 2024-01-29 |
:::
@@ -487,6 +534,7 @@ This demo was tested in the following deployments:
| Architecture | Version | Python | Date |
|:-------------|:--------|:---------|:-----------|
| `darwin-x64` | `2.7.0` | `3.11.7` | 2024-01-29 |
+| `darwin-arm` | `2.7.0` | `3.11.7` | 2024-02-13 |
| `linux-x64` | `2.7.0` | `3.11.3` | 2024-01-29 |
:::
@@ -579,6 +627,302 @@ python3 SheetJSDuk.py pres.numbers
If the program succeeded, the CSV contents will be printed to console and the
file `sheetjsw.xlsb` will be created. That file can be opened with Excel.
+### Zig
+
+:::caution Zig support is considered experimental.
+
+Great open source software grows with user tests and reports. Any issues should
+be reported to the Zig project for further diagnosis.
+
+:::
+
+#### Zig Compilation
+
+The main Duktape code can be added to the Zig build pipeline.
+
+:::note pass
+
+The following explanation was verified against Zig 0.11.0.
+
+:::
+
+Due to restrictions in the Zig C integration, the path to the Duktape `src`
+folder must be added to the include path list:
+
+```zig title="build.zig"
+ const exe = b.addExecutable(.{
+ // ...
+ });
+ // highlight-start
+ // this line is required to make @cInclude("duktape.h") work
+ exe.addIncludePath(.{ .path = "duktape-2.7.0/src" });
+ // highlight-end
+```
+
+The `duktape.c` source file must be added to the build sequence. For Zig version
+0.11.0, Duktape must be compiled with flags `-std=c99 -fno-sanitize=undefined`
+and linked against `libc` and `libm`:
+
+```zig title="build.zig"
+ const exe = b.addExecutable(.{
+ // ...
+ });
+// highlight-start
+ exe.addCSourceFile(.{:
+ .file = .{ .path = "duktape-2.7.0/src/duktape.c" },
+ .flags = &.{ "-std=c99", "-fno-sanitize=undefined" }
+ });
+ exe.linkSystemLibrary("c");
+ exe.linkSystemLibrary("m");
+// highlight-end
+```
+
+#### Zig Import
+
+`duktape.h` can be imported using the `@cImport` directive:
+
+```zig title="main.zig"
+const duktape = @cImport({
+ @cInclude("duktape.h");
+});
+```
+
+Once imported, many API functions can be referenced from the `duktape` scope.
+For example, `duk_peval_string` in the C interface will be available to Zig code
+using the name `duktape.duk_peval_string`.
+
+It is strongly recommended to colocate allocations and cleanup methods using
+`defer`. For example, a Duktape context is created with `duk_create_heap` and
+destroyed with `duk_destroy_heap`. The latter call can be deferred:
+
+```zig
+ const ctx = duktape.duk_create_heap(null, null, null, null, null);
+ defer _ = duktape.duk_destroy_heap(ctx);
+```
+
+#### Zig Translator Caveats
+
+The Zig translator does not properly handle blingo `void` casts. For example,
+`duk_eval_string_noresult` is a function-like macro defined in `duktape.h`:
+
+```c title="duk_eval_string_noresult blingo"
+#define duk_eval_string_noresult(ctx,src) \
+ ((void) duk_eval_raw((ctx), (src), 0, 0 /*args*/ | DUK_COMPILE_EVAL | DUK_COMPILE_NOSOURCE | DUK_COMPILE_STRLEN | DUK_COMPILE_NORESULT | DUK_COMPILE_NOFILENAME))
+```
+
+The compiler will throw an error involving `anyopaque` (C `void`):
+
+```
+error: opaque return type 'anyopaque' not allowed
+```
+
+The blingo performs a `void` cast to suppress certain C compiler warnings. The
+spiritual equivalent in Zig is to assign to `_`.
+
+The `duk_eval_raw` method and each compile-time constant are available in the
+`duktape` scope. A manual translation is shown below:
+
+```zig
+_ = duktape.duk_eval_raw(ctx, src, 0, 0 | duktape.DUK_COMPILE_EVAL | duktape.DUK_COMPILE_NOSOURCE | duktape.DUK_COMPILE_STRLEN | duktape.DUK_COMPILE_NORESULT | duktape.DUK_COMPILE_NOFILENAME);
+```
+
+#### Zig Demo
+
+:::note Tested Deployments
+
+This demo was tested in the following deployments:
+
+| Architecture | Version | Zig | Date |
+|:-------------|:--------|:---------|:-----------|
+| `darwin-x64` | `2.7.0` | `0.11.0` | 2024-03-10 |
+| `win10-x64` | `2.7.0` | `0.11.0` | 2024-03-10 |
+| `linux-x64` | `2.7.0` | `0.11.0` | 2024-03-10 |
+
+On Windows, due to incompatibilities between WSL and PowerShell, some commands
+must be run in WSL Bash.
+
+:::
+
+0) Create a new project folder:
+
+```bash
+mkdir sheetjs-zig
+cd sheetjs-zig
+```
+
+1) Download Zig 0.11.0 from and extract to the
+project folder.
+
+
+
+
+```bash
+curl -LO https://ziglang.org/download/0.11.0/zig-macos-x86_64-0.11.0.tar.xz
+tar -xzf zig-macos-x86_64-0.11.0.tar.xz
+```
+
+
+
+
+```bash
+curl -LO https://ziglang.org/download/0.11.0/zig-linux-x86_64-0.11.0.tar.xz
+xz -d zig-linux-x86_64-0.11.0.tar.xz
+tar -xf zig-linux-x86_64-0.11.0.tar
+```
+
+
+
+
+:::note pass
+
+The following commands should be run within WSL bash.
+
+:::
+
+```bash
+curl -LO https://ziglang.org/download/0.11.0/zig-windows-x86_64-0.11.0.zip
+unzip zig-windows-x86_64-0.11.0.zip
+```
+
+
+
+
+2) Initialize a project:
+
+
+
+
+```bash
+./zig-macos-x86_64-0.11.0/zig init-exe
+```
+
+
+
+
+```bash
+./zig-linux-x86_64-0.11.0/zig init-exe
+```
+
+
+
+
+:::note pass
+
+The following command should be run within Powershell.
+
+:::
+
+```bash
+.\zig-windows-x86_64-0.11.0\zig.exe init-exe
+```
+
+
+
+
+
+3) Download the Duktape source and extract in the current directory. On Windows,
+the commands should be run within WSL:
+
+```bash
+curl -LO https://duktape.org/duktape-2.7.0.tar.xz
+tar -xJf duktape-2.7.0.tar.xz
+```
+
+4) Download the SheetJS Standalone script, shim script and test file. Move all
+three files to the `src` subdirectory:
+
+
+
+The following commands can be run within a shell on macOS and Linux. On Windows,
+the commands should be run within WSL bash:
+
+{`\
+curl -LO https://cdn.sheetjs.com/xlsx-${current}/package/dist/shim.min.js
+curl -LO https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js
+curl -LO https://sheetjs.com/pres.numbers
+mv *.js src`}
+
+
+5) Add the highlighted lines to `build.zig` just after the `exe` definition:
+
+```zig title="build.zig (add highlighted lines)"
+ const exe = b.addExecutable(.{
+ .name = "sheetjs-zig",
+ // In this case the main source file is merely a path, however, in more
+ // complicated build scripts, this could be a generated file.
+ .root_source_file = .{ .path = "src/main.zig" },
+ .target = target,
+ .optimize = optimize,
+ });
+// highlight-start
+ exe.addCSourceFile(.{ .file = .{ .path = "duktape-2.7.0/src/duktape.c" }, .flags = &.{ "-std=c99", "-fno-sanitize=undefined" } });
+ exe.addIncludePath(.{ .path = "duktape-2.7.0/src" });
+ exe.linkSystemLibrary("c");
+ exe.linkSystemLibrary("m");
+// highlight-end
+```
+
+6) Download [`main.zig`](pathname:///duk/main.zig) and replace `src/main.zig`.
+The following command should be run in WSL bash or the macOS or Linux terminal:
+
+```bash
+curl -L -o src/main.zig https://docs.sheetjs.com/duk/main.zig
+```
+
+7) Build and run the program:
+
+
+
+
+```bash
+./zig-macos-x86_64-0.11.0/zig build run -- pres.numbers
+```
+
+
+
+
+```bash
+./zig-linux-x86_64-0.11.0/zig build run -- pres.numbers
+```
+
+:::caution pass
+
+On Arch Linux and HoloOS (Steam Deck), compilation may fail:
+
+```
+zig build-exe sheetjs-zig Debug native: error: error: unable to create compilation: LibCStdLibHeaderNotFound
+```
+
+`glibc` and `linux-api-headers` must be installed:
+
+```bash
+sudo pacman -Syu glibc linux-api-headers
+```
+
+:::
+
+
+
+
+```bash
+.\zig-windows-x86_64-0.11.0\zig.exe build run -- pres.numbers
+```
+
+
+
+
+This step builds and runs the program. The generated program will be placed in
+the `zig-out/bin/` subdirectory.
+
+It should display some metadata along with CSV rows from the first worksheet.
+It will also generate `sheetjs.zig.xlsx`, which can be opened with a spreadsheet
+editor such as Excel.
+
+
### Perl
The Perl binding for Duktape is available as `JavaScript::Duktape::XS` on CPAN.
@@ -594,6 +938,7 @@ This demo was tested in the following deployments:
| Architecture | Version | Date |
|:-------------|:--------|:-----------|
| `darwin-x64` | `2.2.0` | 2024-01-26 |
+| `darwin-arm` | `2.2.0` | 2024-02-13 |
| `linux-x64` | `2.2.0` | 2024-01-26 |
:::
@@ -616,42 +961,10 @@ sudo cpan install JavaScript::Duktape::XS
:::
-2) Save the following codeblock to `SheetJSDuk.pl`:
+2) Download [`SheetJSDuk.pl`](pathname:///duk/SheetJSDuk.pl):
-```perl title="SheetJSDuk.pl"
-# usage: perl SheetJSDuk.pl path/to/file
-use JavaScript::Duktape::XS;
-use File::Slurp;
-use MIME::Base64 qw( encode_base64 decode_base64 );
-
-# Initialize
-my $js = JavaScript::Duktape::XS->new({ max_memory_bytes => 256 * 1024 * 1024 });
-$js->eval("var global = (function(){ return this; }).call(null);");
-
-# Load the ExtendScript build
-my $src = read_file('xlsx.extendscript.js', { binmode => ':raw' });
-$src =~ s/^\xEF\xBB\xBF//;
-my $XLSX = $js->eval($src);
-
-# Print version number
-$js->set('log' => sub { print $_[0], "\n"; });
-$js->eval("log('SheetJS library version ' + XLSX.version);");
-
-# Parse File
-my $raw_data = encode_base64(read_file($ARGV[0], { binmode => ':raw' }), "");
-$js->set("b64", $raw_data);
-$js->eval(qq{
- global.wb = XLSX.read(b64, {type: "base64", WTF:1});
- global.ws = wb.Sheets[wb.SheetNames[0]];
- void 0;
-});
-
-# Print first worksheet CSV
-$js->eval('log(XLSX.utils.sheet_to_csv(global.ws))');
-
-# Write XLSB file
-my $xlsb = $js->eval("XLSX.write(global.wb, {type:'base64', bookType:'xlsb'})");
-write_file("SheetJSDuk.xlsb", decode_base64($xlsb));
+```bash
+curl -LO https://docs.sheetjs.com/duk/SheetJSDuk.pl
```
3) Download the SheetJS ExtendScript build and test file:
diff --git a/docz/docs/03-demos/42-engines/04-jsc.md b/docz/docs/03-demos/42-engines/04-jsc.md
index 3bf1ea9..961eeb9 100644
--- a/docz/docs/03-demos/42-engines/04-jsc.md
+++ b/docz/docs/03-demos/42-engines/04-jsc.md
@@ -127,14 +127,14 @@ try? out.write(to: out_path, atomically: false, encoding: String.Encoding.isoLat
## Complete Example
-:::note
+:::note pass
This demo was tested in the following environments:
| Architecture | Swift | Date |
|:-------------|:--------|:-----------|
-| `darwin-x64` | `5.9.0` | 2023-10-26 |
-| `darwin-arm` | `5.9.0` | 2023-10-18 |
+| `darwin-x64` | `5.9.2` | 2024-02-21 |
+| `darwin-arm` | `5.9.2` | 2024-02-21 |
:::
diff --git a/docz/docs/03-demos/42-engines/05-jint.md b/docz/docs/03-demos/42-engines/05-jint.md
index c1cc5b1..b00e401 100644
--- a/docz/docs/03-demos/42-engines/05-jint.md
+++ b/docz/docs/03-demos/42-engines/05-jint.md
@@ -165,7 +165,7 @@ This demo was tested in the following deployments:
|:-------------|:------------------|:-----------|
| `darwin-x64` | `3.0.0` | 2024-01-22 |
| `darwin-arm` | `3.0.0-beta-2056` | 2023-12-01 |
-| `win10-x64` | `3.0.0-beta-2053` | 2023-10-28 |
+| `win10-x64` | `3.0.0` | 2024-03-04 |
| `win11-arm` | `3.0.0-beta-2056` | 2023-12-01 |
| `linux-x64` | `3.0.0` | 2024-01-22 |
| `linux-arm` | `3.0.0-beta-2056` | 2023-12-01 |
diff --git a/docz/docs/03-demos/42-engines/07-nashorn.md b/docz/docs/03-demos/42-engines/07-nashorn.md
index 07fc0ea..ba4299e 100644
--- a/docz/docs/03-demos/42-engines/07-nashorn.md
+++ b/docz/docs/03-demos/42-engines/07-nashorn.md
@@ -115,7 +115,7 @@ This demo was tested in the following deployments:
| 14.0.2 | Built-in | 2023-12-01 |
| 13.0.14 | Built-in | 2023-12-01 |
| 12.0.2 | Built-in | 2023-12-01 |
-| 11.0.20 | Built-in | 2023-12-01 |
+| 11.0.20 | Built-in | 2024-02-13 |
| 10.0.2 | Built-in | 2023-12-01 |
| 9 | Built-in | 2023-12-01 |
| 1.8.0 | Built-in | 2023-12-01 |
diff --git a/docz/docs/03-demos/42-engines/08-quickjs.md b/docz/docs/03-demos/42-engines/08-quickjs.md
index 632324b..7589325 100644
--- a/docz/docs/03-demos/42-engines/08-quickjs.md
+++ b/docz/docs/03-demos/42-engines/08-quickjs.md
@@ -264,7 +264,7 @@ This demo was tested in the following deployments:
|:-------------|:-----------|:-----------|
| `darwin-x64` | `daa35bc` | 2023-12-09 |
| `darwin-arm` | `2788d71` | 2023-10-18 |
-| `win10-x64` | `daa35bc` | 2023-12-09 |
+| `win10-x64` | `9e561d5` | 2024-03-04 |
| `win11-arm` | `03cc5ec` | 2023-12-01 |
| `linux-x64` | `9e561d5` | 2024-01-22 |
| `linux-arm` | `03cc5ec` | 2023-12-01 |
@@ -342,7 +342,7 @@ This demo was tested in the following environments:
| Git Commit | Date |
|:-----------|:-----------|
-| `9e561d5` | 2024-01-22 |
+| `9e561d5` | 2024-03-04 |
When the demo was tested, commit `9e561d5` corresponded to the latest release.
diff --git a/docz/docs/03-demos/42-engines/15-rb.md b/docz/docs/03-demos/42-engines/15-rb.md
index 075bfc4..443f2f3 100644
--- a/docz/docs/03-demos/42-engines/15-rb.md
+++ b/docz/docs/03-demos/42-engines/15-rb.md
@@ -72,7 +72,7 @@ This demo was tested in the following deployments:
|:-------------|:---------|:--------|:-----------|
| `darwin-x64` | `2.6.10` | `2.9.1` | 2023-11-14 |
| `darwin-arm` | `2.6.10` | `2.9.1` | 2023-12-01 |
-| `win10-x64` | `3.2.2` | `2.9.1` | 2023-10-28 |
+| `win10-x64` | `3.2.3` | `2.9.1` | 2024-03-10 |
| `win11-arm` | `3.0.2` | `2.9.1` | 2023-12-01 |
| `linux-x64` | `3.0.5` | `2.9.1` | 2024-01-26 |
| `linux-arm` | `2.7.4` | `2.9.1` | 2023-12-01 |
@@ -97,7 +97,14 @@ sudo gem install execjs
:::
-1) Download the SheetJS Standalone script and the test file. Save both files in
+1) Create a new project folder:
+
+```bash
+mkdir sheetjs-rb
+cd sheetjs-rb
+```
+
+2) Download the SheetJS Standalone script and the test file. Save both files in
the project directory:
@@ -110,13 +117,13 @@ curl -LO https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js
curl -LO https://sheetjs.com/pres.numbers`}
-2) Download [`ExecSheetJS.rb`](pathname:///execjs/ExecSheetJS.rb):
+3) Download [`ExecSheetJS.rb`](pathname:///execjs/ExecSheetJS.rb):
```bash
curl -LO https://docs.sheetjs.com/execjs/ExecSheetJS.rb
```
-3) Run the demo:
+4) Run the demo:
```bash
ruby ExecSheetJS.rb pres.numbers
diff --git a/docz/docs/03-demos/42-engines/20-chakra.md b/docz/docs/03-demos/42-engines/20-chakra.md
index 1fff777..d064a21 100644
--- a/docz/docs/03-demos/42-engines/20-chakra.md
+++ b/docz/docs/03-demos/42-engines/20-chakra.md
@@ -134,7 +134,7 @@ This demo was tested in the following deployments:
|:-------------|:-----------|:-----------|
| `darwin-x64` | `c3ead3f` | 2023-11-04 |
| `darwin-arm` | `c3ead3f` | 2023-10-19 |
-| `win10-x64` | `c3ead3f` | 2023-10-28 |
+| `win10-x64` | `c3ead3f` | 2024-03-04 |
| `linux-x64` | `c3ead3f` | 2024-01-26 |
:::
@@ -167,7 +167,9 @@ sudo pacman -S cmake clang
-Install Visual Studio 2022 with the "Desktop Development with C++" workflow.
+Install Visual Studio 2022 with the "Desktop Development with C++" workflow and
+the "Git for Windows" individual component.
+
All commands in this demo should be run in a "Native Tools Command Prompt".
@@ -281,6 +283,37 @@ msbuild /m /p:Platform=x64 /p:Configuration=Debug /p:RuntimeLib=static_library B
cd ..
```
+:::caution pass
+
+During some test runs, the build failed with a message referencing `cfguard.h`:
+
+```
+ 44>C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.39.33519\include\cfguard.h(44,1): error C2220: the following warning is treated as an error
+ (compiling source file 'ThreadContextInfo.cpp')
+
+ 44>C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.39.33519\include\cfguard.h(44,1): warning C4005: '_GUARD_CHECK_ICALL': macro redefinition
+```
+
+The source file `lib\Runtime\Base\ThreadContextInfo.cpp` must be patched. The
+highlighted lines must be commented:
+
+```cpp title="lib\Runtime\Base\ThreadContextInfo.cpp (comment highlighted lines)"
+#if defined(_UCRT) && _CONTROL_FLOW_GUARD
+
+// highlight-start
+//# if _MSC_VER >= 1913
+//# include
+//# else
+// highlight-end
+ extern "C" void __fastcall _guard_check_icall(_In_ uintptr_t _Target);
+// highlight-next-line
+//# endif
+#endif
+```
+
+:::
+
+
After building, the generated DLL should be copied into the project folder:
```
diff --git a/docz/docs/03-demos/42-engines/21-boa.md b/docz/docs/03-demos/42-engines/21-boa.md
index 1d4ada7..9bc8c93 100644
--- a/docz/docs/03-demos/42-engines/21-boa.md
+++ b/docz/docs/03-demos/42-engines/21-boa.md
@@ -122,7 +122,7 @@ This demo was tested in the following deployments:
|:-------------|:-----------|
| `darwin-x64` | 2023-11-03 |
| `darwin-arm` | 2023-10-20 |
-| `win10-x64` | 2023-10-28 |
+| `win10-x64` | 2024-03-04 |
| `win11-arm` | 2023-12-01 |
| `linux-x64` | 2024-01-26 |
| `linux-arm` | 2023-12-01 |
diff --git a/docz/docs/03-demos/42-engines/22-perl.md b/docz/docs/03-demos/42-engines/22-perl.md
index 0c5e660..af602f8 100644
--- a/docz/docs/03-demos/42-engines/22-perl.md
+++ b/docz/docs/03-demos/42-engines/22-perl.md
@@ -102,7 +102,7 @@ write_file("SheetJE.fods", $fods);
:::note Tested Deployments
-This demo was tested on 2023-12-05 against JE 0.066
+This demo was tested on 2024-02-13 against JE 0.066
:::
diff --git a/docz/docs/03-demos/42-engines/index.md b/docz/docs/03-demos/42-engines/index.md
index f3b9f36..1390cf5 100644
--- a/docz/docs/03-demos/42-engines/index.md
+++ b/docz/docs/03-demos/42-engines/index.md
@@ -109,7 +109,7 @@ Duktape is an embeddable JS engine written in C. It has been ported to a number
of exotic architectures and operating systems.
This demo has been moved [to a dedicated page](/docs/demos/engines/duktape).
-The demo includes examples in C and Perl.
+The demo includes examples in C, Perl, PHP, Python and Zig.
#### Goja
diff --git a/docz/docs/07-csf/07-features/06-nf.md b/docz/docs/07-csf/07-features/06-nf.md
index bdeaaa7..4166401 100644
--- a/docz/docs/07-csf/07-features/06-nf.md
+++ b/docz/docs/07-csf/07-features/06-nf.md
@@ -369,4 +369,4 @@ the `w` text if available. When programmatically changing values, the `w` text
should be deleted before attempting to export. Utilities will regenerate the `w`
text from the number format (`cell.z`) and the raw value if possible.
-[^1]: On 2023 November 04, [the "Review guidelines for customizing a number format" page](https://support.microsoft.com/en-us/office/review-guidelines-for-customizing-a-number-format-c0a1d1fa-d3f4-4018-96b7-9c9354dd99f5) in the Excel documentation covered custom number format minutiae.
\ No newline at end of file
+[^1]: The ["Review guidelines for customizing a number format"](https://support.microsoft.com/en-us/office/review-guidelines-for-customizing-a-number-format-c0a1d1fa-d3f4-4018-96b7-9c9354dd99f5) page in the Excel documentation covered custom number format minutiae.
\ No newline at end of file
diff --git a/docz/docs/08-api/03-parse-options.md b/docz/docs/08-api/03-parse-options.md
index 415fa97..915a0c3 100644
--- a/docz/docs/08-api/03-parse-options.md
+++ b/docz/docs/08-api/03-parse-options.md
@@ -154,8 +154,8 @@ Plain text format guessing follows the priority order:
| HTML | starts with `<` and HTML tags appear in the first 1024 characters * |
| XML | starts with `<` and the first tag is valid |
| RTF | starts with `{\rt` |
-| DSV | starts with `/sep=.$/`, separator is the specified character |
-| DSV | more unquoted `|` chars than `;` `\t` `,` in the first 1024 |
+| DSV | starts with `sep=` followed by field delimiter and line separator |
+| DSV | more unquoted `\|` chars than `;` `\t` or `,` in the first 1024 |
| DSV | more unquoted `;` chars than `\t` or `,` in the first 1024 |
| TSV | more unquoted `\t` chars than `,` chars in the first 1024 |
| CSV | one of the first 1024 characters is a comma `","` |
diff --git a/docz/docs/09-miscellany/05-contributing.md b/docz/docs/09-miscellany/05-contributing.md
index e3bb5a2..7181b69 100644
--- a/docz/docs/09-miscellany/05-contributing.md
+++ b/docz/docs/09-miscellany/05-contributing.md
@@ -43,7 +43,7 @@ These instructions were tested on the following platforms:
| Linux (Ubuntu 18 AArch64) | `linux-arm` | 2023-12-01 |
| MacOS 10.13.6 (x64) | `darwin-x64` | 2023-09-30 |
| MacOS 14.1.2 (ARM64) | `darwin-arm` | 2023-12-01 |
-| Windows 10 (x64) + WSL Ubuntu | `win10-x64` | 2023-11-27 |
+| Windows 10 (x64) + WSL Ubuntu | `win10-x64` | 2024-03-04 |
| Windows 11 (x64) + WSL Ubuntu | `win11-x64` | 2023-10-14 |
| Windows 11 (ARM) + WSL Ubuntu | `win11-arm` | 2023-09-18 |
diff --git a/docz/docusaurus.config.js b/docz/docusaurus.config.js
index b1049dd..fb58b5f 100644
--- a/docz/docusaurus.config.js
+++ b/docz/docusaurus.config.js
@@ -146,7 +146,7 @@ const config = {
prism: {
theme: lightCodeTheme,
darkTheme: darkCodeTheme,
- additionalLanguages: [ "visual-basic", "swift", "java", "php", "csharp", "perl", "ruby", "cpp", "applescript", "liquid", "rust", "dart", "wolfram", "matlab", "stata" ],
+ additionalLanguages: [ "visual-basic", "swift", "java", "php", "csharp", "perl", "ruby", "cpp", "applescript", "liquid", "rust", "dart", "wolfram", "matlab", "stata", "zig" ],
},
liveCodeBlock: {
playgroundPosition: 'top'
diff --git a/docz/static/chromium/SheetJSChromiumUnpackedV2.zip b/docz/static/chromium/SheetJSChromiumUnpackedV2.zip
index e873bcd..e5b3ab6 100644
Binary files a/docz/static/chromium/SheetJSChromiumUnpackedV2.zip and b/docz/static/chromium/SheetJSChromiumUnpackedV2.zip differ
diff --git a/docz/static/chromium/SheetJSChromiumUnpackedV3.zip b/docz/static/chromium/SheetJSChromiumUnpackedV3.zip
index 068253a..e3f8128 100644
Binary files a/docz/static/chromium/SheetJSChromiumUnpackedV3.zip and b/docz/static/chromium/SheetJSChromiumUnpackedV3.zip differ
diff --git a/docz/static/duk/main.zig b/docz/static/duk/main.zig
new file mode 100644
index 0000000..a1d008d
--- /dev/null
+++ b/docz/static/duk/main.zig
@@ -0,0 +1,67 @@
+const std = @import("std");
+const duktape = @cImport({
+ @cInclude("duktape.h");
+});
+// SheetJS scripts embedded at comptime
+const shim = @embedFile("shim.min.js");
+const xlsx = @embedFile("xlsx.full.min.js");
+
+pub fn main() !void {
+ // initialize duktape
+ const ctx = duktape.duk_create_heap(null, null, null, null, null);
+ defer _ = duktape.duk_destroy_heap(ctx);
+
+ // load SheetJS scripts
+ _ = duktape.duk_peval_string(ctx, shim);
+ _ = duktape.duk_peval_string(ctx, xlsx);
+
+ // display version number
+ _ = duktape.duk_peval_string(ctx, "XLSX.version");
+ const sum = duktape.duk_get_string(ctx, -1);
+ std.debug.print("SheetJS Version {s}\n", .{sum});
+ duktape.duk_pop(ctx);
+
+ // create allocator
+ var gpa = std.heap.GeneralPurposeAllocator(.{}){};
+ defer _ = gpa.deinit();
+ var alloc = gpa.allocator();
+
+ // determine file to read
+ var args = try std.process.argsWithAllocator(alloc);
+ defer args.deinit();
+ _ = args.next();
+ const path = args.next();
+ if (path == null) {
+ std.debug.print("Must specify a filename!", .{});
+ return;
+ }
+ std.debug.print("Reading from {s}\n", .{path.?});
+
+ // read file
+ var file = try std.fs.cwd().readFileAlloc(alloc, path.?, std.math.maxInt(usize));
+ defer alloc.free(file);
+ std.debug.print("Size: {} bytes\n", .{file.len});
+
+ // load into duktape
+ _ = duktape.duk_push_buffer_raw(ctx, 0, duktape.DUK_BUF_FLAG_DYNAMIC | duktape.DUK_BUF_FLAG_EXTERNAL);
+ duktape.duk_config_buffer(ctx, -1, file.ptr, file.len);
+ _ = duktape.duk_put_global_string(ctx, "buf");
+ _ = duktape.duk_eval_raw(ctx, "workbook = XLSX.read(buf.slice(0, buf.length), {type:'buffer'});", 0, duktape.DUK_COMPILE_EVAL | duktape.DUK_COMPILE_NOSOURCE | duktape.DUK_COMPILE_STRLEN | duktape.DUK_COMPILE_NORESULT | duktape.DUK_COMPILE_NOFILENAME);
+
+ // display CSV of first worksheet
+ _ = duktape.duk_peval_string(ctx, "XLSX.utils.sheet_to_csv(workbook.Sheets[workbook.SheetNames[0]])");
+ const csv = duktape.duk_get_string(ctx, -1);
+ std.debug.print("{s}\n", .{csv});
+ duktape.duk_pop(ctx);
+
+ // convert to XLSX
+ _ = duktape.duk_eval_raw(ctx, "XLSX.write(workbook, {type:'array', bookType:'xlsx'})", 0, duktape.DUK_COMPILE_EVAL | duktape.DUK_COMPILE_NOSOURCE | duktape.DUK_COMPILE_STRLEN | duktape.DUK_COMPILE_NOFILENAME);
+ var sz: usize = 0;
+ var c_ptr: *anyopaque = duktape.duk_get_buffer_data(ctx, -1, &sz).?;
+
+ // generate zig slice from C pointer + length
+ var slc: []u8 = @as([*]u8, @ptrCast(c_ptr))[0..sz];
+
+ // write to file
+ _ = try std.fs.cwd().writeFile("sheetjs.zig.xlsx", slc);
+}
diff --git a/docz/static/xlapi/xlvers.png b/docz/static/xlapi/xlvers.png
index 7eddbc5..d936500 100644
Binary files a/docz/static/xlapi/xlvers.png and b/docz/static/xlapi/xlvers.png differ