@vercel/flags-core 1.8.1 → 1.9.0-0fd2f41-20260915094243
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/README.md +50 -5
- package/dist/{chunk-5BWCBI7I.js → chunk-FEALIMCH.js} +276 -49
- package/dist/chunk-FEALIMCH.js.map +1 -0
- package/dist/{chunk-CVDAHZHK.cjs → chunk-OXUU7M2A.cjs} +295 -68
- package/dist/chunk-OXUU7M2A.cjs.map +1 -0
- package/dist/{chunk-DYSF37WV.js → chunk-XFCAUSUZ.js} +276 -49
- package/dist/chunk-XFCAUSUZ.js.map +1 -0
- package/dist/{chunk-CKL562EU.cjs → chunk-ZUO5MVUD.cjs} +295 -68
- package/dist/chunk-ZUO5MVUD.cjs.map +1 -0
- package/dist/index.default.cjs +2 -2
- package/dist/index.default.d.cts +9 -2
- package/dist/index.default.d.ts +9 -2
- package/dist/index.default.js +1 -1
- package/dist/index.next-js.cjs +2 -2
- package/dist/index.next-js.d.cts +9 -2
- package/dist/index.next-js.d.ts +9 -2
- 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-w8u8i22D.d.cts} +15 -5
- package/dist/{types-CIONStRG.d.ts → types-w8u8i22D.d.ts} +15 -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
|
@@ -558,7 +558,7 @@ function bulkEvaluate(flags, shared) {
|
|
|
558
558
|
}
|
|
559
559
|
|
|
560
560
|
// package.json
|
|
561
|
-
var version = "1.
|
|
561
|
+
var version = "1.9.0-0fd2f41-20260915094243";
|
|
562
562
|
|
|
563
563
|
// src/lib/report-value.ts
|
|
564
564
|
function internalReportValue(key, value, data) {
|
|
@@ -956,6 +956,12 @@ function createCreateRawClient(fns) {
|
|
|
956
956
|
};
|
|
957
957
|
}
|
|
958
958
|
|
|
959
|
+
// src/utils/debug.ts
|
|
960
|
+
function debugLog(source, message, details = {}) {
|
|
961
|
+
if (!process.env.DEBUG?.includes("@vercel/flags-core")) return;
|
|
962
|
+
console.log(`@vercel/flags-core [${source}] ${message}`, details);
|
|
963
|
+
}
|
|
964
|
+
|
|
959
965
|
// src/utils/read-bundled-definitions.ts
|
|
960
966
|
var sdkKeyHashCache = /* @__PURE__ */ new Map();
|
|
961
967
|
async function computeHash(sdkKey) {
|
|
@@ -1036,7 +1042,7 @@ var MAX_EVENTS_PER_REQUEST = 2e3;
|
|
|
1036
1042
|
var EVALUATING_OIDC_TOKEN_HEADER = "X-Vercel-Flags-OIDC-Token";
|
|
1037
1043
|
var FLUSH_REASON_HEADER = "X-Vercel-Flags-Flush-Reason";
|
|
1038
1044
|
var isDebugMode = process.env.DEBUG?.includes("@vercel/flags-core");
|
|
1039
|
-
var
|
|
1045
|
+
var debugLog2 = (...args) => {
|
|
1040
1046
|
if (!isDebugMode) return;
|
|
1041
1047
|
console.log(...args);
|
|
1042
1048
|
};
|
|
@@ -1082,7 +1088,7 @@ async function sendIngestChunk(options, eventsToSend, flushId, flushReason) {
|
|
|
1082
1088
|
headers: await getIngestHeaders(options, flushReason),
|
|
1083
1089
|
body: JSON.stringify(eventsToSend)
|
|
1084
1090
|
});
|
|
1085
|
-
|
|
1091
|
+
debugLog2(
|
|
1086
1092
|
`@vercel/flags-core: Ingest response ${response.status} for ${eventsToSend.length} events on ${response.headers.get("x-vercel-id")}`
|
|
1087
1093
|
);
|
|
1088
1094
|
if (response.ok) {
|
|
@@ -1479,6 +1485,178 @@ async function fetchDatafile(options) {
|
|
|
1479
1485
|
}
|
|
1480
1486
|
}
|
|
1481
1487
|
|
|
1488
|
+
// src/controller/header-source.ts
|
|
1489
|
+
import { waitUntil as waitUntil3 } from "@vercel/functions";
|
|
1490
|
+
|
|
1491
|
+
// src/controller/tagged-data.ts
|
|
1492
|
+
function tagData(data, origin) {
|
|
1493
|
+
return Object.assign(data, { _origin: origin });
|
|
1494
|
+
}
|
|
1495
|
+
function originToMetricsSource(origin) {
|
|
1496
|
+
switch (origin) {
|
|
1497
|
+
case "stream":
|
|
1498
|
+
case "poll":
|
|
1499
|
+
case "provided":
|
|
1500
|
+
return "in-memory";
|
|
1501
|
+
case "fetched":
|
|
1502
|
+
return "remote";
|
|
1503
|
+
case "bundled":
|
|
1504
|
+
return "embedded";
|
|
1505
|
+
}
|
|
1506
|
+
}
|
|
1507
|
+
|
|
1508
|
+
// src/controller/typed-emitter.ts
|
|
1509
|
+
var TypedEmitter = class {
|
|
1510
|
+
handlers = /* @__PURE__ */ new Map();
|
|
1511
|
+
on(event, handler) {
|
|
1512
|
+
let set = this.handlers.get(event);
|
|
1513
|
+
if (!set) {
|
|
1514
|
+
set = /* @__PURE__ */ new Set();
|
|
1515
|
+
this.handlers.set(event, set);
|
|
1516
|
+
}
|
|
1517
|
+
set.add(handler);
|
|
1518
|
+
}
|
|
1519
|
+
off(event, handler) {
|
|
1520
|
+
this.handlers.get(event)?.delete(handler);
|
|
1521
|
+
}
|
|
1522
|
+
emit(event, ...args) {
|
|
1523
|
+
const set = this.handlers.get(event);
|
|
1524
|
+
if (set) {
|
|
1525
|
+
for (const handler of set) {
|
|
1526
|
+
handler(...args);
|
|
1527
|
+
}
|
|
1528
|
+
}
|
|
1529
|
+
}
|
|
1530
|
+
};
|
|
1531
|
+
|
|
1532
|
+
// src/controller/header-source.ts
|
|
1533
|
+
var HeaderSource = class extends TypedEmitter {
|
|
1534
|
+
options;
|
|
1535
|
+
abortController;
|
|
1536
|
+
promise;
|
|
1537
|
+
constructor(options) {
|
|
1538
|
+
super();
|
|
1539
|
+
this.options = options;
|
|
1540
|
+
}
|
|
1541
|
+
fetchDatafile() {
|
|
1542
|
+
if (this.promise) {
|
|
1543
|
+
debugLog("header-source", "Reusing pending refresh");
|
|
1544
|
+
return this.promise;
|
|
1545
|
+
}
|
|
1546
|
+
debugLog("header-source", "Starting refresh");
|
|
1547
|
+
const abortController = new AbortController();
|
|
1548
|
+
this.abortController = abortController;
|
|
1549
|
+
this.promise = fetchDatafile({
|
|
1550
|
+
...this.options,
|
|
1551
|
+
signal: abortController.signal
|
|
1552
|
+
}).then((data) => {
|
|
1553
|
+
abortController.signal.throwIfAborted();
|
|
1554
|
+
debugLog("header-source", "Refresh completed", {
|
|
1555
|
+
projectId: data.projectId,
|
|
1556
|
+
configUpdatedAt: Number(data.configUpdatedAt),
|
|
1557
|
+
revision: data.revision
|
|
1558
|
+
});
|
|
1559
|
+
this.emit("data", data);
|
|
1560
|
+
return data;
|
|
1561
|
+
}).catch((error) => {
|
|
1562
|
+
debugLog("header-source", "Refresh failed", {
|
|
1563
|
+
aborted: abortController.signal.aborted
|
|
1564
|
+
});
|
|
1565
|
+
throw error;
|
|
1566
|
+
}).finally(() => {
|
|
1567
|
+
if (this.abortController === abortController) {
|
|
1568
|
+
this.promise = void 0;
|
|
1569
|
+
this.abortController = void 0;
|
|
1570
|
+
}
|
|
1571
|
+
});
|
|
1572
|
+
return this.promise;
|
|
1573
|
+
}
|
|
1574
|
+
getUpdatedAtHeader(projectId) {
|
|
1575
|
+
const ctx = getRequestContext();
|
|
1576
|
+
const headerName = ctx.headers?.["x-vercel-edge-config-versions"] != null ? "x-vercel-edge-config-versions" : "edge-config-versions";
|
|
1577
|
+
const header = ctx.headers?.[headerName];
|
|
1578
|
+
if (!header) {
|
|
1579
|
+
debugLog("header-source", "Header unavailable", {
|
|
1580
|
+
projectId,
|
|
1581
|
+
reason: "missing-header"
|
|
1582
|
+
});
|
|
1583
|
+
return;
|
|
1584
|
+
}
|
|
1585
|
+
const prefix = `flags_${projectId}=`;
|
|
1586
|
+
const value = header.split(";").map((part) => part.trim()).find((part) => part.startsWith(prefix))?.slice(prefix.length);
|
|
1587
|
+
const timestamp = Number(value);
|
|
1588
|
+
if (!Number.isFinite(timestamp) || timestamp <= 0) {
|
|
1589
|
+
debugLog("header-source", "Header unavailable", {
|
|
1590
|
+
projectId,
|
|
1591
|
+
headerName,
|
|
1592
|
+
reason: value === void 0 ? "project-not-found" : "invalid-timestamp"
|
|
1593
|
+
});
|
|
1594
|
+
return;
|
|
1595
|
+
}
|
|
1596
|
+
debugLog("header-source", "Header version available", {
|
|
1597
|
+
projectId,
|
|
1598
|
+
headerName,
|
|
1599
|
+
timestamp
|
|
1600
|
+
});
|
|
1601
|
+
return timestamp;
|
|
1602
|
+
}
|
|
1603
|
+
async resolveData(currentData) {
|
|
1604
|
+
if (!currentData.configUpdatedAt) {
|
|
1605
|
+
debugLog("header-source", "Skipping header refresh", {
|
|
1606
|
+
projectId: currentData.projectId,
|
|
1607
|
+
reason: "missing-data-timestamp"
|
|
1608
|
+
});
|
|
1609
|
+
return;
|
|
1610
|
+
}
|
|
1611
|
+
const updatedAtHeader = this.getUpdatedAtHeader(currentData.projectId);
|
|
1612
|
+
if (!updatedAtHeader) {
|
|
1613
|
+
return;
|
|
1614
|
+
}
|
|
1615
|
+
const currentUpdatedAt = Number(currentData.configUpdatedAt);
|
|
1616
|
+
const deltaMs = updatedAtHeader - currentUpdatedAt;
|
|
1617
|
+
debugLog("header-source", "Freshness decision", {
|
|
1618
|
+
projectId: currentData.projectId,
|
|
1619
|
+
currentUpdatedAt,
|
|
1620
|
+
headerUpdatedAt: updatedAtHeader,
|
|
1621
|
+
deltaMs,
|
|
1622
|
+
action: updatedAtHeader <= currentUpdatedAt ? "serve-cached" : updatedAtHeader <= currentUpdatedAt + 1e4 ? "background-refresh" : "blocking-refresh"
|
|
1623
|
+
});
|
|
1624
|
+
if (updatedAtHeader <= currentUpdatedAt) {
|
|
1625
|
+
return [currentData, "HIT"];
|
|
1626
|
+
}
|
|
1627
|
+
if (updatedAtHeader <= currentUpdatedAt + 1e4) {
|
|
1628
|
+
const pending = this.fetchDatafile();
|
|
1629
|
+
const signal = this.abortController?.signal;
|
|
1630
|
+
const background = pending.catch((error) => {
|
|
1631
|
+
if (!signal?.aborted) {
|
|
1632
|
+
console.error("@vercel/flags-core: Header refresh failed:", error);
|
|
1633
|
+
}
|
|
1634
|
+
});
|
|
1635
|
+
waitUntil3(background);
|
|
1636
|
+
return [currentData, "STALE"];
|
|
1637
|
+
}
|
|
1638
|
+
const data = await this.fetchDatafile();
|
|
1639
|
+
return [tagData(data, "fetched"), "MISS"];
|
|
1640
|
+
}
|
|
1641
|
+
read(currentData) {
|
|
1642
|
+
return this.resolveData(currentData);
|
|
1643
|
+
}
|
|
1644
|
+
isAvailable(projectId) {
|
|
1645
|
+
return !!this.getUpdatedAtHeader(projectId);
|
|
1646
|
+
}
|
|
1647
|
+
/**
|
|
1648
|
+
* Abort the current header-driven fetch and discard its pending work.
|
|
1649
|
+
*/
|
|
1650
|
+
stop() {
|
|
1651
|
+
debugLog("header-source", "Stopping header refresh", {
|
|
1652
|
+
pending: this.promise !== void 0
|
|
1653
|
+
});
|
|
1654
|
+
this.abortController?.abort();
|
|
1655
|
+
this.abortController = void 0;
|
|
1656
|
+
this.promise = void 0;
|
|
1657
|
+
}
|
|
1658
|
+
};
|
|
1659
|
+
|
|
1482
1660
|
// src/controller/normalized-options.ts
|
|
1483
1661
|
var DEFAULT_STREAM_INIT_TIMEOUT_MS = 3e3;
|
|
1484
1662
|
var DEFAULT_POLLING_INTERVAL_MS = 3e4;
|
|
@@ -1530,30 +1708,6 @@ function normalizeOptions(options) {
|
|
|
1530
1708
|
};
|
|
1531
1709
|
}
|
|
1532
1710
|
|
|
1533
|
-
// src/controller/typed-emitter.ts
|
|
1534
|
-
var TypedEmitter = class {
|
|
1535
|
-
handlers = /* @__PURE__ */ new Map();
|
|
1536
|
-
on(event, handler) {
|
|
1537
|
-
let set = this.handlers.get(event);
|
|
1538
|
-
if (!set) {
|
|
1539
|
-
set = /* @__PURE__ */ new Set();
|
|
1540
|
-
this.handlers.set(event, set);
|
|
1541
|
-
}
|
|
1542
|
-
set.add(handler);
|
|
1543
|
-
}
|
|
1544
|
-
off(event, handler) {
|
|
1545
|
-
this.handlers.get(event)?.delete(handler);
|
|
1546
|
-
}
|
|
1547
|
-
emit(event, ...args) {
|
|
1548
|
-
const set = this.handlers.get(event);
|
|
1549
|
-
if (set) {
|
|
1550
|
-
for (const handler of set) {
|
|
1551
|
-
handler(...args);
|
|
1552
|
-
}
|
|
1553
|
-
}
|
|
1554
|
-
}
|
|
1555
|
-
};
|
|
1556
|
-
|
|
1557
1711
|
// src/controller/polling-source.ts
|
|
1558
1712
|
var PollingSource = class extends TypedEmitter {
|
|
1559
1713
|
config;
|
|
@@ -1839,7 +1993,11 @@ var StreamSource = class extends TypedEmitter {
|
|
|
1839
1993
|
* If already started, returns the existing promise.
|
|
1840
1994
|
*/
|
|
1841
1995
|
start() {
|
|
1842
|
-
if (this.promise)
|
|
1996
|
+
if (this.promise) {
|
|
1997
|
+
debugLog("stream-source", "Reusing stream connection");
|
|
1998
|
+
return this.promise;
|
|
1999
|
+
}
|
|
2000
|
+
debugLog("stream-source", "Starting stream connection");
|
|
1843
2001
|
const abortController = new AbortController();
|
|
1844
2002
|
this.abortController = abortController;
|
|
1845
2003
|
abortController.signal.addEventListener(
|
|
@@ -1863,21 +2021,41 @@ var StreamSource = class extends TypedEmitter {
|
|
|
1863
2021
|
},
|
|
1864
2022
|
{
|
|
1865
2023
|
onDatafile: (newData) => {
|
|
2024
|
+
debugLog("stream-source", "Connected with datafile", {
|
|
2025
|
+
projectId: newData.projectId,
|
|
2026
|
+
configUpdatedAt: Number(newData.configUpdatedAt),
|
|
2027
|
+
revision: newData.revision
|
|
2028
|
+
});
|
|
1866
2029
|
this.emit("data", newData);
|
|
1867
2030
|
this.emit("connected");
|
|
1868
2031
|
},
|
|
1869
2032
|
onPrimed: (message) => {
|
|
2033
|
+
debugLog("stream-source", "Connected with current revision", {
|
|
2034
|
+
projectId: message.projectId,
|
|
2035
|
+
revision: message.revision
|
|
2036
|
+
});
|
|
1870
2037
|
this.emit("primed", message);
|
|
1871
2038
|
this.emit("connected");
|
|
1872
2039
|
},
|
|
1873
2040
|
onDisconnect: () => {
|
|
2041
|
+
debugLog("stream-source", "Disconnected", {
|
|
2042
|
+
aborted: abortController.signal.aborted
|
|
2043
|
+
});
|
|
1874
2044
|
this.emit("disconnected");
|
|
1875
2045
|
}
|
|
1876
2046
|
}
|
|
1877
2047
|
);
|
|
1878
|
-
this.promise = promise
|
|
1879
|
-
|
|
2048
|
+
this.promise = promise.catch((error) => {
|
|
2049
|
+
debugLog("stream-source", "Stream initialization failed", {
|
|
2050
|
+
aborted: abortController.signal.aborted
|
|
2051
|
+
});
|
|
2052
|
+
throw error;
|
|
2053
|
+
});
|
|
2054
|
+
return this.promise;
|
|
1880
2055
|
} catch (error) {
|
|
2056
|
+
debugLog("stream-source", "Stream initialization failed", {
|
|
2057
|
+
aborted: abortController.signal.aborted
|
|
2058
|
+
});
|
|
1881
2059
|
this.promise = void 0;
|
|
1882
2060
|
this.abortController = void 0;
|
|
1883
2061
|
throw error;
|
|
@@ -1887,29 +2065,15 @@ var StreamSource = class extends TypedEmitter {
|
|
|
1887
2065
|
* Stop the stream connection.
|
|
1888
2066
|
*/
|
|
1889
2067
|
stop() {
|
|
2068
|
+
debugLog("stream-source", "Stopping stream connection", {
|
|
2069
|
+
active: this.abortController !== void 0
|
|
2070
|
+
});
|
|
1890
2071
|
this.abortController?.abort();
|
|
1891
2072
|
this.abortController = void 0;
|
|
1892
2073
|
this.promise = void 0;
|
|
1893
2074
|
}
|
|
1894
2075
|
};
|
|
1895
2076
|
|
|
1896
|
-
// src/controller/tagged-data.ts
|
|
1897
|
-
function tagData(data, origin) {
|
|
1898
|
-
return Object.assign(data, { _origin: origin });
|
|
1899
|
-
}
|
|
1900
|
-
function originToMetricsSource(origin) {
|
|
1901
|
-
switch (origin) {
|
|
1902
|
-
case "stream":
|
|
1903
|
-
case "poll":
|
|
1904
|
-
case "provided":
|
|
1905
|
-
return "in-memory";
|
|
1906
|
-
case "fetched":
|
|
1907
|
-
return "remote";
|
|
1908
|
-
case "bundled":
|
|
1909
|
-
return "embedded";
|
|
1910
|
-
}
|
|
1911
|
-
}
|
|
1912
|
-
|
|
1913
2077
|
// src/controller/index.ts
|
|
1914
2078
|
function parseConfigUpdatedAt(value) {
|
|
1915
2079
|
if (typeof value === "number") return value;
|
|
@@ -1934,6 +2098,7 @@ var Controller = class {
|
|
|
1934
2098
|
streamSource;
|
|
1935
2099
|
pollingSource;
|
|
1936
2100
|
bundledSource;
|
|
2101
|
+
headerSource;
|
|
1937
2102
|
// Usage tracking
|
|
1938
2103
|
usageTracker;
|
|
1939
2104
|
isFirstGetData = true;
|
|
@@ -1953,6 +2118,7 @@ var Controller = class {
|
|
|
1953
2118
|
auth: this.options.auth,
|
|
1954
2119
|
readBundledDefinitions
|
|
1955
2120
|
});
|
|
2121
|
+
this.headerSource = new HeaderSource(this.options);
|
|
1956
2122
|
this.wireSourceEvents();
|
|
1957
2123
|
if (this.options.datafile) {
|
|
1958
2124
|
this.data = tagData(this.options.datafile, "provided");
|
|
@@ -1988,6 +2154,11 @@ var Controller = class {
|
|
|
1988
2154
|
onPollError = (error) => {
|
|
1989
2155
|
console.error("@vercel/flags-core: Poll failed:", error);
|
|
1990
2156
|
};
|
|
2157
|
+
onFetchedData = (data) => {
|
|
2158
|
+
if (this.isNewerData(data)) {
|
|
2159
|
+
this.data = tagData(data, "fetched");
|
|
2160
|
+
}
|
|
2161
|
+
};
|
|
1991
2162
|
// ---------------------------------------------------------------------------
|
|
1992
2163
|
// Source event wiring
|
|
1993
2164
|
// ---------------------------------------------------------------------------
|
|
@@ -1998,6 +2169,7 @@ var Controller = class {
|
|
|
1998
2169
|
this.streamSource.on("disconnected", this.onStreamDisconnected);
|
|
1999
2170
|
this.pollingSource.on("data", this.onPollData);
|
|
2000
2171
|
this.pollingSource.on("error", this.onPollError);
|
|
2172
|
+
this.headerSource.on("data", this.onFetchedData);
|
|
2001
2173
|
}
|
|
2002
2174
|
unwireSourceEvents() {
|
|
2003
2175
|
this.streamSource.off("data", this.onStreamData);
|
|
@@ -2006,11 +2178,18 @@ var Controller = class {
|
|
|
2006
2178
|
this.streamSource.off("disconnected", this.onStreamDisconnected);
|
|
2007
2179
|
this.pollingSource.off("data", this.onPollData);
|
|
2008
2180
|
this.pollingSource.off("error", this.onPollError);
|
|
2181
|
+
this.headerSource.off("data", this.onFetchedData);
|
|
2009
2182
|
}
|
|
2010
2183
|
// ---------------------------------------------------------------------------
|
|
2011
2184
|
// State machine
|
|
2012
2185
|
// ---------------------------------------------------------------------------
|
|
2013
2186
|
transition(to) {
|
|
2187
|
+
debugLog("controller", "State changed", {
|
|
2188
|
+
from: this.state,
|
|
2189
|
+
to,
|
|
2190
|
+
projectId: this.data?.projectId,
|
|
2191
|
+
origin: this.data?._origin
|
|
2192
|
+
});
|
|
2014
2193
|
this.state = to;
|
|
2015
2194
|
}
|
|
2016
2195
|
get isConnected() {
|
|
@@ -2023,6 +2202,8 @@ var Controller = class {
|
|
|
2023
2202
|
return "streaming";
|
|
2024
2203
|
case "polling":
|
|
2025
2204
|
return "polling";
|
|
2205
|
+
case "vercel":
|
|
2206
|
+
return "vercel";
|
|
2026
2207
|
default:
|
|
2027
2208
|
return "offline";
|
|
2028
2209
|
}
|
|
@@ -2039,6 +2220,14 @@ var Controller = class {
|
|
|
2039
2220
|
* Offline mode (neither): datafile → bundled → one-time fetch
|
|
2040
2221
|
*/
|
|
2041
2222
|
async initialize() {
|
|
2223
|
+
debugLog("controller", "Initializing", {
|
|
2224
|
+
buildStep: this.options.buildStep,
|
|
2225
|
+
streamEnabled: this.options.stream.enabled,
|
|
2226
|
+
pollingEnabled: this.options.polling.enabled,
|
|
2227
|
+
hasData: this.data !== void 0,
|
|
2228
|
+
projectId: this.data?.projectId,
|
|
2229
|
+
origin: this.data?._origin
|
|
2230
|
+
});
|
|
2042
2231
|
if (this.options.buildStep) {
|
|
2043
2232
|
this.transition("build:loading");
|
|
2044
2233
|
await this.initializeForBuildStep();
|
|
@@ -2058,7 +2247,9 @@ var Controller = class {
|
|
|
2058
2247
|
}
|
|
2059
2248
|
}
|
|
2060
2249
|
if (this.data) {
|
|
2061
|
-
if (this.
|
|
2250
|
+
if (this.headerSource.isAvailable(this.data.projectId)) {
|
|
2251
|
+
this.transition("vercel");
|
|
2252
|
+
} else if (this.options.stream.enabled) {
|
|
2062
2253
|
this.transition("initializing:stream");
|
|
2063
2254
|
await this.tryInitializeStream();
|
|
2064
2255
|
} else if (this.options.polling.enabled) {
|
|
@@ -2069,6 +2260,9 @@ var Controller = class {
|
|
|
2069
2260
|
}
|
|
2070
2261
|
return;
|
|
2071
2262
|
}
|
|
2263
|
+
debugLog("controller", "Header mode unavailable", {
|
|
2264
|
+
reason: "no-definitions"
|
|
2265
|
+
});
|
|
2072
2266
|
if (this.options.stream.enabled) {
|
|
2073
2267
|
this.transition("initializing:stream");
|
|
2074
2268
|
const streamSuccess = await this.tryInitializeStream();
|
|
@@ -2097,6 +2291,15 @@ var Controller = class {
|
|
|
2097
2291
|
const [result, cacheStatus] = await this.resolveData();
|
|
2098
2292
|
const readMs = Date.now() - startTime;
|
|
2099
2293
|
const source = originToMetricsSource(result._origin);
|
|
2294
|
+
debugLog("controller", "Read resolved", {
|
|
2295
|
+
projectId: result.projectId,
|
|
2296
|
+
mode: this.mode,
|
|
2297
|
+
source,
|
|
2298
|
+
origin: result._origin,
|
|
2299
|
+
cacheStatus,
|
|
2300
|
+
configUpdatedAt: parseConfigUpdatedAt(result.configUpdatedAt),
|
|
2301
|
+
revision: result.revision
|
|
2302
|
+
});
|
|
2100
2303
|
this.trackRead(startTime, cacheHadDefinitions, isFirstRead, source);
|
|
2101
2304
|
if (this.dataViewSource !== result) {
|
|
2102
2305
|
const { _origin, ...rest } = result;
|
|
@@ -2121,6 +2324,7 @@ var Controller = class {
|
|
|
2121
2324
|
this.unwireSourceEvents();
|
|
2122
2325
|
this.streamSource.stop();
|
|
2123
2326
|
this.pollingSource.stop();
|
|
2327
|
+
this.headerSource.stop();
|
|
2124
2328
|
this.data = this.options.datafile ? tagData(this.options.datafile, "provided") : void 0;
|
|
2125
2329
|
this.transition("shutdown");
|
|
2126
2330
|
await this.usageTracker.shutdown();
|
|
@@ -2164,6 +2368,15 @@ var Controller = class {
|
|
|
2164
2368
|
}
|
|
2165
2369
|
}
|
|
2166
2370
|
const source = originToMetricsSource(result._origin);
|
|
2371
|
+
debugLog("controller", "Datafile resolved", {
|
|
2372
|
+
projectId: result.projectId,
|
|
2373
|
+
mode: this.mode,
|
|
2374
|
+
source,
|
|
2375
|
+
origin: result._origin,
|
|
2376
|
+
cacheStatus,
|
|
2377
|
+
configUpdatedAt: parseConfigUpdatedAt(result.configUpdatedAt),
|
|
2378
|
+
revision: result.revision
|
|
2379
|
+
});
|
|
2167
2380
|
if (this.dataViewSource !== result) {
|
|
2168
2381
|
const { _origin, ...rest } = result;
|
|
2169
2382
|
this.dataViewBase = rest;
|
|
@@ -2202,6 +2415,12 @@ var Controller = class {
|
|
|
2202
2415
|
return this.resolveDataForBuildStep();
|
|
2203
2416
|
}
|
|
2204
2417
|
if (this.data) {
|
|
2418
|
+
if (this.mode === "vercel") {
|
|
2419
|
+
const result = await this.headerSource.read(this.data);
|
|
2420
|
+
if (result) {
|
|
2421
|
+
return result;
|
|
2422
|
+
}
|
|
2423
|
+
}
|
|
2205
2424
|
const cacheStatus = this.isConnected ? "HIT" : "STALE";
|
|
2206
2425
|
return [this.data, cacheStatus];
|
|
2207
2426
|
}
|
|
@@ -2240,6 +2459,14 @@ var Controller = class {
|
|
|
2240
2459
|
]);
|
|
2241
2460
|
clearTimeout(timeoutId);
|
|
2242
2461
|
if (result === "timeout") {
|
|
2462
|
+
debugLog(
|
|
2463
|
+
"controller",
|
|
2464
|
+
"Stream initialization timed out; using fallback",
|
|
2465
|
+
{
|
|
2466
|
+
timeoutMs: this.options.stream.initTimeoutMs,
|
|
2467
|
+
origin: this.data?._origin
|
|
2468
|
+
}
|
|
2469
|
+
);
|
|
2243
2470
|
console.warn(
|
|
2244
2471
|
"@vercel/flags-core: Stream initialization timeout, falling back while continuing to connect in the background"
|
|
2245
2472
|
);
|
|
@@ -2683,4 +2910,4 @@ export {
|
|
|
2683
2910
|
resetDefaultFlagsClient,
|
|
2684
2911
|
createClient
|
|
2685
2912
|
};
|
|
2686
|
-
//# sourceMappingURL=chunk-
|
|
2913
|
+
//# sourceMappingURL=chunk-XFCAUSUZ.js.map
|