Skip to content

Feature/cache api upgrade#129

Merged
godronus merged 19 commits into
mainfrom
feature/cache-api-upgrade
May 7, 2026
Merged

Feature/cache api upgrade#129
godronus merged 19 commits into
mainfrom
feature/cache-api-upgrade

Conversation

@godronus
Copy link
Copy Markdown
Collaborator

@godronus godronus commented May 7, 2026

No description provided.

godronus added 19 commits April 29, 2026 10:47
Bumps the FastEdge-wit submodule to b6fdc9f, which adds cache (async),
cache-sync, cache-types, and utils interfaces to the gcore:fastedge
reactor world. Regenerates the merged WIT files under host-api/wit/deps/.

Note: wit-bindgen 0.37.0 (current pin, aligned with StarlingMonkey
wasi-0.2.3) cannot parse `async func` syntax in cache.wit. C bindings
generation succeeds when only cache-sync is in scope. Async cache
support requires wit-bindgen >= 0.51.0 and is being explored on
feature/cache-api-async.
Adds the async `cache` interface to the strip list in merge-wit-bindings.js
so it is removed from the merged world along with its file, leaving only
`cache-sync`. This unblocks `pnpm run wit:bindings` with our pinned
wit-bindgen 0.37.0, which cannot parse `async func` syntax.

Regenerates host-api/bindings to include the new cache-sync and utils
imports. Existing dictionary / secret / key-value signatures are unchanged.

Async cache support is being explored on feature/cache-api-async; see that
branch for the wit-bindgen 0.57.1 output and notes on what bridging
component-model preview-3 subtasks to JS Promises would entail.
Adds the JS API contract for the upcoming POP-local cache module:
- `Cache` static class with get / exists / set / delete / expire / incr
  / decr / getOrSet
- `CacheEntry` Body-like return shape with arrayBuffer / text / json
- `CacheValue` accepts string / ArrayBuffer / ArrayBufferView /
  ReadableStream / Response (status + headers discarded — this is a byte
  cache, not an HTTP cache)
- `WriteOptions` with mutually-exclusive ttl (seconds) / ttlMs / expiresAt

Reads and counters are sync; `set` is async because Response and
ReadableStream inputs require collection before the host call.
`getOrSet` is JS-side stampede protection with in-process coalescing.

Wires the new declarations into types/index.d.ts. C++ implementation is
pending — see context/CACHE_API_HANDOFF.md for the resume guide.
Captures everything decided so far on feature/cache-api so a future
session can pick up the C++ wiring without re-deriving the design:

- Why fastedge::cache exists (POP-local, fast read+write, atomic incr —
  positioned alongside fastedge::kv which is global and eventually
  consistent)
- WIT bindings state, why the async cache interface is excluded for now,
  and what feature/cache-api-async preserves for future async work
- Public TypeScript surface and the design decisions behind it
- Concrete C++ work plan in four layers: host-api wrappers, builtin,
  CMake registration, tests
- The drafted JS shim for getOrSet / coerceToBytes / makeCacheEntry
- Open questions: WriteOptions runtime validation, incr non-integer
  semantics, JS-shim install pattern, future dynamic-TTL extensibility

Adds an index entry under "Known Issues / Future Work" pointing at the
handoff doc.
C++ wrappers around the cache-sync and utils C bindings generated by
wit-bindgen. Mirrors the existing kv_store_* pattern: CacheResult<T> /
CacheOption<T> / CacheError parallel KvStore* templates (slated for
unification into HostResult / HostOption / HostError in a follow-up
cleanup once both shipping forms are in tree).

cache_set / cache_delete return std::optional<CacheError> since their
WIT signatures are void-on-success; everything else returns
CacheResult<T>. Includes utils_set_user_diag — host-api side only;
JS-facing surface for it is a separate follow-up.
Pure C++ builtin exposing the FastEdge POP-local cache as a static
`Cache` class with seven async methods plus a Body-like `CacheEntry`
wrapper:

- get / exists / delete / expire — straight Promise wrappers around
  the sync host call.
- set — accepts string / ArrayBuffer / ArrayBufferView synchronously
  and Response / ReadableStream / anything-with-arrayBuffer
  asynchronously via JS::AddPromiseReactions. ReadableStream is
  auto-wrapped in `new Response(stream)` for the unified path.
- incr / decr — atomic counter primitive; returns Number (with a
  documented Number.MAX_SAFE_INTEGER caveat).
- getOrSet — in-process stampede protection. A no-prototype JSObject
  inflight map persistent-rooted for the engine's lifetime coalesces
  concurrent populators for the same key. Common finalize path used
  by both sync and async coercion.

CacheEntry exposes arrayBuffer / text / json — Body-shape with
Promise-returning methods. arrayBuffer returns a fresh copy so callers
can't mutate the underlying buffer and corrupt subsequent reads.

API design:

- Every method returns Promise<T> — including reads/counters that are
  sync at the host level today. This is forward-compat: when the
  toolchain gains preview-3 async support and we swap to the async
  cache.wit, application code keeps working unchanged.
- WriteOptions is `{ ttl }` (seconds) | `{ ttlMs }` | `{ expiresAt }`
  (Unix epoch seconds), mutually exclusive at runtime.
- CacheValue accepts string / ArrayBuffer / ArrayBufferView /
  ReadableStream / Response. Strings UTF-8 encoded; Response
  status+headers discarded.
- Errors throw synchronously for input validation (caught by `await`
  the same way) and reject the Promise for host I/O errors.

Also wires the import path: src/componentize/es-bundle.ts gets a
`'cache'` case re-exporting `globalThis.Cache` from
`fastedge::cache`, and CMakeLists registers the new builtin.

Updates types/fastedge-cache.d.ts to all-async; passes typecheck.
CACHE_API_HANDOFF.md now describes what shipped rather than the work
plan. Captures the decisions made during implementation:

- All-async surface (the late pivot for forward-compat with the
  eventual async WIT swap).
- Pure C++ builtin with no embedded JS shim, plus the StarlingMonkey
  reference templates used for Body-like + Promise-reaction patterns.
- The all-async refactor, the WriteOptions discriminated union, the
  CacheEntry Body-like return.
- Open questions still on the runtime team (incr non-integer error
  semantics).
- Future cleanups (Host* template generalisation, async WIT swap,
  dynamic-TTL extension, utils.set-user-diag JS surface, future HTTP
  Cache API layer) — all flagged as additive, not breaking.
- Verification steps and integration-test scope for the next agent.

Updates the index entry from "C++ wiring pending" to "implemented,
awaiting verification".
Picks up upstream removal of the async cache.wit interface (component-model
preview-3 async funcs) and an associated cache-types.wit doc-comment edit.
The merge script no longer needs to filter cache.wit out, since it's gone
upstream — drop 'cache' from fastedgeDepsToRemove. No behavioural change:
cache-sync was already what the JS SDK uses, the async interface was being
filtered before this submodule bump anyway.
Regenerate runtime/fastedge/host-api/bindings/{bindings.c,bindings.h,
bindings_component_type.o} with wit-bindgen-cli 0.30.0 to fix a canonical-ABI
lowering regression in 0.37.0 that traps every JS-built component on
wasmtime 36 hosts (FastEdge edge):

  WARN incoming handler cause=error while executing
  Caused by: pointer not aligned
  WARN execute cause=guest never invoked `response-outparam::set` method

0.37.0 generates lowering code that reads pointer/length fields from
variant-with-string types at unaligned offsets — for example in wasi:http
result/option decoding:

  // wit-bindgen 0.30.0 (works)
  option.val = (bindings_string_t) { ... (ptr + 4) ..., ... (ptr + 8) ... };

  // wit-bindgen 0.37.0 (traps)
  option.val = (bindings_string_t) { ... (ptr + 1) ..., ... (ptr + 5) ... };

These helpers fire on every incoming request, so the trap surfaces as
`530: fastedge: Execute error` for all examples — including hello-world
that doesn't touch any new interface. Confirmed end-to-end: hello-world
and cache-basic both run cleanly with 0.30.0-regenerated bindings on the
wasmtime 36 edge host.

The earlier rationale for pinning to 0.37.0 ("align with StarlingMonkey
wasi-0.2.3") was incorrect — StarlingMonkey's host-apis are independent,
and 0.30.0 parses cache-sync/utils/cache-types WIT fine.

Documents the regression and the required version in
context/development/BUILD_SYSTEM.md (new "WIT Bindings & wit-bindgen
Version" section) and adds a CHANGELOG entry. Intentionally not enforcing
the version in create-wit-bindings.sh — the contract is documented and the
verification step (head -1 bindings.h) catches mismatches immediately.
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR upgrades the FastEdge JS SDK runtime and public TypeScript surface by introducing a new POP-local cache API (fastedge::cache), adding entry-style helpers for KV reads (KvStoreEntry), modernizing the ES target to ES2023, and expanding/reshaping documentation + examples accordingly.

Changes:

  • Add POP-local cache API across WIT → host bindings → runtime builtins → TypeScript declarations → docs/examples.
  • Add KvStoreEntry and async “entry-style” KV methods (getEntry, zrangeByScoreEntries, zscanEntries) alongside the existing raw-ArrayBuffer KV APIs.
  • Standardize bundling / scaffolding targets to ES2023 and expand reference docs navigation (FetchEvent, Request/Response notes, Cache/KV overviews).

Reviewed changes

Copilot reviewed 81 out of 88 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
types/index.d.ts Adds cache typings reference to the public types entrypoint.
types/fastedge-kv.d.ts Adds KvStoreEntry + entry-style KV method signatures and docs.
types/fastedge-cache.d.ts Introduces the fastedge::cache public TypeScript API surface.
tsconfig.json Bumps repo TS compilation target to ES2023.
src/componentize/es-bundle.ts Resolves fastedge::cache imports; pins esbuild output to ESM + ES2023.
src/componentize/tests/es-bundle.test.ts Adds unit tests for fastedge:: import resolution including cache.
src/cli/fastedge-init/create-config.ts Updates scaffolded .fastedge/jsconfig.json target to ES2023.
runtime/fastedge/scripts/merge-wit-bindings.js Adjusts WIT merge deps filtering comment/structure.
runtime/fastedge/host-api/wit/deps/fastedge/world.wit Imports new utils and cache-sync interfaces into the world.
runtime/fastedge/host-api/wit/deps/fastedge/utils.wit Adds utils.set-user-diag WIT interface.
runtime/fastedge/host-api/wit/deps/fastedge/cache-types.wit Adds shared cache payload/error WIT types.
runtime/fastedge/host-api/wit/deps/fastedge/cache-sync.wit Adds synchronous cache WIT interface.
runtime/fastedge/host-api/include/fastedge_host_api.h Adds cache host-api result/option/error types + cache function declarations.
runtime/fastedge/host-api/fastedge_host_api.cpp Implements cache + utils host-api wrappers.
runtime/fastedge/host-api/bindings/bindings.h Adds generated bindings/types for cache-sync and utils.
runtime/fastedge/host-api/bindings/bindings.c Adds generated imports/free helpers for cache-sync and utils.
runtime/fastedge/CMakeLists.txt Registers new builtins (fastedge::cache, fastedge::request_info).
runtime/fastedge/builtins/request-info.h Adds request/client/server info builtin declarations.
runtime/fastedge/builtins/request-info.cpp Implements lazy event.client / event.server objects.
runtime/fastedge/builtins/kv-store.h Adds new KV instance method declarations for entry-style APIs.
runtime/fastedge/builtins/kv-store.cpp Implements KvStoreEntry + getEntry/zrangeByScoreEntries/zscanEntries.
runtime/fastedge/builtins/console-override.cpp Flushes stdout unconditionally after console writes.
pnpm-workspace.yaml Adds workspace override to link the in-tree SDK package.
pnpm-lock.yaml Updates workspace lockfile to use linked SDK in examples and records override.
package.json Bumps SDK version to 2.3.0.
llms.txt Trims/adjusts package summary text.
github-pages/src/content/docs/reference/response.md Expands Response API reference (properties/methods + static helpers).
github-pages/src/content/docs/reference/request.md Adds note about immutability of incoming Request/headers and how to modify.
github-pages/src/content/docs/reference/overview.md Removes old welcome/overview page content.
github-pages/src/content/docs/reference/fetch-event/index.md Adds FetchEvent reference including client/server sub-objects.
github-pages/src/content/docs/reference/fastedge/kv/zset.md Documents *Entries zset methods and decoding helpers.
github-pages/src/content/docs/reference/fastedge/kv/open.md Links KV overview vs cache positioning.
github-pages/src/content/docs/reference/fastedge/kv/key-value.md Documents getEntry and clarifies raw ArrayBuffer returns.
github-pages/src/content/docs/reference/fastedge/kv/index.md Adds KV overview page (replication, consistency, KV vs Cache).
github-pages/src/content/docs/reference/fastedge/cache/read-write.md Adds cache read/write docs (get/set/delete/exists + entry accessors).
github-pages/src/content/docs/reference/fastedge/cache/index.md Adds cache overview page (POP-local behavior, when to use).
github-pages/src/content/docs/reference/fastedge/cache/get-or-set.md Documents Cache.getOrSet behavior, coalescing, and null skip-write overload.
github-pages/src/content/docs/reference/fastedge/cache/atomic.md Documents cache atomic counter + TTL operations (incr/decr/expire).
github-pages/src/content/docs/index.mdx Updates docs landing page link to FetchEvent reference.
github-pages/src/content/docs/examples/main-examples.mdx Adds cache example link card.
github-pages/src/content/docs/examples/cache.mdx Adds docs page rendering cache-basic example source.
github-pages/astro.config.mjs Updates sidebar/navigation to include FetchEvent, KV/Cache sections.
fastedge-plugin-source/manifest.json Updates plugin-source manifest version and adds cache example sources/mapping.
fastedge-plugin-source/generate-docs.sh Adds cache types to SDK_API.md sources; pipes prompt via stdin to avoid argv limit.
fastedge-plugin-source/.generation-config.md Updates doc generation rules to include Cache and KV entry APIs.
examples/variables-and-secrets/package.json Bumps example dependency to ^2.3.0.
examples/template-invoice/package.json Bumps example dependency to ^2.3.0.
examples/template-invoice-ab-testing/package.json Bumps example dependency to ^2.3.0.
examples/static-assets/tsconfig.json Modernizes example TS config (ES2023 + Bundler resolution + lib).
examples/static-assets/package.json Bumps example dependency to ^2.3.0.
examples/README.md Adds cache-basic and cache examples to the examples index.
examples/react-with-hono-server/tsconfig.fastedge.json Modernizes FastEdge-side TS config for the example.
examples/react-with-hono-server/package.json Bumps example dependency to ^2.3.0.
examples/mcp-server/tsconfig.json Bumps target/lib to ES2023 and adjusts config.
examples/mcp-server/package.json Bumps example dependency to ^2.3.0.
examples/kv-store/tsconfig.json Modernizes example TS config (ES2023 + Bundler resolution + lib).
examples/kv-store/package.json Bumps example dependency to ^2.3.0.
examples/kv-store-basic/src/index.js Updates example to use getEntry() + entry.text().
examples/kv-store-basic/package.json Bumps example dependency to ^2.3.0.
examples/hello-world/package.json Bumps example dependency to ^2.3.0.
examples/headers/package.json Bumps example dependency to ^2.3.0.
examples/geo-redirect/package.json Bumps example dependency to ^2.3.0.
examples/downstream-modify-response/package.json Bumps example dependency to ^2.3.0.
examples/downstream-fetch/package.json Bumps example dependency to ^2.3.0.
examples/cache/tsconfig.json Adds new cache example TS config.
examples/cache/src/index.ts Adds cache “flagship patterns” example (rate limit, proxy, memo).
examples/cache/README.md Documents cache flagship patterns example usage and build steps.
examples/cache/package.json Adds new cache example package.
examples/cache/.fastedge/build-config.js Adds cache example build config for fastedge-build -c.
examples/cache-basic/src/index.js Adds basic cache operations example (set/get/exists/delete).
examples/cache-basic/README.md Documents cache-basic example usage.
examples/cache-basic/package.json Adds cache-basic example package.
examples/ab-testing/package.json Bumps example dependency to ^2.3.0.
docs/STATIC_SITES.md Table formatting tweaks/normalization.
docs/quickstart.md Updates KV example to getEntry; adds Cache quickstart section/signatures.
docs/INIT_CLI.md Formatting + updates jsconfig target wording to ES2023.
docs/INDEX.md Adds Cache + KV entry APIs into docs index and runtime API tables.
docs/BUILD_CLI.md Documents positional config arg and clarifies static-only config fields; pipeline note updated.
docs/ASSETS_CLI.md Fixes manifest example and adjusts MIME table formatting.
context/development/BUILD_SYSTEM.md Documents esbuild bundling contract + wit-bindgen pin details.
context/CONTEXT_INDEX.md Adds cache API status notes and utils interface follow-up note.
context/CHANGELOG.md Adds detailed changelog entries for cache + types/bundling + wit-bindgen pin.
context/CACHE_API_HANDOFF.md Adds cache implementation handoff document and verification steps.
Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

Comment thread docs/INDEX.md
Comment thread runtime/fastedge/host-api/fastedge_host_api.cpp
Comment thread runtime/fastedge/host-api/fastedge_host_api.cpp
Comment thread runtime/fastedge/builtins/kv-store.cpp
Comment thread runtime/fastedge/builtins/kv-store.cpp
Comment thread runtime/fastedge/builtins/kv-store.cpp
Comment thread runtime/fastedge/host-api/wit/deps/fastedge/utils.wit
@godronus godronus merged commit ee5c63e into main May 7, 2026
24 checks passed
@godronus godronus deleted the feature/cache-api-upgrade branch May 7, 2026 13:36
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 7, 2026

🎉 This PR is included in version 2.3.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants