@vercel/flags-core 1.8.2 → 1.8.3
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 +8 -0
- package/dist/{chunk-AMDRNXFQ.js → chunk-NPKDNJX6.js} +73 -24
- package/dist/chunk-NPKDNJX6.js.map +1 -0
- package/dist/{chunk-ODVYKYSM.cjs → chunk-UX43BKE3.cjs} +86 -37
- package/dist/chunk-UX43BKE3.cjs.map +1 -0
- package/dist/{chunk-3WMSFQ2F.cjs → chunk-UYSSHTCJ.cjs} +86 -37
- package/dist/chunk-UYSSHTCJ.cjs.map +1 -0
- package/dist/{chunk-KK44WKSW.js → chunk-ZUA6TEG3.js} +73 -24
- package/dist/chunk-ZUA6TEG3.js.map +1 -0
- package/dist/index.default.cjs +2 -2
- package/dist/index.default.js +1 -1
- package/dist/index.next-js.cjs +2 -2
- 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 +4 -4
- package/dist/chunk-3WMSFQ2F.cjs.map +0 -1
- package/dist/chunk-AMDRNXFQ.js.map +0 -1
- package/dist/chunk-KK44WKSW.js.map +0 -1
- package/dist/chunk-ODVYKYSM.cjs.map +0 -1
|
@@ -56,7 +56,7 @@ function getSplitBoundaries(outcome) {
|
|
|
56
56
|
function getCompiledRegex(rhs) {
|
|
57
57
|
const cached = compiledRegexCache.get(rhs);
|
|
58
58
|
if (cached) return cached;
|
|
59
|
-
const compiled = new RegExp(rhs.pattern, rhs.flags.replace(/[gy]
|
|
59
|
+
const compiled = new RegExp(rhs.pattern, rhs.flags.replace(/[gy]/g, ""));
|
|
60
60
|
compiledRegexCache.set(rhs, compiled);
|
|
61
61
|
return compiled;
|
|
62
62
|
}
|
|
@@ -559,7 +559,7 @@ function bulkEvaluate(flags, shared) {
|
|
|
559
559
|
}
|
|
560
560
|
|
|
561
561
|
// package.json
|
|
562
|
-
var version = "1.8.
|
|
562
|
+
var version = "1.8.3";
|
|
563
563
|
|
|
564
564
|
// src/lib/report-value.ts
|
|
565
565
|
function internalReportValue(key, value, data) {
|
|
@@ -1509,40 +1509,86 @@ var BundledSource = class {
|
|
|
1509
1509
|
|
|
1510
1510
|
// src/controller/fetch-datafile.ts
|
|
1511
1511
|
var DEFAULT_FETCH_TIMEOUT_MS = 1e4;
|
|
1512
|
+
var DEFAULT_MAX_ATTEMPTS = 3;
|
|
1513
|
+
var DatafileHttpError = class extends Error {
|
|
1514
|
+
constructor(status, statusText) {
|
|
1515
|
+
super(`Failed to fetch data: ${statusText}`);
|
|
1516
|
+
this.status = status;
|
|
1517
|
+
}
|
|
1518
|
+
|
|
1519
|
+
get retryable() {
|
|
1520
|
+
return this.status === 408 || this.status === 429 || this.status >= 500;
|
|
1521
|
+
}
|
|
1522
|
+
};
|
|
1512
1523
|
async function fetchDatafile(options) {
|
|
1513
|
-
|
|
1524
|
+
_optionalChain([options, 'access', _44 => _44.signal, 'optionalAccess', _45 => _45.throwIfAborted, 'call', _46 => _46()]);
|
|
1525
|
+
const maxAttempts = _nullishCoalesce(options.maxAttempts, () => ( DEFAULT_MAX_ATTEMPTS));
|
|
1526
|
+
if (!Number.isInteger(maxAttempts) || maxAttempts < 1) {
|
|
1527
|
+
throw new Error("maxAttempts must be a positive integer");
|
|
1528
|
+
}
|
|
1514
1529
|
const controller = new AbortController();
|
|
1530
|
+
const { signal } = controller;
|
|
1531
|
+
let rejectAbort;
|
|
1532
|
+
const aborted = new Promise((_, reject) => {
|
|
1533
|
+
rejectAbort = reject;
|
|
1534
|
+
});
|
|
1535
|
+
const onAbort = () => rejectAbort(signal.reason);
|
|
1536
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
1537
|
+
const onExternalAbort = () => controller.abort(_optionalChain([options, 'access', _47 => _47.signal, 'optionalAccess', _48 => _48.reason]));
|
|
1538
|
+
_optionalChain([options, 'access', _49 => _49.signal, 'optionalAccess', _50 => _50.addEventListener, 'call', _51 => _51("abort", onExternalAbort, { once: true })]);
|
|
1515
1539
|
const timeoutId = setTimeout(
|
|
1516
|
-
() => controller.abort(
|
|
1540
|
+
() => controller.abort(
|
|
1541
|
+
new Error("@vercel/flags-core: Datafile fetch deadline exceeded")
|
|
1542
|
+
),
|
|
1517
1543
|
DEFAULT_FETCH_TIMEOUT_MS
|
|
1518
1544
|
);
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
throw new Error("Fetch aborted");
|
|
1524
|
-
}
|
|
1525
|
-
options.signal.addEventListener("abort", onExternalAbort, { once: true });
|
|
1526
|
-
}
|
|
1527
|
-
try {
|
|
1545
|
+
let delay;
|
|
1546
|
+
const fetchAttempt = async () => {
|
|
1547
|
+
const token = await options.auth.resolveToken();
|
|
1548
|
+
signal.throwIfAborted();
|
|
1528
1549
|
const res = await options.fetch(`${options.host}/v1/datafile`, {
|
|
1529
1550
|
headers: {
|
|
1530
1551
|
Authorization: `Bearer ${token}`,
|
|
1531
1552
|
"User-Agent": `VercelFlagsCore/${version}`,
|
|
1532
1553
|
...process.env.VERCEL_ENV ? { "X-Vercel-Env": process.env.VERCEL_ENV } : null
|
|
1533
1554
|
},
|
|
1534
|
-
signal
|
|
1555
|
+
signal
|
|
1535
1556
|
});
|
|
1536
|
-
|
|
1537
|
-
_optionalChain([options, 'access', _44 => _44.signal, 'optionalAccess', _45 => _45.removeEventListener, 'call', _46 => _46("abort", onExternalAbort)]);
|
|
1557
|
+
signal.throwIfAborted();
|
|
1538
1558
|
if (!res.ok) {
|
|
1539
|
-
|
|
1559
|
+
void _optionalChain([res, 'access', _52 => _52.body, 'optionalAccess', _53 => _53.cancel, 'call', _54 => _54(), 'access', _55 => _55.catch, 'call', _56 => _56(() => {
|
|
1560
|
+
})]);
|
|
1561
|
+
throw new DatafileHttpError(res.status, res.statusText);
|
|
1540
1562
|
}
|
|
1541
|
-
|
|
1542
|
-
|
|
1563
|
+
const data = await res.json();
|
|
1564
|
+
signal.throwIfAborted();
|
|
1565
|
+
return data;
|
|
1566
|
+
};
|
|
1567
|
+
try {
|
|
1568
|
+
for (let attempt = 0; ; attempt++) {
|
|
1569
|
+
if (attempt > 0) {
|
|
1570
|
+
await Promise.race([
|
|
1571
|
+
new Promise((resolve) => {
|
|
1572
|
+
delay = setTimeout(resolve, 100 * 2 ** (attempt - 1));
|
|
1573
|
+
}),
|
|
1574
|
+
aborted
|
|
1575
|
+
]);
|
|
1576
|
+
}
|
|
1577
|
+
signal.throwIfAborted();
|
|
1578
|
+
try {
|
|
1579
|
+
return await Promise.race([fetchAttempt(), aborted]);
|
|
1580
|
+
} catch (error) {
|
|
1581
|
+
signal.throwIfAborted();
|
|
1582
|
+
if (attempt === maxAttempts - 1 || error instanceof DatafileHttpError && !error.retryable) {
|
|
1583
|
+
throw error instanceof Error ? error : new Error("Unknown fetch error");
|
|
1584
|
+
}
|
|
1585
|
+
}
|
|
1586
|
+
}
|
|
1587
|
+
} finally {
|
|
1543
1588
|
clearTimeout(timeoutId);
|
|
1544
|
-
|
|
1545
|
-
|
|
1589
|
+
clearTimeout(delay);
|
|
1590
|
+
signal.removeEventListener("abort", onAbort);
|
|
1591
|
+
_optionalChain([options, 'access', _57 => _57.signal, 'optionalAccess', _58 => _58.removeEventListener, 'call', _59 => _59("abort", onExternalAbort)]);
|
|
1546
1592
|
}
|
|
1547
1593
|
}
|
|
1548
1594
|
|
|
@@ -1611,7 +1657,7 @@ var TypedEmitter = (_class5 = class {constructor() { _class5.prototype.__init12.
|
|
|
1611
1657
|
set.add(handler);
|
|
1612
1658
|
}
|
|
1613
1659
|
off(event, handler) {
|
|
1614
|
-
_optionalChain([this, 'access',
|
|
1660
|
+
_optionalChain([this, 'access', _60 => _60.handlers, 'access', _61 => _61.get, 'call', _62 => _62(event), 'optionalAccess', _63 => _63.delete, 'call', _64 => _64(handler)]);
|
|
1615
1661
|
}
|
|
1616
1662
|
emit(event, ...args) {
|
|
1617
1663
|
const set = this.handlers.get(event);
|
|
@@ -1637,14 +1683,17 @@ var PollingSource = class extends TypedEmitter {
|
|
|
1637
1683
|
* Emits 'data' on success, 'error' on failure.
|
|
1638
1684
|
*/
|
|
1639
1685
|
async poll() {
|
|
1640
|
-
if (_optionalChain([this, 'access',
|
|
1686
|
+
if (_optionalChain([this, 'access', _65 => _65.abortController, 'optionalAccess', _66 => _66.signal, 'access', _67 => _67.aborted])) return;
|
|
1687
|
+
this.abortController ??= new AbortController();
|
|
1688
|
+
const controller = this.abortController;
|
|
1641
1689
|
try {
|
|
1642
1690
|
const data = await fetchDatafile({
|
|
1643
1691
|
...this.config,
|
|
1644
|
-
signal:
|
|
1692
|
+
signal: controller.signal
|
|
1645
1693
|
});
|
|
1646
1694
|
this.emit("data", data);
|
|
1647
1695
|
} catch (error) {
|
|
1696
|
+
controller.signal.throwIfAborted();
|
|
1648
1697
|
const err = error instanceof Error ? error : new Error("Unknown poll error");
|
|
1649
1698
|
this.emit("error", err);
|
|
1650
1699
|
}
|
|
@@ -1656,9 +1705,9 @@ var PollingSource = class extends TypedEmitter {
|
|
|
1656
1705
|
*/
|
|
1657
1706
|
startInterval() {
|
|
1658
1707
|
if (this.intervalId) return;
|
|
1659
|
-
this.abortController = new AbortController();
|
|
1660
1708
|
this.intervalId = setInterval(
|
|
1661
|
-
() => void this.poll()
|
|
1709
|
+
() => void this.poll().catch(() => {
|
|
1710
|
+
}),
|
|
1662
1711
|
this.config.polling.intervalMs
|
|
1663
1712
|
);
|
|
1664
1713
|
}
|
|
@@ -1670,7 +1719,7 @@ var PollingSource = class extends TypedEmitter {
|
|
|
1670
1719
|
clearInterval(this.intervalId);
|
|
1671
1720
|
this.intervalId = void 0;
|
|
1672
1721
|
}
|
|
1673
|
-
_optionalChain([this, 'access',
|
|
1722
|
+
_optionalChain([this, 'access', _68 => _68.abortController, 'optionalAccess', _69 => _69.abort, 'call', _70 => _70()]);
|
|
1674
1723
|
this.abortController = void 0;
|
|
1675
1724
|
}
|
|
1676
1725
|
};
|
|
@@ -1749,7 +1798,7 @@ async function connectStream(config, callbacks) {
|
|
|
1749
1798
|
if (pingTimeoutId !== void 0) clearTimeout(pingTimeoutId);
|
|
1750
1799
|
if (!initialDataReceived) return;
|
|
1751
1800
|
pingTimeoutId = setTimeout(() => {
|
|
1752
|
-
_optionalChain([responseBody, 'optionalAccess',
|
|
1801
|
+
_optionalChain([responseBody, 'optionalAccess', _71 => _71.cancel, 'call', _72 => _72(), 'access', _73 => _73.catch, 'call', _74 => _74(() => {
|
|
1753
1802
|
})]);
|
|
1754
1803
|
connectionAbort.abort();
|
|
1755
1804
|
}, PING_TIMEOUT_MS);
|
|
@@ -1771,7 +1820,7 @@ async function connectStream(config, callbacks) {
|
|
|
1771
1820
|
if (vercelEnv) {
|
|
1772
1821
|
headers["X-Vercel-Env"] = vercelEnv;
|
|
1773
1822
|
}
|
|
1774
|
-
const revision = _optionalChain([config, 'access',
|
|
1823
|
+
const revision = _optionalChain([config, 'access', _75 => _75.revision, 'optionalCall', _76 => _76()]);
|
|
1775
1824
|
if (revision !== void 0) {
|
|
1776
1825
|
headers["X-Revision"] = String(revision);
|
|
1777
1826
|
}
|
|
@@ -1833,7 +1882,7 @@ async function connectStream(config, callbacks) {
|
|
|
1833
1882
|
resetPingTimeout();
|
|
1834
1883
|
}
|
|
1835
1884
|
if (message.type === "primed") {
|
|
1836
|
-
_optionalChain([onPrimed, 'optionalCall',
|
|
1885
|
+
_optionalChain([onPrimed, 'optionalCall', _77 => _77(message)]);
|
|
1837
1886
|
retryCount = 0;
|
|
1838
1887
|
if (!initialDataReceived) {
|
|
1839
1888
|
initialDataReceived = true;
|
|
@@ -1856,7 +1905,7 @@ async function connectStream(config, callbacks) {
|
|
|
1856
1905
|
clearTimeout(pingTimeoutId);
|
|
1857
1906
|
abortController.signal.removeEventListener("abort", onMainAbort);
|
|
1858
1907
|
if (!abortController.signal.aborted) {
|
|
1859
|
-
_optionalChain([onDisconnect, 'optionalCall',
|
|
1908
|
+
_optionalChain([onDisconnect, 'optionalCall', _78 => _78()]);
|
|
1860
1909
|
retryCount++;
|
|
1861
1910
|
const elapsed = Date.now() - lastAttemptTime;
|
|
1862
1911
|
const minGap = Math.max(0, BASE_RETRY_DELAY_MS - elapsed);
|
|
@@ -1877,7 +1926,7 @@ async function connectStream(config, callbacks) {
|
|
|
1877
1926
|
if (!connectionAbort.signal.aborted) {
|
|
1878
1927
|
lastError = error;
|
|
1879
1928
|
}
|
|
1880
|
-
_optionalChain([onDisconnect, 'optionalCall',
|
|
1929
|
+
_optionalChain([onDisconnect, 'optionalCall', _79 => _79()]);
|
|
1881
1930
|
retryCount++;
|
|
1882
1931
|
const elapsed = Date.now() - lastAttemptTime;
|
|
1883
1932
|
const minGap = Math.max(0, BASE_RETRY_DELAY_MS - elapsed);
|
|
@@ -1956,7 +2005,7 @@ var StreamSource = class extends TypedEmitter {
|
|
|
1956
2005
|
* Stop the stream connection.
|
|
1957
2006
|
*/
|
|
1958
2007
|
stop() {
|
|
1959
|
-
_optionalChain([this, 'access',
|
|
2008
|
+
_optionalChain([this, 'access', _80 => _80.abortController, 'optionalAccess', _81 => _81.abort, 'call', _82 => _82()]);
|
|
1960
2009
|
this.abortController = void 0;
|
|
1961
2010
|
this.promise = void 0;
|
|
1962
2011
|
}
|
|
@@ -2015,7 +2064,7 @@ var Controller = (_class6 = class {
|
|
|
2015
2064
|
this.options = normalizeOptions(options);
|
|
2016
2065
|
this.streamSource = new StreamSource(
|
|
2017
2066
|
this.options,
|
|
2018
|
-
() => _optionalChain([this, 'access',
|
|
2067
|
+
() => _optionalChain([this, 'access', _83 => _83.data, 'optionalAccess', _84 => _84.revision])
|
|
2019
2068
|
);
|
|
2020
2069
|
this.pollingSource = new PollingSource(this.options);
|
|
2021
2070
|
this.bundledSource = new BundledSource({
|
|
@@ -2557,11 +2606,11 @@ var Controller = (_class6 = class {
|
|
|
2557
2606
|
duration: Date.now() - startTime,
|
|
2558
2607
|
mode: mode === "streaming" ? "stream" : mode === "polling" ? "poll" : mode
|
|
2559
2608
|
};
|
|
2560
|
-
const configUpdatedAt = _optionalChain([this, 'access',
|
|
2609
|
+
const configUpdatedAt = _optionalChain([this, 'access', _85 => _85.data, 'optionalAccess', _86 => _86.configUpdatedAt]);
|
|
2561
2610
|
if (typeof configUpdatedAt === "number") {
|
|
2562
2611
|
trackOptions.configUpdatedAt = configUpdatedAt;
|
|
2563
2612
|
}
|
|
2564
|
-
const revision = _optionalChain([this, 'access',
|
|
2613
|
+
const revision = _optionalChain([this, 'access', _87 => _87.data, 'optionalAccess', _88 => _88.revision]);
|
|
2565
2614
|
if (typeof revision === "number") {
|
|
2566
2615
|
trackOptions.revision = revision;
|
|
2567
2616
|
}
|
|
@@ -2759,4 +2808,4 @@ var { flagsClient, resetDefaultFlagsClient, createClient } = make(
|
|
|
2759
2808
|
|
|
2760
2809
|
|
|
2761
2810
|
exports.ResolutionReason = ResolutionReason; exports.evaluate = evaluate; exports.FallbackNotFoundError = FallbackNotFoundError; exports.FallbackEntryNotFoundError = FallbackEntryNotFoundError; exports.Controller = Controller; exports.flagsClient = flagsClient; exports.resetDefaultFlagsClient = resetDefaultFlagsClient; exports.createClient = createClient;
|
|
2762
|
-
//# sourceMappingURL=chunk-
|
|
2811
|
+
//# sourceMappingURL=chunk-UYSSHTCJ.cjs.map
|