Skip to content

feat(flags): share bulk evaluate() + give SvelteKit evaluate() (3/3)#414

Draft
dferber90 wants to merge 1 commit into
shared/evaluationfrom
shared/bulk-evaluate
Draft

feat(flags): share bulk evaluate() + give SvelteKit evaluate() (3/3)#414
dferber90 wants to merge 1 commit into
shared/evaluationfrom
shared/bulk-evaluate

Conversation

@dferber90

Copy link
Copy Markdown
Collaborator

Stacked PR 3 of 3 · base: shared/evaluation (#413)

Extracts the bulk-evaluation orchestration into shared/evaluate.ts (evaluateFlags + the BULKABLE / BULK_IDENTIFY_REF markers), parameterized by how standalone flags are invoked and which errors are framework control flow. Next wraps it in its bulkStore ALS and invokes standalone flags via flagFn(); behavior and public .d.ts are unchanged.

SvelteKit gains a real bulk evaluate(flags, request, secret?) (src/sveltekit/evaluate.ts), exported from flags/sveltekit and used by its precompute. SvelteKit's flag() now stamps adapter, config, and the bulk markers so adapters implementing bulkDecide resolve a whole group in one call. Adds 2 bulk-evaluate tests.

Documents the framework contract (context resolution, secret strategy, isFrameworkError, invokeStandalone, output integration) in shared/README.md so adding a new framework only means writing a thin adapter.

Verification

123/123 tests pass · type-check · biome · attw green · next.d.ts byte-identical · @flags-sdk/vercel builds.

🤖 Generated with Claude Code

Extracts the bulk-evaluation orchestration into shared/evaluate.ts
(`evaluateFlags` + the BULKABLE / BULK_IDENTIFY_REF markers), parameterized
by how standalone flags are invoked and which errors are framework control
flow. Next wraps it in its bulkStore ALS and invokes standalone flags via
`flagFn()`; behavior and public .d.ts are unchanged.

SvelteKit gains a real bulk `evaluate(flags, request, secret?)`
(src/sveltekit/evaluate.ts) exported from flags/sveltekit and used by its
`precompute`. SvelteKit's flag() now stamps `adapter`, `config`, and the bulk
markers so adapters implementing `bulkDecide` resolve a whole group in one
call. Adds 2 bulk-evaluate tests.

Documents the framework contract (context resolution, secret strategy,
isFrameworkError, invokeStandalone, output integration) in shared/README.md
so adding a new framework only means writing a thin adapter.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@vercel

vercel Bot commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
flags-playground Ready Ready Preview, Comment, Open in v0 Jun 25, 2026 1:34pm
flags-sdk-dev Ready Ready Preview, Comment, Open in v0 Jun 25, 2026 1:34pm
flags-sdk-snippets Ready Ready Preview, Comment, Open in v0 Jun 25, 2026 1:34pm
shirt-shop Ready Ready Preview, Comment, Open in v0 Jun 25, 2026 1:34pm
shirt-shop-api Ready Ready Preview, Comment, Open in v0 Jun 25, 2026 1:34pm

Comment on lines +53 to +54
invokeStandalone: (flagFn) =>
(flagFn as (request: Request) => Promise<any>)(request),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
invokeStandalone: (flagFn) =>
(flagFn as (request: Request) => Promise<any>)(request),
// Thread the same resolved secret used for the bulk path's overrides so
// standalone flags decrypt the override cookie consistently. Without this,
// a standalone flag invoked as `flagFn(request)` (no secret) outside a
// `createHandle` context would resolve its own secret via `tryGetSecret()`
// (env `FLAGS_SECRET`), diverging from `resolvedSecret` when `evaluate()`
// was called with a custom secret.
invokeStandalone: (flagFn) =>
(flagFn as (request: Request, secret?: string) => Promise<any>)(
request,
resolvedSecret,
),

In SvelteKit evaluate(), the resolved secret is used for the bulk path's overrides but not threaded to standalone flag invocations, so the two paths can decrypt the override cookie with different secrets within one evaluate() call.

Fix on Vercel

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