Skip to content

Let Almide call the store itself on the JS hosts through JSPI - #7

Draft
O6lvl4 wants to merge 4 commits into
mainfrom
feat/jspi-store
Draft

O6lvl4 wants to merge 4 commits into
mainfrom
feat/jspi-store

Conversation

@O6lvl4

@O6lvl4 O6lvl4 commented Oct 4, 2026 •

Copy link
Copy Markdown
Contributor

What changes

On the Wasm routes (Workers, the Node function adapters), Almide used to return step's reads and write to the JS host, and the host carried them out (adapters/step.mjs). Now Almide makes the storage calls itself, the same way the native host does:

  • src/wasm.almd runs api.step to the end and calls two hooks, store_get / store_put. In Almide they are ordinary functions.
  • The build passes --async-import store_get,store_put (--host js: async @extern via JSPI so Almide code can await JS I/O (prototype works on Node, workerd and the Cloudflare edge) almide#3353). The generated JS suspends the module through JSPI while each KV / Cloud Storage promise settles.
  • serve returns a Promise. handle (no storage) stays synchronous.
  • adapters/store.mjs (was step.mjs) only binds each hook to one store call. It also runs one serve at a time, so a suspended call cannot see another request's store.
  • The Node requirement is now 24 or newer, which JSPI needs. All the function runtimes here are already Node 24.

Verification (2026-10-04)

Compiler: Almide fix-3353 at e9eb4bb90, built locally and passed as ALMIDE_BIN.

  • npm test: 158/158 on Node 24.21.0
  • Local workerd with a fresh KV state: 29/29. 20 concurrent POST /notes: all 20 stored.
  • Deployed Worker with a freshly provisioned KV namespace: 29/29. wrangler tail showed 22 requests, all ok, and 0 exceptions.
    • 20 concurrent POST /notes across isolates kept only 5. This is the existing single-key read-modify-write limitation, now measured; this change does not affect it.
    • The Worker and the namespace were deleted afterwards.
  • Cloud Run functions with GCS_BUCKET, via Terraform, in a disposable project (deleted afterwards), tested from a private in-VPC VM:
    • On the default nodejs24 runtime, every request answered 500. Google's image is Node 24.19.0, and JSPI is only on by default from 24.20.0; the generated init() refused with its JSPI message.
    • Added var.runtime / GCP_BASE_IMAGE (default nodejs24) and re-applied with nodejs26 (beta, 26.7.0). Results: 18/18 octet-stream, /notes 11/11, JSON showed the same 3 known framework rejections, and 403 without a token.
    • The bucket held the two notes, written by Almide through store_put.
    • 20 concurrent POSTs: 17 × 201 and 3 × 503. The 503s were Almide's storage_unavailable after GCS answered 429 to rapid writes of one object, and Almide logged that itself.
  • CI moves to Node 24.21.0; engines is now >=24.20.0.

Draft until Almide ships --async-import

The pinned v0.66.0 release does not have the flag, so CI fails on this branch until a release includes almide/almide#3353. Then .almide-release and the checksums need bumping.

Found along the way:

🤖 Generated with Claude Code

src/wasm.almd now runs api.step to the end like the native host, calling the
hooks store_get / store_put directly. The build marks them --async-import
(almide/almide#3353, branch fix-3353), so the generated JS suspends the module
through JSPI while each KV / Cloud Storage call settles. Only serve returns a
Promise; handle stays synchronous. adapters/store.mjs (was step.mjs) binds the
hooks to a store and no longer runs the step loop.

Verified locally (npm test 158/158, local workerd 29/29) and on the deployed
Worker with a fresh KV namespace (29/29), then deleted. Needs an Almide build
with --async-import until it is released; Node 24+.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Google's nodejs24 runtime is Node 24.19.0, which has no JSPI, so the generated
init() refused every request there. JSPI is on by default from Node 24.20.0.
Terraform gains var.runtime and deploy.sh GCP_BASE_IMAGE (both default
nodejs24); on nodejs26 (beta, 26.7.0) the function passed 18/18, the /notes
scenario 11/11, and Almide wrote the bucket itself. CI moves to Node 24.21.0
and engines to >=24.20.0. Reported the version guidance as almide/almide#3362.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
O6lvl4 and others added 2 commits October 5, 2026 12:52
Almide #3371 replaced the build flag with a marker on the extern before
v0.67.0-rc1 was tagged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant