Skip to content

Commit b34b383

Browse files
mpiannucciclaude
andauthored
Icechunk JS/TS Bindings (#1630)
Builds off #1628 Closes #356 Icechunk JS/TS bindings for node and browser using [napi-rs](https://napi.rs/). There are builds for each platform, so native node targets get native performance and others get wasm-wasi Alpha builds available from [npm](https://www.npmjs.com/package/@earthmover/icechunk/v/2.0.0-alpha.5) --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 24c56fe commit b34b383

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

64 files changed

+13655
-32
lines changed

.codespellrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[codespell]
22
# Ref: https://github.com/codespell-project/codespell#using-a-config-file
3-
skip = .git*,*.svg,*.lock,*.css,.codespellrc
3+
skip = .git*,*.svg,*.lock,*lock.json,*.css,.codespellrc,icechunk-js/.yarn/releases/*,*.cjs
44
check-hidden = true
55
ignore-regex = ^\s*"image/\S+": ".*|\bND\b
66
ignore-words-list = crate,firs,anc

.gitattributes

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,9 @@
11
*.ipynb linguist-detectable=false
2+
3+
# Generated NAPI-RS codes
4+
icechunk-js/index.js linguist-detectable=false
5+
icechunk-js/index.d.ts linguist-detectable=false
6+
icechunk-js/icechunk.wasi-browser.js linguist-detectable=false
7+
icechunk-js/icechunk.wasi.cjs linguist-detectable=false
8+
icechunk-js/wasi-worker-browser.mjs linguist-detectable=false
9+
icechunk-js/wasi-worker.mjs linguist-detectable=false

.github/workflows/codespell.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,7 @@ jobs:
2424
uses: codespell-project/codespell-problem-matcher@9ba2c57125d4908eade4308f32c4ff814c184633 # v1.2.0
2525
- name: Codespell
2626
uses: codespell-project/actions-codespell@406322ec52dd7b488e48c1c4b82e2a8b3a1bf630 # v2
27+
with:
28+
skip: .git*,*.svg,*.lock,*lock.json,*.css,.codespellrc,*.cjs
29+
ignore_words_list: crate,firs,anc
30+
check_hidden: true

.github/workflows/js-ci.yaml

Lines changed: 287 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,287 @@
1+
name: JS CI
2+
3+
env:
4+
DEBUG: napi:*
5+
APP_NAME: icechunk
6+
MACOSX_DEPLOYMENT_TARGET: "10.13"
7+
CARGO_INCREMENTAL: "1"
8+
9+
on:
10+
push:
11+
branches:
12+
- main
13+
- "support/**"
14+
paths:
15+
- "icechunk/**"
16+
- "icechunk-js/**"
17+
pull_request:
18+
types: [opened, synchronize, reopened]
19+
paths:
20+
- "icechunk/**"
21+
- "icechunk-js/**"
22+
workflow_dispatch:
23+
24+
concurrency:
25+
group: ${{ github.workflow }}-${{ github.ref }}
26+
cancel-in-progress: true
27+
28+
jobs:
29+
build:
30+
defaults:
31+
run:
32+
working-directory: ./icechunk-js
33+
strategy:
34+
fail-fast: false
35+
matrix:
36+
settings:
37+
- host: windows-latest
38+
build: yarn build --target x86_64-pc-windows-msvc
39+
target: x86_64-pc-windows-msvc
40+
- host: ubuntu-latest
41+
target: x86_64-unknown-linux-gnu
42+
build: yarn build --target x86_64-unknown-linux-gnu --use-napi-cross
43+
setup: |
44+
# The napi-cross toolchain ships GCC 4.8 which lacks C11
45+
# <stdatomic.h>, breaking aws-lc-sys. Use cmake builder with
46+
# system GCC override for that crate only.
47+
echo "AWS_LC_SYS_CMAKE_BUILDER=1" >> $GITHUB_ENV
48+
echo "AWS_LC_SYS_TARGET_CC=gcc" >> $GITHUB_ENV
49+
echo "AWS_LC_SYS_TARGET_CXX=g++" >> $GITHUB_ENV
50+
- host: macos-latest
51+
target: aarch64-apple-darwin
52+
build: yarn build --target aarch64-apple-darwin
53+
- host: ubuntu-latest
54+
target: wasm32-wasip1-threads
55+
build: yarn build --target wasm32-wasip1-threads
56+
rust: '1.94.1'
57+
setup: |
58+
sudo apt-get update
59+
sudo apt-get install -y --no-install-recommends clang llvm wasi-libc libc++-dev
60+
echo "CC_wasm32_wasip1_threads=clang" >> $GITHUB_ENV
61+
echo "CXX_wasm32_wasip1_threads=clang++" >> $GITHUB_ENV
62+
echo "AR_wasm32_wasip1_threads=llvm-ar" >> $GITHUB_ENV
63+
echo "CC_wasm32_wasi=clang" >> $GITHUB_ENV
64+
echo "CXX_wasm32_wasi=clang++" >> $GITHUB_ENV
65+
echo "AR_wasm32_wasi=llvm-ar" >> $GITHUB_ENV
66+
echo "WASI_SYSROOT=/usr" >> $GITHUB_ENV
67+
echo "CFLAGS_wasm32_wasip1_threads=--sysroot=/usr -isystem /usr/include/wasm32-wasi" >> $GITHUB_ENV
68+
echo "CXXFLAGS_wasm32_wasip1_threads=--sysroot=/usr -isystem /usr/include/wasm32-wasi" >> $GITHUB_ENV
69+
echo "CFLAGS_wasm32_wasi=--sysroot=/usr -isystem /usr/include/wasm32-wasi" >> $GITHUB_ENV
70+
echo "CXXFLAGS_wasm32_wasi=--sysroot=/usr -isystem /usr/include/wasm32-wasi" >> $GITHUB_ENV
71+
name: stable - ${{ matrix.settings.target }} - node@22
72+
runs-on: ${{ matrix.settings.host }}
73+
steps:
74+
- uses: actions/checkout@v6
75+
- name: Setup node
76+
uses: actions/setup-node@v6
77+
with:
78+
node-version: 24
79+
cache: yarn
80+
cache-dependency-path: icechunk-js/yarn.lock
81+
- name: Install
82+
uses: dtolnay/rust-toolchain@stable
83+
with:
84+
toolchain: ${{ matrix.settings.rust || 'stable' }}
85+
targets: ${{ matrix.settings.target }}
86+
- name: Cache cargo
87+
uses: actions/cache@v5
88+
with:
89+
path: |
90+
~/.cargo/registry/index/
91+
~/.cargo/registry/cache/
92+
~/.cargo/git/db/
93+
~/.napi-rs
94+
.cargo-cache
95+
target/
96+
key: ${{ matrix.settings.target }}-cargo-${{ matrix.settings.host }}
97+
- uses: mlugg/setup-zig@v2
98+
if: ${{ contains(matrix.settings.target, 'musl') }}
99+
with:
100+
version: 0.14.1
101+
- name: Install cargo-zigbuild
102+
uses: taiki-e/install-action@v2
103+
if: ${{ contains(matrix.settings.target, 'musl') }}
104+
env:
105+
GITHUB_TOKEN: ${{ github.token }}
106+
with:
107+
tool: cargo-zigbuild
108+
- name: Setup toolchain
109+
run: ${{ matrix.settings.setup }}
110+
if: ${{ matrix.settings.setup }}
111+
shell: bash
112+
- name: Install dependencies
113+
run: yarn install
114+
- name: Build
115+
run: ${{ matrix.settings.build }}
116+
shell: bash
117+
- name: Upload artifact
118+
uses: actions/upload-artifact@v6
119+
with:
120+
name: bindings-${{ matrix.settings.target }}
121+
path: |
122+
icechunk-js/${{ env.APP_NAME }}.*.node
123+
icechunk-js/${{ env.APP_NAME }}.*.wasm
124+
if-no-files-found: error
125+
126+
test-macOS-windows-binding:
127+
name: Test bindings on ${{ matrix.settings.target }} - node@${{ matrix.node }}
128+
needs:
129+
- build
130+
defaults:
131+
run:
132+
working-directory: ./icechunk-js
133+
strategy:
134+
fail-fast: false
135+
matrix:
136+
settings:
137+
- host: windows-latest
138+
target: x86_64-pc-windows-msvc
139+
architecture: x64
140+
- host: macos-latest
141+
target: aarch64-apple-darwin
142+
architecture: arm64
143+
node:
144+
- "20"
145+
- "22"
146+
runs-on: ${{ matrix.settings.host }}
147+
steps:
148+
- uses: actions/checkout@v6
149+
- name: Setup node
150+
uses: actions/setup-node@v6
151+
with:
152+
node-version: ${{ matrix.node }}
153+
cache: yarn
154+
cache-dependency-path: icechunk-js/yarn.lock
155+
architecture: ${{ matrix.settings.architecture }}
156+
- name: Install dependencies
157+
run: yarn install
158+
- name: Download artifacts
159+
uses: actions/download-artifact@v7
160+
with:
161+
name: bindings-${{ matrix.settings.target }}
162+
path: ./icechunk-js
163+
- name: List packages
164+
run: ls -R .
165+
shell: bash
166+
- name: Test bindings
167+
run: yarn test
168+
169+
test-linux-binding:
170+
name: Test bindings on ${{ matrix.target }} - node@${{ matrix.node }}
171+
needs:
172+
- build
173+
defaults:
174+
run:
175+
working-directory: ./icechunk-js
176+
strategy:
177+
fail-fast: false
178+
matrix:
179+
target:
180+
- x86_64-unknown-linux-gnu
181+
node:
182+
- "20"
183+
- "22"
184+
runs-on: ubuntu-latest
185+
steps:
186+
- uses: actions/checkout@v6
187+
- name: Setup node
188+
uses: actions/setup-node@v6
189+
with:
190+
node-version: ${{ matrix.node }}
191+
cache: yarn
192+
cache-dependency-path: icechunk-js/yarn.lock
193+
- name: Install dependencies
194+
run: yarn install
195+
- name: Download artifacts
196+
uses: actions/download-artifact@v7
197+
with:
198+
name: bindings-${{ matrix.target }}
199+
path: ./icechunk-js
200+
- name: List packages
201+
run: ls -R .
202+
shell: bash
203+
- name: Test bindings
204+
run: yarn test
205+
206+
test-wasi:
207+
name: Test WASI target
208+
needs:
209+
- build
210+
runs-on: ubuntu-latest
211+
defaults:
212+
run:
213+
working-directory: ./icechunk-js
214+
steps:
215+
- uses: actions/checkout@v6
216+
- name: Setup node
217+
uses: actions/setup-node@v6
218+
with:
219+
node-version: 24
220+
cache: yarn
221+
cache-dependency-path: icechunk-js/yarn.lock
222+
- name: Install dependencies
223+
run: |
224+
yarn config set supportedArchitectures.cpu "wasm32"
225+
yarn install
226+
- name: Download artifacts
227+
uses: actions/download-artifact@v7
228+
with:
229+
name: bindings-wasm32-wasip1-threads
230+
path: ./icechunk-js
231+
- name: List packages
232+
run: ls -R .
233+
shell: bash
234+
- name: Test bindings
235+
run: yarn test
236+
env:
237+
NAPI_RS_FORCE_WASI: 1
238+
239+
publish:
240+
name: Publish
241+
if: github.event_name == 'workflow_dispatch'
242+
runs-on: ubuntu-latest
243+
defaults:
244+
run:
245+
working-directory: ./icechunk-js
246+
permissions:
247+
contents: write
248+
id-token: write
249+
needs:
250+
- test-macOS-windows-binding
251+
- test-linux-binding
252+
- test-wasi
253+
steps:
254+
- uses: actions/checkout@v6
255+
- name: Setup node
256+
uses: actions/setup-node@v6
257+
with:
258+
node-version: 24
259+
cache: yarn
260+
cache-dependency-path: icechunk-js/yarn.lock
261+
- name: Install dependencies
262+
run: yarn install
263+
- name: Create npm dirs
264+
run: yarn napi create-npm-dirs
265+
- name: Download all artifacts
266+
uses: actions/download-artifact@v7
267+
with:
268+
path: ./icechunk-js/artifacts
269+
- name: Move artifacts
270+
run: yarn artifacts
271+
- name: List packages
272+
run: ls -R ./npm
273+
shell: bash
274+
- name: Publish
275+
run: |
276+
npm config set provenance true
277+
echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" >> ~/.npmrc
278+
VERSION=$(node -p "require('./package.json').version")
279+
if echo "$VERSION" | grep -q "-"; then
280+
TAG=${VERSION%%-*}; TAG=${VERSION#"$TAG"-}; TAG=${TAG%%.*}
281+
npm publish --access public --tag "$TAG"
282+
else
283+
npm publish --access public
284+
fi
285+
env:
286+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
287+
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}

.pre-commit-config.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@ repos:
33
rev: v5.0.0
44
hooks:
55
- id: trailing-whitespace
6+
exclude: 'icechunk-js/\.yarn/releases/.*'
67
- id: end-of-file-fixer
8+
exclude: 'icechunk-js/\.yarn/releases/.*'
79
- id: check-yaml
810
exclude: docs/mkdocs.yml
911
- id: debug-statements

0 commit comments

Comments
 (0)