* [adapter-launchdarkly] support native Marketplace integration
- Read the Edge Config connection string from EXPERIMENTATION_CONFIG,
falling back to EDGE_CONFIG for the legacy Vercel integration
- Make LAUNCHDARKLY_PROJECT_SLUG / projectSlug optional; it is only used
to deep-link flags to the LaunchDarkly dashboard
* [adapter-launchdarkly] read EXPERIMENTATION_CONFIG only
Align with the Statsig adapter: the default adapter reads the Edge Config
connection string from EXPERIMENTATION_CONFIG only and no longer falls back
to EDGE_CONFIG. Legacy Vercel integration users can set EXPERIMENTATION_CONFIG
to their EDGE_CONFIG value or pass edgeConfigConnectionString explicitly.
* [adapter-launchdarkly] mark changeset as major (breaking change)
* Update changelog to have a single recommendation for legacy EDGE_CONFIG env var
* Bring back LAUNCHDARKLY_PROJECT_SLUG as required
* Add FLAGS_EVALUATION metric
* Track variant IDs in evaluation results
* report null instead of fallback
* bucket to the previous minute
* replace variant null with undefined
* invert
* use option instead of env var
* Add track option to black-box flag tests
* Add evaluation metrics controls and flush reasons
* increase max_count
* defaul track:true
* increase batch
* Bound ingest POSTs to 2000 events per request
Flushes can overshoot the scheduler's MAX_COUNT because the map read
happens in a microtask, so a single POST could exceed the server-side
maxItems cap and be rejected with a 400. Chunk sendIngestEvents so each
POST carries at most MAX_EVENTS_PER_REQUEST events.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* Remove count-based flushing from the scheduler
Flushing is now purely time-based (idle window, max window, shutdown).
Batches are only cut down to size when the ingest events are sent, via
the 2000-event chunking in sendIngestEvents, which keeps every POST
below the server-side maxItems cap.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* cleanup
---------
Co-authored-by: Claude Fable 5 <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>
Replace the deterministic 100/200ms retry schedule with full-jitter exponential
backoff, jitter MAX_BATCH_WAIT_MS by ±20% to desynchronize concurrent flushes,
and log when a flush exhausts all retries.
Helpers extracted to utils/backoff.ts so they can be reused.
Co-authored-by: Cursor <cursoragent@cursor.com>
The SDK key validation now uses a regex (/^vf_(?:server|client)_/) to require
the format vf_server_* or vf_client_* instead of accepting any string starting
with vf_. This prevents false positives with third-party service identifiers
that happen to start with vf_ (e.g., Stripe identity flow IDs like
vf_1PyHgVLpWuMxVFx...).
Adds isValidSdkKey() helper function and updates parseSdkKeyFromFlagsConnectionString()
to use the stricter validation. Updates all tests to use valid SDK key formats.
* 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
* Return meaningful result from prepareFlagsDefinitions
- Add PrepareFlagsDefinitionsResult discriminated union type that indicates whether definitions were created
- Change prepareFlagsDefinitions return type from Promise<void> to Promise<PrepareFlagsDefinitionsResult>
- Return { created: false, reason: 'no-sdk-keys' } when no SDK keys are found
- Return { created: true, sdkKeysCount: N } when definitions are successfully created
- Add tests for both return paths to verify the function communicates its result properly
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
* Add changeset for prepareFlagsDefinitions result type
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Haiku 4.5 <noreply@anthropic.com>
* Replace version param with userAgentSuffix in prepare-flags-definitions
Changed the API to use a cleaner approach:
- Removed `version?: string` option in favor of `userAgentSuffix?: string`
- Now imports package version directly from package.json
- Constructs user-agent as: `@vercel/prepare-flags-definitions/{pkgVersion} {suffix}`
- Allows consumers (e.g., vercel-cli, vercel-api) to add context to the header
Added tests verifying both default and suffixed user-agent headers.
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
* add changeset
---------
Co-authored-by: Claude Haiku 4.5 <noreply@anthropic.com>
* Extract @vercel/prepare-flags-definitions package
Extract the core flag definitions preparation logic from the Vercel CLI into a standalone, reusable package. This includes:
- prepareFlagsDefinitions() function that collects SDK keys from env, fetches definitions, and writes to node_modules
- hashSdkKey() helper for SHA-256 hashing
- generateDefinitionsModule() for JS module generation with deduplication and lazy parsing
Follows repo conventions: pnpm workspaces, tsup, vitest, ES modules with CJS fallback.
* Add JSDoc comments from original CLI source
* Add inline comments from original CLI source
* Add optional output parameter with debug logging
* Add output.time for datafile fetching
* Add changeset for @vercel/prepare-flags-definitions