feat(sdk): add cache primitive#1118
Conversation
Greptile SummaryThis PR adds a generic cache primitive to the SDK executor surface, backed by Effect's
Confidence Score: 5/5Safe to merge. Both previously flagged concerns — LRU ordering on The LRU fix ( No files require special attention. Important Files Changed
Reviews (2): Last reviewed commit: "fix(sdk): refresh cache writes in LRU or..." | Re-trigger Greptile |
|
Additional downstream context from my fork: the cache primitive is the base layer I use to move hot-path derived data out of D1 and into host-provided KV. High-level shape: AST outline of downstream usage: makeCloudflareApp(env)
-> layerCloudflareKeyValueStore(env.CACHE)
createExecutor(...)
-> cacheStore = config.cache ?? makeMemoryCacheStore()
-> KeyValueStore.toSchemaStore(cacheStore, ToolTypeScriptPreviewCacheEntry)
-> KeyValueStore.toSchemaStore(cacheStore, ToolSchemaViewCacheEntry)
-> KeyValueStore.toSchemaStore(cacheStore, ToolListCacheEntry)
semanticSearch
-> KeyValueStore.toSchemaStore(executor.cache, ManifestSnapshotEntry)Fork permalinks:
Call stack: This PR is intentionally just the primitive. Once it lands, schema-view caching, TypeScript preview caching, and manifest snapshot work can be proposed as follow-up consumers without forcing this PR to carry those policies. |
## Summary Mirrors the Greptile follow-up from upstream PR RhysSullivan#1118 into fork `dev`. `dev` already has the richer cache primitive surface, including SDK cache config, API scoped service lookup, Cloudflare KV support, host `CACHE` wiring, and later cache consumers. This PR intentionally ports only the remaining behavior drift: refreshing fallback cache insertion order when writing an existing key, plus the focused regression tests from RhysSullivan#1118. ## Changes - Delete an existing fallback cache key before re-inserting it on `set`, so Map insertion order reflects the newest write. - Add `executor-cache.test.ts` coverage for default fallback cache get, remove, TTL expiry, size cleanup, and LRU write refresh behavior. ## Intentional Differences From Upstream RhysSullivan#1118 - No generic cache primitive API changes are included here because `dev` already has them. - No Cloudflare key value store changes are included here because `dev` already has them. - No changeset is included because this PR changes behavior and tests only, with no new public package surface. ## Tests - `bun run --cwd packages/core/sdk test -- src/executor-cache.test.ts` - `bun run --cwd packages/core/sdk typecheck` - `bunx oxlint -c .oxlintrc.jsonc --deny-warnings packages/core/sdk/src/executor.ts packages/core/sdk/src/executor-cache.test.ts` - `git diff --check`
Summary
KeyValueStore.ExecutorConfig.cache, while default executors get a bounded in-memory fallback.maindoes not currently declare.Changes
packages/core/sdk/src/executor.tseffect/unstable/persistence/KeyValueStore.ExecutorConfig.cache?: KeyValueStore.KeyValueStore.Executor.cache: KeyValueStore.KeyValueStore.KeyValueStorewith TTL and capacity eviction.packages/core/sdk/src/test-config.tsmakeTestConfigandmakeTestWorkspaceHarness.packages/core/api/src/server/scoped-executor.tsKeyValueStore.KeyValueStoreservice from the Effect context.createExecutoronly when a host layer provides one.packages/hosts/cloudflare/src/key-value-store.tsmakeCloudflareKeyValueStore(kv)over CloudflareKVNamespace.layerCloudflareKeyValueStore(kv)for host boot layer composition.KeyValueStore.KeyValueStoreError.sizeand bounded parallelclear.packages/hosts/cloudflare/package.json@executor-js/cloudflare/key-value-store..changeset/polite-caches-pull.mdAST-level outline
Call-stack trace
Host-provided cache path
Default cache path
Cloudflare adapter path
Usage / pseudocode
Tests
bunx oxfmt --check packages/core/sdk/src/executor.ts packages/core/sdk/src/test-config.ts packages/core/api/src/server/scoped-executor.ts packages/hosts/cloudflare/src/key-value-store.ts packages/hosts/cloudflare/src/key-value-store.test.ts packages/hosts/cloudflare/package.json .changeset/polite-caches-pull.mdgit diff --checkbunx oxlint -c .oxlintrc.jsonc --deny-warnings packages/core/sdk/src/executor.ts packages/core/sdk/src/test-config.ts packages/core/api/src/server/scoped-executor.ts packages/hosts/cloudflare/src/key-value-store.ts packages/hosts/cloudflare/src/key-value-store.test.tsbun run --cwd packages/core/sdk typecheckbun run --cwd packages/core/api typecheckbun run --cwd packages/hosts/cloudflare test -- src/key-value-store.test.tsbun run --cwd packages/hosts/cloudflare typecheckbun run typecheckValidation notes
bun run format:checkand rootbun run lintcurrently scan.scratchpadand fail on existing scratchpad files outside this PR. Touched-file format and lint checks pass.bun run testruns the suite but currently prints two unrelatedapps/cloudauth expectation failures where the received identity includesorganizationSlug. The cache primitive diff does not touchapps/cloud.Deferred scope
tools.listcache consumer.CACHEbinding wiring because upstreammaindoes not currently declare aCACHEbinding inCloudflareEnvorwrangler.jsonc.