Skip to content

Feature/cache api upgrade#127

Merged
godronus merged 18 commits into
alphafrom
feature/cache-api-upgrade
May 6, 2026
Merged

Feature/cache api upgrade#127
godronus merged 18 commits into
alphafrom
feature/cache-api-upgrade

Conversation

@godronus
Copy link
Copy Markdown
Collaborator

@godronus godronus commented May 5, 2026

No description provided.

godronus added 11 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".
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

Adds a new POP-local fastedge::cache public API to the FastEdge SDK, wiring it through WIT, C++ host/runtime bindings, JS builtins, TypeScript declarations, docs, and examples. It also extends KV with entry-style readers and aligns project/example configs with the newer ES2023 runtime baseline.

Changes:

  • Added fastedge::cache end-to-end: WIT imports, generated bindings, host wrappers, runtime builtin, bundler resolution, TS types, docs, and examples.
  • Added async KvStoreEntry-based helpers (getEntry, zrangeByScoreEntries, zscanEntries) plus related docs/examples.
  • Updated globals/types, example tsconfigs, workspace wiring, and plugin/doc-generation metadata for the expanded SDK surface.

Reviewed changes

Copilot reviewed 47 out of 54 changed files in this pull request and generated 11 comments.

Show a summary per file
File Description
types/index.d.ts Registers new cache type declarations.
types/globals.d.ts Expands global Web/API typings.
types/fastedge-kv.d.ts Adds entry-style KV API types.
types/fastedge-cache.d.ts Defines new public cache API.
tsconfig.json Raises root TS target to ES2023.
src/componentize/es-bundle.ts Resolves fastedge::cache imports; pins esbuild target/format.
src/cli/fastedge-init/create-config.ts Updates scaffolded jsconfig target.
runtime/fastedge/scripts/merge-wit-bindings.js Excludes async cache WIT; documents rationale.
runtime/fastedge/host-api/wit/deps/fastedge/world.wit Imports utils and sync cache interfaces.
runtime/fastedge/host-api/wit/deps/fastedge/utils.wit Adds utils WIT interface.
runtime/fastedge/host-api/wit/deps/fastedge/cache-types.wit Adds shared cache WIT types.
runtime/fastedge/host-api/wit/deps/fastedge/cache-sync.wit Adds sync cache WIT API.
runtime/fastedge/host-api/include/fastedge_host_api.h Declares cache host wrapper types/APIs.
runtime/fastedge/host-api/fastedge_host_api.cpp Implements cache host wrappers.
runtime/fastedge/host-api/bindings/bindings.h Regenerated bindings for cache/utils imports.
runtime/fastedge/CMakeLists.txt Registers new cache builtin.
runtime/fastedge/builtins/kv-store.h Declares new KV entry-style methods.
runtime/fastedge/builtins/kv-store.cpp Implements KvStoreEntry and new KV methods.
runtime/fastedge/builtins/cache.cpp Implements JS-facing cache builtin.
pnpm-workspace.yaml Adds workspace SDK override.
pnpm-lock.yaml Updates lockfile for workspace linking/new examples.
github-pages/src/content/docs/reference/fastedge/kv/zset.md Documents new KV sorted-set entry helpers.
github-pages/src/content/docs/reference/fastedge/kv/key-value.md Documents getEntry KV API.
fastedge-plugin-source/manifest.json Adds cache example/plugin source mappings.
fastedge-plugin-source/generate-docs.sh Includes cache types in SDK doc generation.
fastedge-plugin-source/.generation-config.md Updates SDK doc-generation requirements.
examples/static-assets/tsconfig.json Modernizes example TS config.
examples/README.md Lists new cache examples.
examples/react-with-hono-server/tsconfig.fastedge.json Modernizes FastEdge TS config.
examples/mcp-server/tsconfig.json Modernizes example TS config.
examples/kv-store/tsconfig.json Modernizes example TS config.
examples/kv-store-basic/src/index.js Switches example to getEntry().
examples/cache/tsconfig.json Adds TS config for new cache example.
examples/cache/src/index.ts Adds full cache patterns example.
examples/cache/README.md Documents full cache example.
examples/cache/package.json Adds package metadata for cache example.
examples/cache/.fastedge/build-config.js Adds build config for cache example.
examples/cache-basic/src/index.js Adds basic cache CRUD example.
examples/cache-basic/README.md Documents basic cache example.
examples/cache-basic/package.json Adds package metadata for basic cache example.
docs/STATIC_SITES.md Minor formatting cleanup.
docs/SDK_API.md Documents cache API and new KV entry APIs.
docs/quickstart.md Updates KV quickstart to entry-style API.
docs/INIT_CLI.md Clarifies init prompt behavior.
docs/INDEX.md Refreshes index formatting/version references.
docs/BUILD_CLI.md Documents positional config path and clarifies build pipeline.
docs/ASSETS_CLI.md Minor formatting cleanup.
context/development/BUILD_SYSTEM.md Documents customer bundling/tsconfig behavior.
context/CONTEXT_INDEX.md Adds cache API project status notes.
context/CHANGELOG.md Records cache/KV/tsconfig changes.
context/CACHE_API_HANDOFF.md Adds cache implementation handoff details.
Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

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/cache.cpp Outdated
Comment thread runtime/fastedge/builtins/kv-store.cpp Outdated
Comment thread runtime/fastedge/builtins/kv-store.cpp Outdated
Comment thread docs/INDEX.md Outdated
Comment thread docs/INDEX.md Outdated
Comment thread examples/cache/package.json
Comment thread examples/cache-basic/package.json
Comment thread examples/cache/src/index.ts Outdated
qrdl
qrdl previously approved these changes May 5, 2026
godronus added 2 commits May 5, 2026 18:06
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

Copilot reviewed 47 out of 54 changed files in this pull request and generated 9 comments.

Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

Comment thread runtime/fastedge/builtins/cache.cpp
Comment thread runtime/fastedge/host-api/fastedge_host_api.cpp
Comment thread runtime/fastedge/host-api/fastedge_host_api.cpp
Comment thread context/CACHE_API_HANDOFF.md Outdated
Comment thread examples/cache/src/index.ts Outdated
Comment thread docs/INDEX.md Outdated
Comment thread src/cli/fastedge-init/create-config.ts
Comment thread examples/cache/src/index.ts Outdated
Comment thread examples/kv-store-basic/src/index.js
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

Copilot reviewed 47 out of 54 changed files in this pull request and generated 8 comments.

Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

Comment thread docs/SDK_API.md Outdated
Comment thread docs/INDEX.md Outdated
Comment thread fastedge-plugin-source/.generation-config.md Outdated
Comment thread docs/SDK_API.md Outdated
Comment thread examples/cache/README.md Outdated
Comment thread examples/cache/README.md Outdated
Comment thread context/CACHE_API_HANDOFF.md Outdated
Comment thread docs/INDEX.md Outdated
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

Copilot reviewed 46 out of 53 changed files in this pull request and generated 9 comments.

Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

Comment thread examples/cache/src/index.ts
Comment thread examples/cache/src/index.ts
Comment thread examples/cache/src/index.ts Outdated
Comment thread examples/cache/src/index.ts Outdated
// `fastedge::cache` module:
//
// 1. Per-IP rate limiting (atomic counters)
// 2. Origin-cache proxy (getOrSet with a fetch populator)
Comment thread docs/INDEX.md
Comment thread docs/INDEX.md Outdated
Comment thread docs/INIT_CLI.md Outdated
Comment thread docs/INDEX.md Outdated
import { Cache } from "fastedge::cache";

async function app(event) {
const ip = event.request.headers.get("x-forwarded-for") ?? "unknown";
Comment on lines +38 to +43
case 'cache': {
return {
contents: `
export const Cache = globalThis.Cache;
`,
};
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

added a test suite

qrdl
qrdl previously approved these changes May 6, 2026
@godronus godronus merged commit fb9c276 into alpha May 6, 2026
9 checks passed
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 6, 2026

🎉 This PR is included in version 2.3.0-alpha.1 🎉

The release is available on:

Your semantic-release bot 📦🚀

@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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants