@vercel/flags-core 1.8.1-9d0e81e-20260908151858 → 1.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +20 -2
- package/README.md +2 -0
- package/dist/{chunk-YBQ6KBYF.js → chunk-5BWCBI7I.js} +211 -81
- package/dist/chunk-5BWCBI7I.js.map +1 -0
- package/dist/{chunk-FBO5VAQG.cjs → chunk-CKL562EU.cjs} +233 -103
- package/dist/chunk-CKL562EU.cjs.map +1 -0
- package/dist/{chunk-ODCCX6XB.cjs → chunk-CVDAHZHK.cjs} +233 -103
- package/dist/chunk-CVDAHZHK.cjs.map +1 -0
- package/dist/{chunk-CGPKLGRI.js → chunk-DYSF37WV.js} +211 -81
- package/dist/chunk-DYSF37WV.js.map +1 -0
- package/dist/index.default.cjs +2 -2
- package/dist/index.default.d.cts +14 -6
- package/dist/index.default.d.ts +14 -6
- package/dist/index.default.js +1 -1
- package/dist/index.next-js.cjs +2 -2
- package/dist/index.next-js.d.cts +14 -6
- package/dist/index.next-js.d.ts +14 -6
- package/dist/index.next-js.js +1 -1
- package/dist/openfeature.default.cjs +2 -2
- package/dist/openfeature.default.d.cts +1 -1
- package/dist/openfeature.default.d.ts +1 -1
- package/dist/openfeature.default.js +1 -1
- package/dist/openfeature.next-js.cjs +2 -2
- package/dist/openfeature.next-js.d.cts +1 -1
- package/dist/openfeature.next-js.d.ts +1 -1
- package/dist/openfeature.next-js.js +1 -1
- package/dist/{types-C2-sIv2D.d.cts → types-CIONStRG.d.cts} +87 -5
- package/dist/{types-C2-sIv2D.d.ts → types-CIONStRG.d.ts} +87 -5
- package/package.json +2 -1
- package/dist/chunk-CGPKLGRI.js.map +0 -1
- package/dist/chunk-FBO5VAQG.cjs.map +0 -1
- package/dist/chunk-ODCCX6XB.cjs.map +0 -1
- package/dist/chunk-YBQ6KBYF.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,10 +1,28 @@
|
|
|
1
1
|
# @vercel/flags-core
|
|
2
2
|
|
|
3
|
-
## 1.8.1
|
|
3
|
+
## 1.8.1
|
|
4
4
|
|
|
5
5
|
### Patch Changes
|
|
6
6
|
|
|
7
|
-
- [#
|
|
7
|
+
- [#486](https://github.com/vercel/flags/pull/486) [`c9d2811`](https://github.com/vercel/flags/commit/c9d28116ebca661f4e3c73f301d4b2d35310c823) Thanks [@dferber90](https://github.com/dferber90)! - Add APIs for reporting flag exposures and override values.
|
|
8
|
+
|
|
9
|
+
- The `experimental_reportExposures` client option for supplying an exposure
|
|
10
|
+
reporter.
|
|
11
|
+
- The `experimental_reportOverride` client method for reporting values set by
|
|
12
|
+
the Flags SDK override cookie.
|
|
13
|
+
- The `experimental_exposureLogging` option on `evaluate()` and
|
|
14
|
+
`bulkEvaluate()` for disabling exposure reporting for an individual call.
|
|
15
|
+
- Experiment assignment metadata on `EvaluationResult.experiment`.
|
|
16
|
+
- The `experimental_EvaluationOptions`,
|
|
17
|
+
`experimental_ExperimentAssignment`, `experimental_Exposure`, and
|
|
18
|
+
`experimental_ReportExposures` types.
|
|
19
|
+
|
|
20
|
+
These APIs are not supported for general use yet. Do not use them unless
|
|
21
|
+
Vercel has explicitly enabled them for you.
|
|
22
|
+
|
|
23
|
+
- [#494](https://github.com/vercel/flags/pull/494) [`e0eebe6`](https://github.com/vercel/flags/commit/e0eebe6fbc296636761eb3dc31f2c4be01a398bf) Thanks [@luismeyer](https://github.com/luismeyer)! - Request an uncompressed `/v1/stream` body when running on Bun.
|
|
24
|
+
|
|
25
|
+
Bun's `fetch` negotiates brotli or gzip by default, but its streaming decoder withholds small decoded output until more compressed input arrives. The stream's first datafile is followed by silence until the next ping, so on Bun the initial datafile never surfaced, init timed out, and every flag fell back to its default. Sending `Accept-Encoding: identity` on Bun avoids the decoder entirely; other runtimes are unchanged.
|
|
8
26
|
|
|
9
27
|
## 1.8.0
|
|
10
28
|
|
package/README.md
CHANGED
|
@@ -327,7 +327,43 @@ function getVariant(definition, index) {
|
|
|
327
327
|
variantId
|
|
328
328
|
};
|
|
329
329
|
}
|
|
330
|
-
function
|
|
330
|
+
function getWeightedVariantIndex(params, assignment, seed) {
|
|
331
|
+
const lhs = access(assignment.base, params);
|
|
332
|
+
if (typeof lhs !== "string") return assignment.defaultVariant;
|
|
333
|
+
const bucket = hashInput(lhs, seed);
|
|
334
|
+
const boundaries = getSplitBoundaries(assignment);
|
|
335
|
+
for (let index = 0; index < boundaries.length; index++) {
|
|
336
|
+
if (bucket < boundaries[index]) return index;
|
|
337
|
+
}
|
|
338
|
+
return assignment.defaultVariant;
|
|
339
|
+
}
|
|
340
|
+
function experimentAssignment(experiment, variantId, assignmentReason) {
|
|
341
|
+
if (variantId === null) return void 0;
|
|
342
|
+
return {
|
|
343
|
+
id: experiment.id,
|
|
344
|
+
variantId,
|
|
345
|
+
base: experiment.base,
|
|
346
|
+
rampId: experiment.rampId,
|
|
347
|
+
rampPercentage: experiment.rampPercentage,
|
|
348
|
+
assignmentReason
|
|
349
|
+
};
|
|
350
|
+
}
|
|
351
|
+
function outcomeAssignmentReason(outcome) {
|
|
352
|
+
if (typeof outcome === "number") return "variant";
|
|
353
|
+
switch (outcome.type) {
|
|
354
|
+
case "experiment":
|
|
355
|
+
return "experiment";
|
|
356
|
+
case "split":
|
|
357
|
+
return "split";
|
|
358
|
+
case "rollout":
|
|
359
|
+
return "rollout";
|
|
360
|
+
default: {
|
|
361
|
+
const { type } = outcome;
|
|
362
|
+
return exhaustivenessCheck(type);
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
function resolveOutcome(params, outcome) {
|
|
331
367
|
if (typeof outcome === "number") {
|
|
332
368
|
const variant = getVariant(params.definition, outcome);
|
|
333
369
|
return {
|
|
@@ -337,32 +373,48 @@ function handleOutcome(params, outcome) {
|
|
|
337
373
|
}
|
|
338
374
|
switch (outcome.type) {
|
|
339
375
|
case "split": {
|
|
340
|
-
const
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
376
|
+
const index = getWeightedVariantIndex(
|
|
377
|
+
params,
|
|
378
|
+
outcome,
|
|
379
|
+
params.definition.seed
|
|
344
380
|
);
|
|
345
|
-
if (typeof lhs !== "string") {
|
|
346
|
-
return {
|
|
347
|
-
...defaultOutcome,
|
|
348
|
-
outcomeType: "split" /* SPLIT */
|
|
349
|
-
};
|
|
350
|
-
}
|
|
351
|
-
const bucket = hashInput(lhs, params.definition.seed);
|
|
352
|
-
const boundaries = getSplitBoundaries(outcome);
|
|
353
|
-
for (let index = 0; index < boundaries.length; index++) {
|
|
354
|
-
if (bucket < boundaries[index]) {
|
|
355
|
-
return {
|
|
356
|
-
...getVariant(params.definition, index),
|
|
357
|
-
outcomeType: "split" /* SPLIT */
|
|
358
|
-
};
|
|
359
|
-
}
|
|
360
|
-
}
|
|
361
381
|
return {
|
|
362
|
-
...
|
|
382
|
+
...getVariant(params.definition, index),
|
|
363
383
|
outcomeType: "split" /* SPLIT */
|
|
364
384
|
};
|
|
365
385
|
}
|
|
386
|
+
case "experiment": {
|
|
387
|
+
const experiment = params.definition.experiment;
|
|
388
|
+
if (!experiment) {
|
|
389
|
+
throw new Error("@vercel/flags-core: Experiment not found");
|
|
390
|
+
}
|
|
391
|
+
const unitValue = access(experiment.base, params);
|
|
392
|
+
const defaultVariant = getVariant(
|
|
393
|
+
params.definition,
|
|
394
|
+
experiment.defaultVariant
|
|
395
|
+
);
|
|
396
|
+
const assignment = (variant, assignmentReason) => ({
|
|
397
|
+
...variant,
|
|
398
|
+
outcomeType: "experiment" /* EXPERIMENT */,
|
|
399
|
+
experiment: experimentAssignment(
|
|
400
|
+
experiment,
|
|
401
|
+
variant.variantId,
|
|
402
|
+
assignmentReason
|
|
403
|
+
)
|
|
404
|
+
});
|
|
405
|
+
if (typeof unitValue !== "string") {
|
|
406
|
+
return assignment(defaultVariant, "not-enrolled");
|
|
407
|
+
}
|
|
408
|
+
const rampPercentage = experiment.rampPercentage ?? 100;
|
|
409
|
+
const enrolled = rampPercentage >= 100 || rampPercentage > 0 && hashInput(unitValue, experiment.enrollmentSeed) < boundaryFor(rampPercentage, 100);
|
|
410
|
+
if (!enrolled) return assignment(defaultVariant, "not-enrolled");
|
|
411
|
+
const index = getWeightedVariantIndex(
|
|
412
|
+
params,
|
|
413
|
+
experiment,
|
|
414
|
+
params.definition.seed
|
|
415
|
+
);
|
|
416
|
+
return assignment(getVariant(params.definition, index), "experiment");
|
|
417
|
+
}
|
|
366
418
|
case "rollout": {
|
|
367
419
|
const lhs = access(outcome.base, params);
|
|
368
420
|
const defaultOutcome = getVariant(
|
|
@@ -435,6 +487,19 @@ function handleOutcome(params, outcome) {
|
|
|
435
487
|
}
|
|
436
488
|
}
|
|
437
489
|
}
|
|
490
|
+
function handleOutcome(params, outcome, assignmentReason) {
|
|
491
|
+
const result = resolveOutcome(params, outcome);
|
|
492
|
+
const experiment = params.definition.experiment;
|
|
493
|
+
if (!experiment || result.experiment) return result;
|
|
494
|
+
return {
|
|
495
|
+
...result,
|
|
496
|
+
experiment: experimentAssignment(
|
|
497
|
+
experiment,
|
|
498
|
+
result.variantId,
|
|
499
|
+
assignmentReason ?? outcomeAssignmentReason(outcome)
|
|
500
|
+
)
|
|
501
|
+
};
|
|
502
|
+
}
|
|
438
503
|
function evaluate(params, _visited) {
|
|
439
504
|
const envConfig = params.definition.environments[params.environment];
|
|
440
505
|
if (typeof envConfig === "number") {
|
|
@@ -474,7 +539,7 @@ function evaluate(params, _visited) {
|
|
|
474
539
|
(targetList) => matchTargetList(targetList, params)
|
|
475
540
|
);
|
|
476
541
|
if (matchedIndex > -1) {
|
|
477
|
-
return Object.assign(handleOutcome(params, matchedIndex), {
|
|
542
|
+
return Object.assign(handleOutcome(params, matchedIndex, "targeted"), {
|
|
478
543
|
reason: "target_match" /* TARGET_MATCH */
|
|
479
544
|
});
|
|
480
545
|
}
|
|
@@ -508,7 +573,7 @@ function bulkEvaluate(flags, shared) {
|
|
|
508
573
|
}
|
|
509
574
|
|
|
510
575
|
// package.json
|
|
511
|
-
var version = "1.8.1
|
|
576
|
+
var version = "1.8.1";
|
|
512
577
|
|
|
513
578
|
// src/lib/report-value.ts
|
|
514
579
|
function internalReportValue(key, value, data) {
|
|
@@ -727,6 +792,8 @@ async function bulkEvaluate2(id, flags, entities) {
|
|
|
727
792
|
}
|
|
728
793
|
|
|
729
794
|
// src/create-raw-client.ts
|
|
795
|
+
import { waitUntil } from "@vercel/functions";
|
|
796
|
+
import { dequal } from "dequal/lite";
|
|
730
797
|
var idCount = 0;
|
|
731
798
|
async function performInitialize(instance, initFn) {
|
|
732
799
|
try {
|
|
@@ -740,7 +807,8 @@ async function performInitialize(instance, initFn) {
|
|
|
740
807
|
function createCreateRawClient(fns) {
|
|
741
808
|
return function createRawClient({
|
|
742
809
|
controller,
|
|
743
|
-
origin
|
|
810
|
+
origin,
|
|
811
|
+
experimental_reportExposures
|
|
744
812
|
}) {
|
|
745
813
|
const id = idCount++;
|
|
746
814
|
controllerInstanceMap.set(id, {
|
|
@@ -748,6 +816,35 @@ function createCreateRawClient(fns) {
|
|
|
748
816
|
initialized: false,
|
|
749
817
|
initPromise: null
|
|
750
818
|
});
|
|
819
|
+
function report(exposures, entity) {
|
|
820
|
+
if (!experimental_reportExposures || exposures.length === 0) return;
|
|
821
|
+
const pending = (async () => {
|
|
822
|
+
try {
|
|
823
|
+
await experimental_reportExposures(exposures, entity);
|
|
824
|
+
} catch (error) {
|
|
825
|
+
console.error(
|
|
826
|
+
"@vercel/flags-core: Failed to report experiment exposures",
|
|
827
|
+
error
|
|
828
|
+
);
|
|
829
|
+
}
|
|
830
|
+
})();
|
|
831
|
+
try {
|
|
832
|
+
waitUntil(pending);
|
|
833
|
+
} catch {
|
|
834
|
+
}
|
|
835
|
+
}
|
|
836
|
+
function getExposure(flagKey, result) {
|
|
837
|
+
if (!result.experiment) return null;
|
|
838
|
+
return {
|
|
839
|
+
flagKey,
|
|
840
|
+
experimentId: result.experiment.id,
|
|
841
|
+
variantId: result.experiment.variantId,
|
|
842
|
+
base: result.experiment.base,
|
|
843
|
+
...result.experiment.rampId === void 0 ? {} : { rampId: result.experiment.rampId },
|
|
844
|
+
...result.experiment.rampPercentage === void 0 ? {} : { rampPercentage: result.experiment.rampPercentage },
|
|
845
|
+
assignmentReason: result.experiment.assignmentReason
|
|
846
|
+
};
|
|
847
|
+
}
|
|
751
848
|
const api = {
|
|
752
849
|
origin,
|
|
753
850
|
initialize: async () => {
|
|
@@ -782,7 +879,7 @@ function createCreateRawClient(fns) {
|
|
|
782
879
|
getFallbackDatafile: () => {
|
|
783
880
|
return fns.getFallbackDatafile(id);
|
|
784
881
|
},
|
|
785
|
-
evaluate: async (flagKey, defaultValue, entities) => {
|
|
882
|
+
evaluate: async (flagKey, defaultValue, entities, options) => {
|
|
786
883
|
const instance = controllerInstanceMap.get(id);
|
|
787
884
|
if (!instance?.initialized) {
|
|
788
885
|
try {
|
|
@@ -790,9 +887,22 @@ function createCreateRawClient(fns) {
|
|
|
790
887
|
} catch {
|
|
791
888
|
}
|
|
792
889
|
}
|
|
793
|
-
|
|
890
|
+
const entity = entities ?? {};
|
|
891
|
+
const result = await fns.evaluate(
|
|
892
|
+
id,
|
|
893
|
+
flagKey,
|
|
894
|
+
defaultValue,
|
|
895
|
+
entity
|
|
896
|
+
);
|
|
897
|
+
if (experimental_reportExposures && options?.experimental_exposureLogging !== false) {
|
|
898
|
+
const exposure = getExposure(flagKey, result);
|
|
899
|
+
if (exposure) {
|
|
900
|
+
report([exposure], entity);
|
|
901
|
+
}
|
|
902
|
+
}
|
|
903
|
+
return result;
|
|
794
904
|
},
|
|
795
|
-
bulkEvaluate: async (flags, entities) => {
|
|
905
|
+
bulkEvaluate: async (flags, entities, options) => {
|
|
796
906
|
const instance = controllerInstanceMap.get(id);
|
|
797
907
|
if (!instance?.initialized) {
|
|
798
908
|
try {
|
|
@@ -800,7 +910,61 @@ function createCreateRawClient(fns) {
|
|
|
800
910
|
} catch {
|
|
801
911
|
}
|
|
802
912
|
}
|
|
803
|
-
|
|
913
|
+
const entity = entities ?? {};
|
|
914
|
+
const results = await fns.bulkEvaluate(id, flags, entity);
|
|
915
|
+
if (experimental_reportExposures && options?.experimental_exposureLogging !== false) {
|
|
916
|
+
const exposures = [];
|
|
917
|
+
const seen = /* @__PURE__ */ new Set();
|
|
918
|
+
for (const flag of flags) {
|
|
919
|
+
if (seen.has(flag.key)) continue;
|
|
920
|
+
seen.add(flag.key);
|
|
921
|
+
const result = results[flag.key];
|
|
922
|
+
if (!result) continue;
|
|
923
|
+
const exposure = getExposure(flag.key, result);
|
|
924
|
+
if (exposure) exposures.push(exposure);
|
|
925
|
+
}
|
|
926
|
+
report(exposures, entity);
|
|
927
|
+
}
|
|
928
|
+
return results;
|
|
929
|
+
},
|
|
930
|
+
experimental_reportOverride: async ({
|
|
931
|
+
key,
|
|
932
|
+
value,
|
|
933
|
+
entities
|
|
934
|
+
}) => {
|
|
935
|
+
if (!experimental_reportExposures) return;
|
|
936
|
+
try {
|
|
937
|
+
const instance = controllerInstanceMap.get(id);
|
|
938
|
+
if (!instance?.initialized) await api.initialize();
|
|
939
|
+
const datafile = await fns.getDatafile(id);
|
|
940
|
+
const definition = datafile.definitions[key];
|
|
941
|
+
const experiment = definition?.experiment;
|
|
942
|
+
if (!experiment) return;
|
|
943
|
+
const variantIndex = definition.variants.findIndex(
|
|
944
|
+
(variant) => dequal(variant, value)
|
|
945
|
+
);
|
|
946
|
+
const variantId = variantIndex < 0 ? null : definition.variantIds?.[variantIndex] ?? null;
|
|
947
|
+
const entity = entities ?? {};
|
|
948
|
+
report(
|
|
949
|
+
[
|
|
950
|
+
{
|
|
951
|
+
flagKey: key,
|
|
952
|
+
experimentId: experiment.id,
|
|
953
|
+
variantId,
|
|
954
|
+
base: experiment.base,
|
|
955
|
+
rampId: experiment.rampId,
|
|
956
|
+
rampPercentage: experiment.rampPercentage,
|
|
957
|
+
assignmentReason: "override"
|
|
958
|
+
}
|
|
959
|
+
],
|
|
960
|
+
entity
|
|
961
|
+
);
|
|
962
|
+
} catch (error) {
|
|
963
|
+
console.error(
|
|
964
|
+
"@vercel/flags-core: Failed to report experiment override",
|
|
965
|
+
error
|
|
966
|
+
);
|
|
967
|
+
}
|
|
804
968
|
}
|
|
805
969
|
};
|
|
806
970
|
return api;
|
|
@@ -881,17 +1045,6 @@ function getJitteredWaitMs(baseMs, ratio) {
|
|
|
881
1045
|
return Math.floor(min + Math.random() * span);
|
|
882
1046
|
}
|
|
883
1047
|
|
|
884
|
-
// src/utils/runtime-ingest.ts
|
|
885
|
-
var FLAGS_CONTEXT_SYMBOL = /* @__PURE__ */ Symbol.for("@vercel/flags-context");
|
|
886
|
-
function getRuntimeIngest() {
|
|
887
|
-
try {
|
|
888
|
-
const context = globalThis[FLAGS_CONTEXT_SYMBOL];
|
|
889
|
-
return typeof context?.ingest === "function" ? context.ingest : void 0;
|
|
890
|
-
} catch {
|
|
891
|
-
return void 0;
|
|
892
|
-
}
|
|
893
|
-
}
|
|
894
|
-
|
|
895
1048
|
// src/utils/ingest.ts
|
|
896
1049
|
var MAX_RETRIES = 3;
|
|
897
1050
|
var MAX_EVENTS_PER_REQUEST = 2e3;
|
|
@@ -925,28 +1078,8 @@ async function getIngestHeaders(options, flushReason) {
|
|
|
925
1078
|
...isDebugMode ? { "x-vercel-debug-ingest": "1" } : null
|
|
926
1079
|
};
|
|
927
1080
|
}
|
|
928
|
-
function getRuntimeIngestHeaders(options, flushReason) {
|
|
929
|
-
return {
|
|
930
|
-
"Content-Type": "application/json",
|
|
931
|
-
...options.auth.sdkKey ? { Authorization: `Bearer ${options.auth.sdkKey}` } : null,
|
|
932
|
-
"User-Agent": `VercelFlagsCore/${version}`,
|
|
933
|
-
[FLUSH_REASON_HEADER]: flushReason,
|
|
934
|
-
...options.metricEnvironment ?? process.env.VERCEL_ENV ? {
|
|
935
|
-
"X-Vercel-Env": options.metricEnvironment ?? process.env.VERCEL_ENV
|
|
936
|
-
} : null,
|
|
937
|
-
...isDebugMode ? { "x-vercel-debug-ingest": "1" } : null
|
|
938
|
-
};
|
|
939
|
-
}
|
|
940
1081
|
async function sendIngestEvents(options, events, flushId, flushReason) {
|
|
941
|
-
|
|
942
|
-
const runtimeIngest = getRuntimeIngest();
|
|
943
|
-
if (runtimeIngest) {
|
|
944
|
-
const headers = getRuntimeIngestHeaders(options, flushReason);
|
|
945
|
-
eventsToSend = eventsToSend.filter(
|
|
946
|
-
(event) => !runtimeIngest({ headers, body: [event] })
|
|
947
|
-
);
|
|
948
|
-
if (eventsToSend.length === 0) return;
|
|
949
|
-
}
|
|
1082
|
+
const eventsToSend = events.map((event) => event.ingestEvent());
|
|
950
1083
|
for (let i = 0; i < eventsToSend.length; i += MAX_EVENTS_PER_REQUEST) {
|
|
951
1084
|
await sendIngestChunk(
|
|
952
1085
|
options,
|
|
@@ -1010,7 +1143,7 @@ function getRequestContext() {
|
|
|
1010
1143
|
}
|
|
1011
1144
|
|
|
1012
1145
|
// src/utils/scheduler.ts
|
|
1013
|
-
import { waitUntil } from "@vercel/functions";
|
|
1146
|
+
import { waitUntil as waitUntil2 } from "@vercel/functions";
|
|
1014
1147
|
var IDLE_FLUSH_WAIT_MS = 5e3;
|
|
1015
1148
|
var IDLE_FLUSH_JITTER_RATIO = 0.2;
|
|
1016
1149
|
var MAX_FLUSH_WAIT_MS = 6e4;
|
|
@@ -1033,7 +1166,7 @@ var Scheduler = class {
|
|
|
1033
1166
|
await this.onFlush(reason);
|
|
1034
1167
|
})();
|
|
1035
1168
|
try {
|
|
1036
|
-
|
|
1169
|
+
waitUntil2(this.pending);
|
|
1037
1170
|
} catch {
|
|
1038
1171
|
}
|
|
1039
1172
|
this.maxTimeout = setTimeout(
|
|
@@ -1205,7 +1338,7 @@ var UsageTracker = class {
|
|
|
1205
1338
|
if (this.trackedRequests.has(ctx)) return;
|
|
1206
1339
|
this.trackedRequests.add(ctx);
|
|
1207
1340
|
this.readEvents.push(new FlagsConfigReadEvent(headers, options));
|
|
1208
|
-
this.
|
|
1341
|
+
this.scheduler.scheduleFlush();
|
|
1209
1342
|
} catch (error) {
|
|
1210
1343
|
console.error("@vercel/flags-core: Failed to record event:", error);
|
|
1211
1344
|
}
|
|
@@ -1229,7 +1362,7 @@ var UsageTracker = class {
|
|
|
1229
1362
|
new FlagsEvaluationEvent(bucketedOptions)
|
|
1230
1363
|
);
|
|
1231
1364
|
}
|
|
1232
|
-
this.
|
|
1365
|
+
this.scheduler.scheduleFlush();
|
|
1233
1366
|
} catch (error) {
|
|
1234
1367
|
console.error(
|
|
1235
1368
|
"@vercel/flags-core: Failed to record evaluation event:",
|
|
@@ -1237,19 +1370,6 @@ var UsageTracker = class {
|
|
|
1237
1370
|
);
|
|
1238
1371
|
}
|
|
1239
1372
|
}
|
|
1240
|
-
/**
|
|
1241
|
-
* Flushes immediately when the runtime provides an ingest transport,
|
|
1242
|
-
* otherwise falls back to the time-based scheduler.
|
|
1243
|
-
*/
|
|
1244
|
-
requestFlush() {
|
|
1245
|
-
if (getRuntimeIngest()) {
|
|
1246
|
-
void this.flushEvents("immediate").catch((error) => {
|
|
1247
|
-
console.error("@vercel/flags-core: Failed to flush events:", error);
|
|
1248
|
-
});
|
|
1249
|
-
} else {
|
|
1250
|
-
this.scheduler.scheduleFlush();
|
|
1251
|
-
}
|
|
1252
|
-
}
|
|
1253
1373
|
/**
|
|
1254
1374
|
* Send all events to the ingest service
|
|
1255
1375
|
*/
|
|
@@ -1501,6 +1621,11 @@ var PollingSource = class extends TypedEmitter {
|
|
|
1501
1621
|
}
|
|
1502
1622
|
};
|
|
1503
1623
|
|
|
1624
|
+
// src/utils/runtime.ts
|
|
1625
|
+
function isBun() {
|
|
1626
|
+
return typeof globalThis.Bun !== "undefined";
|
|
1627
|
+
}
|
|
1628
|
+
|
|
1504
1629
|
// src/utils/sleep.ts
|
|
1505
1630
|
function sleep(ms) {
|
|
1506
1631
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
@@ -1585,6 +1710,9 @@ async function connectStream(config, callbacks) {
|
|
|
1585
1710
|
"User-Agent": `VercelFlagsCore/${version}`,
|
|
1586
1711
|
"X-Retry-Attempt": String(retryCount)
|
|
1587
1712
|
};
|
|
1713
|
+
if (isBun()) {
|
|
1714
|
+
headers["Accept-Encoding"] = "identity";
|
|
1715
|
+
}
|
|
1588
1716
|
const vercelEnv = process.env.VERCEL_ENV;
|
|
1589
1717
|
if (vercelEnv) {
|
|
1590
1718
|
headers["X-Vercel-Env"] = vercelEnv;
|
|
@@ -2489,11 +2617,13 @@ function make(createRawClient) {
|
|
|
2489
2617
|
const optionsOnly = typeof sdkKeyOrConnectionStringOrOptions === "object" && sdkKeyOrConnectionStringOrOptions !== null;
|
|
2490
2618
|
const sdkKeyOrConnectionString = optionsOnly ? void 0 : sdkKeyOrConnectionStringOrOptions;
|
|
2491
2619
|
const createClientOptions = optionsOnly ? sdkKeyOrConnectionStringOrOptions : options;
|
|
2620
|
+
const { experimental_reportExposures, ...controllerOptions } = createClientOptions ?? {};
|
|
2492
2621
|
const auth = new Authentication(sdkKeyOrConnectionString);
|
|
2493
|
-
const controller = new Controller({ auth, ...
|
|
2622
|
+
const controller = new Controller({ auth, ...controllerOptions });
|
|
2494
2623
|
return createRawClient({
|
|
2495
2624
|
controller,
|
|
2496
|
-
origin: { provider: "vercel", sdkKey: auth.sdkKey }
|
|
2625
|
+
origin: { provider: "vercel", sdkKey: auth.sdkKey },
|
|
2626
|
+
...experimental_reportExposures ? { experimental_reportExposures } : {}
|
|
2497
2627
|
});
|
|
2498
2628
|
}
|
|
2499
2629
|
function resetDefaultFlagsClient2() {
|
|
@@ -2543,4 +2673,4 @@ export {
|
|
|
2543
2673
|
resetDefaultFlagsClient,
|
|
2544
2674
|
createClient
|
|
2545
2675
|
};
|
|
2546
|
-
//# sourceMappingURL=chunk-
|
|
2676
|
+
//# sourceMappingURL=chunk-5BWCBI7I.js.map
|