diff --git a/docz/data/engines.xls b/docz/data/engines.xls
index b1c7633..03dbce0 100644
--- a/docz/data/engines.xls
+++ b/docz/data/engines.xls
@@ -37,7 +37,7 @@
-
@@ -181,6 +181,16 @@
✔ |
✔ |
+
+ GraalJS |
+ Java |
+ ✔ |
+ |
+ |
+ |
+ |
+ |
+
@@ -208,7 +218,7 @@
-
diff --git a/docz/docs/03-demos/01-math/11-tensorflow.md b/docz/docs/03-demos/01-math/11-tensorflow.md
index f225108..da7ffad 100644
--- a/docz/docs/03-demos/01-math/11-tensorflow.md
+++ b/docz/docs/03-demos/01-math/11-tensorflow.md
@@ -42,7 +42,7 @@ Each browser demo was tested in the following environments:
| Browser | TF.js version | Date |
|:------------|:--------------|:-----------|
| Chrome 119 | `4.14.0` | 2023-12-09 |
-| Safari 16.6 | `4.14.0` | 2023-12-09 |
+| Safari 17.4 | `4.14.0` | 2024-03-23 |
:::
diff --git a/docz/docs/03-demos/27-local/01-file.md b/docz/docs/03-demos/27-local/01-file.md
index 1e090e6..d5739d7 100644
--- a/docz/docs/03-demos/27-local/01-file.md
+++ b/docz/docs/03-demos/27-local/01-file.md
@@ -453,7 +453,7 @@ Some lesser-used browsers do not support File System Access API:
| Browser | Date |
|:------------|:-----------|
-| Safari 17.0 | 2023-11-04 |
+| Safari 17.4 | 2024-03-23 |
| Firefox 119 | 2023-11-04 |
:::
diff --git a/docz/docs/03-demos/27-local/09-indexeddb.md b/docz/docs/03-demos/27-local/09-indexeddb.md
index 368e357..abf28c6 100644
--- a/docz/docs/03-demos/27-local/09-indexeddb.md
+++ b/docz/docs/03-demos/27-local/09-indexeddb.md
@@ -44,7 +44,7 @@ This demo was last tested in the following environments:
| Browser | Date | `localForage` |
|:------------|:-----------|:--------------|
| Chrome 122 | 2024-03-21 | 1.10.0 |
-| Safari 17.0 | 2023-11-30 | 1.10.0 |
+| Safari 17.4 | 2024-03-23 | 1.10.0 |
:::
diff --git a/docz/docs/03-demos/42-engines/07-nashorn.md b/docz/docs/03-demos/42-engines/07-nashorn.md
index ba4299e..e35e84a 100644
--- a/docz/docs/03-demos/42-engines/07-nashorn.md
+++ b/docz/docs/03-demos/42-engines/07-nashorn.md
@@ -105,23 +105,26 @@ This demo was tested in the following deployments:
| OpenJDK | Nashorn | Date |
|:--------|:----------------|:-----------|
-| 21.0.1 | 15.4 standalone | 2023-12-01 |
-| 20.0.2 | 15.4 standalone | 2023-12-01 |
-| 19.0.2 | 15.4 standalone | 2023-12-01 |
-| 18.0.2 | 15.4 standalone | 2023-12-01 |
-| 17.0.9 | 15.4 standalone | 2023-12-01 |
-| 16.0.1 | 15.4 standalone | 2023-12-01 |
-| 15.0.10 | 15.4 standalone | 2023-12-01 |
-| 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 | 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 |
+| 22 | 15.4 standalone | 2024-03-23 |
+| 21.0.2 | 15.4 standalone | 2024-03-23 |
+| 20.0.2 | 15.4 standalone | 2024-03-23 |
+| 19.0.2 | 15.4 standalone | 2024-03-23 |
+| 18.0.2 | 15.4 standalone | 2024-03-23 |
+| 17.0.10 | 15.4 standalone | 2024-03-23 |
+| 16.0.1 | 15.4 standalone | 2024-03-23 |
+| 15.0.10 | 15.4 standalone | 2024-03-23 |
+| 14.0.2 | Built-in | 2024-03-23 |
+| 13.0.14 | Built-in | 2024-03-23 |
+| 12.0.2 | Built-in | 2024-03-23 |
+| 11.0.20 | Built-in | 2024-03-23 |
+| 10.0.2 | Built-in | 2024-03-23 |
+| 9 | Built-in | 2024-03-23 |
+| 1.8.0 | Built-in | 2024-03-23 |
:::
+### Compilation
+
@@ -174,6 +177,8 @@ javac SheetJSNashorn.java
This program tries to parse the file specified by the first argument and prints
CSV rows from the first worksheet.
+### Standalone Test
+
4) Run the command directly:
@@ -193,6 +198,9 @@ java -cp .:asm-9.5.jar:asm-tree-9.5.jar:asm-commons-9.5.jar:asm-analysis-9.5.jar
+If successful, CSV rows from the first worksheet will be displayed.
+
+### Java Archive Test
5) Assemble a Java Archive:
@@ -200,9 +208,7 @@ java -cp .:asm-9.5.jar:asm-tree-9.5.jar:asm-commons-9.5.jar:asm-analysis-9.5.jar
jar -cf SheetJSNashorn.jar SheetJSNashorn.class xlsx.full.min.js shim.min.js
```
-6) Verify the Java Archive.
-
-Create new directory and copy the archives and test file:
+6) Create new directory and copy the archives and test file:
```bash
mkdir -p sheethorn
@@ -210,7 +216,7 @@ cp *.jar pres.xlsx sheethorn
cd sheethorn
```
-Invoke the command in the archive:
+7) Run the program using the Java Archive:
@@ -229,4 +235,4 @@ java -cp .:asm-9.5.jar:asm-tree-9.5.jar:asm-commons-9.5.jar:asm-analysis-9.5.jar
-This should print the same CSV rows from Step 3.
+This should print the same CSV rows from Step 4.
diff --git a/docz/docs/03-demos/42-engines/24-graaljs.md b/docz/docs/03-demos/42-engines/24-graaljs.md
new file mode 100644
index 0000000..cd76a47
--- /dev/null
+++ b/docz/docs/03-demos/42-engines/24-graaljs.md
@@ -0,0 +1,140 @@
+---
+title: Data Processing with GraalJS
+sidebar_label: Java + GraalJS
+pagination_prev: demos/bigdata/index
+pagination_next: solutions/input
+---
+
+import current from '/version.js';
+import CodeBlock from '@theme/CodeBlock';
+
+[GraalJS](https://www.graalvm.org/latest/reference-manual/js/) is a JS engine
+for Java. The project offers a JSR-223 compliant OpenJDK-compatible build.
+
+[SheetJS](https://sheetjs.com) is a JavaScript library for reading and writing
+data from spreadsheets.
+
+The ["Complete Example"](#complete-example) section includes a complete Java
+command-line tool for reading data from spreadsheets and printing CSV rows.
+
+:::info pass
+
+The Java packages used in this demo are covered under open source licenses. The
+Universal Permissive License covers most of the packages, while `icu4j` uses
+a different, yet still permissive, license.
+
+:::
+
+## Integration Details
+
+:::info pass
+
+When this demo was last tested, raw byte arrays could not be passed to GraalJS.
+
+**This is a limitation of the default GraalJS behavior.**
+
+Instead, this demo uses Nashorn Compatibility Mode[^1] through a runtime flag:
+
+```js
+java -Dpolyglot.js.nashorn-compat=true ...
+```
+
+:::
+
+The [Nashorn demo](/docs/demos/engines/nashorn) code and explanation applies to
+JSR-223 compatible `ScriptEngine` implementations, including GraalJS.
+
+## Complete Example
+
+:::note Tested Deployments
+
+This demo was tested in the following deployments:
+
+| OpenJDK | GraalJS | Date |
+|:--------|:--------|:-----------|
+| 22 | 24.0.0 | 2024-03-23 |
+| 21.0.2 | 24.0.0 | 2024-03-23 |
+
+:::
+
+### Compilation
+
+0) Download GraalJS and its dependencies:
+
+```bash
+curl -LO "https://repo1.maven.org/maven2/org/graalvm/js/js-scriptengine/24.0.0/js-scriptengine-24.0.0.jar"
+curl -LO "https://repo1.maven.org/maven2/org/graalvm/js/js-language/24.0.0/js-language-24.0.0.jar"
+curl -LO "https://repo1.maven.org/maven2/org/graalvm/polyglot/polyglot/24.0.0/polyglot-24.0.0.jar"
+curl -LO "https://repo1.maven.org/maven2/org/graalvm/sdk/collections/24.0.0/collections-24.0.0.jar"
+curl -LO "https://repo1.maven.org/maven2/org/graalvm/truffle/truffle-api/24.0.0/truffle-api-24.0.0.jar"
+curl -LO "https://repo1.maven.org/maven2/org/graalvm/sdk/nativeimage/24.0.0/nativeimage-24.0.0.jar"
+curl -LO "https://repo1.maven.org/maven2/org/graalvm/shadowed/icu4j/24.0.0/icu4j-24.0.0.jar"
+curl -LO "https://repo1.maven.org/maven2/org/graalvm/regex/regex/24.0.0/regex-24.0.0.jar"
+```
+
+1) Download the SheetJS Standalone script, shim script and test file. Move all
+three files to the project directory:
+
+
+
+{`\
+curl -LO https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js
+curl -LO https://cdn.sheetjs.com/xlsx-${current}/package/dist/shim.min.js
+curl -LO https://sheetjs.com/pres.xlsx`}
+
+
+2) Download [`SheetJSNashorn.java`](pathname:///nashorn/SheetJSNashorn.java):
+
+```bash
+curl -LO https://docs.sheetjs.com/nashorn/SheetJSNashorn.java
+```
+
+3) Build the sample class:
+
+```bash
+javac SheetJSNashorn.java
+```
+
+This program tries to parse the file specified by the first argument and prints
+CSV rows from the first worksheet.
+
+### Standalone Test
+
+4) Run the command directly:
+
+```bash
+java -cp .:js-scriptengine-24.0.0.jar:js-language-24.0.0.jar:polyglot-24.0.0.jar:collections-24.0.0.jar:truffle-api-24.0.0.jar:nativeimage-24.0.0.jar:icu4j-24.0.0.jar:regex-24.0.0.jar -Dpolyglot.js.nashorn-compat=true SheetJSNashorn pres.xlsx
+```
+
+If successful, CSV rows from the first worksheet will be displayed.
+
+### Java Archive Test
+
+5) Assemble a Java Archive:
+
+```bash
+jar -cf SheetJSNashorn.jar SheetJSNashorn.class xlsx.full.min.js shim.min.js
+```
+
+6) Create new directory and copy the archives and test file:
+
+```bash
+mkdir -p sheethorn
+cp *.jar pres.xlsx sheethorn
+cd sheethorn
+```
+
+7) Run the program using the Java Archive:
+
+```bash
+java -cp .:js-scriptengine-24.0.0.jar:js-language-24.0.0.jar:polyglot-24.0.0.jar:collections-24.0.0.jar:truffle-api-24.0.0.jar:nativeimage-24.0.0.jar:icu4j-24.0.0.jar:regex-24.0.0.jar:SheetJSNashorn.jar -Dpolyglot.js.nashorn-compat=true SheetJSNashorn pres.xlsx
+```
+
+
+This should print the same CSV rows from Step 4.
+
+[^1]: See ["Nashorn Compatibility Mode"](https://www.graalvm.org/latest/reference-manual/js/NashornMigrationGuide/#nashorn-compatibility-mode) in the GraalJS documentation.
diff --git a/tests/nashorntest.sh b/tests/nashorntest.sh
new file mode 100755
index 0000000..4b6663c
--- /dev/null
+++ b/tests/nashorntest.sh
@@ -0,0 +1,48 @@
+#!/bin/bash
+
+cd /tmp
+mkdir -p nashorn
+cd nashorn
+
+curl -LO https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min.js
+curl -LO https://cdn.sheetjs.com/xlsx-latest/package/dist/shim.min.js
+curl -LO https://sheetjs.com/pres.xlsx
+curl -LO https://docs.sheetjs.com/nashorn/SheetJSNashorn.java
+
+curl -L -o nashorn-core-15.4.jar "https://search.maven.org/remotecontent?filepath=org/openjdk/nashorn/nashorn-core/15.4/nashorn-core-15.4.jar"
+curl -L -o asm-9.5.jar "https://search.maven.org/remotecontent?filepath=org/ow2/asm/asm/9.5/asm-9.5.jar"
+curl -L -o asm-tree-9.5.jar "https://search.maven.org/remotecontent?filepath=org/ow2/asm/asm-tree/9.5/asm-tree-9.5.jar"
+curl -L -o asm-commons-9.5.jar "https://search.maven.org/remotecontent?filepath=org/ow2/asm/asm-commons/9.5/asm-commons-9.5.jar"
+curl -L -o asm-analysis-9.5.jar "https://search.maven.org/remotecontent?filepath=org/ow2/asm/asm-analysis/9.5/asm-analysis-9.5.jar"
+curl -L -o asm-util-9.5.jar "https://search.maven.org/remotecontent?filepath=org/ow2/asm/asm-util/9.5/asm-util-9.5.jar"
+
+# Standalone Nashorn
+for n in {15..22}; do
+ export JAVA_HOME=`/usr/libexec/java_home -v $n`
+ java -version
+ rm -fr SheetJSNashorn.class SheetJSNashorn.jar sheethorn
+ javac SheetJSNashorn.java
+ java -cp .:asm-9.5.jar:asm-tree-9.5.jar:asm-commons-9.5.jar:asm-analysis-9.5.jar:asm-util-9.5.jar:nashorn-core-15.4.jar SheetJSNashorn pres.xlsx
+ jar -cf SheetJSNashorn.jar SheetJSNashorn.class xlsx.full.min.js shim.min.js
+ mkdir -p sheethorn
+ cp *.jar pres.xlsx sheethorn
+ cd sheethorn
+ java -cp .:asm-9.5.jar:asm-tree-9.5.jar:asm-commons-9.5.jar:asm-analysis-9.5.jar:asm-util-9.5.jar:nashorn-core-15.4.jar:SheetJSNashorn.jar SheetJSNashorn pres.xlsx
+ cd -
+done
+
+# Built-in Nashorn
+for n in 1.8 {9..14}; do
+ export JAVA_HOME=`/usr/libexec/java_home -v $n`
+ java -version
+ rm -fr SheetJSNashorn.class SheetJSNashorn.jar sheethorn
+ javac SheetJSNashorn.java
+ java SheetJSNashorn pres.xlsx
+ jar -cf SheetJSNashorn.jar SheetJSNashorn.class xlsx.full.min.js shim.min.js
+ mkdir -p sheethorn
+ cp *.jar pres.xlsx sheethorn
+ cd sheethorn
+ java -cp .:SheetJSNashorn.jar SheetJSNashorn pres.xlsx
+ cd -
+done
+