@vercel/flags-core 1.5.1 → 1.6.0-7d29945-20260616152249
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 +3 -9
- package/dist/{chunk-JTIP7QPD.cjs → chunk-LPIUDLYE.cjs} +488 -254
- package/dist/chunk-LPIUDLYE.cjs.map +1 -0
- package/dist/{chunk-AXRUQULC.cjs → chunk-NHWFZTK2.cjs} +487 -253
- package/dist/chunk-NHWFZTK2.cjs.map +1 -0
- package/dist/{chunk-ITF6ZJ32.js → chunk-PSYHUXJC.js} +433 -199
- package/dist/chunk-PSYHUXJC.js.map +1 -0
- package/dist/{chunk-4B7CLR4J.js → chunk-S62BO7JU.js} +433 -199
- package/dist/chunk-S62BO7JU.js.map +1 -0
- package/dist/index.default.cjs +2 -2
- package/dist/index.default.d.cts +18 -3
- package/dist/index.default.d.ts +18 -3
- package/dist/index.default.js +1 -1
- package/dist/index.next-js.cjs +2 -2
- package/dist/index.next-js.d.cts +18 -3
- package/dist/index.next-js.d.ts +18 -3
- package/dist/index.next-js.js +1 -1
- package/dist/openfeature.default.cjs +2 -2
- package/dist/openfeature.default.js +1 -1
- package/dist/openfeature.next-js.cjs +2 -2
- package/dist/openfeature.next-js.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-4B7CLR4J.js.map +0 -1
- package/dist/chunk-AXRUQULC.cjs.map +0 -1
- package/dist/chunk-ITF6ZJ32.js.map +0 -1
- package/dist/chunk-JTIP7QPD.cjs.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } var _class; var _class2; var _class3;var __defProp = Object.defineProperty;
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } var _class; var _class2; var _class3; var _class4; var _class5;var __defProp = Object.defineProperty;
|
|
2
2
|
var __export = (target, all) => {
|
|
3
3
|
for (var name in all)
|
|
4
4
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -50,6 +50,22 @@ var MAX_REGEX_INPUT_LENGTH = 1e4;
|
|
|
50
50
|
var UINT32_MAX = 4294967295;
|
|
51
51
|
var SCALED_WEIGHTS = /* @__PURE__ */ Symbol("@vercel/flags-core:scaledWeights");
|
|
52
52
|
var COMPILED_REGEX = /* @__PURE__ */ Symbol("@vercel/flags-core:compiledRegex");
|
|
53
|
+
var EVALUATION_VARIANT_INDEX = /* @__PURE__ */ Symbol(
|
|
54
|
+
"@vercel/flags-core:evaluationVariantIndex"
|
|
55
|
+
);
|
|
56
|
+
function withVariantIndex(value, outcomeType, variantIndex) {
|
|
57
|
+
return Object.defineProperty(
|
|
58
|
+
{
|
|
59
|
+
value,
|
|
60
|
+
outcomeType
|
|
61
|
+
},
|
|
62
|
+
EVALUATION_VARIANT_INDEX,
|
|
63
|
+
{ value: variantIndex }
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
function getEvaluationVariantIndex(result) {
|
|
67
|
+
return result[EVALUATION_VARIANT_INDEX];
|
|
68
|
+
}
|
|
53
69
|
function getScaledWeights(outcome) {
|
|
54
70
|
const cached = outcome[SCALED_WEIGHTS];
|
|
55
71
|
if (cached) return cached;
|
|
@@ -313,10 +329,11 @@ function getVariant(variants, index) {
|
|
|
313
329
|
}
|
|
314
330
|
function handleOutcome(params, outcome) {
|
|
315
331
|
if (typeof outcome === "number") {
|
|
316
|
-
return
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
332
|
+
return withVariantIndex(
|
|
333
|
+
getVariant(params.definition.variants, outcome),
|
|
334
|
+
"value" /* VALUE */,
|
|
335
|
+
outcome
|
|
336
|
+
);
|
|
320
337
|
}
|
|
321
338
|
switch (outcome.type) {
|
|
322
339
|
case "split": {
|
|
@@ -326,15 +343,21 @@ function handleOutcome(params, outcome) {
|
|
|
326
343
|
outcome.defaultVariant
|
|
327
344
|
);
|
|
328
345
|
if (typeof lhs !== "string") {
|
|
329
|
-
return
|
|
346
|
+
return withVariantIndex(
|
|
347
|
+
defaultOutcome,
|
|
348
|
+
"split" /* SPLIT */,
|
|
349
|
+
outcome.defaultVariant
|
|
350
|
+
);
|
|
330
351
|
}
|
|
331
352
|
const value = _jsxxhash.xxHash32.call(void 0, lhs, params.definition.seed);
|
|
332
353
|
const scaledWeights = getScaledWeights(outcome);
|
|
333
354
|
const variantIndex = findWeightedIndex(scaledWeights, value, UINT32_MAX);
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
355
|
+
const selectedVariantIndex = variantIndex === -1 ? outcome.defaultVariant : variantIndex;
|
|
356
|
+
return withVariantIndex(
|
|
357
|
+
selectedVariantIndex === outcome.defaultVariant ? defaultOutcome : getVariant(params.definition.variants, selectedVariantIndex),
|
|
358
|
+
"split" /* SPLIT */,
|
|
359
|
+
selectedVariantIndex
|
|
360
|
+
);
|
|
338
361
|
}
|
|
339
362
|
case "rollout": {
|
|
340
363
|
const lhs = access(outcome.base, params);
|
|
@@ -343,18 +366,20 @@ function handleOutcome(params, outcome) {
|
|
|
343
366
|
outcome.defaultVariant
|
|
344
367
|
);
|
|
345
368
|
if (typeof lhs !== "string") {
|
|
346
|
-
return
|
|
369
|
+
return withVariantIndex(
|
|
370
|
+
defaultOutcome,
|
|
371
|
+
"rollout" /* ROLLOUT */,
|
|
372
|
+
outcome.defaultVariant
|
|
373
|
+
);
|
|
347
374
|
}
|
|
348
375
|
const now = Date.now();
|
|
349
376
|
const elapsed = now - outcome.startTimestamp;
|
|
350
377
|
if (elapsed < 0 || outcome.slots.length === 0) {
|
|
351
|
-
return
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
outcomeType: "rollout" /* ROLLOUT */
|
|
357
|
-
};
|
|
378
|
+
return withVariantIndex(
|
|
379
|
+
getVariant(params.definition.variants, outcome.rollFromVariant),
|
|
380
|
+
"rollout" /* ROLLOUT */,
|
|
381
|
+
outcome.rollFromVariant
|
|
382
|
+
);
|
|
358
383
|
}
|
|
359
384
|
let cumulativeDuration = 0;
|
|
360
385
|
let currentPromille = 0;
|
|
@@ -369,32 +394,27 @@ function handleOutcome(params, outcome) {
|
|
|
369
394
|
}
|
|
370
395
|
if (exhausted) currentPromille = 1e5;
|
|
371
396
|
if (currentPromille <= 0) {
|
|
372
|
-
return
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
outcomeType: "rollout" /* ROLLOUT */
|
|
378
|
-
};
|
|
397
|
+
return withVariantIndex(
|
|
398
|
+
getVariant(params.definition.variants, outcome.rollFromVariant),
|
|
399
|
+
"rollout" /* ROLLOUT */,
|
|
400
|
+
outcome.rollFromVariant
|
|
401
|
+
);
|
|
379
402
|
}
|
|
380
403
|
if (currentPromille >= 1e5) {
|
|
381
|
-
return
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
outcomeType: "rollout" /* ROLLOUT */
|
|
387
|
-
};
|
|
404
|
+
return withVariantIndex(
|
|
405
|
+
getVariant(params.definition.variants, outcome.rollToVariant),
|
|
406
|
+
"rollout" /* ROLLOUT */,
|
|
407
|
+
outcome.rollToVariant
|
|
408
|
+
);
|
|
388
409
|
}
|
|
389
410
|
const value = _jsxxhash.xxHash32.call(void 0, lhs, params.definition.seed);
|
|
390
411
|
const threshold = currentPromille / 1e5 * UINT32_MAX;
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
};
|
|
412
|
+
const selectedVariantIndex = value < threshold ? outcome.rollToVariant : outcome.rollFromVariant;
|
|
413
|
+
return withVariantIndex(
|
|
414
|
+
getVariant(params.definition.variants, selectedVariantIndex),
|
|
415
|
+
"rollout" /* ROLLOUT */,
|
|
416
|
+
selectedVariantIndex
|
|
417
|
+
);
|
|
398
418
|
}
|
|
399
419
|
default: {
|
|
400
420
|
const { type } = outcome;
|
|
@@ -482,7 +502,7 @@ function findWeightedIndex(weights, value, maxValue) {
|
|
|
482
502
|
}
|
|
483
503
|
|
|
484
504
|
// package.json
|
|
485
|
-
var version = "1.
|
|
505
|
+
var version = "1.6.0-7d29945-20260616152249";
|
|
486
506
|
|
|
487
507
|
// src/lib/report-value.ts
|
|
488
508
|
function internalReportValue(key, value, data) {
|
|
@@ -521,6 +541,14 @@ function getFallbackDatafile(id) {
|
|
|
521
541
|
if (ds.getFallbackDatafile) return ds.getFallbackDatafile();
|
|
522
542
|
throw new Error("flags: This data source does not support fallbacks");
|
|
523
543
|
}
|
|
544
|
+
function getVariantIdentifier(definition, result) {
|
|
545
|
+
const variantIndex = getEvaluationVariantIndex(result);
|
|
546
|
+
if (variantIndex === void 0) return "unknown";
|
|
547
|
+
return _nullishCoalesce(_optionalChain([definition, 'access', _20 => _20.variantIds, 'optionalAccess', _21 => _21[variantIndex]]), () => ( String(variantIndex)));
|
|
548
|
+
}
|
|
549
|
+
function trackEvaluation(controller, options) {
|
|
550
|
+
_optionalChain([controller, 'access', _22 => _22.trackEvaluation, 'optionalCall', _23 => _23(options)]);
|
|
551
|
+
}
|
|
524
552
|
async function evaluate2(id, flagKey, defaultValue, entities) {
|
|
525
553
|
const controller = getInstance(id).controller;
|
|
526
554
|
let datafile;
|
|
@@ -528,11 +556,17 @@ async function evaluate2(id, flagKey, defaultValue, entities) {
|
|
|
528
556
|
datafile = await controller.read();
|
|
529
557
|
} catch (error) {
|
|
530
558
|
if (defaultValue !== void 0) {
|
|
531
|
-
|
|
559
|
+
const result2 = {
|
|
532
560
|
value: defaultValue,
|
|
533
561
|
reason: "error" /* ERROR */,
|
|
534
562
|
errorMessage: error instanceof Error ? error.message : "Failed to read datafile"
|
|
535
563
|
};
|
|
564
|
+
trackEvaluation(controller, {
|
|
565
|
+
flagKey,
|
|
566
|
+
variant: "unknown",
|
|
567
|
+
reason: result2.reason
|
|
568
|
+
});
|
|
569
|
+
return result2;
|
|
536
570
|
}
|
|
537
571
|
throw error;
|
|
538
572
|
}
|
|
@@ -545,7 +579,7 @@ async function evaluate2(id, flagKey, defaultValue, entities) {
|
|
|
545
579
|
reason: "error" /* ERROR */
|
|
546
580
|
});
|
|
547
581
|
}
|
|
548
|
-
|
|
582
|
+
const result2 = {
|
|
549
583
|
value: defaultValue,
|
|
550
584
|
reason: "error" /* ERROR */,
|
|
551
585
|
errorCode: "FLAG_NOT_FOUND" /* FLAG_NOT_FOUND */,
|
|
@@ -559,6 +593,12 @@ async function evaluate2(id, flagKey, defaultValue, entities) {
|
|
|
559
593
|
mode: datafile.metrics.mode
|
|
560
594
|
}
|
|
561
595
|
};
|
|
596
|
+
trackEvaluation(controller, {
|
|
597
|
+
flagKey,
|
|
598
|
+
variant: "unknown",
|
|
599
|
+
reason: result2.reason
|
|
600
|
+
});
|
|
601
|
+
return result2;
|
|
562
602
|
}
|
|
563
603
|
const evalStartTime = Date.now();
|
|
564
604
|
const result = evaluate({
|
|
@@ -577,6 +617,14 @@ async function evaluate2(id, flagKey, defaultValue, entities) {
|
|
|
577
617
|
outcomeType: result.reason !== "error" /* ERROR */ ? result.outcomeType : void 0
|
|
578
618
|
});
|
|
579
619
|
}
|
|
620
|
+
trackEvaluation(controller, {
|
|
621
|
+
flagKey,
|
|
622
|
+
variant: getVariantIdentifier(
|
|
623
|
+
flagDefinition,
|
|
624
|
+
result
|
|
625
|
+
),
|
|
626
|
+
reason: result.reason
|
|
627
|
+
});
|
|
580
628
|
return Object.assign(result, {
|
|
581
629
|
metrics: {
|
|
582
630
|
evaluationMs: evaluationDurationMs,
|
|
@@ -602,6 +650,11 @@ async function bulkEvaluate2(id, flags, entities) {
|
|
|
602
650
|
reason: "error" /* ERROR */,
|
|
603
651
|
errorMessage
|
|
604
652
|
};
|
|
653
|
+
trackEvaluation(controller, {
|
|
654
|
+
flagKey: flag.key,
|
|
655
|
+
variant: "unknown",
|
|
656
|
+
reason: "error" /* ERROR */
|
|
657
|
+
});
|
|
605
658
|
}
|
|
606
659
|
return results2;
|
|
607
660
|
}
|
|
@@ -633,6 +686,11 @@ async function bulkEvaluate2(id, flags, entities) {
|
|
|
633
686
|
errorMessage: `@vercel/flags-core: Definition not found for flag "${key}"`,
|
|
634
687
|
metrics: { evaluationMs: 0, ...baseMetrics }
|
|
635
688
|
};
|
|
689
|
+
trackEvaluation(controller, {
|
|
690
|
+
flagKey: key,
|
|
691
|
+
variant: "unknown",
|
|
692
|
+
reason: "error" /* ERROR */
|
|
693
|
+
});
|
|
636
694
|
continue;
|
|
637
695
|
}
|
|
638
696
|
toEvaluate[key] = { definition: flagDefinition, defaultValue };
|
|
@@ -654,6 +712,14 @@ async function bulkEvaluate2(id, flags, entities) {
|
|
|
654
712
|
outcomeType: result.reason !== "error" /* ERROR */ ? result.outcomeType : void 0
|
|
655
713
|
});
|
|
656
714
|
}
|
|
715
|
+
trackEvaluation(controller, {
|
|
716
|
+
flagKey: key,
|
|
717
|
+
variant: getVariantIdentifier(
|
|
718
|
+
toEvaluate[key].definition,
|
|
719
|
+
result
|
|
720
|
+
),
|
|
721
|
+
reason: result.reason
|
|
722
|
+
});
|
|
657
723
|
results[key] = Object.assign(result, {
|
|
658
724
|
metrics: { evaluationMs: evaluationDurationMs, ...baseMetrics }
|
|
659
725
|
});
|
|
@@ -706,7 +772,7 @@ function createCreateRawClient(fns) {
|
|
|
706
772
|
},
|
|
707
773
|
getDatafile: async () => {
|
|
708
774
|
const instance = controllerInstanceMap.get(id);
|
|
709
|
-
if (_optionalChain([instance, 'optionalAccess',
|
|
775
|
+
if (_optionalChain([instance, 'optionalAccess', _24 => _24.initPromise])) {
|
|
710
776
|
try {
|
|
711
777
|
await instance.initPromise;
|
|
712
778
|
} catch (e) {
|
|
@@ -719,7 +785,7 @@ function createCreateRawClient(fns) {
|
|
|
719
785
|
},
|
|
720
786
|
evaluate: async (flagKey, defaultValue, entities) => {
|
|
721
787
|
const instance = controllerInstanceMap.get(id);
|
|
722
|
-
if (!_optionalChain([instance, 'optionalAccess',
|
|
788
|
+
if (!_optionalChain([instance, 'optionalAccess', _25 => _25.initialized])) {
|
|
723
789
|
try {
|
|
724
790
|
await api.initialize();
|
|
725
791
|
} catch (e2) {
|
|
@@ -729,7 +795,7 @@ function createCreateRawClient(fns) {
|
|
|
729
795
|
},
|
|
730
796
|
bulkEvaluate: async (flags, entities) => {
|
|
731
797
|
const instance = controllerInstanceMap.get(id);
|
|
732
|
-
if (!_optionalChain([instance, 'optionalAccess',
|
|
798
|
+
if (!_optionalChain([instance, 'optionalAccess', _26 => _26.initialized])) {
|
|
733
799
|
try {
|
|
734
800
|
await api.initialize();
|
|
735
801
|
} catch (e3) {
|
|
@@ -798,8 +864,8 @@ async function readBundledDefinitions(auth) {
|
|
|
798
864
|
return { definitions: null, state: "missing-entry" };
|
|
799
865
|
}
|
|
800
866
|
|
|
801
|
-
// src/utils/
|
|
802
|
-
var
|
|
867
|
+
// src/utils/ingest.ts
|
|
868
|
+
var _oidc = require('@vercel/oidc');
|
|
803
869
|
|
|
804
870
|
// src/utils/backoff.ts
|
|
805
871
|
var DEFAULT_BASE_MS = 250;
|
|
@@ -810,64 +876,304 @@ function getRetryDelayMs(attempt, options = {}) {
|
|
|
810
876
|
const ceiling = Math.min(capMs, baseMs * 2 ** Math.max(0, attempt - 1));
|
|
811
877
|
return Math.floor(Math.random() * ceiling);
|
|
812
878
|
}
|
|
813
|
-
function getJitteredWaitMs(baseMs, ratio) {
|
|
814
|
-
const min = baseMs * (1 - ratio);
|
|
815
|
-
const span = baseMs * 2 * ratio;
|
|
816
|
-
return Math.floor(min + Math.random() * span);
|
|
817
|
-
}
|
|
818
879
|
|
|
819
|
-
// src/utils/
|
|
820
|
-
var
|
|
821
|
-
var
|
|
880
|
+
// src/utils/ingest.ts
|
|
881
|
+
var MAX_RETRIES = 3;
|
|
882
|
+
var EVALUATING_OIDC_TOKEN_HEADER = "X-Vercel-Flags-Evaluating-OIDC-Token";
|
|
883
|
+
var isDebugMode = _optionalChain([process, 'access', _27 => _27.env, 'access', _28 => _28.DEBUG, 'optionalAccess', _29 => _29.includes, 'call', _30 => _30("@vercel/flags-core")]);
|
|
822
884
|
var debugLog = (...args) => {
|
|
823
885
|
if (!isDebugMode) return;
|
|
824
886
|
console.log(...args);
|
|
825
887
|
};
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
888
|
+
async function getEvaluatingOidcToken(auth) {
|
|
889
|
+
if (!auth.sdkKey) return void 0;
|
|
890
|
+
try {
|
|
891
|
+
return await _oidc.getVercelOidcToken.call(void 0, );
|
|
892
|
+
} catch (e4) {
|
|
893
|
+
return void 0;
|
|
894
|
+
}
|
|
895
|
+
}
|
|
896
|
+
async function getIngestHeaders(options) {
|
|
897
|
+
const token = await options.auth.resolveToken();
|
|
898
|
+
const evaluatingOidcToken = await getEvaluatingOidcToken(options.auth);
|
|
899
|
+
return {
|
|
900
|
+
"Content-Type": "application/json",
|
|
901
|
+
Authorization: `Bearer ${token}`,
|
|
902
|
+
"User-Agent": `VercelFlagsCore/${version}`,
|
|
903
|
+
...process.env.VERCEL_ENV ? { "X-Vercel-Env": process.env.VERCEL_ENV } : null,
|
|
904
|
+
...evaluatingOidcToken ? { [EVALUATING_OIDC_TOKEN_HEADER]: evaluatingOidcToken } : null,
|
|
905
|
+
...isDebugMode ? { "x-vercel-debug-ingest": "1" } : null
|
|
906
|
+
};
|
|
907
|
+
}
|
|
908
|
+
async function sendIngestEvents(options, events, flushId) {
|
|
909
|
+
const eventsToSend = events.map((event) => event.ingestEvent());
|
|
910
|
+
for (let attempt = 1; attempt <= MAX_RETRIES; attempt++) {
|
|
911
|
+
try {
|
|
912
|
+
const response = await options.fetch(`${options.host}/v1/ingest`, {
|
|
913
|
+
method: "POST",
|
|
914
|
+
headers: await getIngestHeaders(options),
|
|
915
|
+
body: JSON.stringify(eventsToSend)
|
|
916
|
+
});
|
|
917
|
+
debugLog(
|
|
918
|
+
`@vercel/flags-core: Ingest response ${response.status} for ${eventsToSend.length} events on ${response.headers.get("x-vercel-id")}`
|
|
919
|
+
);
|
|
920
|
+
if (response.ok) {
|
|
921
|
+
break;
|
|
922
|
+
}
|
|
923
|
+
throw new Error(
|
|
924
|
+
`Ingest endpoint responded with status ${response.status} for ${eventsToSend.length} events on request ${response.headers.get("x-vercel-id")}.
|
|
925
|
+
Response body: ${await response.text().catch(() => null)}`
|
|
926
|
+
);
|
|
927
|
+
} catch (error) {
|
|
928
|
+
console.error(
|
|
929
|
+
`@vercel/flags-core: Error sending events (attempt=${attempt}/${MAX_RETRIES} flushId=${flushId}):`,
|
|
930
|
+
error
|
|
931
|
+
);
|
|
932
|
+
if (attempt < MAX_RETRIES) {
|
|
933
|
+
const delayMs = getRetryDelayMs(attempt);
|
|
934
|
+
await new Promise((res) => setTimeout(res, delayMs));
|
|
935
|
+
} else {
|
|
936
|
+
console.error(
|
|
937
|
+
`@vercel/flags-core: Dropped ${eventsToSend.length} events after ${MAX_RETRIES} attempts (flushId=${flushId})`
|
|
938
|
+
);
|
|
939
|
+
}
|
|
940
|
+
}
|
|
941
|
+
}
|
|
942
|
+
}
|
|
943
|
+
|
|
944
|
+
// src/utils/request-context.ts
|
|
830
945
|
var SYMBOL_FOR_REQ_CONTEXT = /* @__PURE__ */ Symbol.for("@vercel/request-context");
|
|
831
946
|
var fromSymbol = globalThis;
|
|
832
947
|
function getRequestContext() {
|
|
833
948
|
try {
|
|
834
|
-
const ctx = _optionalChain([fromSymbol, 'access',
|
|
949
|
+
const ctx = _optionalChain([fromSymbol, 'access', _31 => _31[SYMBOL_FOR_REQ_CONTEXT], 'optionalAccess', _32 => _32.get, 'optionalCall', _33 => _33()]);
|
|
835
950
|
if (ctx && Object.hasOwn(ctx, "headers")) {
|
|
836
951
|
return {
|
|
837
952
|
ctx,
|
|
838
953
|
headers: ctx.headers
|
|
839
954
|
};
|
|
840
955
|
}
|
|
841
|
-
return { ctx, headers: void 0 };
|
|
842
|
-
} catch (
|
|
956
|
+
return { ctx: void 0, headers: void 0 };
|
|
957
|
+
} catch (e5) {
|
|
843
958
|
return { ctx: void 0, headers: void 0 };
|
|
844
959
|
}
|
|
845
960
|
}
|
|
846
|
-
|
|
847
|
-
|
|
961
|
+
|
|
962
|
+
// src/utils/scheduler.ts
|
|
963
|
+
var _functions = require('@vercel/functions');
|
|
964
|
+
var MAX_COUNT = 50;
|
|
965
|
+
var IDLE_FLUSH_WAIT_MS = 5e3;
|
|
966
|
+
var MAX_FLUSH_WAIT_MS = 6e4;
|
|
967
|
+
var Scheduler = (_class = class {
|
|
968
|
+
constructor(onFlush) {;_class.prototype.__init.call(this);_class.prototype.__init2.call(this);_class.prototype.__init3.call(this);_class.prototype.__init4.call(this);_class.prototype.__init5.call(this);
|
|
969
|
+
this.onFlush = onFlush;
|
|
970
|
+
}
|
|
971
|
+
__init() {this.count = 0}
|
|
972
|
+
__init2() {this.resolveWait = null}
|
|
973
|
+
__init3() {this.pending = null}
|
|
974
|
+
__init4() {this.idleTimeout = null}
|
|
975
|
+
__init5() {this.maxTimeout = null}
|
|
976
|
+
increment() {
|
|
977
|
+
this.count += 1;
|
|
978
|
+
if (this.count >= MAX_COUNT) {
|
|
979
|
+
this.resolveScheduledFlush();
|
|
980
|
+
}
|
|
981
|
+
}
|
|
982
|
+
scheduleFlush() {
|
|
983
|
+
if (!this.pending) {
|
|
984
|
+
this.pending = (async () => {
|
|
985
|
+
await new Promise((res) => {
|
|
986
|
+
this.resolveWait = res;
|
|
987
|
+
});
|
|
988
|
+
this.reset();
|
|
989
|
+
await this.onFlush();
|
|
990
|
+
})();
|
|
991
|
+
try {
|
|
992
|
+
_functions.waitUntil.call(void 0, this.pending);
|
|
993
|
+
} catch (e6) {
|
|
994
|
+
}
|
|
995
|
+
this.maxTimeout = setTimeout(
|
|
996
|
+
() => this.resolveScheduledFlush(),
|
|
997
|
+
MAX_FLUSH_WAIT_MS
|
|
998
|
+
);
|
|
999
|
+
}
|
|
1000
|
+
this.resetIdleTimeout();
|
|
1001
|
+
}
|
|
1002
|
+
/**
|
|
1003
|
+
* Resolves any in-flight scheduled flush and waits for its ingest to finish.
|
|
1004
|
+
*/
|
|
1005
|
+
async shutdown() {
|
|
1006
|
+
this.clearTimeouts();
|
|
1007
|
+
const pending = this.pending;
|
|
1008
|
+
_optionalChain([this, 'access', _34 => _34.resolveWait, 'optionalCall', _35 => _35()]);
|
|
1009
|
+
if (pending) await pending;
|
|
1010
|
+
}
|
|
1011
|
+
resetIdleTimeout() {
|
|
1012
|
+
if (this.idleTimeout) clearTimeout(this.idleTimeout);
|
|
1013
|
+
this.idleTimeout = setTimeout(
|
|
1014
|
+
() => this.resolveScheduledFlush(),
|
|
1015
|
+
IDLE_FLUSH_WAIT_MS
|
|
1016
|
+
);
|
|
1017
|
+
}
|
|
1018
|
+
resolveScheduledFlush() {
|
|
1019
|
+
this.clearTimeouts();
|
|
1020
|
+
_optionalChain([this, 'access', _36 => _36.resolveWait, 'optionalCall', _37 => _37()]);
|
|
1021
|
+
}
|
|
1022
|
+
reset() {
|
|
1023
|
+
this.pending = null;
|
|
1024
|
+
this.resolveWait = null;
|
|
1025
|
+
this.count = 0;
|
|
1026
|
+
this.clearTimeouts();
|
|
1027
|
+
}
|
|
1028
|
+
clearTimeouts() {
|
|
1029
|
+
if (this.idleTimeout) {
|
|
1030
|
+
clearTimeout(this.idleTimeout);
|
|
1031
|
+
this.idleTimeout = null;
|
|
1032
|
+
}
|
|
1033
|
+
if (this.maxTimeout) {
|
|
1034
|
+
clearTimeout(this.maxTimeout);
|
|
1035
|
+
this.maxTimeout = null;
|
|
1036
|
+
}
|
|
1037
|
+
}
|
|
1038
|
+
}, _class);
|
|
1039
|
+
|
|
1040
|
+
// src/utils/usage/flags-config-read.ts
|
|
1041
|
+
var FlagsConfigReadEvent = class {
|
|
848
1042
|
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
1043
|
+
constructor(headers, options) {
|
|
1044
|
+
this.payload = {
|
|
1045
|
+
deploymentId: process.env.VERCEL_DEPLOYMENT_ID,
|
|
1046
|
+
region: process.env.VERCEL_REGION
|
|
1047
|
+
};
|
|
1048
|
+
if (headers) {
|
|
1049
|
+
this.payload.vercelRequestId = _nullishCoalesce(headers["x-vercel-id"], () => ( void 0));
|
|
1050
|
+
this.payload.invocationHost = _nullishCoalesce(headers.host, () => ( void 0));
|
|
1051
|
+
}
|
|
1052
|
+
if (options) {
|
|
1053
|
+
this.payload.configOrigin = options.configOrigin;
|
|
1054
|
+
if (options.cacheStatus !== void 0) {
|
|
1055
|
+
this.payload.cacheStatus = options.cacheStatus;
|
|
1056
|
+
}
|
|
1057
|
+
if (options.cacheAction !== void 0) {
|
|
1058
|
+
this.payload.cacheAction = options.cacheAction;
|
|
1059
|
+
}
|
|
1060
|
+
if (options.cacheIsFirstRead !== void 0) {
|
|
1061
|
+
this.payload.cacheIsFirstRead = options.cacheIsFirstRead;
|
|
1062
|
+
}
|
|
1063
|
+
if (options.cacheIsBlocking !== void 0) {
|
|
1064
|
+
this.payload.cacheIsBlocking = options.cacheIsBlocking;
|
|
1065
|
+
}
|
|
1066
|
+
if (options.duration !== void 0) {
|
|
1067
|
+
this.payload.duration = options.duration;
|
|
1068
|
+
}
|
|
1069
|
+
if (options.configUpdatedAt !== void 0) {
|
|
1070
|
+
this.payload.configUpdatedAt = options.configUpdatedAt;
|
|
1071
|
+
}
|
|
1072
|
+
if (options.mode !== void 0) {
|
|
1073
|
+
this.payload.mode = options.mode;
|
|
1074
|
+
}
|
|
1075
|
+
if (options.revision !== void 0) {
|
|
1076
|
+
this.payload.revision = String(options.revision);
|
|
1077
|
+
}
|
|
1078
|
+
}
|
|
1079
|
+
const environment = process.env.VERCEL_ENV || process.env.NODE_ENV || void 0;
|
|
1080
|
+
if (environment) {
|
|
1081
|
+
this.payload.environment = environment;
|
|
1082
|
+
}
|
|
1083
|
+
}
|
|
1084
|
+
ingestEvent() {
|
|
1085
|
+
return {
|
|
1086
|
+
type: "FLAGS_CONFIG_READ",
|
|
1087
|
+
ts: Date.now(),
|
|
1088
|
+
payload: this.payload
|
|
1089
|
+
};
|
|
1090
|
+
}
|
|
1091
|
+
};
|
|
1092
|
+
|
|
1093
|
+
// src/utils/usage/flags-evaluation.ts
|
|
1094
|
+
function evaluationBatchKey(options) {
|
|
1095
|
+
return JSON.stringify([
|
|
1096
|
+
options.flagKey,
|
|
1097
|
+
options.variant,
|
|
1098
|
+
options.reason,
|
|
1099
|
+
_nullishCoalesce(options.clientName, () => ( null))
|
|
1100
|
+
]);
|
|
1101
|
+
}
|
|
1102
|
+
var FlagsEvaluationEvent = class {
|
|
1103
|
+
|
|
1104
|
+
constructor(eventOptions) {
|
|
1105
|
+
this.payload = {
|
|
1106
|
+
flagKey: eventOptions.flagKey,
|
|
1107
|
+
variant: eventOptions.variant,
|
|
1108
|
+
reason: eventOptions.reason,
|
|
1109
|
+
count: 1
|
|
1110
|
+
};
|
|
1111
|
+
if (eventOptions.clientName) {
|
|
1112
|
+
this.payload.clientName = eventOptions.clientName;
|
|
1113
|
+
}
|
|
1114
|
+
Object.defineProperty(this, "batchKey", {
|
|
1115
|
+
value: JSON.stringify([
|
|
1116
|
+
this.payload.flagKey,
|
|
1117
|
+
this.payload.variant,
|
|
1118
|
+
this.payload.reason,
|
|
1119
|
+
_nullishCoalesce(this.payload.clientName, () => ( null))
|
|
1120
|
+
]),
|
|
1121
|
+
enumerable: false
|
|
1122
|
+
});
|
|
1123
|
+
}
|
|
1124
|
+
increment() {
|
|
1125
|
+
this.payload.count += 1;
|
|
1126
|
+
}
|
|
1127
|
+
ingestEvent() {
|
|
1128
|
+
return {
|
|
1129
|
+
type: "FLAGS_EVALUATION",
|
|
1130
|
+
ts: Date.now(),
|
|
1131
|
+
payload: this.payload
|
|
1132
|
+
};
|
|
1133
|
+
}
|
|
1134
|
+
};
|
|
1135
|
+
|
|
1136
|
+
// src/utils/weak-map.ts
|
|
1137
|
+
var BetterWeakMap = (_class2 = class {constructor() { _class2.prototype.__init6.call(this);_class2.prototype.__init7.call(this); }
|
|
1138
|
+
__init6() {this._values = []}
|
|
1139
|
+
__init7() {this._keys = []}
|
|
1140
|
+
set(key, value) {
|
|
1141
|
+
this._keys.push(key);
|
|
1142
|
+
this._values.push(value);
|
|
1143
|
+
}
|
|
1144
|
+
values() {
|
|
1145
|
+
return this._values;
|
|
1146
|
+
}
|
|
1147
|
+
has(key) {
|
|
1148
|
+
return this._keys.includes(key);
|
|
1149
|
+
}
|
|
1150
|
+
keys() {
|
|
1151
|
+
return this._keys;
|
|
1152
|
+
}
|
|
1153
|
+
clear() {
|
|
1154
|
+
this._values = [];
|
|
1155
|
+
this._keys = [];
|
|
1156
|
+
}
|
|
1157
|
+
}, _class2);
|
|
1158
|
+
|
|
1159
|
+
// src/utils/usage-tracker.ts
|
|
1160
|
+
var UsageTracker = (_class3 = class {
|
|
1161
|
+
__init8() {this.flushCount = 0}
|
|
1162
|
+
|
|
1163
|
+
|
|
1164
|
+
__init9() {this.readEvents = new BetterWeakMap()}
|
|
1165
|
+
__init10() {this.evaluationEvents = /* @__PURE__ */ new Map()}
|
|
1166
|
+
constructor(options) {;_class3.prototype.__init8.call(this);_class3.prototype.__init9.call(this);_class3.prototype.__init10.call(this);
|
|
856
1167
|
this.options = options;
|
|
1168
|
+
this.scheduler = new Scheduler(() => this.flushEvents());
|
|
857
1169
|
}
|
|
858
1170
|
/**
|
|
859
1171
|
* Triggers an immediate flush of any pending events.
|
|
860
1172
|
* Returns a promise that resolves when the flush completes.
|
|
861
1173
|
*/
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
return this.batcher.pending;
|
|
866
|
-
}
|
|
867
|
-
if (this.batcher.events.length > 0) {
|
|
868
|
-
return this.flushEvents();
|
|
869
|
-
}
|
|
870
|
-
return RESOLVED_VOID;
|
|
1174
|
+
async shutdown() {
|
|
1175
|
+
await this.scheduler.shutdown();
|
|
1176
|
+
await this.flushEvents();
|
|
871
1177
|
}
|
|
872
1178
|
/**
|
|
873
1179
|
* Tracks a config read event. Deduplicates by request context.
|
|
@@ -876,132 +1182,53 @@ var UsageTracker = (_class = class {
|
|
|
876
1182
|
try {
|
|
877
1183
|
const { ctx, headers } = getRequestContext();
|
|
878
1184
|
if (!ctx) return;
|
|
879
|
-
if (this.
|
|
880
|
-
|
|
881
|
-
const event = {
|
|
882
|
-
type: "FLAGS_CONFIG_READ",
|
|
883
|
-
ts: Date.now(),
|
|
884
|
-
payload: {
|
|
885
|
-
deploymentId: process.env.VERCEL_DEPLOYMENT_ID,
|
|
886
|
-
region: process.env.VERCEL_REGION
|
|
887
|
-
}
|
|
888
|
-
};
|
|
889
|
-
if (headers) {
|
|
890
|
-
event.payload.vercelRequestId = _nullishCoalesce(headers["x-vercel-id"], () => ( void 0));
|
|
891
|
-
event.payload.invocationHost = _nullishCoalesce(headers.host, () => ( void 0));
|
|
892
|
-
}
|
|
893
|
-
if (options) {
|
|
894
|
-
event.payload.configOrigin = options.configOrigin;
|
|
895
|
-
if (options.cacheStatus !== void 0) {
|
|
896
|
-
event.payload.cacheStatus = options.cacheStatus;
|
|
897
|
-
}
|
|
898
|
-
if (options.cacheAction !== void 0) {
|
|
899
|
-
event.payload.cacheAction = options.cacheAction;
|
|
900
|
-
}
|
|
901
|
-
if (options.cacheIsFirstRead !== void 0) {
|
|
902
|
-
event.payload.cacheIsFirstRead = options.cacheIsFirstRead;
|
|
903
|
-
}
|
|
904
|
-
if (options.cacheIsBlocking !== void 0) {
|
|
905
|
-
event.payload.cacheIsBlocking = options.cacheIsBlocking;
|
|
906
|
-
}
|
|
907
|
-
if (options.duration !== void 0) {
|
|
908
|
-
event.payload.duration = options.duration;
|
|
909
|
-
}
|
|
910
|
-
if (options.configUpdatedAt !== void 0) {
|
|
911
|
-
event.payload.configUpdatedAt = options.configUpdatedAt;
|
|
912
|
-
}
|
|
913
|
-
if (options.mode !== void 0) {
|
|
914
|
-
event.payload.mode = options.mode;
|
|
915
|
-
}
|
|
916
|
-
if (options.revision !== void 0) {
|
|
917
|
-
event.payload.revision = String(options.revision);
|
|
918
|
-
}
|
|
919
|
-
}
|
|
920
|
-
const environment = process.env.VERCEL_ENV || process.env.NODE_ENV || void 0;
|
|
921
|
-
if (environment) {
|
|
922
|
-
event.payload.environment = environment;
|
|
1185
|
+
if (this.readEvents.has(ctx)) {
|
|
1186
|
+
return;
|
|
923
1187
|
}
|
|
924
|
-
this.
|
|
925
|
-
this.scheduleFlush();
|
|
1188
|
+
this.readEvents.set(ctx, new FlagsConfigReadEvent(headers, options));
|
|
1189
|
+
this.scheduler.scheduleFlush();
|
|
1190
|
+
this.scheduler.increment();
|
|
926
1191
|
} catch (error) {
|
|
927
1192
|
console.error("@vercel/flags-core: Failed to record event:", error);
|
|
928
1193
|
}
|
|
929
1194
|
}
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
this.
|
|
942
|
-
this.batcher.resolveWait = null;
|
|
943
|
-
if (timeout) clearTimeout(timeout);
|
|
944
|
-
await this.flushEvents();
|
|
945
|
-
})();
|
|
946
|
-
try {
|
|
947
|
-
_functions.waitUntil.call(void 0, pending);
|
|
948
|
-
} catch (e5) {
|
|
1195
|
+
/**
|
|
1196
|
+
* Tracks a flag evaluation event.
|
|
1197
|
+
*/
|
|
1198
|
+
trackEvaluation(options) {
|
|
1199
|
+
try {
|
|
1200
|
+
const batchKey = evaluationBatchKey(options);
|
|
1201
|
+
const existingEvent = this.evaluationEvents.get(batchKey);
|
|
1202
|
+
if (existingEvent) {
|
|
1203
|
+
existingEvent.increment();
|
|
1204
|
+
} else {
|
|
1205
|
+
this.evaluationEvents.set(batchKey, new FlagsEvaluationEvent(options));
|
|
1206
|
+
this.scheduler.increment();
|
|
949
1207
|
}
|
|
950
|
-
this.
|
|
951
|
-
}
|
|
952
|
-
|
|
953
|
-
|
|
1208
|
+
this.scheduler.scheduleFlush();
|
|
1209
|
+
} catch (error) {
|
|
1210
|
+
console.error(
|
|
1211
|
+
"@vercel/flags-core: Failed to record evaluation event:",
|
|
1212
|
+
error
|
|
1213
|
+
);
|
|
954
1214
|
}
|
|
955
1215
|
}
|
|
1216
|
+
/**
|
|
1217
|
+
* Send all events to the ingest service
|
|
1218
|
+
*/
|
|
956
1219
|
async flushEvents() {
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
method: "POST",
|
|
968
|
-
headers: {
|
|
969
|
-
"Content-Type": "application/json",
|
|
970
|
-
Authorization: `Bearer ${token}`,
|
|
971
|
-
"User-Agent": `VercelFlagsCore/${version}`,
|
|
972
|
-
...process.env.VERCEL_ENV ? { "X-Vercel-Env": process.env.VERCEL_ENV } : null,
|
|
973
|
-
...isDebugMode ? { "x-vercel-debug-ingest": "1" } : null
|
|
974
|
-
},
|
|
975
|
-
body: JSON.stringify(eventsToSend)
|
|
976
|
-
}
|
|
977
|
-
);
|
|
978
|
-
debugLog(
|
|
979
|
-
`@vercel/flags-core: Ingest response ${response.status} for ${eventsToSend.length} events on ${response.headers.get("x-vercel-id")}`
|
|
980
|
-
);
|
|
981
|
-
if (response.ok) {
|
|
982
|
-
break;
|
|
983
|
-
}
|
|
984
|
-
throw new Error(
|
|
985
|
-
`Ingest endpoint responded with status ${response.status} for ${eventsToSend.length} events on request ${response.headers.get("x-vercel-id")}.
|
|
986
|
-
Response body: ${await response.text().catch(() => null)}`
|
|
987
|
-
);
|
|
988
|
-
} catch (error) {
|
|
989
|
-
console.error(
|
|
990
|
-
`@vercel/flags-core: Error sending events (attempt=${attempt}/${MAX_RETRIES} flushId=${flushId}):`,
|
|
991
|
-
error
|
|
992
|
-
);
|
|
993
|
-
if (attempt < MAX_RETRIES) {
|
|
994
|
-
const delayMs = getRetryDelayMs(attempt);
|
|
995
|
-
await new Promise((res) => setTimeout(res, delayMs));
|
|
996
|
-
} else {
|
|
997
|
-
console.error(
|
|
998
|
-
`@vercel/flags-core: Dropped ${eventsToSend.length} events after ${MAX_RETRIES} attempts (flushId=${flushId})`
|
|
999
|
-
);
|
|
1000
|
-
}
|
|
1001
|
-
}
|
|
1002
|
-
}
|
|
1220
|
+
const events = [
|
|
1221
|
+
...this.readEvents.values(),
|
|
1222
|
+
...this.evaluationEvents.values()
|
|
1223
|
+
];
|
|
1224
|
+
if (events.length === 0) return;
|
|
1225
|
+
this.flushCount += 1;
|
|
1226
|
+
const flushId = this.flushCount;
|
|
1227
|
+
this.readEvents.clear();
|
|
1228
|
+
this.evaluationEvents.clear();
|
|
1229
|
+
await sendIngestEvents(this.options, events, flushId);
|
|
1003
1230
|
}
|
|
1004
|
-
},
|
|
1231
|
+
}, _class3);
|
|
1005
1232
|
|
|
1006
1233
|
// src/errors.ts
|
|
1007
1234
|
var FallbackNotFoundError = class extends Error {
|
|
@@ -1060,7 +1287,7 @@ var BundledSource = class {
|
|
|
1060
1287
|
*/
|
|
1061
1288
|
async tryLoad() {
|
|
1062
1289
|
const result = await this.getResult();
|
|
1063
|
-
if (_optionalChain([result, 'optionalAccess',
|
|
1290
|
+
if (_optionalChain([result, 'optionalAccess', _38 => _38.state]) === "ok" && result.definitions) {
|
|
1064
1291
|
return result.definitions;
|
|
1065
1292
|
}
|
|
1066
1293
|
return void 0;
|
|
@@ -1100,14 +1327,14 @@ async function fetchDatafile(options) {
|
|
|
1100
1327
|
signal: controller.signal
|
|
1101
1328
|
});
|
|
1102
1329
|
clearTimeout(timeoutId);
|
|
1103
|
-
_optionalChain([options, 'access',
|
|
1330
|
+
_optionalChain([options, 'access', _39 => _39.signal, 'optionalAccess', _40 => _40.removeEventListener, 'call', _41 => _41("abort", onExternalAbort)]);
|
|
1104
1331
|
if (!res.ok) {
|
|
1105
1332
|
throw new Error(`Failed to fetch data: ${res.statusText}`);
|
|
1106
1333
|
}
|
|
1107
1334
|
return res.json();
|
|
1108
1335
|
} catch (error) {
|
|
1109
1336
|
clearTimeout(timeoutId);
|
|
1110
|
-
_optionalChain([options, 'access',
|
|
1337
|
+
_optionalChain([options, 'access', _42 => _42.signal, 'optionalAccess', _43 => _43.removeEventListener, 'call', _44 => _44("abort", onExternalAbort)]);
|
|
1111
1338
|
throw error instanceof Error ? error : new Error("Unknown fetch error");
|
|
1112
1339
|
}
|
|
1113
1340
|
}
|
|
@@ -1156,13 +1383,14 @@ function normalizeOptions(options) {
|
|
|
1156
1383
|
polling,
|
|
1157
1384
|
buildStep,
|
|
1158
1385
|
fetch: _nullishCoalesce(options.fetch, () => ( globalThis.fetch)),
|
|
1159
|
-
host: "https://flags.vercel.com"
|
|
1386
|
+
host: "https://flags.vercel.com",
|
|
1387
|
+
clientName: options.clientName
|
|
1160
1388
|
};
|
|
1161
1389
|
}
|
|
1162
1390
|
|
|
1163
1391
|
// src/controller/typed-emitter.ts
|
|
1164
|
-
var TypedEmitter = (
|
|
1165
|
-
|
|
1392
|
+
var TypedEmitter = (_class4 = class {constructor() { _class4.prototype.__init11.call(this); }
|
|
1393
|
+
__init11() {this.handlers = /* @__PURE__ */ new Map()}
|
|
1166
1394
|
on(event, handler) {
|
|
1167
1395
|
let set = this.handlers.get(event);
|
|
1168
1396
|
if (!set) {
|
|
@@ -1172,7 +1400,7 @@ var TypedEmitter = (_class2 = class {constructor() { _class2.prototype.__init4.c
|
|
|
1172
1400
|
set.add(handler);
|
|
1173
1401
|
}
|
|
1174
1402
|
off(event, handler) {
|
|
1175
|
-
_optionalChain([this, 'access',
|
|
1403
|
+
_optionalChain([this, 'access', _45 => _45.handlers, 'access', _46 => _46.get, 'call', _47 => _47(event), 'optionalAccess', _48 => _48.delete, 'call', _49 => _49(handler)]);
|
|
1176
1404
|
}
|
|
1177
1405
|
emit(event, ...args) {
|
|
1178
1406
|
const set = this.handlers.get(event);
|
|
@@ -1182,7 +1410,7 @@ var TypedEmitter = (_class2 = class {constructor() { _class2.prototype.__init4.c
|
|
|
1182
1410
|
}
|
|
1183
1411
|
}
|
|
1184
1412
|
}
|
|
1185
|
-
},
|
|
1413
|
+
}, _class4);
|
|
1186
1414
|
|
|
1187
1415
|
// src/controller/polling-source.ts
|
|
1188
1416
|
var PollingSource = class extends TypedEmitter {
|
|
@@ -1198,11 +1426,11 @@ var PollingSource = class extends TypedEmitter {
|
|
|
1198
1426
|
* Emits 'data' on success, 'error' on failure.
|
|
1199
1427
|
*/
|
|
1200
1428
|
async poll() {
|
|
1201
|
-
if (_optionalChain([this, 'access',
|
|
1429
|
+
if (_optionalChain([this, 'access', _50 => _50.abortController, 'optionalAccess', _51 => _51.signal, 'access', _52 => _52.aborted])) return;
|
|
1202
1430
|
try {
|
|
1203
1431
|
const data = await fetchDatafile({
|
|
1204
1432
|
...this.config,
|
|
1205
|
-
signal: _optionalChain([this, 'access',
|
|
1433
|
+
signal: _optionalChain([this, 'access', _53 => _53.abortController, 'optionalAccess', _54 => _54.signal])
|
|
1206
1434
|
});
|
|
1207
1435
|
this.emit("data", data);
|
|
1208
1436
|
} catch (error) {
|
|
@@ -1231,7 +1459,7 @@ var PollingSource = class extends TypedEmitter {
|
|
|
1231
1459
|
clearInterval(this.intervalId);
|
|
1232
1460
|
this.intervalId = void 0;
|
|
1233
1461
|
}
|
|
1234
|
-
_optionalChain([this, 'access',
|
|
1462
|
+
_optionalChain([this, 'access', _55 => _55.abortController, 'optionalAccess', _56 => _56.abort, 'call', _57 => _57()]);
|
|
1235
1463
|
this.abortController = void 0;
|
|
1236
1464
|
}
|
|
1237
1465
|
};
|
|
@@ -1279,13 +1507,9 @@ async function connectStream(config, callbacks) {
|
|
|
1279
1507
|
});
|
|
1280
1508
|
void (async () => {
|
|
1281
1509
|
let initialDataReceived = false;
|
|
1282
|
-
let lastError;
|
|
1283
1510
|
while (!abortController.signal.aborted) {
|
|
1284
1511
|
if (retryCount > MAX_RETRY_COUNT) {
|
|
1285
|
-
console.error(
|
|
1286
|
-
"@vercel/flags-core: Max retry count exceeded",
|
|
1287
|
-
_nullishCoalesce(lastError, () => ( "stream closed repeatedly without an error"))
|
|
1288
|
-
);
|
|
1512
|
+
console.error("@vercel/flags-core: Max retry count exceeded");
|
|
1289
1513
|
if (!initialDataReceived) {
|
|
1290
1514
|
rejectInit(
|
|
1291
1515
|
new Error("stream: max retry count exceeded before receiving data")
|
|
@@ -1305,7 +1529,7 @@ async function connectStream(config, callbacks) {
|
|
|
1305
1529
|
if (pingTimeoutId !== void 0) clearTimeout(pingTimeoutId);
|
|
1306
1530
|
if (!initialDataReceived) return;
|
|
1307
1531
|
pingTimeoutId = setTimeout(() => {
|
|
1308
|
-
_optionalChain([responseBody, 'optionalAccess',
|
|
1532
|
+
_optionalChain([responseBody, 'optionalAccess', _58 => _58.cancel, 'call', _59 => _59(), 'access', _60 => _60.catch, 'call', _61 => _61(() => {
|
|
1309
1533
|
})]);
|
|
1310
1534
|
connectionAbort.abort();
|
|
1311
1535
|
}, PING_TIMEOUT_MS);
|
|
@@ -1324,7 +1548,7 @@ async function connectStream(config, callbacks) {
|
|
|
1324
1548
|
if (vercelEnv) {
|
|
1325
1549
|
headers["X-Vercel-Env"] = vercelEnv;
|
|
1326
1550
|
}
|
|
1327
|
-
const revision = _optionalChain([config, 'access',
|
|
1551
|
+
const revision = _optionalChain([config, 'access', _62 => _62.revision, 'optionalCall', _63 => _63()]);
|
|
1328
1552
|
if (revision !== void 0) {
|
|
1329
1553
|
headers["X-Revision"] = String(revision);
|
|
1330
1554
|
}
|
|
@@ -1370,7 +1594,7 @@ async function connectStream(config, callbacks) {
|
|
|
1370
1594
|
let message;
|
|
1371
1595
|
try {
|
|
1372
1596
|
message = JSON.parse(line);
|
|
1373
|
-
} catch (
|
|
1597
|
+
} catch (e7) {
|
|
1374
1598
|
console.warn(
|
|
1375
1599
|
"@vercel/flags-core: Failed to parse stream message, skipping"
|
|
1376
1600
|
);
|
|
@@ -1386,7 +1610,7 @@ async function connectStream(config, callbacks) {
|
|
|
1386
1610
|
resetPingTimeout();
|
|
1387
1611
|
}
|
|
1388
1612
|
if (message.type === "primed") {
|
|
1389
|
-
_optionalChain([onPrimed, 'optionalCall',
|
|
1613
|
+
_optionalChain([onPrimed, 'optionalCall', _64 => _64(message)]);
|
|
1390
1614
|
retryCount = 0;
|
|
1391
1615
|
if (!initialDataReceived) {
|
|
1392
1616
|
initialDataReceived = true;
|
|
@@ -1409,7 +1633,7 @@ async function connectStream(config, callbacks) {
|
|
|
1409
1633
|
clearTimeout(pingTimeoutId);
|
|
1410
1634
|
abortController.signal.removeEventListener("abort", onMainAbort);
|
|
1411
1635
|
if (!abortController.signal.aborted) {
|
|
1412
|
-
_optionalChain([onDisconnect, 'optionalCall',
|
|
1636
|
+
_optionalChain([onDisconnect, 'optionalCall', _65 => _65()]);
|
|
1413
1637
|
retryCount++;
|
|
1414
1638
|
const elapsed = Date.now() - lastAttemptTime;
|
|
1415
1639
|
const minGap = Math.max(0, BASE_RETRY_DELAY_MS - elapsed);
|
|
@@ -1428,9 +1652,9 @@ async function connectStream(config, callbacks) {
|
|
|
1428
1652
|
break;
|
|
1429
1653
|
}
|
|
1430
1654
|
if (!connectionAbort.signal.aborted) {
|
|
1431
|
-
|
|
1655
|
+
console.error("@vercel/flags-core: Stream error", error);
|
|
1432
1656
|
}
|
|
1433
|
-
_optionalChain([onDisconnect, 'optionalCall',
|
|
1657
|
+
_optionalChain([onDisconnect, 'optionalCall', _66 => _66()]);
|
|
1434
1658
|
retryCount++;
|
|
1435
1659
|
const elapsed = Date.now() - lastAttemptTime;
|
|
1436
1660
|
const minGap = Math.max(0, BASE_RETRY_DELAY_MS - elapsed);
|
|
@@ -1509,7 +1733,7 @@ var StreamSource = class extends TypedEmitter {
|
|
|
1509
1733
|
* Stop the stream connection.
|
|
1510
1734
|
*/
|
|
1511
1735
|
stop() {
|
|
1512
|
-
_optionalChain([this, 'access',
|
|
1736
|
+
_optionalChain([this, 'access', _67 => _67.abortController, 'optionalAccess', _68 => _68.abort, 'call', _69 => _69()]);
|
|
1513
1737
|
this.abortController = void 0;
|
|
1514
1738
|
this.promise = void 0;
|
|
1515
1739
|
}
|
|
@@ -1541,34 +1765,34 @@ function parseConfigUpdatedAt(value) {
|
|
|
1541
1765
|
}
|
|
1542
1766
|
return void 0;
|
|
1543
1767
|
}
|
|
1544
|
-
var Controller = (
|
|
1768
|
+
var Controller = (_class5 = class {
|
|
1545
1769
|
|
|
1546
1770
|
// State machine
|
|
1547
|
-
|
|
1771
|
+
__init12() {this.state = "idle"}
|
|
1548
1772
|
// Data state — tagged with origin
|
|
1549
1773
|
|
|
1550
1774
|
// Memoized data spread for read() / getDatafile().
|
|
1551
1775
|
// Rebuilt only when `this.data` reference changes (e.g. on stream/poll update).
|
|
1552
1776
|
// Holds the result of stripping `_origin`; metrics are appended per-call.
|
|
1553
|
-
|
|
1554
|
-
|
|
1777
|
+
__init13() {this.dataViewSource = void 0}
|
|
1778
|
+
__init14() {this.dataViewBase = void 0}
|
|
1555
1779
|
// Sources (I/O delegates)
|
|
1556
1780
|
|
|
1557
1781
|
|
|
1558
1782
|
|
|
1559
1783
|
// Usage tracking
|
|
1560
1784
|
|
|
1561
|
-
|
|
1785
|
+
__init15() {this.isFirstGetData = true}
|
|
1562
1786
|
// Build-step deduplication
|
|
1563
|
-
|
|
1564
|
-
|
|
1787
|
+
__init16() {this.buildDataPromise = null}
|
|
1788
|
+
__init17() {this.buildReadTracked = false}
|
|
1565
1789
|
// Suppresses usage tracking when the SDK key is unauthorized
|
|
1566
|
-
|
|
1567
|
-
constructor(options) {;
|
|
1790
|
+
__init18() {this.unauthorized = false}
|
|
1791
|
+
constructor(options) {;_class5.prototype.__init12.call(this);_class5.prototype.__init13.call(this);_class5.prototype.__init14.call(this);_class5.prototype.__init15.call(this);_class5.prototype.__init16.call(this);_class5.prototype.__init17.call(this);_class5.prototype.__init18.call(this);_class5.prototype.__init19.call(this);_class5.prototype.__init20.call(this);_class5.prototype.__init21.call(this);_class5.prototype.__init22.call(this);_class5.prototype.__init23.call(this);_class5.prototype.__init24.call(this);
|
|
1568
1792
|
this.options = normalizeOptions(options);
|
|
1569
1793
|
this.streamSource = new StreamSource(
|
|
1570
1794
|
this.options,
|
|
1571
|
-
() => _optionalChain([this, 'access',
|
|
1795
|
+
() => _optionalChain([this, 'access', _70 => _70.data, 'optionalAccess', _71 => _71.revision])
|
|
1572
1796
|
);
|
|
1573
1797
|
this.pollingSource = new PollingSource(this.options);
|
|
1574
1798
|
this.bundledSource = new BundledSource({
|
|
@@ -1582,32 +1806,32 @@ var Controller = (_class3 = class {
|
|
|
1582
1806
|
this.usageTracker = new UsageTracker(this.options);
|
|
1583
1807
|
}
|
|
1584
1808
|
// Source event handlers (stored for cleanup)
|
|
1585
|
-
|
|
1809
|
+
__init19() {this.onStreamData = (data) => {
|
|
1586
1810
|
if (this.isNewerData(data)) {
|
|
1587
1811
|
this.data = tagData(data, "stream");
|
|
1588
1812
|
}
|
|
1589
1813
|
}}
|
|
1590
|
-
|
|
1814
|
+
__init20() {this.onStreamPrimed = () => {
|
|
1591
1815
|
if (this.state === "degraded" || this.state === "initializing:stream") {
|
|
1592
1816
|
this.transition("streaming");
|
|
1593
1817
|
}
|
|
1594
1818
|
}}
|
|
1595
|
-
|
|
1819
|
+
__init21() {this.onStreamConnected = () => {
|
|
1596
1820
|
if (this.state === "degraded" || this.state === "initializing:stream") {
|
|
1597
1821
|
this.transition("streaming");
|
|
1598
1822
|
}
|
|
1599
1823
|
}}
|
|
1600
|
-
|
|
1824
|
+
__init22() {this.onStreamDisconnected = () => {
|
|
1601
1825
|
if (this.state === "streaming") {
|
|
1602
1826
|
this.transition("degraded");
|
|
1603
1827
|
}
|
|
1604
1828
|
}}
|
|
1605
|
-
|
|
1829
|
+
__init23() {this.onPollData = (data) => {
|
|
1606
1830
|
if (this.isNewerData(data)) {
|
|
1607
1831
|
this.data = tagData(data, "poll");
|
|
1608
1832
|
}
|
|
1609
1833
|
}}
|
|
1610
|
-
|
|
1834
|
+
__init24() {this.onPollError = (error) => {
|
|
1611
1835
|
console.error("@vercel/flags-core: Poll failed:", error);
|
|
1612
1836
|
}}
|
|
1613
1837
|
// ---------------------------------------------------------------------------
|
|
@@ -1676,7 +1900,7 @@ var Controller = (_class3 = class {
|
|
|
1676
1900
|
if (bundled) {
|
|
1677
1901
|
this.data = tagData(bundled, "bundled");
|
|
1678
1902
|
}
|
|
1679
|
-
} catch (
|
|
1903
|
+
} catch (e8) {
|
|
1680
1904
|
}
|
|
1681
1905
|
}
|
|
1682
1906
|
if (this.data) {
|
|
@@ -1745,7 +1969,7 @@ var Controller = (_class3 = class {
|
|
|
1745
1969
|
this.pollingSource.stop();
|
|
1746
1970
|
this.data = this.options.datafile ? tagData(this.options.datafile, "provided") : void 0;
|
|
1747
1971
|
this.transition("shutdown");
|
|
1748
|
-
await this.usageTracker.
|
|
1972
|
+
await this.usageTracker.shutdown();
|
|
1749
1973
|
}
|
|
1750
1974
|
/**
|
|
1751
1975
|
* Returns the datafile with metrics.
|
|
@@ -1778,7 +2002,7 @@ var Controller = (_class3 = class {
|
|
|
1778
2002
|
this.data = tagData(fetched, "fetched");
|
|
1779
2003
|
result = this.data;
|
|
1780
2004
|
cacheStatus = "MISS";
|
|
1781
|
-
} catch (
|
|
2005
|
+
} catch (e9) {
|
|
1782
2006
|
throw new Error(
|
|
1783
2007
|
"@vercel/flags-core: No flag definitions available. Initialize the client or provide a datafile."
|
|
1784
2008
|
);
|
|
@@ -1863,7 +2087,7 @@ var Controller = (_class3 = class {
|
|
|
1863
2087
|
clearTimeout(timeoutId);
|
|
1864
2088
|
if (result === "timeout") {
|
|
1865
2089
|
console.warn(
|
|
1866
|
-
"@vercel/flags-core: Stream initialization timeout, falling back
|
|
2090
|
+
"@vercel/flags-core: Stream initialization timeout, falling back"
|
|
1867
2091
|
);
|
|
1868
2092
|
void this.streamSource.start().catch(() => {
|
|
1869
2093
|
});
|
|
@@ -1897,7 +2121,7 @@ var Controller = (_class3 = class {
|
|
|
1897
2121
|
return true;
|
|
1898
2122
|
}
|
|
1899
2123
|
return false;
|
|
1900
|
-
} catch (
|
|
2124
|
+
} catch (e10) {
|
|
1901
2125
|
return false;
|
|
1902
2126
|
}
|
|
1903
2127
|
}
|
|
@@ -1913,7 +2137,7 @@ var Controller = (_class3 = class {
|
|
|
1913
2137
|
clearTimeout(timeoutId);
|
|
1914
2138
|
if (result === "timeout") {
|
|
1915
2139
|
console.warn(
|
|
1916
|
-
"@vercel/flags-core: Polling initialization timeout, falling back
|
|
2140
|
+
"@vercel/flags-core: Polling initialization timeout, falling back"
|
|
1917
2141
|
);
|
|
1918
2142
|
return false;
|
|
1919
2143
|
}
|
|
@@ -1922,7 +2146,7 @@ var Controller = (_class3 = class {
|
|
|
1922
2146
|
return true;
|
|
1923
2147
|
}
|
|
1924
2148
|
return false;
|
|
1925
|
-
} catch (
|
|
2149
|
+
} catch (e11) {
|
|
1926
2150
|
clearTimeout(timeoutId);
|
|
1927
2151
|
return false;
|
|
1928
2152
|
}
|
|
@@ -1972,7 +2196,7 @@ var Controller = (_class3 = class {
|
|
|
1972
2196
|
fetch: this.options.fetch
|
|
1973
2197
|
});
|
|
1974
2198
|
return tagData(fetched, "fetched");
|
|
1975
|
-
} catch (
|
|
2199
|
+
} catch (e12) {
|
|
1976
2200
|
}
|
|
1977
2201
|
throw new Error(
|
|
1978
2202
|
"@vercel/flags-core: No flag definitions available during build. Provide a datafile or bundled definitions."
|
|
@@ -2006,7 +2230,7 @@ var Controller = (_class3 = class {
|
|
|
2006
2230
|
this.data = tagData(fetched, "fetched");
|
|
2007
2231
|
this.transition("degraded");
|
|
2008
2232
|
return;
|
|
2009
|
-
} catch (
|
|
2233
|
+
} catch (e13) {
|
|
2010
2234
|
}
|
|
2011
2235
|
}
|
|
2012
2236
|
throw new Error(
|
|
@@ -2058,7 +2282,7 @@ var Controller = (_class3 = class {
|
|
|
2058
2282
|
this.data = tagData(fetched, "fetched");
|
|
2059
2283
|
this.transition("degraded");
|
|
2060
2284
|
return [this.data, "MISS"];
|
|
2061
|
-
} catch (
|
|
2285
|
+
} catch (e14) {
|
|
2062
2286
|
}
|
|
2063
2287
|
}
|
|
2064
2288
|
throw new Error(
|
|
@@ -2110,11 +2334,11 @@ var Controller = (_class3 = class {
|
|
|
2110
2334
|
duration: Date.now() - startTime,
|
|
2111
2335
|
mode: mode === "streaming" ? "stream" : mode === "polling" ? "poll" : mode
|
|
2112
2336
|
};
|
|
2113
|
-
const configUpdatedAt = _optionalChain([this, 'access',
|
|
2337
|
+
const configUpdatedAt = _optionalChain([this, 'access', _72 => _72.data, 'optionalAccess', _73 => _73.configUpdatedAt]);
|
|
2114
2338
|
if (typeof configUpdatedAt === "number") {
|
|
2115
2339
|
trackOptions.configUpdatedAt = configUpdatedAt;
|
|
2116
2340
|
}
|
|
2117
|
-
const revision = _optionalChain([this, 'access',
|
|
2341
|
+
const revision = _optionalChain([this, 'access', _74 => _74.data, 'optionalAccess', _75 => _75.revision]);
|
|
2118
2342
|
if (typeof revision === "number") {
|
|
2119
2343
|
trackOptions.revision = revision;
|
|
2120
2344
|
}
|
|
@@ -2123,10 +2347,20 @@ var Controller = (_class3 = class {
|
|
|
2123
2347
|
}
|
|
2124
2348
|
this.usageTracker.trackRead(trackOptions);
|
|
2125
2349
|
}
|
|
2126
|
-
|
|
2350
|
+
/**
|
|
2351
|
+
* Tracks a flag evaluation for usage analytics.
|
|
2352
|
+
*/
|
|
2353
|
+
trackEvaluation(options) {
|
|
2354
|
+
if (this.unauthorized) return;
|
|
2355
|
+
this.usageTracker.trackEvaluation({
|
|
2356
|
+
...options,
|
|
2357
|
+
clientName: _nullishCoalesce(options.clientName, () => ( this.options.clientName))
|
|
2358
|
+
});
|
|
2359
|
+
}
|
|
2360
|
+
}, _class5);
|
|
2127
2361
|
|
|
2128
2362
|
// src/controller/auth.ts
|
|
2129
|
-
|
|
2363
|
+
|
|
2130
2364
|
|
|
2131
2365
|
// src/utils/sdk-keys.ts
|
|
2132
2366
|
var SDK_KEY_REGEX = /^vf_(?:server|client)_/;
|
|
@@ -2137,7 +2371,7 @@ function parseSdkKeyFromFlagsConnectionString(text) {
|
|
|
2137
2371
|
const params = new URLSearchParams(text.slice(6));
|
|
2138
2372
|
const sdkKey = params.get("sdkKey");
|
|
2139
2373
|
if (sdkKey && SDK_KEY_REGEX.test(sdkKey)) return sdkKey;
|
|
2140
|
-
} catch (
|
|
2374
|
+
} catch (e15) {
|
|
2141
2375
|
}
|
|
2142
2376
|
return null;
|
|
2143
2377
|
}
|
|
@@ -2146,7 +2380,7 @@ function parseSdkKeyFromFlagsConnectionString(text) {
|
|
|
2146
2380
|
async function getOidcToken() {
|
|
2147
2381
|
try {
|
|
2148
2382
|
return await _oidc.getVercelOidcToken.call(void 0, );
|
|
2149
|
-
} catch (
|
|
2383
|
+
} catch (e16) {
|
|
2150
2384
|
throw new Error(
|
|
2151
2385
|
[
|
|
2152
2386
|
"@vercel/flags-core: Failed to get OIDC token.",
|
|
@@ -2265,4 +2499,4 @@ var {
|
|
|
2265
2499
|
|
|
2266
2500
|
|
|
2267
2501
|
exports.ResolutionReason = ResolutionReason; exports.evaluate = evaluate; exports.FallbackNotFoundError = FallbackNotFoundError; exports.FallbackEntryNotFoundError = FallbackEntryNotFoundError; exports.Controller = Controller; exports.flagsClient = flagsClient; exports.resetDefaultFlagsClient = resetDefaultFlagsClient; exports.createClient = createClient;
|
|
2268
|
-
//# sourceMappingURL=chunk-
|
|
2502
|
+
//# sourceMappingURL=chunk-NHWFZTK2.cjs.map
|