Lifts the per-request evaluation pipeline into src/shared/ and points both
frameworks at it, so behavior is defined once. The Next-specific
isInternalNextError check becomes an injected `isFrameworkError` hook on
applyResult (Next passes it; SvelteKit defaults to none).
- shared/evaluation.ts: evaluationCache (+ getUsedFlags accessor), getEntities
+ identify-args dedupe, and applyResult (cache -> override -> produce ->
defaultValue/error -> report).
- shared/flag-meta.ts: resolveAdapter, getDecide (with adapter validation),
getIdentify, getOrigin.
SvelteKit's flag() now runs through this pipeline. This is a behavior change
that brings it to parity with Next — SvelteKit now:
- falls back to defaultValue when decide throws or returns undefined
- honors config.reportValue / adapter.config.reportValue
- resolves adapter.origin (value or (key) => origin)
- dedupes evaluation via the shared headers-keyed cache (replacing the
per-store usedFlags/identifiers maps); createHandle's transformPageChunk
reads used flags via getUsedFlags()
- getProviderData emits defaultValue + declaredInCode
Adds `defaultValue?` to the SvelteKit Flag type (additive) and 9 parity tests.
Next's public .d.ts is unchanged.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Both flags/next and flags/sveltekit implemented the same flag pipeline
twice and had drifted. This lifts the parts that are framework-agnostic
(or trivially so) into src/shared/, with each framework keeping thin
wrappers for its differences. Zero public API change — the generated
.d.ts for flags, flags/next and flags/sveltekit are byte-identical.
- shared/seal.ts: sealHeaders/sealCookies/transformToHeaders
(was duplicated in next/evaluate.ts and sveltekit/index.ts)
- shared/overrides.ts: readOverrides + memoized decrypt; SvelteKit now
gets the override memoization Next already had. Removes next/overrides.ts.
- shared/precompute.ts: combine/serialize/deserialize/generatePermutations
+ getPrecomputed core. Frameworks keep wrappers for secret defaulting
and the getPrecomputed(flag) vs getPrecomputed(key) signatures.
- shared/discovery.ts: shared authorize -> 401-or-data -> version-header
control flow behind createFlagsDiscoveryEndpoint.
Named "shared" rather than "core" to avoid confusion with the separate
@vercel/flags-core package.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* Allow passing an adapter factory directly to flag()
flag() now accepts the adapter factory by reference (`adapter: vercelAdapter`)
as a shorthand for calling it (`adapter: vercelAdapter()`). The factory is
resolved once per declaration; passing an instance keeps working. Applies to
both the Next.js and SvelteKit entrypoints.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* [@flags-sdk/vercel] reuse adapter instance
* reword changeset
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* use __no_flags__ to handle precompute with empty flags
* handle __no_flags__ in serialize
* add __no_flags__ handling to sveltekit
* avoid returning undefined when defaultValue is set
This could only happen on precomputed flags in case of bad usage.
* add error messages
* test console logs
* update changeset
* use `$env/dynamic/private` from SvelteKit for convenience: people don't have to pass FLAGS_SECRET manually anymore then
* allow flag to be called outside of the lifecycle of the handle hook, with a request object being the key for deduplication etc
* add support for identifiers
* fix types
* new function for managing precomputed flags
* align with next.js API instead
* update example app
* lockfile
* test
* fix example
* restructure examples app
* make it two flags to show power of precompute + code
* add manual approach
* lets see if preview deployment is picked up
* change crypto usage to be usable in middleware
* make sveltekit flags pkg usable within edge middleware
* use ISR
* changeset
* enhance error message
* use static env instead of dynamic env
* bump kit
* use vercel adapter
* make sure Vite tooling is used for sveltekit entry point
---------
Co-authored-by: Dominik Ferber <dominik.ferber@gmail.com>
* Create LaunchDarkly adapter
* Update example to include a LaunchDarkly flag
* Add missing env to turbo
* Rename to defaultLaunchDarklyAdapter
* Add winter sale example for providers
* Update winter-sale
* Document usage in readme
* Allow to set the default value through the adapter
* Fix readme
* Add default value for adapter
* Make argument optional
* Add @ts-expect-error
* Add a LaunchDarkly adapter (#10)
* add ld example
* reword
* remove winter-sale example
* remove defaultValue
* use @flags-sdk/launchdarkly
* add install steps
* add changeset
* move @vercel/edge-config to peer deps
* add more secrets
* spell out name
* remove unused env var
* rename properties
* Capitalize
* Change import
* Fix more imports
* expose ldClient
* move peerDeps to real deps
* clarify Edge Config requirement in README
* remove adapter-launchdarkly snippet
* upgrade next@canary
* polish @flags-sdk/launchdarkly README
---------
Co-authored-by: Dominik Ferber <dominik.ferber@gmail.com>
* throw when decide returns undefined
* throw on undefined unless defaultValue is defined
* wip
* bring back JsonValue
* do not enforce on typescript level for now
* add changeset
* mention exported types
* add precise types
* fix summer-sale example