@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
|
@@ -73,7 +73,7 @@ function getSplitBoundaries(outcome) {
|
|
|
73
73
|
function getCompiledRegex(rhs) {
|
|
74
74
|
const cached = compiledRegexCache.get(rhs);
|
|
75
75
|
if (cached) return cached;
|
|
76
|
-
const compiled = new RegExp(rhs.pattern, rhs.flags.replace(/[gy]
|
|
76
|
+
const compiled = new RegExp(rhs.pattern, rhs.flags.replace(/[gy]/g, ""));
|
|
77
77
|
compiledRegexCache.set(rhs, compiled);
|
|
78
78
|
return compiled;
|
|
79
79
|
}
|
|
@@ -576,7 +576,7 @@ function bulkEvaluate(flags, shared) {
|
|
|
576
576
|
}
|
|
577
577
|
|
|
578
578
|
// package.json
|
|
579
|
-
var version = "1.8.
|
|
579
|
+
var version = "1.8.3";
|
|
580
580
|
|
|
581
581
|
// src/lib/report-value.ts
|
|
582
582
|
function internalReportValue(key, value, data) {
|
|
@@ -1526,40 +1526,86 @@ var BundledSource = class {
|
|
|
1526
1526
|
|
|
1527
1527
|
// src/controller/fetch-datafile.ts
|
|
1528
1528
|
var DEFAULT_FETCH_TIMEOUT_MS = 1e4;
|
|
1529
|
+
var DEFAULT_MAX_ATTEMPTS = 3;
|
|
1530
|
+
var DatafileHttpError = class extends Error {
|
|
1531
|
+
constructor(status, statusText) {
|
|
1532
|
+
super(`Failed to fetch data: ${statusText}`);
|
|
1533
|
+
this.status = status;
|
|
1534
|
+
}
|
|
1535
|
+
|
|
1536
|
+
get retryable() {
|
|
1537
|
+
return this.status === 408 || this.status === 429 || this.status >= 500;
|
|
1538
|
+
}
|
|
1539
|
+
};
|
|
1529
1540
|
async function fetchDatafile(options) {
|
|
1530
|
-
|
|
1541
|
+
_optionalChain([options, 'access', _44 => _44.signal, 'optionalAccess', _45 => _45.throwIfAborted, 'call', _46 => _46()]);
|
|
1542
|
+
const maxAttempts = _nullishCoalesce(options.maxAttempts, () => ( DEFAULT_MAX_ATTEMPTS));
|
|
1543
|
+
if (!Number.isInteger(maxAttempts) || maxAttempts < 1) {
|
|
1544
|
+
throw new Error("maxAttempts must be a positive integer");
|
|
1545
|
+
}
|
|
1531
1546
|
const controller = new AbortController();
|
|
1547
|
+
const { signal } = controller;
|
|
1548
|
+
let rejectAbort;
|
|
1549
|
+
const aborted = new Promise((_, reject) => {
|
|
1550
|
+
rejectAbort = reject;
|
|
1551
|
+
});
|
|
1552
|
+
const onAbort = () => rejectAbort(signal.reason);
|
|
1553
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
1554
|
+
const onExternalAbort = () => controller.abort(_optionalChain([options, 'access', _47 => _47.signal, 'optionalAccess', _48 => _48.reason]));
|
|
1555
|
+
_optionalChain([options, 'access', _49 => _49.signal, 'optionalAccess', _50 => _50.addEventListener, 'call', _51 => _51("abort", onExternalAbort, { once: true })]);
|
|
1532
1556
|
const timeoutId = setTimeout(
|
|
1533
|
-
() => controller.abort(
|
|
1557
|
+
() => controller.abort(
|
|
1558
|
+
new Error("@vercel/flags-core: Datafile fetch deadline exceeded")
|
|
1559
|
+
),
|
|
1534
1560
|
DEFAULT_FETCH_TIMEOUT_MS
|
|
1535
1561
|
);
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
throw new Error("Fetch aborted");
|
|
1541
|
-
}
|
|
1542
|
-
options.signal.addEventListener("abort", onExternalAbort, { once: true });
|
|
1543
|
-
}
|
|
1544
|
-
try {
|
|
1562
|
+
let delay;
|
|
1563
|
+
const fetchAttempt = async () => {
|
|
1564
|
+
const token = await options.auth.resolveToken();
|
|
1565
|
+
signal.throwIfAborted();
|
|
1545
1566
|
const res = await options.fetch(`${options.host}/v1/datafile`, {
|
|
1546
1567
|
headers: {
|
|
1547
1568
|
Authorization: `Bearer ${token}`,
|
|
1548
1569
|
"User-Agent": `VercelFlagsCore/${version}`,
|
|
1549
1570
|
...process.env.VERCEL_ENV ? { "X-Vercel-Env": process.env.VERCEL_ENV } : null
|
|
1550
1571
|
},
|
|
1551
|
-
signal
|
|
1572
|
+
signal
|
|
1552
1573
|
});
|
|
1553
|
-
|
|
1554
|
-
_optionalChain([options, 'access', _44 => _44.signal, 'optionalAccess', _45 => _45.removeEventListener, 'call', _46 => _46("abort", onExternalAbort)]);
|
|
1574
|
+
signal.throwIfAborted();
|
|
1555
1575
|
if (!res.ok) {
|
|
1556
|
-
|
|
1576
|
+
void _optionalChain([res, 'access', _52 => _52.body, 'optionalAccess', _53 => _53.cancel, 'call', _54 => _54(), 'access', _55 => _55.catch, 'call', _56 => _56(() => {
|
|
1577
|
+
})]);
|
|
1578
|
+
throw new DatafileHttpError(res.status, res.statusText);
|
|
1557
1579
|
}
|
|
1558
|
-
|
|
1559
|
-
|
|
1580
|
+
const data = await res.json();
|
|
1581
|
+
signal.throwIfAborted();
|
|
1582
|
+
return data;
|
|
1583
|
+
};
|
|
1584
|
+
try {
|
|
1585
|
+
for (let attempt = 0; ; attempt++) {
|
|
1586
|
+
if (attempt > 0) {
|
|
1587
|
+
await Promise.race([
|
|
1588
|
+
new Promise((resolve) => {
|
|
1589
|
+
delay = setTimeout(resolve, 100 * 2 ** (attempt - 1));
|
|
1590
|
+
}),
|
|
1591
|
+
aborted
|
|
1592
|
+
]);
|
|
1593
|
+
}
|
|
1594
|
+
signal.throwIfAborted();
|
|
1595
|
+
try {
|
|
1596
|
+
return await Promise.race([fetchAttempt(), aborted]);
|
|
1597
|
+
} catch (error) {
|
|
1598
|
+
signal.throwIfAborted();
|
|
1599
|
+
if (attempt === maxAttempts - 1 || error instanceof DatafileHttpError && !error.retryable) {
|
|
1600
|
+
throw error instanceof Error ? error : new Error("Unknown fetch error");
|
|
1601
|
+
}
|
|
1602
|
+
}
|
|
1603
|
+
}
|
|
1604
|
+
} finally {
|
|
1560
1605
|
clearTimeout(timeoutId);
|
|
1561
|
-
|
|
1562
|
-
|
|
1606
|
+
clearTimeout(delay);
|
|
1607
|
+
signal.removeEventListener("abort", onAbort);
|
|
1608
|
+
_optionalChain([options, 'access', _57 => _57.signal, 'optionalAccess', _58 => _58.removeEventListener, 'call', _59 => _59("abort", onExternalAbort)]);
|
|
1563
1609
|
}
|
|
1564
1610
|
}
|
|
1565
1611
|
|
|
@@ -1628,7 +1674,7 @@ var TypedEmitter = (_class5 = class {constructor() { _class5.prototype.__init12.
|
|
|
1628
1674
|
set.add(handler);
|
|
1629
1675
|
}
|
|
1630
1676
|
off(event, handler) {
|
|
1631
|
-
_optionalChain([this, 'access',
|
|
1677
|
+
_optionalChain([this, 'access', _60 => _60.handlers, 'access', _61 => _61.get, 'call', _62 => _62(event), 'optionalAccess', _63 => _63.delete, 'call', _64 => _64(handler)]);
|
|
1632
1678
|
}
|
|
1633
1679
|
emit(event, ...args) {
|
|
1634
1680
|
const set = this.handlers.get(event);
|
|
@@ -1654,14 +1700,17 @@ var PollingSource = class extends TypedEmitter {
|
|
|
1654
1700
|
* Emits 'data' on success, 'error' on failure.
|
|
1655
1701
|
*/
|
|
1656
1702
|
async poll() {
|
|
1657
|
-
if (_optionalChain([this, 'access',
|
|
1703
|
+
if (_optionalChain([this, 'access', _65 => _65.abortController, 'optionalAccess', _66 => _66.signal, 'access', _67 => _67.aborted])) return;
|
|
1704
|
+
this.abortController ??= new AbortController();
|
|
1705
|
+
const controller = this.abortController;
|
|
1658
1706
|
try {
|
|
1659
1707
|
const data = await fetchDatafile({
|
|
1660
1708
|
...this.config,
|
|
1661
|
-
signal:
|
|
1709
|
+
signal: controller.signal
|
|
1662
1710
|
});
|
|
1663
1711
|
this.emit("data", data);
|
|
1664
1712
|
} catch (error) {
|
|
1713
|
+
controller.signal.throwIfAborted();
|
|
1665
1714
|
const err = error instanceof Error ? error : new Error("Unknown poll error");
|
|
1666
1715
|
this.emit("error", err);
|
|
1667
1716
|
}
|
|
@@ -1673,9 +1722,9 @@ var PollingSource = class extends TypedEmitter {
|
|
|
1673
1722
|
*/
|
|
1674
1723
|
startInterval() {
|
|
1675
1724
|
if (this.intervalId) return;
|
|
1676
|
-
this.abortController = new AbortController();
|
|
1677
1725
|
this.intervalId = setInterval(
|
|
1678
|
-
() => void this.poll()
|
|
1726
|
+
() => void this.poll().catch(() => {
|
|
1727
|
+
}),
|
|
1679
1728
|
this.config.polling.intervalMs
|
|
1680
1729
|
);
|
|
1681
1730
|
}
|
|
@@ -1687,7 +1736,7 @@ var PollingSource = class extends TypedEmitter {
|
|
|
1687
1736
|
clearInterval(this.intervalId);
|
|
1688
1737
|
this.intervalId = void 0;
|
|
1689
1738
|
}
|
|
1690
|
-
_optionalChain([this, 'access',
|
|
1739
|
+
_optionalChain([this, 'access', _68 => _68.abortController, 'optionalAccess', _69 => _69.abort, 'call', _70 => _70()]);
|
|
1691
1740
|
this.abortController = void 0;
|
|
1692
1741
|
}
|
|
1693
1742
|
};
|
|
@@ -1766,7 +1815,7 @@ async function connectStream(config, callbacks) {
|
|
|
1766
1815
|
if (pingTimeoutId !== void 0) clearTimeout(pingTimeoutId);
|
|
1767
1816
|
if (!initialDataReceived) return;
|
|
1768
1817
|
pingTimeoutId = setTimeout(() => {
|
|
1769
|
-
_optionalChain([responseBody, 'optionalAccess',
|
|
1818
|
+
_optionalChain([responseBody, 'optionalAccess', _71 => _71.cancel, 'call', _72 => _72(), 'access', _73 => _73.catch, 'call', _74 => _74(() => {
|
|
1770
1819
|
})]);
|
|
1771
1820
|
connectionAbort.abort();
|
|
1772
1821
|
}, PING_TIMEOUT_MS);
|
|
@@ -1788,7 +1837,7 @@ async function connectStream(config, callbacks) {
|
|
|
1788
1837
|
if (vercelEnv) {
|
|
1789
1838
|
headers["X-Vercel-Env"] = vercelEnv;
|
|
1790
1839
|
}
|
|
1791
|
-
const revision = _optionalChain([config, 'access',
|
|
1840
|
+
const revision = _optionalChain([config, 'access', _75 => _75.revision, 'optionalCall', _76 => _76()]);
|
|
1792
1841
|
if (revision !== void 0) {
|
|
1793
1842
|
headers["X-Revision"] = String(revision);
|
|
1794
1843
|
}
|
|
@@ -1850,7 +1899,7 @@ async function connectStream(config, callbacks) {
|
|
|
1850
1899
|
resetPingTimeout();
|
|
1851
1900
|
}
|
|
1852
1901
|
if (message.type === "primed") {
|
|
1853
|
-
_optionalChain([onPrimed, 'optionalCall',
|
|
1902
|
+
_optionalChain([onPrimed, 'optionalCall', _77 => _77(message)]);
|
|
1854
1903
|
retryCount = 0;
|
|
1855
1904
|
if (!initialDataReceived) {
|
|
1856
1905
|
initialDataReceived = true;
|
|
@@ -1873,7 +1922,7 @@ async function connectStream(config, callbacks) {
|
|
|
1873
1922
|
clearTimeout(pingTimeoutId);
|
|
1874
1923
|
abortController.signal.removeEventListener("abort", onMainAbort);
|
|
1875
1924
|
if (!abortController.signal.aborted) {
|
|
1876
|
-
_optionalChain([onDisconnect, 'optionalCall',
|
|
1925
|
+
_optionalChain([onDisconnect, 'optionalCall', _78 => _78()]);
|
|
1877
1926
|
retryCount++;
|
|
1878
1927
|
const elapsed = Date.now() - lastAttemptTime;
|
|
1879
1928
|
const minGap = Math.max(0, BASE_RETRY_DELAY_MS - elapsed);
|
|
@@ -1894,7 +1943,7 @@ async function connectStream(config, callbacks) {
|
|
|
1894
1943
|
if (!connectionAbort.signal.aborted) {
|
|
1895
1944
|
lastError = error;
|
|
1896
1945
|
}
|
|
1897
|
-
_optionalChain([onDisconnect, 'optionalCall',
|
|
1946
|
+
_optionalChain([onDisconnect, 'optionalCall', _79 => _79()]);
|
|
1898
1947
|
retryCount++;
|
|
1899
1948
|
const elapsed = Date.now() - lastAttemptTime;
|
|
1900
1949
|
const minGap = Math.max(0, BASE_RETRY_DELAY_MS - elapsed);
|
|
@@ -1973,7 +2022,7 @@ var StreamSource = class extends TypedEmitter {
|
|
|
1973
2022
|
* Stop the stream connection.
|
|
1974
2023
|
*/
|
|
1975
2024
|
stop() {
|
|
1976
|
-
_optionalChain([this, 'access',
|
|
2025
|
+
_optionalChain([this, 'access', _80 => _80.abortController, 'optionalAccess', _81 => _81.abort, 'call', _82 => _82()]);
|
|
1977
2026
|
this.abortController = void 0;
|
|
1978
2027
|
this.promise = void 0;
|
|
1979
2028
|
}
|
|
@@ -2032,7 +2081,7 @@ var Controller = (_class6 = class {
|
|
|
2032
2081
|
this.options = normalizeOptions(options);
|
|
2033
2082
|
this.streamSource = new StreamSource(
|
|
2034
2083
|
this.options,
|
|
2035
|
-
() => _optionalChain([this, 'access',
|
|
2084
|
+
() => _optionalChain([this, 'access', _83 => _83.data, 'optionalAccess', _84 => _84.revision])
|
|
2036
2085
|
);
|
|
2037
2086
|
this.pollingSource = new PollingSource(this.options);
|
|
2038
2087
|
this.bundledSource = new BundledSource({
|
|
@@ -2574,11 +2623,11 @@ var Controller = (_class6 = class {
|
|
|
2574
2623
|
duration: Date.now() - startTime,
|
|
2575
2624
|
mode: mode === "streaming" ? "stream" : mode === "polling" ? "poll" : mode
|
|
2576
2625
|
};
|
|
2577
|
-
const configUpdatedAt = _optionalChain([this, 'access',
|
|
2626
|
+
const configUpdatedAt = _optionalChain([this, 'access', _85 => _85.data, 'optionalAccess', _86 => _86.configUpdatedAt]);
|
|
2578
2627
|
if (typeof configUpdatedAt === "number") {
|
|
2579
2628
|
trackOptions.configUpdatedAt = configUpdatedAt;
|
|
2580
2629
|
}
|
|
2581
|
-
const revision = _optionalChain([this, 'access',
|
|
2630
|
+
const revision = _optionalChain([this, 'access', _87 => _87.data, 'optionalAccess', _88 => _88.revision]);
|
|
2582
2631
|
if (typeof revision === "number") {
|
|
2583
2632
|
trackOptions.revision = revision;
|
|
2584
2633
|
}
|
|
@@ -2750,4 +2799,4 @@ var {
|
|
|
2750
2799
|
|
|
2751
2800
|
|
|
2752
2801
|
exports.ResolutionReason = ResolutionReason; exports.evaluate = evaluate; exports.FallbackNotFoundError = FallbackNotFoundError; exports.FallbackEntryNotFoundError = FallbackEntryNotFoundError; exports.Controller = Controller; exports.flagsClient = flagsClient; exports.resetDefaultFlagsClient = resetDefaultFlagsClient; exports.createClient = createClient;
|
|
2753
|
-
//# sourceMappingURL=chunk-
|
|
2802
|
+
//# sourceMappingURL=chunk-UX43BKE3.cjs.map
|