@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
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# @vercel/flags-core
|
|
2
2
|
|
|
3
|
+
## 1.8.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#497](https://github.com/vercel/flags/pull/497) [`4848877`](https://github.com/vercel/flags/commit/4848877ca60c8595745b7759e351e936d7fe5889) Thanks [@feugy](https://github.com/feugy)! - Allow passing a custom `waitUntil` function to `createClient` for background
|
|
8
|
+
usage and exposure reporting. Pending exposure reports are drained by
|
|
9
|
+
`client.shutdown()`. The Next.js conditional export uses `after` from
|
|
10
|
+
`next/server` by default.
|
|
11
|
+
|
|
12
|
+
- [#490](https://github.com/vercel/flags/pull/490) [`186ea50`](https://github.com/vercel/flags/commit/186ea5092b22cd3eadf136824ecb2d7293a047fd) Thanks [@AndyBitz](https://github.com/AndyBitz)! - Use the runtime-provided ingest transport when available
|
|
13
|
+
|
|
3
14
|
## 1.8.1
|
|
4
15
|
|
|
5
16
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -12,18 +12,27 @@ npm i @vercel/flags-core
|
|
|
12
12
|
|
|
13
13
|
## Usage
|
|
14
14
|
|
|
15
|
+
Create a shared client at module scope, but evaluate flags inside a request handler when using Vercel OIDC authentication. `evaluate()` and `bulkEvaluate()` initialize the client automatically on first use; you do not need to call `initialize()` first.
|
|
16
|
+
|
|
17
|
+
For example, in an Express app deployed to Vercel:
|
|
18
|
+
|
|
15
19
|
```ts
|
|
20
|
+
import express from 'express';
|
|
16
21
|
import { createClient } from '@vercel/flags-core';
|
|
17
22
|
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
await client.initialize();
|
|
23
|
+
const app = express();
|
|
24
|
+
const client = createClient(); // Uses Vercel OIDC; does not initialize yet.
|
|
21
25
|
|
|
22
|
-
|
|
23
|
-
|
|
26
|
+
app.get('/api/feature', async (_req, res) => {
|
|
27
|
+
const result = await client.evaluate<boolean>('show-new-feature', false);
|
|
28
|
+
res.json({ enabled: result.value });
|
|
24
29
|
});
|
|
30
|
+
|
|
31
|
+
export default app;
|
|
25
32
|
```
|
|
26
33
|
|
|
34
|
+
Outside Vercel, pass an SDK key explicitly: `createClient(process.env.FLAGS)`.
|
|
35
|
+
|
|
27
36
|
## Evaluation Metrics
|
|
28
37
|
|
|
29
38
|
To associate evaluation metrics with an environment, pass the
|
|
@@ -1,5 +1,6 @@
|
|
|
1
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 _class6;// src/index.next-js.ts
|
|
2
2
|
var _cache = require('next/cache');
|
|
3
|
+
var _server = require('next/server');
|
|
3
4
|
|
|
4
5
|
// src/evaluate.ts
|
|
5
6
|
var _jsxxhash = require('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) {
|
|
@@ -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 = _functions.waitUntil
|
|
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 (e) {
|
|
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,12 +1038,23 @@ 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 _optionalChain([context, 'optionalAccess', _31 => _31.ingest]) === "function" ? context.ingest : void 0;
|
|
1047
|
+
} catch (e5) {
|
|
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;
|
|
1036
1055
|
var EVALUATING_OIDC_TOKEN_HEADER = "X-Vercel-Flags-OIDC-Token";
|
|
1037
1056
|
var FLUSH_REASON_HEADER = "X-Vercel-Flags-Flush-Reason";
|
|
1038
|
-
var isDebugMode = _optionalChain([process, 'access',
|
|
1057
|
+
var isDebugMode = _optionalChain([process, 'access', _32 => _32.env, 'access', _33 => _33.DEBUG, 'optionalAccess', _34 => _34.includes, 'call', _35 => _35("@vercel/flags-core")]);
|
|
1039
1058
|
var debugLog = (...args) => {
|
|
1040
1059
|
if (!isDebugMode) return;
|
|
1041
1060
|
console.log(...args);
|
|
@@ -1044,7 +1063,7 @@ async function getEvaluatingOidcToken(auth) {
|
|
|
1044
1063
|
if (!auth.sdkKey) return void 0;
|
|
1045
1064
|
try {
|
|
1046
1065
|
return await _oidc.getVercelOidcToken.call(void 0, );
|
|
1047
|
-
} catch (
|
|
1066
|
+
} catch (e6) {
|
|
1048
1067
|
return void 0;
|
|
1049
1068
|
}
|
|
1050
1069
|
}
|
|
@@ -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
|
+
..._nullishCoalesce(options.metricEnvironment, () => ( process.env.VERCEL_ENV)) ? {
|
|
1092
|
+
"X-Vercel-Env": _nullishCoalesce(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,
|
|
@@ -1114,7 +1153,7 @@ var SYMBOL_FOR_REQ_CONTEXT = /* @__PURE__ */ Symbol.for("@vercel/request-context
|
|
|
1114
1153
|
var fromSymbol = globalThis;
|
|
1115
1154
|
function getRequestContext() {
|
|
1116
1155
|
try {
|
|
1117
|
-
const ctx = _optionalChain([fromSymbol, 'access',
|
|
1156
|
+
const ctx = _optionalChain([fromSymbol, 'access', _36 => _36[SYMBOL_FOR_REQ_CONTEXT], 'optionalAccess', _37 => _37.get, 'optionalCall', _38 => _38()]);
|
|
1118
1157
|
if (ctx && Object.hasOwn(ctx, "headers")) {
|
|
1119
1158
|
return {
|
|
1120
1159
|
ctx,
|
|
@@ -1122,7 +1161,7 @@ function getRequestContext() {
|
|
|
1122
1161
|
};
|
|
1123
1162
|
}
|
|
1124
1163
|
return { ctx, headers: void 0 };
|
|
1125
|
-
} catch (
|
|
1164
|
+
} catch (e7) {
|
|
1126
1165
|
return { ctx: void 0, headers: void 0 };
|
|
1127
1166
|
}
|
|
1128
1167
|
}
|
|
@@ -1133,10 +1172,12 @@ 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 = class {
|
|
1136
|
-
constructor(onFlush) {;_class.prototype.__init.call(this);_class.prototype.__init2.call(this);_class.prototype.__init3.call(this);_class.prototype.__init4.call(this);
|
|
1175
|
+
constructor(onFlush, scheduleTask = _functions.waitUntil) {;_class.prototype.__init.call(this);_class.prototype.__init2.call(this);_class.prototype.__init3.call(this);_class.prototype.__init4.call(this);
|
|
1137
1176
|
this.onFlush = onFlush;
|
|
1177
|
+
this.scheduleTask = scheduleTask;
|
|
1138
1178
|
}
|
|
1139
1179
|
|
|
1180
|
+
|
|
1140
1181
|
__init() {this.resolveWait = null}
|
|
1141
1182
|
__init2() {this.pending = null}
|
|
1142
1183
|
__init3() {this.idleTimeout = null}
|
|
@@ -1151,8 +1192,8 @@ var Scheduler = (_class = class {
|
|
|
1151
1192
|
await this.onFlush(reason);
|
|
1152
1193
|
})();
|
|
1153
1194
|
try {
|
|
1154
|
-
|
|
1155
|
-
} catch (
|
|
1195
|
+
this.scheduleTask(this.pending);
|
|
1196
|
+
} catch (e8) {
|
|
1156
1197
|
}
|
|
1157
1198
|
this.maxTimeout = setTimeout(
|
|
1158
1199
|
() => this.resolveScheduledFlush("max_timeout"),
|
|
@@ -1179,7 +1220,7 @@ var Scheduler = (_class = class {
|
|
|
1179
1220
|
}
|
|
1180
1221
|
resolveScheduledFlush(reason) {
|
|
1181
1222
|
this.clearTimeouts();
|
|
1182
|
-
_optionalChain([this, 'access',
|
|
1223
|
+
_optionalChain([this, 'access', _39 => _39.resolveWait, 'optionalCall', _40 => _40(reason)]);
|
|
1183
1224
|
}
|
|
1184
1225
|
reset() {
|
|
1185
1226
|
this.pending = null;
|
|
@@ -1298,12 +1339,18 @@ var UsageTracker = (_class4 = class {
|
|
|
1298
1339
|
__init7() {this.flushCount = 0}
|
|
1299
1340
|
|
|
1300
1341
|
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1342
|
+
|
|
1343
|
+
__init8() {this.inflightFlushes = /* @__PURE__ */ new Set()}
|
|
1344
|
+
__init9() {this.trackedRequests = /* @__PURE__ */ new WeakSet()}
|
|
1345
|
+
__init10() {this.readEvents = []}
|
|
1346
|
+
__init11() {this.evaluationEvents = /* @__PURE__ */ new Map()}
|
|
1347
|
+
constructor(options) {;_class4.prototype.__init7.call(this);_class4.prototype.__init8.call(this);_class4.prototype.__init9.call(this);_class4.prototype.__init10.call(this);_class4.prototype.__init11.call(this);
|
|
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 = (_class4 = 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 = (_class4 = 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 = (_class4 = 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 = (_class4 = 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
|
+
_optionalChain([this, 'access', _41 => _41.waitUntil, 'optionalCall', _42 => _42(flush)]);
|
|
1419
|
+
} catch (e9) {
|
|
1420
|
+
}
|
|
1421
|
+
} else {
|
|
1422
|
+
this.scheduler.scheduleFlush();
|
|
1423
|
+
}
|
|
1424
|
+
}
|
|
1358
1425
|
/**
|
|
1359
1426
|
* Send all events to the ingest service
|
|
1360
1427
|
*/
|
|
@@ -1427,7 +1494,7 @@ var BundledSource = class {
|
|
|
1427
1494
|
*/
|
|
1428
1495
|
async tryLoad() {
|
|
1429
1496
|
const result = await this.getResult();
|
|
1430
|
-
if (_optionalChain([result, 'optionalAccess',
|
|
1497
|
+
if (_optionalChain([result, 'optionalAccess', _43 => _43.state]) === "ok" && result.definitions) {
|
|
1431
1498
|
return result.definitions;
|
|
1432
1499
|
}
|
|
1433
1500
|
return void 0;
|
|
@@ -1467,19 +1534,20 @@ async function fetchDatafile(options) {
|
|
|
1467
1534
|
signal: controller.signal
|
|
1468
1535
|
});
|
|
1469
1536
|
clearTimeout(timeoutId);
|
|
1470
|
-
_optionalChain([options, 'access',
|
|
1537
|
+
_optionalChain([options, 'access', _44 => _44.signal, 'optionalAccess', _45 => _45.removeEventListener, 'call', _46 => _46("abort", onExternalAbort)]);
|
|
1471
1538
|
if (!res.ok) {
|
|
1472
1539
|
throw new Error(`Failed to fetch data: ${res.statusText}`);
|
|
1473
1540
|
}
|
|
1474
1541
|
return res.json();
|
|
1475
1542
|
} catch (error) {
|
|
1476
1543
|
clearTimeout(timeoutId);
|
|
1477
|
-
_optionalChain([options, 'access',
|
|
1544
|
+
_optionalChain([options, 'access', _47 => _47.signal, 'optionalAccess', _48 => _48.removeEventListener, 'call', _49 => _49("abort", onExternalAbort)]);
|
|
1478
1545
|
throw error instanceof Error ? error : new Error("Unknown fetch error");
|
|
1479
1546
|
}
|
|
1480
1547
|
}
|
|
1481
1548
|
|
|
1482
1549
|
// src/controller/normalized-options.ts
|
|
1550
|
+
|
|
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: _nullishCoalesce(options.fetch, () => ( globalThis.fetch)),
|
|
1594
|
+
waitUntil: _nullishCoalesce(options.waitUntil, () => ( _functions.waitUntil)),
|
|
1526
1595
|
host: "https://flags.vercel.com",
|
|
1527
1596
|
metricEnvironment: options.metricEnvironment,
|
|
1528
1597
|
clientName: options.clientName,
|
|
@@ -1531,8 +1600,8 @@ function normalizeOptions(options) {
|
|
|
1531
1600
|
}
|
|
1532
1601
|
|
|
1533
1602
|
// src/controller/typed-emitter.ts
|
|
1534
|
-
var TypedEmitter = (_class5 = class {constructor() { _class5.prototype.
|
|
1535
|
-
|
|
1603
|
+
var TypedEmitter = (_class5 = class {constructor() { _class5.prototype.__init12.call(this); }
|
|
1604
|
+
__init12() {this.handlers = /* @__PURE__ */ new Map()}
|
|
1536
1605
|
on(event, handler) {
|
|
1537
1606
|
let set = this.handlers.get(event);
|
|
1538
1607
|
if (!set) {
|
|
@@ -1542,7 +1611,7 @@ var TypedEmitter = (_class5 = class {constructor() { _class5.prototype.__init11.
|
|
|
1542
1611
|
set.add(handler);
|
|
1543
1612
|
}
|
|
1544
1613
|
off(event, handler) {
|
|
1545
|
-
_optionalChain([this, 'access',
|
|
1614
|
+
_optionalChain([this, 'access', _50 => _50.handlers, 'access', _51 => _51.get, 'call', _52 => _52(event), 'optionalAccess', _53 => _53.delete, 'call', _54 => _54(handler)]);
|
|
1546
1615
|
}
|
|
1547
1616
|
emit(event, ...args) {
|
|
1548
1617
|
const set = this.handlers.get(event);
|
|
@@ -1568,11 +1637,11 @@ var PollingSource = class extends TypedEmitter {
|
|
|
1568
1637
|
* Emits 'data' on success, 'error' on failure.
|
|
1569
1638
|
*/
|
|
1570
1639
|
async poll() {
|
|
1571
|
-
if (_optionalChain([this, 'access',
|
|
1640
|
+
if (_optionalChain([this, 'access', _55 => _55.abortController, 'optionalAccess', _56 => _56.signal, 'access', _57 => _57.aborted])) return;
|
|
1572
1641
|
try {
|
|
1573
1642
|
const data = await fetchDatafile({
|
|
1574
1643
|
...this.config,
|
|
1575
|
-
signal: _optionalChain([this, 'access',
|
|
1644
|
+
signal: _optionalChain([this, 'access', _58 => _58.abortController, 'optionalAccess', _59 => _59.signal])
|
|
1576
1645
|
});
|
|
1577
1646
|
this.emit("data", data);
|
|
1578
1647
|
} catch (error) {
|
|
@@ -1601,7 +1670,7 @@ var PollingSource = class extends TypedEmitter {
|
|
|
1601
1670
|
clearInterval(this.intervalId);
|
|
1602
1671
|
this.intervalId = void 0;
|
|
1603
1672
|
}
|
|
1604
|
-
_optionalChain([this, 'access',
|
|
1673
|
+
_optionalChain([this, 'access', _60 => _60.abortController, 'optionalAccess', _61 => _61.abort, 'call', _62 => _62()]);
|
|
1605
1674
|
this.abortController = void 0;
|
|
1606
1675
|
}
|
|
1607
1676
|
};
|
|
@@ -1680,7 +1749,7 @@ async function connectStream(config, callbacks) {
|
|
|
1680
1749
|
if (pingTimeoutId !== void 0) clearTimeout(pingTimeoutId);
|
|
1681
1750
|
if (!initialDataReceived) return;
|
|
1682
1751
|
pingTimeoutId = setTimeout(() => {
|
|
1683
|
-
_optionalChain([responseBody, 'optionalAccess',
|
|
1752
|
+
_optionalChain([responseBody, 'optionalAccess', _63 => _63.cancel, 'call', _64 => _64(), 'access', _65 => _65.catch, 'call', _66 => _66(() => {
|
|
1684
1753
|
})]);
|
|
1685
1754
|
connectionAbort.abort();
|
|
1686
1755
|
}, PING_TIMEOUT_MS);
|
|
@@ -1702,7 +1771,7 @@ async function connectStream(config, callbacks) {
|
|
|
1702
1771
|
if (vercelEnv) {
|
|
1703
1772
|
headers["X-Vercel-Env"] = vercelEnv;
|
|
1704
1773
|
}
|
|
1705
|
-
const revision = _optionalChain([config, 'access',
|
|
1774
|
+
const revision = _optionalChain([config, 'access', _67 => _67.revision, 'optionalCall', _68 => _68()]);
|
|
1706
1775
|
if (revision !== void 0) {
|
|
1707
1776
|
headers["X-Revision"] = String(revision);
|
|
1708
1777
|
}
|
|
@@ -1748,7 +1817,7 @@ async function connectStream(config, callbacks) {
|
|
|
1748
1817
|
let message;
|
|
1749
1818
|
try {
|
|
1750
1819
|
message = JSON.parse(line);
|
|
1751
|
-
} catch (
|
|
1820
|
+
} catch (e10) {
|
|
1752
1821
|
console.warn(
|
|
1753
1822
|
"@vercel/flags-core: Failed to parse stream message, skipping"
|
|
1754
1823
|
);
|
|
@@ -1764,7 +1833,7 @@ async function connectStream(config, callbacks) {
|
|
|
1764
1833
|
resetPingTimeout();
|
|
1765
1834
|
}
|
|
1766
1835
|
if (message.type === "primed") {
|
|
1767
|
-
_optionalChain([onPrimed, 'optionalCall',
|
|
1836
|
+
_optionalChain([onPrimed, 'optionalCall', _69 => _69(message)]);
|
|
1768
1837
|
retryCount = 0;
|
|
1769
1838
|
if (!initialDataReceived) {
|
|
1770
1839
|
initialDataReceived = true;
|
|
@@ -1787,7 +1856,7 @@ async function connectStream(config, callbacks) {
|
|
|
1787
1856
|
clearTimeout(pingTimeoutId);
|
|
1788
1857
|
abortController.signal.removeEventListener("abort", onMainAbort);
|
|
1789
1858
|
if (!abortController.signal.aborted) {
|
|
1790
|
-
_optionalChain([onDisconnect, 'optionalCall',
|
|
1859
|
+
_optionalChain([onDisconnect, 'optionalCall', _70 => _70()]);
|
|
1791
1860
|
retryCount++;
|
|
1792
1861
|
const elapsed = Date.now() - lastAttemptTime;
|
|
1793
1862
|
const minGap = Math.max(0, BASE_RETRY_DELAY_MS - elapsed);
|
|
@@ -1808,7 +1877,7 @@ async function connectStream(config, callbacks) {
|
|
|
1808
1877
|
if (!connectionAbort.signal.aborted) {
|
|
1809
1878
|
lastError = error;
|
|
1810
1879
|
}
|
|
1811
|
-
_optionalChain([onDisconnect, 'optionalCall',
|
|
1880
|
+
_optionalChain([onDisconnect, 'optionalCall', _71 => _71()]);
|
|
1812
1881
|
retryCount++;
|
|
1813
1882
|
const elapsed = Date.now() - lastAttemptTime;
|
|
1814
1883
|
const minGap = Math.max(0, BASE_RETRY_DELAY_MS - elapsed);
|
|
@@ -1887,7 +1956,7 @@ var StreamSource = class extends TypedEmitter {
|
|
|
1887
1956
|
* Stop the stream connection.
|
|
1888
1957
|
*/
|
|
1889
1958
|
stop() {
|
|
1890
|
-
_optionalChain([this, 'access',
|
|
1959
|
+
_optionalChain([this, 'access', _72 => _72.abortController, 'optionalAccess', _73 => _73.abort, 'call', _74 => _74()]);
|
|
1891
1960
|
this.abortController = void 0;
|
|
1892
1961
|
this.promise = void 0;
|
|
1893
1962
|
}
|
|
@@ -1922,31 +1991,31 @@ function parseConfigUpdatedAt(value) {
|
|
|
1922
1991
|
var Controller = (_class6 = class {
|
|
1923
1992
|
|
|
1924
1993
|
// State machine
|
|
1925
|
-
|
|
1994
|
+
__init13() {this.state = "idle"}
|
|
1926
1995
|
// Data state — tagged with origin
|
|
1927
1996
|
|
|
1928
1997
|
// Memoized data spread for read() / getDatafile().
|
|
1929
1998
|
// Rebuilt only when `this.data` reference changes (e.g. on stream/poll update).
|
|
1930
1999
|
// Holds the result of stripping `_origin`; metrics are appended per-call.
|
|
1931
|
-
|
|
1932
|
-
|
|
2000
|
+
__init14() {this.dataViewSource = void 0}
|
|
2001
|
+
__init15() {this.dataViewBase = void 0}
|
|
1933
2002
|
// Sources (I/O delegates)
|
|
1934
2003
|
|
|
1935
2004
|
|
|
1936
2005
|
|
|
1937
2006
|
// Usage tracking
|
|
1938
2007
|
|
|
1939
|
-
|
|
2008
|
+
__init16() {this.isFirstGetData = true}
|
|
1940
2009
|
// Build-step deduplication
|
|
1941
|
-
|
|
1942
|
-
|
|
2010
|
+
__init17() {this.buildDataPromise = null}
|
|
2011
|
+
__init18() {this.buildReadTracked = false}
|
|
1943
2012
|
// Suppresses usage tracking when the SDK key is unauthorized
|
|
1944
|
-
|
|
1945
|
-
constructor(options) {;_class6.prototype.
|
|
2013
|
+
__init19() {this.unauthorized = false}
|
|
2014
|
+
constructor(options) {;_class6.prototype.__init13.call(this);_class6.prototype.__init14.call(this);_class6.prototype.__init15.call(this);_class6.prototype.__init16.call(this);_class6.prototype.__init17.call(this);_class6.prototype.__init18.call(this);_class6.prototype.__init19.call(this);_class6.prototype.__init20.call(this);_class6.prototype.__init21.call(this);_class6.prototype.__init22.call(this);_class6.prototype.__init23.call(this);_class6.prototype.__init24.call(this);_class6.prototype.__init25.call(this);
|
|
1946
2015
|
this.options = normalizeOptions(options);
|
|
1947
2016
|
this.streamSource = new StreamSource(
|
|
1948
2017
|
this.options,
|
|
1949
|
-
() => _optionalChain([this, 'access',
|
|
2018
|
+
() => _optionalChain([this, 'access', _75 => _75.data, 'optionalAccess', _76 => _76.revision])
|
|
1950
2019
|
);
|
|
1951
2020
|
this.pollingSource = new PollingSource(this.options);
|
|
1952
2021
|
this.bundledSource = new BundledSource({
|
|
@@ -1960,32 +2029,32 @@ var Controller = (_class6 = class {
|
|
|
1960
2029
|
this.usageTracker = new UsageTracker(this.options);
|
|
1961
2030
|
}
|
|
1962
2031
|
// Source event handlers (stored for cleanup)
|
|
1963
|
-
|
|
2032
|
+
__init20() {this.onStreamData = (data) => {
|
|
1964
2033
|
if (this.isNewerData(data)) {
|
|
1965
2034
|
this.data = tagData(data, "stream");
|
|
1966
2035
|
}
|
|
1967
2036
|
}}
|
|
1968
|
-
|
|
2037
|
+
__init21() {this.onStreamPrimed = () => {
|
|
1969
2038
|
if (this.state === "degraded" || this.state === "initializing:stream") {
|
|
1970
2039
|
this.transition("streaming");
|
|
1971
2040
|
}
|
|
1972
2041
|
}}
|
|
1973
|
-
|
|
2042
|
+
__init22() {this.onStreamConnected = () => {
|
|
1974
2043
|
if (this.state === "degraded" || this.state === "initializing:stream") {
|
|
1975
2044
|
this.transition("streaming");
|
|
1976
2045
|
}
|
|
1977
2046
|
}}
|
|
1978
|
-
|
|
2047
|
+
__init23() {this.onStreamDisconnected = () => {
|
|
1979
2048
|
if (this.state === "streaming") {
|
|
1980
2049
|
this.transition("degraded");
|
|
1981
2050
|
}
|
|
1982
2051
|
}}
|
|
1983
|
-
|
|
2052
|
+
__init24() {this.onPollData = (data) => {
|
|
1984
2053
|
if (this.isNewerData(data)) {
|
|
1985
2054
|
this.data = tagData(data, "poll");
|
|
1986
2055
|
}
|
|
1987
2056
|
}}
|
|
1988
|
-
|
|
2057
|
+
__init25() {this.onPollError = (error) => {
|
|
1989
2058
|
console.error("@vercel/flags-core: Poll failed:", error);
|
|
1990
2059
|
}}
|
|
1991
2060
|
// ---------------------------------------------------------------------------
|
|
@@ -2054,7 +2123,7 @@ var Controller = (_class6 = class {
|
|
|
2054
2123
|
if (bundled) {
|
|
2055
2124
|
this.data = tagData(bundled, "bundled");
|
|
2056
2125
|
}
|
|
2057
|
-
} catch (
|
|
2126
|
+
} catch (e11) {
|
|
2058
2127
|
}
|
|
2059
2128
|
}
|
|
2060
2129
|
if (this.data) {
|
|
@@ -2156,7 +2225,7 @@ var Controller = (_class6 = class {
|
|
|
2156
2225
|
this.data = tagData(fetched, "fetched");
|
|
2157
2226
|
result = this.data;
|
|
2158
2227
|
cacheStatus = "MISS";
|
|
2159
|
-
} catch (
|
|
2228
|
+
} catch (e12) {
|
|
2160
2229
|
throw new Error(
|
|
2161
2230
|
"@vercel/flags-core: No flag definitions available. Initialize the client or provide a datafile."
|
|
2162
2231
|
);
|
|
@@ -2275,7 +2344,7 @@ var Controller = (_class6 = class {
|
|
|
2275
2344
|
return true;
|
|
2276
2345
|
}
|
|
2277
2346
|
return false;
|
|
2278
|
-
} catch (
|
|
2347
|
+
} catch (e13) {
|
|
2279
2348
|
return false;
|
|
2280
2349
|
}
|
|
2281
2350
|
}
|
|
@@ -2300,7 +2369,7 @@ var Controller = (_class6 = class {
|
|
|
2300
2369
|
return true;
|
|
2301
2370
|
}
|
|
2302
2371
|
return false;
|
|
2303
|
-
} catch (
|
|
2372
|
+
} catch (e14) {
|
|
2304
2373
|
clearTimeout(timeoutId);
|
|
2305
2374
|
return false;
|
|
2306
2375
|
}
|
|
@@ -2350,7 +2419,7 @@ var Controller = (_class6 = class {
|
|
|
2350
2419
|
fetch: this.options.fetch
|
|
2351
2420
|
});
|
|
2352
2421
|
return tagData(fetched, "fetched");
|
|
2353
|
-
} catch (
|
|
2422
|
+
} catch (e15) {
|
|
2354
2423
|
}
|
|
2355
2424
|
throw new Error(
|
|
2356
2425
|
"@vercel/flags-core: No flag definitions available during build. Provide a datafile or bundled definitions."
|
|
@@ -2384,7 +2453,7 @@ var Controller = (_class6 = class {
|
|
|
2384
2453
|
this.data = tagData(fetched, "fetched");
|
|
2385
2454
|
this.transition("degraded");
|
|
2386
2455
|
return;
|
|
2387
|
-
} catch (
|
|
2456
|
+
} catch (e16) {
|
|
2388
2457
|
}
|
|
2389
2458
|
}
|
|
2390
2459
|
throw new Error(
|
|
@@ -2436,7 +2505,7 @@ var Controller = (_class6 = class {
|
|
|
2436
2505
|
this.data = tagData(fetched, "fetched");
|
|
2437
2506
|
this.transition("degraded");
|
|
2438
2507
|
return [this.data, "MISS"];
|
|
2439
|
-
} catch (
|
|
2508
|
+
} catch (e17) {
|
|
2440
2509
|
}
|
|
2441
2510
|
}
|
|
2442
2511
|
throw new Error(
|
|
@@ -2488,11 +2557,11 @@ var Controller = (_class6 = class {
|
|
|
2488
2557
|
duration: Date.now() - startTime,
|
|
2489
2558
|
mode: mode === "streaming" ? "stream" : mode === "polling" ? "poll" : mode
|
|
2490
2559
|
};
|
|
2491
|
-
const configUpdatedAt = _optionalChain([this, 'access',
|
|
2560
|
+
const configUpdatedAt = _optionalChain([this, 'access', _77 => _77.data, 'optionalAccess', _78 => _78.configUpdatedAt]);
|
|
2492
2561
|
if (typeof configUpdatedAt === "number") {
|
|
2493
2562
|
trackOptions.configUpdatedAt = configUpdatedAt;
|
|
2494
2563
|
}
|
|
2495
|
-
const revision = _optionalChain([this, 'access',
|
|
2564
|
+
const revision = _optionalChain([this, 'access', _79 => _79.data, 'optionalAccess', _80 => _80.revision]);
|
|
2496
2565
|
if (typeof revision === "number") {
|
|
2497
2566
|
trackOptions.revision = revision;
|
|
2498
2567
|
}
|
|
@@ -2525,7 +2594,7 @@ function parseSdkKeyFromFlagsConnectionString(text) {
|
|
|
2525
2594
|
const params = new URLSearchParams(text.slice(6));
|
|
2526
2595
|
const sdkKey = params.get("sdkKey");
|
|
2527
2596
|
if (sdkKey && SDK_KEY_REGEX.test(sdkKey)) return sdkKey;
|
|
2528
|
-
} catch (
|
|
2597
|
+
} catch (e18) {
|
|
2529
2598
|
}
|
|
2530
2599
|
return null;
|
|
2531
2600
|
}
|
|
@@ -2534,7 +2603,7 @@ function parseSdkKeyFromFlagsConnectionString(text) {
|
|
|
2534
2603
|
async function getOidcToken() {
|
|
2535
2604
|
try {
|
|
2536
2605
|
return await _oidc.getVercelOidcToken.call(void 0, );
|
|
2537
|
-
} catch (
|
|
2606
|
+
} catch (e19) {
|
|
2538
2607
|
throw new Error(
|
|
2539
2608
|
[
|
|
2540
2609
|
"@vercel/flags-core: Failed to get OIDC token.",
|
|
@@ -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 } = _nullishCoalesce(createClientOptions, () => ( {}));
|
|
2606
2675
|
const auth = new Authentication(sdkKeyOrConnectionString);
|
|
2607
|
-
const
|
|
2676
|
+
const waitUntil2 = _nullishCoalesce(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
|
}
|
|
@@ -2634,7 +2709,7 @@ function setCacheLife() {
|
|
|
2634
2709
|
try {
|
|
2635
2710
|
_cache.cacheLife.call(void 0, { revalidate: 0, expire: 0 });
|
|
2636
2711
|
_cache.cacheLife.call(void 0, { stale: 60 });
|
|
2637
|
-
} catch (
|
|
2712
|
+
} catch (e20) {
|
|
2638
2713
|
}
|
|
2639
2714
|
}
|
|
2640
2715
|
var cachedFns = {
|
|
@@ -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: _server.after }
|
|
2674
2750
|
);
|
|
2675
2751
|
|
|
2676
2752
|
|
|
@@ -2683,4 +2759,4 @@ var { flagsClient, resetDefaultFlagsClient, createClient } = make(
|
|
|
2683
2759
|
|
|
2684
2760
|
|
|
2685
2761
|
exports.ResolutionReason = ResolutionReason; exports.evaluate = evaluate; exports.FallbackNotFoundError = FallbackNotFoundError; exports.FallbackEntryNotFoundError = FallbackEntryNotFoundError; exports.Controller = Controller; exports.flagsClient = flagsClient; exports.resetDefaultFlagsClient = resetDefaultFlagsClient; exports.createClient = createClient;
|
|
2686
|
-
//# sourceMappingURL=chunk-
|
|
2762
|
+
//# sourceMappingURL=chunk-3WMSFQ2F.cjs.map
|