@vercel/flags-core 1.8.1 → 1.8.2
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 +11 -0
- package/README.md +14 -5
- package/dist/{chunk-CKL562EU.cjs → chunk-3WMSFQ2F.cjs} +142 -66
- package/dist/chunk-3WMSFQ2F.cjs.map +1 -0
- package/dist/{chunk-5BWCBI7I.js → chunk-AMDRNXFQ.js} +92 -15
- package/dist/chunk-AMDRNXFQ.js.map +1 -0
- package/dist/{chunk-DYSF37WV.js → chunk-KK44WKSW.js} +91 -15
- package/dist/chunk-KK44WKSW.js.map +1 -0
- package/dist/{chunk-CVDAHZHK.cjs → chunk-ODVYKYSM.cjs} +143 -66
- package/dist/chunk-ODVYKYSM.cjs.map +1 -0
- package/dist/index.default.cjs +2 -2
- package/dist/index.default.d.cts +9 -3
- package/dist/index.default.d.ts +9 -3
- package/dist/index.default.js +1 -1
- package/dist/index.next-js.cjs +2 -2
- package/dist/index.next-js.d.cts +9 -3
- package/dist/index.next-js.d.ts +9 -3
- 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-CIONStRG.d.cts → types-DLWRa9bG.d.cts} +17 -5
- package/dist/{types-CIONStRG.d.ts → types-DLWRa9bG.d.ts} +17 -5
- package/package.json +1 -1
- package/dist/chunk-5BWCBI7I.js.map +0 -1
- package/dist/chunk-CKL562EU.cjs.map +0 -1
- package/dist/chunk-CVDAHZHK.cjs.map +0 -1
- package/dist/chunk-DYSF37WV.js.map +0 -1
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// src/index.next-js.ts
|
|
2
2
|
import { cacheLife } from "next/cache";
|
|
3
|
+
import { after } from "next/server";
|
|
3
4
|
|
|
4
5
|
// src/evaluate.ts
|
|
5
6
|
import { xxHash32 as hashInput } from "js-xxhash";
|
|
@@ -558,7 +559,7 @@ function bulkEvaluate(flags, shared) {
|
|
|
558
559
|
}
|
|
559
560
|
|
|
560
561
|
// package.json
|
|
561
|
-
var version = "1.8.
|
|
562
|
+
var version = "1.8.2";
|
|
562
563
|
|
|
563
564
|
// src/lib/report-value.ts
|
|
564
565
|
function internalReportValue(key, value, data) {
|
|
@@ -777,7 +778,7 @@ async function bulkEvaluate2(id, flags, entities) {
|
|
|
777
778
|
}
|
|
778
779
|
|
|
779
780
|
// src/create-raw-client.ts
|
|
780
|
-
import { waitUntil } from "@vercel/functions";
|
|
781
|
+
import { waitUntil as defaultWaitUntil } from "@vercel/functions";
|
|
781
782
|
import { dequal } from "dequal/lite";
|
|
782
783
|
var idCount = 0;
|
|
783
784
|
async function performInitialize(instance, initFn) {
|
|
@@ -793,9 +794,11 @@ function createCreateRawClient(fns) {
|
|
|
793
794
|
return function createRawClient({
|
|
794
795
|
controller,
|
|
795
796
|
origin,
|
|
796
|
-
experimental_reportExposures
|
|
797
|
+
experimental_reportExposures,
|
|
798
|
+
waitUntil: waitUntil2 = defaultWaitUntil
|
|
797
799
|
}) {
|
|
798
800
|
const id = idCount++;
|
|
801
|
+
const pendingExposureReports = /* @__PURE__ */ new Set();
|
|
799
802
|
controllerInstanceMap.set(id, {
|
|
800
803
|
controller,
|
|
801
804
|
initialized: false,
|
|
@@ -813,8 +816,10 @@ function createCreateRawClient(fns) {
|
|
|
813
816
|
);
|
|
814
817
|
}
|
|
815
818
|
})();
|
|
819
|
+
pendingExposureReports.add(pending);
|
|
820
|
+
void pending.finally(() => pendingExposureReports.delete(pending));
|
|
816
821
|
try {
|
|
817
|
-
|
|
822
|
+
waitUntil2(pending);
|
|
818
823
|
} catch {
|
|
819
824
|
}
|
|
820
825
|
}
|
|
@@ -849,6 +854,9 @@ function createCreateRawClient(fns) {
|
|
|
849
854
|
},
|
|
850
855
|
shutdown: async () => {
|
|
851
856
|
await fns.shutdown(id);
|
|
857
|
+
while (pendingExposureReports.size > 0) {
|
|
858
|
+
await Promise.all(pendingExposureReports);
|
|
859
|
+
}
|
|
852
860
|
controllerInstanceMap.delete(id);
|
|
853
861
|
},
|
|
854
862
|
getDatafile: async () => {
|
|
@@ -1030,6 +1038,17 @@ function getJitteredWaitMs(baseMs, ratio) {
|
|
|
1030
1038
|
return Math.floor(min + Math.random() * span);
|
|
1031
1039
|
}
|
|
1032
1040
|
|
|
1041
|
+
// src/utils/runtime-ingest.ts
|
|
1042
|
+
var FLAGS_CONTEXT_SYMBOL = /* @__PURE__ */ Symbol.for("@vercel/flags-context");
|
|
1043
|
+
function getRuntimeIngest() {
|
|
1044
|
+
try {
|
|
1045
|
+
const context = globalThis[FLAGS_CONTEXT_SYMBOL];
|
|
1046
|
+
return typeof context?.ingest === "function" ? context.ingest : void 0;
|
|
1047
|
+
} catch {
|
|
1048
|
+
return void 0;
|
|
1049
|
+
}
|
|
1050
|
+
}
|
|
1051
|
+
|
|
1033
1052
|
// src/utils/ingest.ts
|
|
1034
1053
|
var MAX_RETRIES = 3;
|
|
1035
1054
|
var MAX_EVENTS_PER_REQUEST = 2e3;
|
|
@@ -1063,8 +1082,28 @@ async function getIngestHeaders(options, flushReason) {
|
|
|
1063
1082
|
...isDebugMode ? { "x-vercel-debug-ingest": "1" } : null
|
|
1064
1083
|
};
|
|
1065
1084
|
}
|
|
1085
|
+
function getRuntimeIngestHeaders(options, flushReason) {
|
|
1086
|
+
return {
|
|
1087
|
+
"Content-Type": "application/json",
|
|
1088
|
+
...options.auth.sdkKey ? { Authorization: `Bearer ${options.auth.sdkKey}` } : null,
|
|
1089
|
+
"User-Agent": `VercelFlagsCore/${version}`,
|
|
1090
|
+
[FLUSH_REASON_HEADER]: flushReason,
|
|
1091
|
+
...options.metricEnvironment ?? process.env.VERCEL_ENV ? {
|
|
1092
|
+
"X-Vercel-Env": options.metricEnvironment ?? process.env.VERCEL_ENV
|
|
1093
|
+
} : null,
|
|
1094
|
+
...isDebugMode ? { "x-vercel-debug-ingest": "1" } : null
|
|
1095
|
+
};
|
|
1096
|
+
}
|
|
1066
1097
|
async function sendIngestEvents(options, events, flushId, flushReason) {
|
|
1067
|
-
|
|
1098
|
+
let eventsToSend = events.map((event) => event.ingestEvent());
|
|
1099
|
+
const runtimeIngest = getRuntimeIngest();
|
|
1100
|
+
if (runtimeIngest) {
|
|
1101
|
+
const headers = getRuntimeIngestHeaders(options, flushReason);
|
|
1102
|
+
eventsToSend = eventsToSend.filter(
|
|
1103
|
+
(event) => !runtimeIngest({ headers, body: [event] })
|
|
1104
|
+
);
|
|
1105
|
+
if (eventsToSend.length === 0) return;
|
|
1106
|
+
}
|
|
1068
1107
|
for (let i = 0; i < eventsToSend.length; i += MAX_EVENTS_PER_REQUEST) {
|
|
1069
1108
|
await sendIngestChunk(
|
|
1070
1109
|
options,
|
|
@@ -1128,15 +1167,17 @@ function getRequestContext() {
|
|
|
1128
1167
|
}
|
|
1129
1168
|
|
|
1130
1169
|
// src/utils/scheduler.ts
|
|
1131
|
-
import { waitUntil
|
|
1170
|
+
import { waitUntil } from "@vercel/functions";
|
|
1132
1171
|
var IDLE_FLUSH_WAIT_MS = 5e3;
|
|
1133
1172
|
var IDLE_FLUSH_JITTER_RATIO = 0.2;
|
|
1134
1173
|
var MAX_FLUSH_WAIT_MS = 6e4;
|
|
1135
1174
|
var Scheduler = class {
|
|
1136
|
-
constructor(onFlush) {
|
|
1175
|
+
constructor(onFlush, scheduleTask = waitUntil) {
|
|
1137
1176
|
this.onFlush = onFlush;
|
|
1177
|
+
this.scheduleTask = scheduleTask;
|
|
1138
1178
|
}
|
|
1139
1179
|
onFlush;
|
|
1180
|
+
scheduleTask;
|
|
1140
1181
|
resolveWait = null;
|
|
1141
1182
|
pending = null;
|
|
1142
1183
|
idleTimeout = null;
|
|
@@ -1151,7 +1192,7 @@ var Scheduler = class {
|
|
|
1151
1192
|
await this.onFlush(reason);
|
|
1152
1193
|
})();
|
|
1153
1194
|
try {
|
|
1154
|
-
|
|
1195
|
+
this.scheduleTask(this.pending);
|
|
1155
1196
|
} catch {
|
|
1156
1197
|
}
|
|
1157
1198
|
this.maxTimeout = setTimeout(
|
|
@@ -1298,12 +1339,18 @@ var UsageTracker = class {
|
|
|
1298
1339
|
flushCount = 0;
|
|
1299
1340
|
options;
|
|
1300
1341
|
scheduler;
|
|
1342
|
+
waitUntil;
|
|
1343
|
+
inflightFlushes = /* @__PURE__ */ new Set();
|
|
1301
1344
|
trackedRequests = /* @__PURE__ */ new WeakSet();
|
|
1302
1345
|
readEvents = [];
|
|
1303
1346
|
evaluationEvents = /* @__PURE__ */ new Map();
|
|
1304
1347
|
constructor(options) {
|
|
1305
1348
|
this.options = options;
|
|
1306
|
-
this.
|
|
1349
|
+
this.waitUntil = options.waitUntil;
|
|
1350
|
+
this.scheduler = new Scheduler(
|
|
1351
|
+
(reason) => this.flushEvents(reason),
|
|
1352
|
+
options.waitUntil
|
|
1353
|
+
);
|
|
1307
1354
|
}
|
|
1308
1355
|
/**
|
|
1309
1356
|
* Triggers an immediate flush of any pending events.
|
|
@@ -1312,6 +1359,7 @@ var UsageTracker = class {
|
|
|
1312
1359
|
async shutdown() {
|
|
1313
1360
|
await this.scheduler.shutdown();
|
|
1314
1361
|
await this.flushEvents("shutdown");
|
|
1362
|
+
await Promise.all([...this.inflightFlushes]);
|
|
1315
1363
|
}
|
|
1316
1364
|
/**
|
|
1317
1365
|
* Tracks a config read event. Deduplicates by request context.
|
|
@@ -1323,7 +1371,7 @@ var UsageTracker = class {
|
|
|
1323
1371
|
if (this.trackedRequests.has(ctx)) return;
|
|
1324
1372
|
this.trackedRequests.add(ctx);
|
|
1325
1373
|
this.readEvents.push(new FlagsConfigReadEvent(headers, options));
|
|
1326
|
-
this.
|
|
1374
|
+
this.requestFlush();
|
|
1327
1375
|
} catch (error) {
|
|
1328
1376
|
console.error("@vercel/flags-core: Failed to record event:", error);
|
|
1329
1377
|
}
|
|
@@ -1347,7 +1395,7 @@ var UsageTracker = class {
|
|
|
1347
1395
|
new FlagsEvaluationEvent(bucketedOptions)
|
|
1348
1396
|
);
|
|
1349
1397
|
}
|
|
1350
|
-
this.
|
|
1398
|
+
this.requestFlush();
|
|
1351
1399
|
} catch (error) {
|
|
1352
1400
|
console.error(
|
|
1353
1401
|
"@vercel/flags-core: Failed to record evaluation event:",
|
|
@@ -1355,6 +1403,25 @@ var UsageTracker = class {
|
|
|
1355
1403
|
);
|
|
1356
1404
|
}
|
|
1357
1405
|
}
|
|
1406
|
+
/**
|
|
1407
|
+
* Flushes immediately when the runtime provides an ingest transport,
|
|
1408
|
+
* otherwise falls back to the time-based scheduler.
|
|
1409
|
+
*/
|
|
1410
|
+
requestFlush() {
|
|
1411
|
+
if (getRuntimeIngest()) {
|
|
1412
|
+
const flush = this.flushEvents("immediate").catch((error) => {
|
|
1413
|
+
console.error("@vercel/flags-core: Failed to flush events:", error);
|
|
1414
|
+
});
|
|
1415
|
+
this.inflightFlushes.add(flush);
|
|
1416
|
+
void flush.finally(() => this.inflightFlushes.delete(flush));
|
|
1417
|
+
try {
|
|
1418
|
+
this.waitUntil?.(flush);
|
|
1419
|
+
} catch {
|
|
1420
|
+
}
|
|
1421
|
+
} else {
|
|
1422
|
+
this.scheduler.scheduleFlush();
|
|
1423
|
+
}
|
|
1424
|
+
}
|
|
1358
1425
|
/**
|
|
1359
1426
|
* Send all events to the ingest service
|
|
1360
1427
|
*/
|
|
@@ -1480,6 +1547,7 @@ async function fetchDatafile(options) {
|
|
|
1480
1547
|
}
|
|
1481
1548
|
|
|
1482
1549
|
// src/controller/normalized-options.ts
|
|
1550
|
+
import { waitUntil as defaultWaitUntil2 } from "@vercel/functions";
|
|
1483
1551
|
var DEFAULT_STREAM_INIT_TIMEOUT_MS = 3e3;
|
|
1484
1552
|
var DEFAULT_POLLING_INTERVAL_MS = 3e4;
|
|
1485
1553
|
var MIN_POLLING_INTERVAL_MS = 3e4;
|
|
@@ -1523,6 +1591,7 @@ function normalizeOptions(options) {
|
|
|
1523
1591
|
polling,
|
|
1524
1592
|
buildStep,
|
|
1525
1593
|
fetch: options.fetch ?? globalThis.fetch,
|
|
1594
|
+
waitUntil: options.waitUntil ?? defaultWaitUntil2,
|
|
1526
1595
|
host: "https://flags.vercel.com",
|
|
1527
1596
|
metricEnvironment: options.metricEnvironment,
|
|
1528
1597
|
clientName: options.clientName,
|
|
@@ -2596,7 +2665,7 @@ var Authentication = class {
|
|
|
2596
2665
|
};
|
|
2597
2666
|
|
|
2598
2667
|
// src/index.make.ts
|
|
2599
|
-
function make(createRawClient) {
|
|
2668
|
+
function make(createRawClient, defaults) {
|
|
2600
2669
|
let _defaultFlagsClient = null;
|
|
2601
2670
|
function createClient2(sdkKeyOrConnectionStringOrOptions, options) {
|
|
2602
2671
|
const optionsOnly = typeof sdkKeyOrConnectionStringOrOptions === "object" && sdkKeyOrConnectionStringOrOptions !== null;
|
|
@@ -2604,10 +2673,16 @@ function make(createRawClient) {
|
|
|
2604
2673
|
const createClientOptions = optionsOnly ? sdkKeyOrConnectionStringOrOptions : options;
|
|
2605
2674
|
const { experimental_reportExposures, ...controllerOptions } = createClientOptions ?? {};
|
|
2606
2675
|
const auth = new Authentication(sdkKeyOrConnectionString);
|
|
2607
|
-
const
|
|
2676
|
+
const waitUntil2 = controllerOptions.waitUntil ?? defaults.waitUntil;
|
|
2677
|
+
const controller = new Controller({
|
|
2678
|
+
auth,
|
|
2679
|
+
...controllerOptions,
|
|
2680
|
+
waitUntil: waitUntil2
|
|
2681
|
+
});
|
|
2608
2682
|
return createRawClient({
|
|
2609
2683
|
controller,
|
|
2610
2684
|
origin: { provider: "vercel", sdkKey: auth.sdkKey },
|
|
2685
|
+
waitUntil: waitUntil2,
|
|
2611
2686
|
...experimental_reportExposures ? { experimental_reportExposures } : {}
|
|
2612
2687
|
});
|
|
2613
2688
|
}
|
|
@@ -2670,7 +2745,8 @@ var cachedFns = {
|
|
|
2670
2745
|
}
|
|
2671
2746
|
};
|
|
2672
2747
|
var { flagsClient, resetDefaultFlagsClient, createClient } = make(
|
|
2673
|
-
createCreateRawClient(cachedFns)
|
|
2748
|
+
createCreateRawClient(cachedFns),
|
|
2749
|
+
{ waitUntil: after }
|
|
2674
2750
|
);
|
|
2675
2751
|
|
|
2676
2752
|
export {
|
|
@@ -2683,4 +2759,4 @@ export {
|
|
|
2683
2759
|
resetDefaultFlagsClient,
|
|
2684
2760
|
createClient
|
|
2685
2761
|
};
|
|
2686
|
-
//# sourceMappingURL=chunk-
|
|
2762
|
+
//# sourceMappingURL=chunk-KK44WKSW.js.map
|