@farm.js/core 0.1.0-beta.3 → 0.1.0-beta.5
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/dist/agent-runtime.d.mts +2 -1
- package/dist/agent-runtime.d.ts +2 -1
- package/dist/api/route-manager.cjs +313 -10
- package/dist/api/route-manager.cjs.map +1 -1
- package/dist/api/route-manager.d.mts +3 -2
- package/dist/api/route-manager.d.ts +3 -2
- package/dist/api/route-manager.mjs +6 -5
- package/dist/api/runtime.cjs +313 -10
- package/dist/api/runtime.cjs.map +1 -1
- package/dist/api/runtime.d.mts +2 -1
- package/dist/api/runtime.d.ts +2 -1
- package/dist/api/runtime.mjs +4 -3
- package/dist/api.cjs +642 -57
- package/dist/api.cjs.map +1 -1
- package/dist/api.d.mts +3 -2
- package/dist/api.d.ts +3 -2
- package/dist/api.mjs +29 -9
- package/dist/{app-DOKxo-LH.d.ts → app-BjN-da13.d.ts} +38 -3
- package/dist/{app-BB3Iu3xh.d.mts → app-CakAr8Be.d.mts} +38 -3
- package/dist/app-markdown.d.mts +2 -1
- package/dist/app-markdown.d.ts +2 -1
- package/dist/cache.cjs +395 -12
- package/dist/cache.cjs.map +1 -1
- package/dist/cache.d.mts +100 -6
- package/dist/cache.d.ts +100 -6
- package/dist/cache.mjs +8 -2
- package/dist/{chunk-XUBZ7JI4.mjs → chunk-2CUKEMVR.mjs} +187 -16
- package/dist/chunk-2CUKEMVR.mjs.map +1 -0
- package/dist/{chunk-OHC6VCDI.mjs → chunk-2NHCNRF6.mjs} +521 -42
- package/dist/chunk-2NHCNRF6.mjs.map +1 -0
- package/dist/{chunk-6WXJ54TC.mjs → chunk-65A7QIKI.mjs} +5 -5
- package/dist/{chunk-6WXJ54TC.mjs.map → chunk-65A7QIKI.mjs.map} +1 -1
- package/dist/{chunk-5QH4IKY3.mjs → chunk-7N62DNSO.mjs} +2 -2
- package/dist/{chunk-XJSHJN4M.mjs → chunk-A2LUXHD2.mjs} +593 -49
- package/dist/chunk-A2LUXHD2.mjs.map +1 -0
- package/dist/chunk-ALCLXXTY.mjs +187 -0
- package/dist/chunk-ALCLXXTY.mjs.map +1 -0
- package/dist/{chunk-CSU4KJJF.mjs → chunk-C2ROET2V.mjs} +2 -2
- package/dist/{chunk-JNYVN7YP.mjs → chunk-EEABSBKK.mjs} +2 -2
- package/dist/{chunk-JNYVN7YP.mjs.map → chunk-EEABSBKK.mjs.map} +1 -1
- package/dist/{chunk-BIOIOWXZ.mjs → chunk-HNIQFZKB.mjs} +2 -2
- package/dist/{chunk-MH6FKW2I.mjs → chunk-J5YWQVI5.mjs} +4 -4
- package/dist/chunk-J5YWQVI5.mjs.map +1 -0
- package/dist/{chunk-G5I34UA6.mjs → chunk-JDEOUK5V.mjs} +4 -4
- package/dist/{chunk-T543TMFY.mjs → chunk-NM3CRAAL.mjs} +3 -2
- package/dist/chunk-NM3CRAAL.mjs.map +1 -0
- package/dist/{chunk-LWMGIEJA.mjs → chunk-PFE6GMNE.mjs} +47 -37
- package/dist/chunk-PFE6GMNE.mjs.map +1 -0
- package/dist/{chunk-6VS6CKAV.mjs → chunk-QM746KUO.mjs} +8 -1
- package/dist/chunk-QM746KUO.mjs.map +1 -0
- package/dist/{chunk-5FW6PQ3J.mjs → chunk-QTZZ2ISQ.mjs} +41 -16
- package/dist/chunk-QTZZ2ISQ.mjs.map +1 -0
- package/dist/{chunk-SHRJG6OG.mjs → chunk-RBRLLZL5.mjs} +18 -3
- package/dist/chunk-RBRLLZL5.mjs.map +1 -0
- package/dist/{chunk-NRRFGX45.mjs → chunk-TQAEEJB4.mjs} +3 -3
- package/dist/{chunk-45LKHSHJ.mjs → chunk-UB5UOSHB.mjs} +24 -12
- package/dist/chunk-UB5UOSHB.mjs.map +1 -0
- package/dist/chunk-V3XURYJO.mjs +756 -0
- package/dist/chunk-V3XURYJO.mjs.map +1 -0
- package/dist/{chunk-HZYXGV4K.mjs → chunk-VY2UYN5R.mjs} +24 -4
- package/dist/chunk-VY2UYN5R.mjs.map +1 -0
- package/dist/{chunk-C33RALN7.mjs → chunk-W2CRQFF6.mjs} +79 -15
- package/dist/chunk-W2CRQFF6.mjs.map +1 -0
- package/dist/{chunk-LG3YINQN.mjs → chunk-Z5CQMP54.mjs} +3 -3
- package/dist/{client-DiViK9yK.d.mts → client-BT1mFQas.d.mts} +23 -4
- package/dist/{client-DpEBJbts.d.ts → client-Nn0q4eO4.d.ts} +23 -4
- package/dist/{client-plugins-CTnsZz_A.d.ts → client-plugins-Cw4qUGsw.d.ts} +6 -0
- package/dist/{client-plugins-Cnr0D3kk.d.mts → client-plugins-DQQ1adXM.d.mts} +6 -0
- package/dist/client-plugins.d.mts +2 -1
- package/dist/client-plugins.d.ts +2 -1
- package/dist/client.cjs +665 -82
- package/dist/client.cjs.map +1 -1
- package/dist/client.d.mts +71 -5
- package/dist/client.d.ts +71 -5
- package/dist/client.mjs +10 -7
- package/dist/config.d.mts +2 -1
- package/dist/config.d.ts +2 -1
- package/dist/{devtools-HE4FTUDN.mjs → devtools-LVC3VB5P.mjs} +4 -4
- package/dist/docs.cjs +11 -1
- package/dist/docs.cjs.map +1 -1
- package/dist/docs.mjs +4 -4
- package/dist/index.cjs +2113 -198
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +16 -16
- package/dist/index.d.ts +16 -16
- package/dist/index.mjs +49 -21
- package/dist/index.mjs.map +1 -1
- package/dist/integrations.d.mts +2 -1
- package/dist/integrations.d.ts +2 -1
- package/dist/internal/build-runtime.cjs +1455 -90
- package/dist/internal/build-runtime.cjs.map +1 -1
- package/dist/internal/build-runtime.d.mts +4 -3
- package/dist/internal/build-runtime.d.ts +4 -3
- package/dist/internal/build-runtime.mjs +15 -14
- package/dist/internal/config-runtime.cjs +12 -1
- package/dist/internal/config-runtime.cjs.map +1 -1
- package/dist/internal/config-runtime.d.mts +3 -2
- package/dist/internal/config-runtime.d.ts +3 -2
- package/dist/internal/config-runtime.mjs +3 -3
- package/dist/internal/production-runtime.cjs +282 -6
- package/dist/internal/production-runtime.cjs.map +1 -1
- package/dist/internal/production-runtime.d.mts +4 -4
- package/dist/internal/production-runtime.d.ts +4 -4
- package/dist/internal/production-runtime.mjs +4 -2
- package/dist/{metadata-eoVmHoyv.d.ts → metadata-BAPg_Nmo.d.ts} +1 -1
- package/dist/{metadata-Dp8AdvsB.d.mts → metadata-_6i9oFG3.d.mts} +1 -1
- package/dist/middleware.d.mts +4 -3
- package/dist/middleware.d.ts +4 -3
- package/dist/navigation.cjs +40 -15
- package/dist/navigation.cjs.map +1 -1
- package/dist/navigation.mjs +2 -2
- package/dist/plugin.cjs +913 -53
- package/dist/plugin.cjs.map +1 -1
- package/dist/plugin.d.mts +2 -1
- package/dist/plugin.d.ts +2 -1
- package/dist/plugin.mjs +11 -10
- package/dist/{production-runtime-BqTnUTai.d.ts → production-runtime-BoJDc5mc.d.ts} +1 -1
- package/dist/{production-runtime-DtDdG9fc.d.mts → production-runtime-DPfgMV9Y.d.mts} +1 -1
- package/dist/routes.cjs +276 -6
- package/dist/routes.cjs.map +1 -1
- package/dist/routes.d.mts +1 -1
- package/dist/routes.d.ts +1 -1
- package/dist/routes.mjs +3 -3
- package/dist/{runtime-C1B7pSGT.d.mts → runtime-9nQjVM7X.d.mts} +8 -9
- package/dist/{runtime-CdPHt0bv.d.ts → runtime-DgeS2skB.d.ts} +8 -9
- package/dist/server-action-security.cjs +28 -10
- package/dist/server-action-security.cjs.map +1 -1
- package/dist/server-action-security.d.mts +2 -1
- package/dist/server-action-security.d.ts +2 -1
- package/dist/server-action-security.mjs +2 -2
- package/dist/server-fn-client.d.mts +1 -0
- package/dist/server-fn-client.d.ts +1 -0
- package/dist/server-fn.cjs +785 -3
- package/dist/server-fn.cjs.map +1 -1
- package/dist/server-fn.d.mts +10 -1
- package/dist/server-fn.d.ts +10 -1
- package/dist/server-fn.mjs +6 -3
- package/dist/server-plugins.d.mts +3 -2
- package/dist/server-plugins.d.ts +3 -2
- package/dist/server-query-client.cjs +279 -8
- package/dist/server-query-client.cjs.map +1 -1
- package/dist/server-query-client.mjs +4 -4
- package/dist/server-query.cjs +381 -10
- package/dist/server-query.cjs.map +1 -1
- package/dist/server-query.mjs +5 -5
- package/dist/server.cjs +1086 -76
- package/dist/server.cjs.map +1 -1
- package/dist/server.d.mts +8 -7
- package/dist/server.d.ts +8 -7
- package/dist/server.mjs +31 -16
- package/dist/server.mjs.map +1 -1
- package/dist/testing.cjs +341 -20
- package/dist/testing.cjs.map +1 -1
- package/dist/testing.d.mts +3 -2
- package/dist/testing.d.ts +3 -2
- package/dist/testing.mjs +7 -6
- package/dist/testing.mjs.map +1 -1
- package/dist/transport-BmbGTXA5.d.mts +49 -0
- package/dist/transport-BmbGTXA5.d.ts +49 -0
- package/dist/{utils-8USa5BiY.d.mts → utils-CHXlMDkg.d.mts} +1 -1
- package/dist/{utils-DKJb6K6G.d.ts → utils-Drsyz1Vj.d.ts} +1 -1
- package/dist/version.cjs +1 -1
- package/dist/version.cjs.map +1 -1
- package/dist/version.mjs +1 -1
- package/dist/vite.cjs +914 -54
- package/dist/vite.cjs.map +1 -1
- package/dist/vite.d.mts +2 -1
- package/dist/vite.d.ts +2 -1
- package/dist/vite.mjs +11 -10
- package/package.json +1 -1
- package/types/api.d.ts +44 -0
- package/types/client.d.ts +85 -4
- package/dist/chunk-45LKHSHJ.mjs.map +0 -1
- package/dist/chunk-5FW6PQ3J.mjs.map +0 -1
- package/dist/chunk-6VS6CKAV.mjs.map +0 -1
- package/dist/chunk-C33RALN7.mjs.map +0 -1
- package/dist/chunk-GZWT6VI5.mjs +0 -382
- package/dist/chunk-GZWT6VI5.mjs.map +0 -1
- package/dist/chunk-HZYXGV4K.mjs.map +0 -1
- package/dist/chunk-LWMGIEJA.mjs.map +0 -1
- package/dist/chunk-MH6FKW2I.mjs.map +0 -1
- package/dist/chunk-OHC6VCDI.mjs.map +0 -1
- package/dist/chunk-SHRJG6OG.mjs.map +0 -1
- package/dist/chunk-T543TMFY.mjs.map +0 -1
- package/dist/chunk-XJSHJN4M.mjs.map +0 -1
- package/dist/chunk-XUBZ7JI4.mjs.map +0 -1
- /package/dist/{chunk-5QH4IKY3.mjs.map → chunk-7N62DNSO.mjs.map} +0 -0
- /package/dist/{chunk-CSU4KJJF.mjs.map → chunk-C2ROET2V.mjs.map} +0 -0
- /package/dist/{chunk-BIOIOWXZ.mjs.map → chunk-HNIQFZKB.mjs.map} +0 -0
- /package/dist/{chunk-G5I34UA6.mjs.map → chunk-JDEOUK5V.mjs.map} +0 -0
- /package/dist/{chunk-NRRFGX45.mjs.map → chunk-TQAEEJB4.mjs.map} +0 -0
- /package/dist/{chunk-LG3YINQN.mjs.map → chunk-Z5CQMP54.mjs.map} +0 -0
- /package/dist/{devtools-HE4FTUDN.mjs.map → devtools-LVC3VB5P.mjs.map} +0 -0
package/dist/server.cjs
CHANGED
|
@@ -1819,7 +1819,8 @@ var init_route_rules = __esm({
|
|
|
1819
1819
|
// src/cache-invalidation.ts
|
|
1820
1820
|
function getFarmCacheInvalidationState() {
|
|
1821
1821
|
return globalState[FARM_CACHE_INVALIDATION_STATE] ?? (globalState[FARM_CACHE_INVALIDATION_STATE] = {
|
|
1822
|
-
listeners: /* @__PURE__ */ new Set()
|
|
1822
|
+
listeners: /* @__PURE__ */ new Set(),
|
|
1823
|
+
taskListeners: /* @__PURE__ */ new Set()
|
|
1823
1824
|
});
|
|
1824
1825
|
}
|
|
1825
1826
|
function notifyFarmCacheInvalidation(key) {
|
|
@@ -1828,6 +1829,11 @@ function notifyFarmCacheInvalidation(key) {
|
|
|
1828
1829
|
listener(key);
|
|
1829
1830
|
}
|
|
1830
1831
|
}
|
|
1832
|
+
function notifyFarmCacheTask(task) {
|
|
1833
|
+
for (const listener of getFarmCacheInvalidationState().taskListeners) {
|
|
1834
|
+
listener(task);
|
|
1835
|
+
}
|
|
1836
|
+
}
|
|
1831
1837
|
function applyFarmCacheInvalidations(keys) {
|
|
1832
1838
|
if (!Array.isArray(keys)) return;
|
|
1833
1839
|
for (const key of keys) {
|
|
@@ -1859,6 +1865,11 @@ function subscribeFarmCacheInvalidation(listener) {
|
|
|
1859
1865
|
state.listeners.add(listener);
|
|
1860
1866
|
return () => state.listeners.delete(listener);
|
|
1861
1867
|
}
|
|
1868
|
+
function subscribeFarmCacheTask(listener) {
|
|
1869
|
+
const state = getFarmCacheInvalidationState();
|
|
1870
|
+
state.taskListeners.add(listener);
|
|
1871
|
+
return () => state.taskListeners.delete(listener);
|
|
1872
|
+
}
|
|
1862
1873
|
var FARM_CACHE_INVALIDATION_HEADER, FARM_CACHE_INVALIDATION_STATE, globalState;
|
|
1863
1874
|
var init_cache_invalidation = __esm({
|
|
1864
1875
|
"src/cache-invalidation.ts"() {
|
|
@@ -1868,10 +1879,12 @@ var init_cache_invalidation = __esm({
|
|
|
1868
1879
|
globalState = globalThis;
|
|
1869
1880
|
__name(getFarmCacheInvalidationState, "getFarmCacheInvalidationState");
|
|
1870
1881
|
__name(notifyFarmCacheInvalidation, "notifyFarmCacheInvalidation");
|
|
1882
|
+
__name(notifyFarmCacheTask, "notifyFarmCacheTask");
|
|
1871
1883
|
__name(applyFarmCacheInvalidations, "applyFarmCacheInvalidations");
|
|
1872
1884
|
__name(encodeFarmCacheInvalidations, "encodeFarmCacheInvalidations");
|
|
1873
1885
|
__name(decodeFarmCacheInvalidations, "decodeFarmCacheInvalidations");
|
|
1874
1886
|
__name(subscribeFarmCacheInvalidation, "subscribeFarmCacheInvalidation");
|
|
1887
|
+
__name(subscribeFarmCacheTask, "subscribeFarmCacheTask");
|
|
1875
1888
|
}
|
|
1876
1889
|
});
|
|
1877
1890
|
|
|
@@ -1967,16 +1980,24 @@ function sanitizeServerActionError(_error) {
|
|
|
1967
1980
|
message: "Server function failed"
|
|
1968
1981
|
};
|
|
1969
1982
|
}
|
|
1970
|
-
function runWithServerActionRequest(request, callback) {
|
|
1983
|
+
async function runWithServerActionRequest(request, callback) {
|
|
1971
1984
|
throwIfAborted(request.signal);
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1985
|
+
const context = {
|
|
1986
|
+
request,
|
|
1987
|
+
signal: request.signal,
|
|
1988
|
+
invalidations: /* @__PURE__ */ new Set(),
|
|
1989
|
+
cacheTasks: /* @__PURE__ */ new Set()
|
|
1990
|
+
};
|
|
1991
|
+
return getServerActionStorage().run(context, async () => {
|
|
1992
|
+
try {
|
|
1993
|
+
const result = await callback();
|
|
1994
|
+
await Promise.all(context.cacheTasks);
|
|
1995
|
+
return result;
|
|
1996
|
+
} catch (error) {
|
|
1997
|
+
await Promise.allSettled(context.cacheTasks);
|
|
1998
|
+
throw error;
|
|
1999
|
+
}
|
|
2000
|
+
});
|
|
1980
2001
|
}
|
|
1981
2002
|
function getServerActionExecutionContext() {
|
|
1982
2003
|
return getServerActionStorage().getStore();
|
|
@@ -2287,6 +2308,9 @@ var init_server_action_security = __esm({
|
|
|
2287
2308
|
subscribeFarmCacheInvalidation((key) => {
|
|
2288
2309
|
getServerActionExecutionContext()?.invalidations.add(key);
|
|
2289
2310
|
});
|
|
2311
|
+
subscribeFarmCacheTask((task) => {
|
|
2312
|
+
getServerActionExecutionContext()?.cacheTasks.add(task);
|
|
2313
|
+
});
|
|
2290
2314
|
__name(getServerActionStorage, "getServerActionStorage");
|
|
2291
2315
|
__name(getFallbackAbortController, "getFallbackAbortController");
|
|
2292
2316
|
__name(parseBodySizeLimit, "parseBodySizeLimit");
|
|
@@ -9467,6 +9491,7 @@ async function resolveConfig(userConfig, mode) {
|
|
|
9467
9491
|
observability: userConfig.observability ?? false,
|
|
9468
9492
|
devtools: resolveFarmDevtoolsConfig(userConfig.devtools, mode),
|
|
9469
9493
|
storage: userConfig.storage || {},
|
|
9494
|
+
cache: userConfig.cache || {},
|
|
9470
9495
|
suppressLintOnLink: userConfig.suppressLintOnLink ?? false,
|
|
9471
9496
|
experimental: {
|
|
9472
9497
|
serverComponents: false,
|
|
@@ -12721,6 +12746,7 @@ var init_image_sharp = __esm({
|
|
|
12721
12746
|
// src/server.ts
|
|
12722
12747
|
var server_exports = {};
|
|
12723
12748
|
__export(server_exports, {
|
|
12749
|
+
DEFAULT_FARM_DEV_SERVER_PORT: () => DEFAULT_FARM_DEV_SERVER_PORT,
|
|
12724
12750
|
DEFAULT_SERVER_ACTION_BODY_SIZE_LIMIT: () => DEFAULT_SERVER_ACTION_BODY_SIZE_LIMIT,
|
|
12725
12751
|
FARM_SERVER_QUERY_SYMBOL: () => FARM_SERVER_QUERY_SYMBOL,
|
|
12726
12752
|
FarmApp: () => FarmApp,
|
|
@@ -12733,7 +12759,9 @@ __export(server_exports, {
|
|
|
12733
12759
|
_runWithAfterRequest: () => _runWithAfterRequest,
|
|
12734
12760
|
_withAfterNodeMiddleware: () => _withAfterNodeMiddleware,
|
|
12735
12761
|
after: () => after,
|
|
12762
|
+
applyFarmCacheInvalidationTargets: () => applyFarmCacheInvalidationTargets,
|
|
12736
12763
|
applyFarmCacheInvalidations: () => applyFarmCacheInvalidations,
|
|
12764
|
+
configureFarmCache: () => configureFarmCache,
|
|
12737
12765
|
createClientOnlyFn: () => createClientOnlyFn,
|
|
12738
12766
|
createFarmApp: () => createFarmApp,
|
|
12739
12767
|
createFarmCacheKey: () => createFarmCacheKey,
|
|
@@ -12799,6 +12827,7 @@ __export(server_exports, {
|
|
|
12799
12827
|
segmentsToPattern: () => segmentsToPattern,
|
|
12800
12828
|
sqliteStorage: () => sqliteStorage,
|
|
12801
12829
|
startDevServer: () => startDevServer,
|
|
12830
|
+
storageCacheAdapter: () => storageCacheAdapter,
|
|
12802
12831
|
toViteModuleId: () => toViteModuleId,
|
|
12803
12832
|
unstable_cache: () => unstable_cache,
|
|
12804
12833
|
updateTag: () => updateTag,
|
|
@@ -13502,12 +13531,92 @@ function defineCacheKey() {
|
|
|
13502
13531
|
};
|
|
13503
13532
|
}
|
|
13504
13533
|
__name(defineCacheKey, "defineCacheKey");
|
|
13534
|
+
function storageCacheAdapter(storage, options = {}) {
|
|
13535
|
+
if (!storage || typeof storage.getItem !== "function" || typeof storage.setItem !== "function") {
|
|
13536
|
+
throw new TypeError("storageCacheAdapter expects a compatible storage client.");
|
|
13537
|
+
}
|
|
13538
|
+
const base = normalizeCacheNamespace(options.base || "farm-cache");
|
|
13539
|
+
const entryKey = /* @__PURE__ */ __name((key) => `${base}:entry:${key}`, "entryKey");
|
|
13540
|
+
const tagKey = /* @__PURE__ */ __name((tag) => `${base}:tag:${tag}`, "tagKey");
|
|
13541
|
+
return {
|
|
13542
|
+
name: "storage",
|
|
13543
|
+
get: /* @__PURE__ */ __name((key) => storage.getItem(entryKey(key)), "get"),
|
|
13544
|
+
set: /* @__PURE__ */ __name(async (key, entry) => {
|
|
13545
|
+
await storage.setItem(entryKey(key), entry);
|
|
13546
|
+
}, "set"),
|
|
13547
|
+
delete: /* @__PURE__ */ __name(async (key) => {
|
|
13548
|
+
await storage.removeItem(entryKey(key));
|
|
13549
|
+
}, "delete"),
|
|
13550
|
+
clear: storage.clear ? async () => {
|
|
13551
|
+
await storage.clear(base);
|
|
13552
|
+
} : void 0,
|
|
13553
|
+
getTagVersions: /* @__PURE__ */ __name(async (tags) => {
|
|
13554
|
+
const versions = await Promise.all(
|
|
13555
|
+
tags.map(async (tag) => {
|
|
13556
|
+
const value = await storage.getItem(tagKey(tag));
|
|
13557
|
+
return [tag, normalizeAdapterVersion(value)];
|
|
13558
|
+
})
|
|
13559
|
+
);
|
|
13560
|
+
return Object.fromEntries(versions);
|
|
13561
|
+
}, "getTagVersions"),
|
|
13562
|
+
invalidateTags: /* @__PURE__ */ __name(async (tags) => {
|
|
13563
|
+
await Promise.all(
|
|
13564
|
+
tags.map(async (tag) => {
|
|
13565
|
+
const key = tagKey(tag);
|
|
13566
|
+
const current = normalizeAdapterVersion(await storage.getItem(key));
|
|
13567
|
+
await storage.setItem(key, Math.max(Date.now(), current + 1));
|
|
13568
|
+
})
|
|
13569
|
+
);
|
|
13570
|
+
}, "invalidateTags")
|
|
13571
|
+
};
|
|
13572
|
+
}
|
|
13573
|
+
__name(storageCacheAdapter, "storageCacheAdapter");
|
|
13505
13574
|
var _FarmDataCache = class _FarmDataCache {
|
|
13506
|
-
constructor() {
|
|
13575
|
+
constructor(config = {}) {
|
|
13507
13576
|
this.entries = /* @__PURE__ */ new Map();
|
|
13508
13577
|
this.inflight = /* @__PURE__ */ new Map();
|
|
13509
13578
|
this.invalidatedTagVersions = /* @__PURE__ */ new Map();
|
|
13510
13579
|
this.version = 0;
|
|
13580
|
+
this.namespace = "farm";
|
|
13581
|
+
this.local = true;
|
|
13582
|
+
this.lease = {
|
|
13583
|
+
enabled: true,
|
|
13584
|
+
ttlMs: 1e4,
|
|
13585
|
+
waitTimeoutMs: 1e4,
|
|
13586
|
+
pollIntervalMs: 25
|
|
13587
|
+
};
|
|
13588
|
+
this.configure(config);
|
|
13589
|
+
}
|
|
13590
|
+
configure(config = {}) {
|
|
13591
|
+
this.adapter = config.adapter;
|
|
13592
|
+
this.namespace = normalizeCacheNamespace(config.namespace || "farm");
|
|
13593
|
+
this.local = !config.adapter;
|
|
13594
|
+
this.lease = config.lease === false ? { ...this.lease, enabled: false } : {
|
|
13595
|
+
enabled: true,
|
|
13596
|
+
ttlMs: normalizePositiveDuration(config.lease?.ttlMs, 1e4, "cache.lease.ttlMs"),
|
|
13597
|
+
waitTimeoutMs: normalizePositiveDuration(
|
|
13598
|
+
config.lease?.waitTimeoutMs,
|
|
13599
|
+
1e4,
|
|
13600
|
+
"cache.lease.waitTimeoutMs"
|
|
13601
|
+
),
|
|
13602
|
+
pollIntervalMs: normalizePositiveDuration(
|
|
13603
|
+
config.lease?.pollIntervalMs,
|
|
13604
|
+
25,
|
|
13605
|
+
"cache.lease.pollIntervalMs"
|
|
13606
|
+
)
|
|
13607
|
+
};
|
|
13608
|
+
if (!this.local) {
|
|
13609
|
+
this.entries.clear();
|
|
13610
|
+
this.inflight.clear();
|
|
13611
|
+
this.invalidatedTagVersions.clear();
|
|
13612
|
+
this.version = 0;
|
|
13613
|
+
}
|
|
13614
|
+
}
|
|
13615
|
+
get adapterName() {
|
|
13616
|
+
return this.adapter?.name || (this.adapter ? "custom" : "memory");
|
|
13617
|
+
}
|
|
13618
|
+
get hasAdapter() {
|
|
13619
|
+
return this.adapter !== void 0;
|
|
13511
13620
|
}
|
|
13512
13621
|
get size() {
|
|
13513
13622
|
return this.entries.size;
|
|
@@ -13543,6 +13652,45 @@ var _FarmDataCache = class _FarmDataCache {
|
|
|
13543
13652
|
});
|
|
13544
13653
|
return this.toPublicEntry(entry);
|
|
13545
13654
|
}
|
|
13655
|
+
async getEntryAsync(key, options = {}) {
|
|
13656
|
+
if (this.local) {
|
|
13657
|
+
const localEntry = this.getEntry(key, options);
|
|
13658
|
+
if (localEntry) return localEntry;
|
|
13659
|
+
}
|
|
13660
|
+
if (!this.adapter) {
|
|
13661
|
+
return this.local ? void 0 : this.getEntry(key, options);
|
|
13662
|
+
}
|
|
13663
|
+
const entry = await this.adapter.get(this.createAdapterKey(key));
|
|
13664
|
+
if (!entry) {
|
|
13665
|
+
emitFarmEvent({ type: "cache.miss", key });
|
|
13666
|
+
return void 0;
|
|
13667
|
+
}
|
|
13668
|
+
assertFarmCacheEntry(entry, key);
|
|
13669
|
+
const stale = await this.isAdapterEntryStale(entry, options.now);
|
|
13670
|
+
if (stale) {
|
|
13671
|
+
emitFarmEvent({
|
|
13672
|
+
type: "cache.stale",
|
|
13673
|
+
key,
|
|
13674
|
+
tags: [...entry.tags],
|
|
13675
|
+
revalidate: entry.revalidate
|
|
13676
|
+
});
|
|
13677
|
+
if (!options.allowStale) {
|
|
13678
|
+
emitFarmEvent({ type: "cache.miss", key, reason: "stale" });
|
|
13679
|
+
return void 0;
|
|
13680
|
+
}
|
|
13681
|
+
}
|
|
13682
|
+
emitFarmEvent({
|
|
13683
|
+
type: "cache.hit",
|
|
13684
|
+
key,
|
|
13685
|
+
tags: [...entry.tags],
|
|
13686
|
+
revalidate: entry.revalidate,
|
|
13687
|
+
stale
|
|
13688
|
+
});
|
|
13689
|
+
if (this.local && !stale) {
|
|
13690
|
+
this.hydrateLocalEntry(entry);
|
|
13691
|
+
}
|
|
13692
|
+
return { ...entry, key };
|
|
13693
|
+
}
|
|
13546
13694
|
set(key, value, options = {}) {
|
|
13547
13695
|
const tags = /* @__PURE__ */ new Set();
|
|
13548
13696
|
for (const tag of options.tags ?? []) {
|
|
@@ -13555,6 +13703,7 @@ var _FarmDataCache = class _FarmDataCache {
|
|
|
13555
13703
|
key,
|
|
13556
13704
|
value,
|
|
13557
13705
|
tags,
|
|
13706
|
+
tagVersions: void 0,
|
|
13558
13707
|
createdAt: options.createdAt ?? Date.now(),
|
|
13559
13708
|
createdVersion: ++this.version,
|
|
13560
13709
|
revalidate: normalizeRevalidate(options.revalidate)
|
|
@@ -13568,11 +13717,45 @@ var _FarmDataCache = class _FarmDataCache {
|
|
|
13568
13717
|
});
|
|
13569
13718
|
return this.toPublicEntry(entry);
|
|
13570
13719
|
}
|
|
13720
|
+
async setAsync(key, value, options = {}, tagVersions) {
|
|
13721
|
+
const tags = normalizeCacheOptionsTags(options);
|
|
13722
|
+
const capturedVersions = tagVersions ?? await this.getAdapterTagVersions(Array.from(tags.values()));
|
|
13723
|
+
const entry = {
|
|
13724
|
+
key,
|
|
13725
|
+
value,
|
|
13726
|
+
tags: Array.from(tags),
|
|
13727
|
+
tagVersions: capturedVersions,
|
|
13728
|
+
createdAt: options.createdAt ?? Date.now(),
|
|
13729
|
+
createdVersion: ++this.version,
|
|
13730
|
+
revalidate: normalizeRevalidate(options.revalidate)
|
|
13731
|
+
};
|
|
13732
|
+
if (this.local) {
|
|
13733
|
+
this.hydrateLocalEntry(entry);
|
|
13734
|
+
}
|
|
13735
|
+
if (this.adapter) {
|
|
13736
|
+
await this.adapter.set(this.createAdapterKey(key), entry);
|
|
13737
|
+
}
|
|
13738
|
+
emitFarmEvent({
|
|
13739
|
+
type: "cache.set",
|
|
13740
|
+
key,
|
|
13741
|
+
tags: [...entry.tags],
|
|
13742
|
+
revalidate: entry.revalidate
|
|
13743
|
+
});
|
|
13744
|
+
return entry;
|
|
13745
|
+
}
|
|
13571
13746
|
delete(key) {
|
|
13572
13747
|
const deleted = this.entries.delete(key);
|
|
13573
13748
|
emitFarmEvent({ type: "cache.delete", key, deleted });
|
|
13574
13749
|
return deleted;
|
|
13575
13750
|
}
|
|
13751
|
+
async deleteAsync(key) {
|
|
13752
|
+
const deleted = this.entries.delete(key);
|
|
13753
|
+
if (this.adapter) {
|
|
13754
|
+
await this.adapter.delete(this.createAdapterKey(key));
|
|
13755
|
+
}
|
|
13756
|
+
emitFarmEvent({ type: "cache.delete", key, deleted: this.adapter ? true : deleted });
|
|
13757
|
+
return this.adapter ? true : deleted;
|
|
13758
|
+
}
|
|
13576
13759
|
clear() {
|
|
13577
13760
|
const count = this.entries.size;
|
|
13578
13761
|
this.entries.clear();
|
|
@@ -13581,6 +13764,10 @@ var _FarmDataCache = class _FarmDataCache {
|
|
|
13581
13764
|
this.version = 0;
|
|
13582
13765
|
emitFarmEvent({ type: "cache.clear", count });
|
|
13583
13766
|
}
|
|
13767
|
+
async clearAsync() {
|
|
13768
|
+
this.clear();
|
|
13769
|
+
await this.adapter?.clear?.();
|
|
13770
|
+
}
|
|
13584
13771
|
isStale(entry, now = Date.now()) {
|
|
13585
13772
|
if (typeof entry.revalidate === "number" && entry.revalidate > 0 && now - entry.createdAt >= entry.revalidate * 1e3) {
|
|
13586
13773
|
return true;
|
|
@@ -13593,6 +13780,12 @@ var _FarmDataCache = class _FarmDataCache {
|
|
|
13593
13780
|
}
|
|
13594
13781
|
return false;
|
|
13595
13782
|
}
|
|
13783
|
+
async isStaleAsync(entry, now = Date.now()) {
|
|
13784
|
+
if (this.adapter) {
|
|
13785
|
+
return this.isAdapterEntryStale(entry, now);
|
|
13786
|
+
}
|
|
13787
|
+
return this.isStale(entry, now);
|
|
13788
|
+
}
|
|
13596
13789
|
revalidateTag(tag, options = {}) {
|
|
13597
13790
|
const normalized = normalizeCacheTag(tag);
|
|
13598
13791
|
const count = this.invalidateTag(normalized);
|
|
@@ -13601,6 +13794,15 @@ var _FarmDataCache = class _FarmDataCache {
|
|
|
13601
13794
|
);
|
|
13602
13795
|
return count;
|
|
13603
13796
|
}
|
|
13797
|
+
async revalidateTagAsync(tag, options = {}) {
|
|
13798
|
+
const normalized = normalizeCacheTag(tag);
|
|
13799
|
+
const count = this.invalidateTag(normalized);
|
|
13800
|
+
await this.adapter?.invalidateTags?.([this.createAdapterTag(normalized)]);
|
|
13801
|
+
emitFarmEvent(
|
|
13802
|
+
options.source === "updateTag" ? { type: "cache.updateTag", tag: normalized, count } : { type: "cache.revalidateTag", tag: normalized, profile: options.profile, count }
|
|
13803
|
+
);
|
|
13804
|
+
return count;
|
|
13805
|
+
}
|
|
13604
13806
|
revalidatePath(routePath) {
|
|
13605
13807
|
const normalizedPath = normalizeRevalidatePath(routePath);
|
|
13606
13808
|
const pathTag = createPathCacheTag(normalizedPath);
|
|
@@ -13617,8 +13819,25 @@ var _FarmDataCache = class _FarmDataCache {
|
|
|
13617
13819
|
}
|
|
13618
13820
|
return count;
|
|
13619
13821
|
}
|
|
13822
|
+
async revalidatePathAsync(routePath) {
|
|
13823
|
+
const normalizedPath = normalizeRevalidatePath(routePath);
|
|
13824
|
+
const pathTag = createPathCacheTag(normalizedPath);
|
|
13825
|
+
const pprCount = this.countEntriesForTags([pathTag, "ppr"]);
|
|
13826
|
+
const count = this.invalidateTag(pathTag);
|
|
13827
|
+
await this.adapter?.invalidateTags?.([this.createAdapterTag(pathTag)]);
|
|
13828
|
+
emitFarmEvent({ type: "cache.revalidatePath", path: normalizedPath, count });
|
|
13829
|
+
if (pprCount > 0) {
|
|
13830
|
+
emitFarmEvent({
|
|
13831
|
+
type: "ppr.shell.invalidated",
|
|
13832
|
+
route: normalizedPath,
|
|
13833
|
+
reason: "revalidatePath",
|
|
13834
|
+
count: pprCount
|
|
13835
|
+
});
|
|
13836
|
+
}
|
|
13837
|
+
return count;
|
|
13838
|
+
}
|
|
13620
13839
|
async getOrSet(key, producer, options = {}) {
|
|
13621
|
-
const cached = this.
|
|
13840
|
+
const cached = await this.getEntryAsync(key);
|
|
13622
13841
|
if (cached) {
|
|
13623
13842
|
return cached.value;
|
|
13624
13843
|
}
|
|
@@ -13627,10 +13846,8 @@ var _FarmDataCache = class _FarmDataCache {
|
|
|
13627
13846
|
emitFarmEvent({ type: "cache.dedupe", key });
|
|
13628
13847
|
return inflight;
|
|
13629
13848
|
}
|
|
13630
|
-
const
|
|
13631
|
-
|
|
13632
|
-
return value;
|
|
13633
|
-
}).catch((error) => {
|
|
13849
|
+
const tags = Array.from(normalizeCacheOptionsTags(options));
|
|
13850
|
+
const promise = this.fillCacheEntry(key, producer, options, tags).catch((error) => {
|
|
13634
13851
|
emitFarmEvent({ type: "cache.error", key, operation: "set", error });
|
|
13635
13852
|
throw error;
|
|
13636
13853
|
}).finally(() => {
|
|
@@ -13639,6 +13856,40 @@ var _FarmDataCache = class _FarmDataCache {
|
|
|
13639
13856
|
this.inflight.set(key, promise);
|
|
13640
13857
|
return promise;
|
|
13641
13858
|
}
|
|
13859
|
+
async fillCacheEntry(key, producer, options, tags) {
|
|
13860
|
+
const leaseKey = `${this.namespace}:lease:${key}`;
|
|
13861
|
+
let leaseToken;
|
|
13862
|
+
if (this.adapter?.acquireLease && this.adapter.releaseLease && this.lease.enabled) {
|
|
13863
|
+
leaseToken = await this.adapter.acquireLease(leaseKey, this.lease.ttlMs);
|
|
13864
|
+
if (!leaseToken) {
|
|
13865
|
+
const shared = await this.waitForAdapterEntry(key);
|
|
13866
|
+
if (shared) {
|
|
13867
|
+
emitFarmEvent({ type: "cache.dedupe", key });
|
|
13868
|
+
return shared.value;
|
|
13869
|
+
}
|
|
13870
|
+
leaseToken = await this.adapter.acquireLease(leaseKey, this.lease.ttlMs);
|
|
13871
|
+
}
|
|
13872
|
+
}
|
|
13873
|
+
try {
|
|
13874
|
+
const initialTagVersions = await this.getAdapterTagVersions(tags);
|
|
13875
|
+
const value = await producer();
|
|
13876
|
+
await this.setAsync(key, value, options, initialTagVersions);
|
|
13877
|
+
return value;
|
|
13878
|
+
} finally {
|
|
13879
|
+
if (leaseToken && this.adapter?.releaseLease) {
|
|
13880
|
+
await this.adapter.releaseLease(leaseKey, leaseToken);
|
|
13881
|
+
}
|
|
13882
|
+
}
|
|
13883
|
+
}
|
|
13884
|
+
async waitForAdapterEntry(key) {
|
|
13885
|
+
const deadline = Date.now() + this.lease.waitTimeoutMs;
|
|
13886
|
+
while (Date.now() < deadline) {
|
|
13887
|
+
await delay(this.lease.pollIntervalMs);
|
|
13888
|
+
const entry = await this.getEntryAsync(key);
|
|
13889
|
+
if (entry) return entry;
|
|
13890
|
+
}
|
|
13891
|
+
return void 0;
|
|
13892
|
+
}
|
|
13642
13893
|
countEntriesForTag(tag) {
|
|
13643
13894
|
let count = 0;
|
|
13644
13895
|
for (const entry of this.entries.values()) {
|
|
@@ -13666,11 +13917,53 @@ var _FarmDataCache = class _FarmDataCache {
|
|
|
13666
13917
|
key: entry.key,
|
|
13667
13918
|
value: entry.value,
|
|
13668
13919
|
tags: Array.from(entry.tags),
|
|
13920
|
+
tagVersions: entry.tagVersions,
|
|
13669
13921
|
createdAt: entry.createdAt,
|
|
13670
13922
|
createdVersion: entry.createdVersion,
|
|
13671
13923
|
revalidate: entry.revalidate
|
|
13672
13924
|
};
|
|
13673
13925
|
}
|
|
13926
|
+
hydrateLocalEntry(entry) {
|
|
13927
|
+
this.entries.set(entry.key, {
|
|
13928
|
+
key: entry.key,
|
|
13929
|
+
value: entry.value,
|
|
13930
|
+
tags: new Set(entry.tags.map(normalizeCacheTag)),
|
|
13931
|
+
tagVersions: entry.tagVersions,
|
|
13932
|
+
createdAt: entry.createdAt,
|
|
13933
|
+
createdVersion: entry.createdVersion ?? ++this.version,
|
|
13934
|
+
revalidate: normalizeRevalidate(entry.revalidate)
|
|
13935
|
+
});
|
|
13936
|
+
}
|
|
13937
|
+
createAdapterKey(key) {
|
|
13938
|
+
return `${this.namespace}:entry:${key}`;
|
|
13939
|
+
}
|
|
13940
|
+
createAdapterTag(tag) {
|
|
13941
|
+
return `${this.namespace}:tag:${tag}`;
|
|
13942
|
+
}
|
|
13943
|
+
async getAdapterTagVersions(tags) {
|
|
13944
|
+
if (!this.adapter?.getTagVersions || tags.length === 0) return {};
|
|
13945
|
+
const normalized = tags.map(normalizeCacheTag);
|
|
13946
|
+
const physicalTags = normalized.map((tag) => this.createAdapterTag(tag));
|
|
13947
|
+
const versions = await this.adapter.getTagVersions(physicalTags);
|
|
13948
|
+
return Object.fromEntries(
|
|
13949
|
+
normalized.map((tag, index) => [
|
|
13950
|
+
tag,
|
|
13951
|
+
normalizeAdapterVersion(versions[physicalTags[index]])
|
|
13952
|
+
])
|
|
13953
|
+
);
|
|
13954
|
+
}
|
|
13955
|
+
async isAdapterEntryStale(entry, now = Date.now()) {
|
|
13956
|
+
if (typeof entry.revalidate === "number" && entry.revalidate > 0 && now - entry.createdAt >= entry.revalidate * 1e3) {
|
|
13957
|
+
return true;
|
|
13958
|
+
}
|
|
13959
|
+
const currentVersions = await this.getAdapterTagVersions(entry.tags);
|
|
13960
|
+
for (const tag of entry.tags) {
|
|
13961
|
+
if (normalizeAdapterVersion(currentVersions[tag]) > normalizeAdapterVersion(entry.tagVersions?.[tag])) {
|
|
13962
|
+
return true;
|
|
13963
|
+
}
|
|
13964
|
+
}
|
|
13965
|
+
return false;
|
|
13966
|
+
}
|
|
13674
13967
|
};
|
|
13675
13968
|
__name(_FarmDataCache, "FarmDataCache");
|
|
13676
13969
|
var FarmDataCache = _FarmDataCache;
|
|
@@ -13683,6 +13976,10 @@ function getFarmDataCache() {
|
|
|
13683
13976
|
return sharedFarmDataCache;
|
|
13684
13977
|
}
|
|
13685
13978
|
__name(getFarmDataCache, "getFarmDataCache");
|
|
13979
|
+
function configureFarmCache(config) {
|
|
13980
|
+
sharedFarmDataCache.configure(config);
|
|
13981
|
+
}
|
|
13982
|
+
__name(configureFarmCache, "configureFarmCache");
|
|
13686
13983
|
function unstable_cache(fn, keyParts = [], options = {}) {
|
|
13687
13984
|
return async (...args) => {
|
|
13688
13985
|
const locale = getActiveFarmI18nSnapshot()?.locale;
|
|
@@ -13698,30 +13995,71 @@ function unstable_cache(fn, keyParts = [], options = {}) {
|
|
|
13698
13995
|
}
|
|
13699
13996
|
__name(unstable_cache, "unstable_cache");
|
|
13700
13997
|
function revalidateTag(_tag, _profile) {
|
|
13701
|
-
getFarmDataCache()
|
|
13998
|
+
const cache = getFarmDataCache();
|
|
13999
|
+
if (cache.hasAdapter) {
|
|
14000
|
+
const task = cache.revalidateTagAsync(_tag, {
|
|
14001
|
+
source: "revalidateTag",
|
|
14002
|
+
profile: _profile
|
|
14003
|
+
}).then(() => void 0);
|
|
14004
|
+
notifyFarmCacheTask(task);
|
|
14005
|
+
return task;
|
|
14006
|
+
}
|
|
14007
|
+
cache.revalidateTag(_tag, {
|
|
13702
14008
|
source: "revalidateTag",
|
|
13703
14009
|
profile: _profile
|
|
13704
14010
|
});
|
|
13705
14011
|
}
|
|
13706
14012
|
__name(revalidateTag, "revalidateTag");
|
|
13707
14013
|
function updateTag(tag) {
|
|
13708
|
-
|
|
14014
|
+
const cache = getFarmDataCache();
|
|
14015
|
+
if (cache.hasAdapter) {
|
|
14016
|
+
const task = cache.revalidateTagAsync(tag, { source: "updateTag" }).then(() => void 0);
|
|
14017
|
+
notifyFarmCacheTask(task);
|
|
14018
|
+
return task;
|
|
14019
|
+
}
|
|
14020
|
+
cache.revalidateTag(tag, { source: "updateTag" });
|
|
13709
14021
|
}
|
|
13710
14022
|
__name(updateTag, "updateTag");
|
|
13711
14023
|
function revalidatePath(routePath) {
|
|
13712
|
-
getFarmDataCache()
|
|
14024
|
+
const cache = getFarmDataCache();
|
|
14025
|
+
if (cache.hasAdapter) {
|
|
14026
|
+
const task = cache.revalidatePathAsync(routePath).then(() => void 0);
|
|
14027
|
+
notifyFarmCacheTask(task);
|
|
14028
|
+
return task;
|
|
14029
|
+
}
|
|
14030
|
+
cache.revalidatePath(routePath);
|
|
13713
14031
|
}
|
|
13714
14032
|
__name(revalidatePath, "revalidatePath");
|
|
13715
14033
|
function invalidate(key) {
|
|
13716
14034
|
const clientKey = createRouteDataCacheKey(key);
|
|
13717
|
-
|
|
14035
|
+
const task = updateTag(createRouteDataCacheTag(key));
|
|
13718
14036
|
notifyFarmCacheInvalidation(clientKey);
|
|
14037
|
+
return task;
|
|
13719
14038
|
}
|
|
13720
14039
|
__name(invalidate, "invalidate");
|
|
13721
14040
|
function invalidateRouteData(key) {
|
|
13722
|
-
invalidate(key);
|
|
14041
|
+
return invalidate(key);
|
|
13723
14042
|
}
|
|
13724
14043
|
__name(invalidateRouteData, "invalidateRouteData");
|
|
14044
|
+
async function applyFarmCacheInvalidationTargets(targets) {
|
|
14045
|
+
if (!Array.isArray(targets)) {
|
|
14046
|
+
throw new TypeError("Cache invalidations must resolve to an array of targets.");
|
|
14047
|
+
}
|
|
14048
|
+
const clientKeys = [];
|
|
14049
|
+
for (const target of targets) {
|
|
14050
|
+
assertFarmCacheInvalidationTarget(target);
|
|
14051
|
+
if ("key" in target) {
|
|
14052
|
+
await invalidate(target.key);
|
|
14053
|
+
clientKeys.push(createRouteDataCacheKey(target.key));
|
|
14054
|
+
} else if ("path" in target) {
|
|
14055
|
+
await revalidatePath(target.path);
|
|
14056
|
+
} else {
|
|
14057
|
+
await updateTag(target.tag);
|
|
14058
|
+
}
|
|
14059
|
+
}
|
|
14060
|
+
return Array.from(new Set(clientKeys));
|
|
14061
|
+
}
|
|
14062
|
+
__name(applyFarmCacheInvalidationTargets, "applyFarmCacheInvalidationTargets");
|
|
13725
14063
|
function createPathCacheTag(routePath) {
|
|
13726
14064
|
return `path:${normalizeRevalidatePath(routePath)}`;
|
|
13727
14065
|
}
|
|
@@ -13782,6 +14120,67 @@ function normalizeCacheTag(tag) {
|
|
|
13782
14120
|
return normalized;
|
|
13783
14121
|
}
|
|
13784
14122
|
__name(normalizeCacheTag, "normalizeCacheTag");
|
|
14123
|
+
function normalizeCacheNamespace(namespace) {
|
|
14124
|
+
if (typeof namespace !== "string") {
|
|
14125
|
+
throw new TypeError("Cache namespace must be a string.");
|
|
14126
|
+
}
|
|
14127
|
+
const normalized = namespace.trim().replace(/:+$/g, "");
|
|
14128
|
+
if (!normalized) {
|
|
14129
|
+
throw new Error("Cache namespace cannot be empty.");
|
|
14130
|
+
}
|
|
14131
|
+
return normalized;
|
|
14132
|
+
}
|
|
14133
|
+
__name(normalizeCacheNamespace, "normalizeCacheNamespace");
|
|
14134
|
+
function normalizeAdapterVersion(value) {
|
|
14135
|
+
return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : 0;
|
|
14136
|
+
}
|
|
14137
|
+
__name(normalizeAdapterVersion, "normalizeAdapterVersion");
|
|
14138
|
+
function normalizePositiveDuration(value, fallback, name) {
|
|
14139
|
+
if (value === void 0) return fallback;
|
|
14140
|
+
if (!Number.isFinite(value) || value <= 0) {
|
|
14141
|
+
throw new TypeError(`${name} must be a positive number of milliseconds.`);
|
|
14142
|
+
}
|
|
14143
|
+
return Math.floor(value);
|
|
14144
|
+
}
|
|
14145
|
+
__name(normalizePositiveDuration, "normalizePositiveDuration");
|
|
14146
|
+
function delay(ms) {
|
|
14147
|
+
return new Promise((resolve5) => setTimeout(resolve5, ms));
|
|
14148
|
+
}
|
|
14149
|
+
__name(delay, "delay");
|
|
14150
|
+
function normalizeCacheOptionsTags(options) {
|
|
14151
|
+
const tags = /* @__PURE__ */ new Set();
|
|
14152
|
+
for (const tag of options.tags ?? []) {
|
|
14153
|
+
tags.add(normalizeCacheTag(tag));
|
|
14154
|
+
}
|
|
14155
|
+
for (const routePath of options.paths ?? []) {
|
|
14156
|
+
tags.add(createPathCacheTag(routePath));
|
|
14157
|
+
}
|
|
14158
|
+
return tags;
|
|
14159
|
+
}
|
|
14160
|
+
__name(normalizeCacheOptionsTags, "normalizeCacheOptionsTags");
|
|
14161
|
+
function assertFarmCacheEntry(entry, expectedKey) {
|
|
14162
|
+
if (!entry || typeof entry !== "object" || entry.key !== expectedKey || !Array.isArray(entry.tags) || typeof entry.createdAt !== "number") {
|
|
14163
|
+
throw new TypeError(
|
|
14164
|
+
`Cache adapter returned an invalid entry for ${JSON.stringify(expectedKey)}.`
|
|
14165
|
+
);
|
|
14166
|
+
}
|
|
14167
|
+
}
|
|
14168
|
+
__name(assertFarmCacheEntry, "assertFarmCacheEntry");
|
|
14169
|
+
function assertFarmCacheInvalidationTarget(target) {
|
|
14170
|
+
if (!target || typeof target !== "object") {
|
|
14171
|
+
throw new TypeError("Cache invalidation targets must be { key }, { path }, or { tag }.");
|
|
14172
|
+
}
|
|
14173
|
+
if ("key" in target) {
|
|
14174
|
+
const key = target.key;
|
|
14175
|
+
if (typeof key === "string" || Array.isArray(key)) return;
|
|
14176
|
+
} else if ("path" in target && typeof target.path === "string") {
|
|
14177
|
+
return;
|
|
14178
|
+
} else if ("tag" in target && typeof target.tag === "string") {
|
|
14179
|
+
return;
|
|
14180
|
+
}
|
|
14181
|
+
throw new TypeError("Cache invalidation targets must contain a string/array key, path, or tag.");
|
|
14182
|
+
}
|
|
14183
|
+
__name(assertFarmCacheInvalidationTarget, "assertFarmCacheInvalidationTarget");
|
|
13785
14184
|
function getFunctionCacheIdentity(fn) {
|
|
13786
14185
|
if (fn.name) {
|
|
13787
14186
|
return `name:${fn.name}`;
|
|
@@ -14922,6 +15321,76 @@ function normalizePathname(pathname) {
|
|
|
14922
15321
|
}
|
|
14923
15322
|
__name(normalizePathname, "normalizePathname");
|
|
14924
15323
|
|
|
15324
|
+
// src/routing/route-slots.ts
|
|
15325
|
+
var SLOT_SEGMENT = /^@([A-Za-z][A-Za-z0-9_-]*)$/;
|
|
15326
|
+
function parseRouteSlotFile(filePath) {
|
|
15327
|
+
const normalized = filePath.replace(/\\/g, "/");
|
|
15328
|
+
const parts = normalized.split("/").filter(Boolean);
|
|
15329
|
+
const fileName = parts.at(-1) ?? "";
|
|
15330
|
+
const baseName = fileName.replace(/\.(tsx?|jsx?)$/, "");
|
|
15331
|
+
if (baseName !== "page" && baseName !== "default") return null;
|
|
15332
|
+
const slotIndex = parts.findIndex((part) => SLOT_SEGMENT.test(part));
|
|
15333
|
+
if (slotIndex < 0) return null;
|
|
15334
|
+
if (parts.slice(slotIndex + 1, -1).some((part) => SLOT_SEGMENT.test(part))) {
|
|
15335
|
+
throw new Error(`Nested route slots are not supported in "${filePath}"`);
|
|
15336
|
+
}
|
|
15337
|
+
const slotMatch = parts[slotIndex].match(SLOT_SEGMENT);
|
|
15338
|
+
const name = slotMatch?.[1];
|
|
15339
|
+
if (!name) return null;
|
|
15340
|
+
const ownerParts = parts.slice(0, slotIndex);
|
|
15341
|
+
const contentParts = parts.slice(slotIndex + 1, -1);
|
|
15342
|
+
const marker = parseInterceptionMarker(contentParts[0]);
|
|
15343
|
+
let targetBase = ownerParts;
|
|
15344
|
+
let targetParts = contentParts;
|
|
15345
|
+
if (marker) {
|
|
15346
|
+
targetBase = marker.root === true ? [] : ownerParts.slice(0, Math.max(0, ownerParts.length - marker.up));
|
|
15347
|
+
targetParts = [...marker.remainder ? [marker.remainder] : [], ...contentParts.slice(1)];
|
|
15348
|
+
}
|
|
15349
|
+
const ownerFile = [...ownerParts, "layout.tsx"].join("/");
|
|
15350
|
+
const routeFile = [
|
|
15351
|
+
...baseName === "default" ? ownerParts : targetBase,
|
|
15352
|
+
...baseName === "default" ? [] : targetParts,
|
|
15353
|
+
"page.tsx"
|
|
15354
|
+
].join("/");
|
|
15355
|
+
return {
|
|
15356
|
+
name,
|
|
15357
|
+
ownerRoute: parseRoutePath(ownerFile || "layout.tsx"),
|
|
15358
|
+
route: parseRoutePath(routeFile || "page.tsx"),
|
|
15359
|
+
interception: marker !== null,
|
|
15360
|
+
fallback: baseName === "default"
|
|
15361
|
+
};
|
|
15362
|
+
}
|
|
15363
|
+
__name(parseRouteSlotFile, "parseRouteSlotFile");
|
|
15364
|
+
function createRouteSlotContainerId(name, ownerPattern) {
|
|
15365
|
+
const owner = ownerPattern === "/" ? "root" : ownerPattern.replace(/^\//, "").replace(/[^A-Za-z0-9_-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
15366
|
+
return `__farm_slot_${name}_${owner || "root"}__`;
|
|
15367
|
+
}
|
|
15368
|
+
__name(createRouteSlotContainerId, "createRouteSlotContainerId");
|
|
15369
|
+
function parseInterceptionMarker(segment) {
|
|
15370
|
+
if (!segment) return null;
|
|
15371
|
+
if (segment.startsWith("(...)")) {
|
|
15372
|
+
return {
|
|
15373
|
+
up: 0,
|
|
15374
|
+
root: true,
|
|
15375
|
+
remainder: segment.slice(5)
|
|
15376
|
+
};
|
|
15377
|
+
}
|
|
15378
|
+
if (segment.startsWith("(.)")) {
|
|
15379
|
+
return {
|
|
15380
|
+
up: 0,
|
|
15381
|
+
remainder: segment.slice(3)
|
|
15382
|
+
};
|
|
15383
|
+
}
|
|
15384
|
+
let remainder = segment;
|
|
15385
|
+
let up = 0;
|
|
15386
|
+
while (remainder.startsWith("(..)")) {
|
|
15387
|
+
up += 1;
|
|
15388
|
+
remainder = remainder.slice(4);
|
|
15389
|
+
}
|
|
15390
|
+
return up > 0 ? { up, remainder } : null;
|
|
15391
|
+
}
|
|
15392
|
+
__name(parseInterceptionMarker, "parseInterceptionMarker");
|
|
15393
|
+
|
|
14925
15394
|
// src/routing/route-manager.ts
|
|
14926
15395
|
function routeSpecificity(entry) {
|
|
14927
15396
|
return entry.route.segments.reduce((score, segment) => {
|
|
@@ -14935,6 +15404,7 @@ var _RouteManager = class _RouteManager {
|
|
|
14935
15404
|
constructor(config, viteServer) {
|
|
14936
15405
|
this.routes = /* @__PURE__ */ new Map();
|
|
14937
15406
|
this.layouts = /* @__PURE__ */ new Map();
|
|
15407
|
+
this.routeSlots = /* @__PURE__ */ new Map();
|
|
14938
15408
|
this.loadings = /* @__PURE__ */ new Map();
|
|
14939
15409
|
this.errors = /* @__PURE__ */ new Map();
|
|
14940
15410
|
this.metadataImages = /* @__PURE__ */ new Map();
|
|
@@ -14950,6 +15420,7 @@ var _RouteManager = class _RouteManager {
|
|
|
14950
15420
|
async discoverRoutes() {
|
|
14951
15421
|
this.routes.clear();
|
|
14952
15422
|
this.layouts.clear();
|
|
15423
|
+
this.routeSlots.clear();
|
|
14953
15424
|
this.loadings.clear();
|
|
14954
15425
|
this.errors.clear();
|
|
14955
15426
|
this.metadataImages.clear();
|
|
@@ -14960,6 +15431,13 @@ var _RouteManager = class _RouteManager {
|
|
|
14960
15431
|
await this.discoverFileRoutes(source);
|
|
14961
15432
|
await this.discoverProgrammaticRoutes(source);
|
|
14962
15433
|
}
|
|
15434
|
+
for (const slot of this.routeSlots.values()) {
|
|
15435
|
+
if (slot.interception && !this.routes.has(slot.pattern)) {
|
|
15436
|
+
throw new Error(
|
|
15437
|
+
`Intercepting route slot "${slot.name}" targets "${slot.pattern}", but no canonical page exists for that URL`
|
|
15438
|
+
);
|
|
15439
|
+
}
|
|
15440
|
+
}
|
|
14963
15441
|
this.routes = new Map(
|
|
14964
15442
|
Array.from(this.routes.entries()).sort(
|
|
14965
15443
|
([, left], [, right]) => routeSpecificity(right) - routeSpecificity(left)
|
|
@@ -14975,7 +15453,7 @@ var _RouteManager = class _RouteManager {
|
|
|
14975
15453
|
/**
|
|
14976
15454
|
* Find matching route for a given URL path
|
|
14977
15455
|
*/
|
|
14978
|
-
matchRoute(pathname) {
|
|
15456
|
+
matchRoute(pathname, options = {}) {
|
|
14979
15457
|
const routePathname = this.toRoutePathname(pathname);
|
|
14980
15458
|
const normalizedPath = routePathname === "/" ? "/" : routePathname.replace(/\/$/, "");
|
|
14981
15459
|
let matchedRoute = null;
|
|
@@ -14989,10 +15467,12 @@ var _RouteManager = class _RouteManager {
|
|
|
14989
15467
|
}
|
|
14990
15468
|
}
|
|
14991
15469
|
const layouts = this.findMatchingLayouts(normalizedPath);
|
|
15470
|
+
const slots = this.findMatchingRouteSlots(normalizedPath, options.interceptFrom);
|
|
14992
15471
|
return {
|
|
14993
15472
|
route: matchedRoute,
|
|
14994
15473
|
params,
|
|
14995
|
-
layouts
|
|
15474
|
+
layouts,
|
|
15475
|
+
slots
|
|
14996
15476
|
};
|
|
14997
15477
|
}
|
|
14998
15478
|
/**
|
|
@@ -15007,6 +15487,9 @@ var _RouteManager = class _RouteManager {
|
|
|
15007
15487
|
getLayouts() {
|
|
15008
15488
|
return new Map(this.layouts);
|
|
15009
15489
|
}
|
|
15490
|
+
getRouteSlots() {
|
|
15491
|
+
return new Map(this.routeSlots);
|
|
15492
|
+
}
|
|
15010
15493
|
/** Resolve route rules, inherited layouts, and the page export in precedence order. */
|
|
15011
15494
|
async resolveRouteRuntimeConfig(pattern) {
|
|
15012
15495
|
const routeEntry = this.routes.get(pattern);
|
|
@@ -15165,7 +15648,22 @@ var _RouteManager = class _RouteManager {
|
|
|
15165
15648
|
pattern: entry.pattern,
|
|
15166
15649
|
modulePath: toUrlPath(entry.modulePath)
|
|
15167
15650
|
}));
|
|
15168
|
-
|
|
15651
|
+
const slots = Array.from(this.routeSlots.values()).map((entry) => {
|
|
15652
|
+
const metadata = getClientModuleMetadata(entry.modulePath, projectRoot);
|
|
15653
|
+
return {
|
|
15654
|
+
name: entry.name,
|
|
15655
|
+
ownerPattern: entry.ownerPattern,
|
|
15656
|
+
pattern: entry.pattern,
|
|
15657
|
+
modulePath: toUrlPath(entry.modulePath),
|
|
15658
|
+
containerId: entry.containerId,
|
|
15659
|
+
interception: entry.interception,
|
|
15660
|
+
fallback: entry.fallback,
|
|
15661
|
+
shouldHydrate: metadata.shouldHydrate,
|
|
15662
|
+
isClientComponent: metadata.isClientComponent,
|
|
15663
|
+
segments: entry.route.segments
|
|
15664
|
+
};
|
|
15665
|
+
});
|
|
15666
|
+
return { routes, layouts, slots };
|
|
15169
15667
|
}
|
|
15170
15668
|
/**
|
|
15171
15669
|
* Load a route module dynamically
|
|
@@ -15242,6 +15740,7 @@ var _RouteManager = class _RouteManager {
|
|
|
15242
15740
|
async discoverFileRoutes(source) {
|
|
15243
15741
|
const appDir = resolveAppPath(source.root, source.srcDir, "app");
|
|
15244
15742
|
const pageFiles = await safeGlobFiles("**/page.{ts,tsx,js,jsx,md,mdx}", appDir);
|
|
15743
|
+
const slotDefaultFiles = await safeGlobFiles("**/@*/**/default.{ts,tsx,js,jsx}", appDir);
|
|
15245
15744
|
const layoutFiles = await safeGlobFiles("**/layout.{ts,tsx,js,jsx}", appDir);
|
|
15246
15745
|
const loadingFiles = await safeGlobFiles("**/loading.{ts,tsx,js,jsx}", appDir);
|
|
15247
15746
|
const errorFiles = await safeGlobFiles("**/error.{ts,tsx,js,jsx}", appDir);
|
|
@@ -15250,7 +15749,7 @@ var _RouteManager = class _RouteManager {
|
|
|
15250
15749
|
appDir
|
|
15251
15750
|
);
|
|
15252
15751
|
for (const [kind, files, target] of [
|
|
15253
|
-
["page", pageFiles, this.routes],
|
|
15752
|
+
["page", pageFiles.filter((file) => parseRouteSlotFile(file) === null), this.routes],
|
|
15254
15753
|
["layout", layoutFiles, this.layouts],
|
|
15255
15754
|
["loading", loadingFiles, this.loadings],
|
|
15256
15755
|
["error", errorFiles, this.errors]
|
|
@@ -15274,6 +15773,32 @@ var _RouteManager = class _RouteManager {
|
|
|
15274
15773
|
});
|
|
15275
15774
|
}
|
|
15276
15775
|
}
|
|
15776
|
+
for (const file of [...pageFiles, ...slotDefaultFiles]) {
|
|
15777
|
+
const slot = parseRouteSlotFile(file);
|
|
15778
|
+
if (!slot) continue;
|
|
15779
|
+
const modulePath = import_path5.default.join(appDir, file);
|
|
15780
|
+
const pattern = this.createRoutePattern(slot.route);
|
|
15781
|
+
const ownerPattern = this.createRoutePattern(slot.ownerRoute);
|
|
15782
|
+
const key = `${ownerPattern}:${slot.name}:${slot.interception ? "intercept" : "slot"}:${slot.fallback ? "default" : pattern}`;
|
|
15783
|
+
const existing = this.routeSlots.get(key);
|
|
15784
|
+
if (existing?.sourceRoot === source.root) {
|
|
15785
|
+
throw new Error(
|
|
15786
|
+
`Duplicate route slot "${slot.name}" for "${pattern}". Found both ${existing.modulePath} and ${modulePath}.`
|
|
15787
|
+
);
|
|
15788
|
+
}
|
|
15789
|
+
this.routeSlots.set(key, {
|
|
15790
|
+
route: slot.route,
|
|
15791
|
+
modulePath,
|
|
15792
|
+
pattern,
|
|
15793
|
+
source: "file",
|
|
15794
|
+
sourceRoot: source.root,
|
|
15795
|
+
name: slot.name,
|
|
15796
|
+
ownerPattern,
|
|
15797
|
+
interception: slot.interception,
|
|
15798
|
+
fallback: slot.fallback,
|
|
15799
|
+
containerId: createRouteSlotContainerId(slot.name, ownerPattern)
|
|
15800
|
+
});
|
|
15801
|
+
}
|
|
15277
15802
|
for (const file of metadataImageFiles) {
|
|
15278
15803
|
const fileBase = import_path5.default.basename(file, import_path5.default.extname(file));
|
|
15279
15804
|
const kind = fileBase === "twitter-image" ? "twitter" : "opengraph";
|
|
@@ -15399,6 +15924,71 @@ var _RouteManager = class _RouteManager {
|
|
|
15399
15924
|
}
|
|
15400
15925
|
return matchingLayouts;
|
|
15401
15926
|
}
|
|
15927
|
+
findMatchingRouteSlots(pathname, interceptFrom) {
|
|
15928
|
+
const groups = /* @__PURE__ */ new Map();
|
|
15929
|
+
for (const entry of this.routeSlots.values()) {
|
|
15930
|
+
if (!this.matchesRoutePrefix(pathname, entry.ownerPattern)) continue;
|
|
15931
|
+
const key = `${entry.ownerPattern}:${entry.name}`;
|
|
15932
|
+
const entries = groups.get(key) ?? [];
|
|
15933
|
+
entries.push(entry);
|
|
15934
|
+
groups.set(key, entries);
|
|
15935
|
+
}
|
|
15936
|
+
const normalizedFrom = interceptFrom ? this.toRoutePathname(new URL(interceptFrom, "http://farm.local").pathname) : void 0;
|
|
15937
|
+
const matches = [];
|
|
15938
|
+
for (const entries of groups.values()) {
|
|
15939
|
+
const candidates = entries.filter((entry) => !entry.fallback).filter(
|
|
15940
|
+
(entry) => !entry.interception || normalizedFrom !== void 0 && this.matchesRoutePrefix(normalizedFrom, entry.ownerPattern)
|
|
15941
|
+
).map((entry) => ({
|
|
15942
|
+
entry,
|
|
15943
|
+
match: matchRoute(pathname, entry.route.segments)
|
|
15944
|
+
})).filter((candidate) => candidate.match.matches).sort((left, right) => {
|
|
15945
|
+
if (left.entry.interception !== right.entry.interception) {
|
|
15946
|
+
return left.entry.interception ? -1 : 1;
|
|
15947
|
+
}
|
|
15948
|
+
return routeSpecificity(right.entry) - routeSpecificity(left.entry);
|
|
15949
|
+
});
|
|
15950
|
+
const selected = candidates[0];
|
|
15951
|
+
if (selected) {
|
|
15952
|
+
matches.push({
|
|
15953
|
+
name: selected.entry.name,
|
|
15954
|
+
ownerPattern: selected.entry.ownerPattern,
|
|
15955
|
+
containerId: selected.entry.containerId,
|
|
15956
|
+
interception: selected.entry.interception,
|
|
15957
|
+
fallback: false,
|
|
15958
|
+
route: selected.entry,
|
|
15959
|
+
params: selected.match.params
|
|
15960
|
+
});
|
|
15961
|
+
continue;
|
|
15962
|
+
}
|
|
15963
|
+
const fallback = entries.find((entry) => entry.fallback);
|
|
15964
|
+
if (fallback) {
|
|
15965
|
+
matches.push({
|
|
15966
|
+
name: fallback.name,
|
|
15967
|
+
ownerPattern: fallback.ownerPattern,
|
|
15968
|
+
containerId: fallback.containerId,
|
|
15969
|
+
interception: false,
|
|
15970
|
+
fallback: true,
|
|
15971
|
+
route: fallback,
|
|
15972
|
+
params: {}
|
|
15973
|
+
});
|
|
15974
|
+
}
|
|
15975
|
+
}
|
|
15976
|
+
return matches.sort((left, right) => {
|
|
15977
|
+
const ownerDifference = left.route.route.segments.length - right.route.route.segments.length;
|
|
15978
|
+
return ownerDifference || left.name.localeCompare(right.name);
|
|
15979
|
+
});
|
|
15980
|
+
}
|
|
15981
|
+
matchesRoutePrefix(pathname, pattern) {
|
|
15982
|
+
if (pattern === "/") return true;
|
|
15983
|
+
const patternSegments = parseRoutePath(`${pattern}/page.tsx`).segments;
|
|
15984
|
+
const pathSegments = pathname.split("/").filter(Boolean);
|
|
15985
|
+
if (patternSegments.length > pathSegments.length) return false;
|
|
15986
|
+
for (let index = 0; index < patternSegments.length; index++) {
|
|
15987
|
+
const segment = patternSegments[index];
|
|
15988
|
+
if (!segment.isDynamic && segment.segment !== pathSegments[index]) return false;
|
|
15989
|
+
}
|
|
15990
|
+
return true;
|
|
15991
|
+
}
|
|
15402
15992
|
findNearestBoundary(pathname, boundaries) {
|
|
15403
15993
|
const normalizedPath = pathname === "/" ? "/" : pathname.replace(/\/$/, "");
|
|
15404
15994
|
const pathSegments = normalizedPath.split("/").filter(Boolean);
|
|
@@ -16941,7 +17531,9 @@ var _ServerRenderer = class _ServerRenderer {
|
|
|
16941
17531
|
async runWithRequestContext(request, fn) {
|
|
16942
17532
|
return _runWithCurrentRequest(
|
|
16943
17533
|
request,
|
|
16944
|
-
() => this.i18nRuntime?.config.enabled ? _runWithFarmI18nRequest(this.i18nRuntime, request, fn, {
|
|
17534
|
+
() => this.i18nRuntime?.config.enabled ? _runWithFarmI18nRequest(this.i18nRuntime, request, fn, {
|
|
17535
|
+
redirect: false
|
|
17536
|
+
}) : fn()
|
|
16945
17537
|
);
|
|
16946
17538
|
}
|
|
16947
17539
|
async resolveRouteContext(input) {
|
|
@@ -16964,11 +17556,11 @@ var _ServerRenderer = class _ServerRenderer {
|
|
|
16964
17556
|
/**
|
|
16965
17557
|
* Check if a path should be served from SSG cache
|
|
16966
17558
|
*/
|
|
16967
|
-
shouldServeSSG(pathname) {
|
|
17559
|
+
async shouldServeSSG(pathname) {
|
|
16968
17560
|
const ssgPage = matchSSGPage(pathname, this.ssgManifest);
|
|
16969
17561
|
if (!ssgPage) return null;
|
|
16970
|
-
const cached = this.getCachedSSGPage(pathname);
|
|
16971
|
-
if (cached && this.dataCache.
|
|
17562
|
+
const cached = await this.getCachedSSGPage(pathname);
|
|
17563
|
+
if (cached && await this.dataCache.isStaleAsync(cached)) {
|
|
16972
17564
|
this.regenerateSSGPage(ssgPage);
|
|
16973
17565
|
}
|
|
16974
17566
|
return ssgPage;
|
|
@@ -16980,12 +17572,12 @@ var _ServerRenderer = class _ServerRenderer {
|
|
|
16980
17572
|
return createFarmCacheKey(["ppr", normalizeRevalidatePath(pathname), search]);
|
|
16981
17573
|
}
|
|
16982
17574
|
getCachedSSGPage(urlPath) {
|
|
16983
|
-
return this.dataCache.
|
|
17575
|
+
return this.dataCache.getEntryAsync(this.getSSGCacheKey(urlPath), {
|
|
16984
17576
|
allowStale: true
|
|
16985
17577
|
});
|
|
16986
17578
|
}
|
|
16987
|
-
cacheSSGPage(page2, html, options) {
|
|
16988
|
-
this.dataCache.
|
|
17579
|
+
async cacheSSGPage(page2, html, options) {
|
|
17580
|
+
await this.dataCache.setAsync(
|
|
16989
17581
|
this.getSSGCacheKey(page2.urlPath),
|
|
16990
17582
|
{ html, document: options.document },
|
|
16991
17583
|
{
|
|
@@ -16997,11 +17589,11 @@ var _ServerRenderer = class _ServerRenderer {
|
|
|
16997
17589
|
);
|
|
16998
17590
|
}
|
|
16999
17591
|
getCachedPPRShell(pathname, search) {
|
|
17000
|
-
return this.dataCache.
|
|
17592
|
+
return this.dataCache.getEntryAsync(this.getPPRCacheKey(pathname, search));
|
|
17001
17593
|
}
|
|
17002
|
-
cachePPRShell(options, html) {
|
|
17594
|
+
async cachePPRShell(options, html) {
|
|
17003
17595
|
const key = this.getPPRCacheKey(options.pathname, options.search);
|
|
17004
|
-
this.dataCache.
|
|
17596
|
+
await this.dataCache.setAsync(
|
|
17005
17597
|
key,
|
|
17006
17598
|
{ html },
|
|
17007
17599
|
{
|
|
@@ -17099,7 +17691,7 @@ var _ServerRenderer = class _ServerRenderer {
|
|
|
17099
17691
|
}
|
|
17100
17692
|
const { renderToString } = await import("react-dom/server");
|
|
17101
17693
|
const html = renderToString(await this.wrapWithIntegrationProviders(pageElement));
|
|
17102
|
-
this.cacheSSGPage(page2, html, { document: false });
|
|
17694
|
+
await this.cacheSSGPage(page2, html, { document: false });
|
|
17103
17695
|
logger.info(`ISR: Regenerated ${page2.urlPath}`);
|
|
17104
17696
|
} catch (error) {
|
|
17105
17697
|
logger.error(`ISR regeneration failed for ${page2.urlPath}: ${error}`);
|
|
@@ -17113,7 +17705,7 @@ var _ServerRenderer = class _ServerRenderer {
|
|
|
17113
17705
|
* Serve a pre-rendered SSG page
|
|
17114
17706
|
*/
|
|
17115
17707
|
async serveSSGPage(req, res, page2) {
|
|
17116
|
-
const cached = this.getCachedSSGPage(page2.urlPath);
|
|
17708
|
+
const cached = await this.getCachedSSGPage(page2.urlPath);
|
|
17117
17709
|
if (cached) {
|
|
17118
17710
|
res.setHeader("Content-Type", "text/html; charset=utf-8");
|
|
17119
17711
|
res.setHeader("X-Farm-SSG", "cached");
|
|
@@ -17131,9 +17723,12 @@ var _ServerRenderer = class _ServerRenderer {
|
|
|
17131
17723
|
if (fs2.existsSync(htmlPath)) {
|
|
17132
17724
|
const stat = fs2.statSync(htmlPath);
|
|
17133
17725
|
const html = fs2.readFileSync(htmlPath, "utf-8");
|
|
17134
|
-
this.cacheSSGPage(page2, html, {
|
|
17135
|
-
|
|
17136
|
-
|
|
17726
|
+
await this.cacheSSGPage(page2, html, {
|
|
17727
|
+
document: true,
|
|
17728
|
+
createdAt: stat.mtimeMs
|
|
17729
|
+
});
|
|
17730
|
+
const fileCacheEntry = await this.getCachedSSGPage(page2.urlPath);
|
|
17731
|
+
if (fileCacheEntry && await this.dataCache.isStaleAsync(fileCacheEntry)) {
|
|
17137
17732
|
this.regenerateSSGPage(page2);
|
|
17138
17733
|
}
|
|
17139
17734
|
res.setHeader("Content-Type", "text/html; charset=utf-8");
|
|
@@ -17179,6 +17774,7 @@ var _ServerRenderer = class _ServerRenderer {
|
|
|
17179
17774
|
let pathname = "/";
|
|
17180
17775
|
let params = {};
|
|
17181
17776
|
let layouts = [];
|
|
17777
|
+
let routeSlots = [];
|
|
17182
17778
|
let searchParamsObject = {};
|
|
17183
17779
|
let middlewareMap = /* @__PURE__ */ new Map();
|
|
17184
17780
|
let middlewareContext = /* @__PURE__ */ new Map();
|
|
@@ -17211,7 +17807,7 @@ var _ServerRenderer = class _ServerRenderer {
|
|
|
17211
17807
|
}
|
|
17212
17808
|
this.applyDeploymentHeaders(req, res);
|
|
17213
17809
|
if (process.env.NODE_ENV === "production") {
|
|
17214
|
-
const ssgPage = this.shouldServeSSG(pathname);
|
|
17810
|
+
const ssgPage = await this.shouldServeSSG(pathname);
|
|
17215
17811
|
if (ssgPage) {
|
|
17216
17812
|
const served = await this.serveSSGPage(req, res, ssgPage);
|
|
17217
17813
|
if (served) {
|
|
@@ -17224,6 +17820,7 @@ var _ServerRenderer = class _ServerRenderer {
|
|
|
17224
17820
|
const route = match.route;
|
|
17225
17821
|
params = match.params;
|
|
17226
17822
|
layouts = match.layouts;
|
|
17823
|
+
routeSlots = match.slots ?? [];
|
|
17227
17824
|
if (!route) {
|
|
17228
17825
|
emitFarmEvent({ type: "route.notFound", pathname });
|
|
17229
17826
|
await this.render404(req, res);
|
|
@@ -17240,7 +17837,9 @@ var _ServerRenderer = class _ServerRenderer {
|
|
|
17240
17837
|
errorBoundaryEntry = this.routeManager.getMatchingError(pathname);
|
|
17241
17838
|
middlewareMap = toMiddlewareMap2(req.__FARM_MIDDLEWARE_DATA__);
|
|
17242
17839
|
middlewareContext = toMiddlewareMap2(req.__FARM_MIDDLEWARE_CONTEXT__);
|
|
17243
|
-
pluginExposedContext = getRequestContextSnapshot(req, {
|
|
17840
|
+
pluginExposedContext = getRequestContextSnapshot(req, {
|
|
17841
|
+
exposedOnly: true
|
|
17842
|
+
});
|
|
17244
17843
|
const currentRequest = createWebRequestFromFarmRequest(req);
|
|
17245
17844
|
const routeContext = await this.resolveRouteContext({
|
|
17246
17845
|
request: currentRequest,
|
|
@@ -17304,8 +17903,16 @@ var _ServerRenderer = class _ServerRenderer {
|
|
|
17304
17903
|
revalidate: renderingConfig.revalidate
|
|
17305
17904
|
} : void 0;
|
|
17306
17905
|
if (renderingConfig.ppr && pprBypassReason) {
|
|
17307
|
-
emitFarmEvent({
|
|
17308
|
-
|
|
17906
|
+
emitFarmEvent({
|
|
17907
|
+
type: "ppr.shell.bypass",
|
|
17908
|
+
route: pathname,
|
|
17909
|
+
reason: pprBypassReason
|
|
17910
|
+
});
|
|
17911
|
+
emitFarmEvent({
|
|
17912
|
+
type: "cache.bypass",
|
|
17913
|
+
route: pathname,
|
|
17914
|
+
reason: pprBypassReason
|
|
17915
|
+
});
|
|
17309
17916
|
if (pprBypassReason === "refresh") {
|
|
17310
17917
|
pprRefreshRoute = pathname;
|
|
17311
17918
|
emitFarmEvent({ type: "ppr.refresh.start", route: pathname });
|
|
@@ -17313,14 +17920,22 @@ var _ServerRenderer = class _ServerRenderer {
|
|
|
17313
17920
|
}
|
|
17314
17921
|
if (pprShellOptions) {
|
|
17315
17922
|
const pprCacheKey = this.getPPRCacheKey(pathname, url.search);
|
|
17316
|
-
const cachedPPRShell = this.getCachedPPRShell(pathname, url.search);
|
|
17923
|
+
const cachedPPRShell = await this.getCachedPPRShell(pathname, url.search);
|
|
17317
17924
|
if (cachedPPRShell) {
|
|
17318
|
-
emitFarmEvent({
|
|
17925
|
+
emitFarmEvent({
|
|
17926
|
+
type: "ppr.shell.hit",
|
|
17927
|
+
route: pathname,
|
|
17928
|
+
key: pprCacheKey
|
|
17929
|
+
});
|
|
17319
17930
|
this.serveCachedPPRShell(res, cachedPPRShell.value, renderingConfig.revalidate);
|
|
17320
17931
|
completeRender(res.statusCode || 200, pathname);
|
|
17321
17932
|
return;
|
|
17322
17933
|
}
|
|
17323
|
-
emitFarmEvent({
|
|
17934
|
+
emitFarmEvent({
|
|
17935
|
+
type: "ppr.shell.miss",
|
|
17936
|
+
route: pathname,
|
|
17937
|
+
key: pprCacheKey
|
|
17938
|
+
});
|
|
17324
17939
|
}
|
|
17325
17940
|
let LoadingFallbackComponent = null;
|
|
17326
17941
|
if (loadingBoundaryEntry) {
|
|
@@ -17344,14 +17959,77 @@ var _ServerRenderer = class _ServerRenderer {
|
|
|
17344
17959
|
);
|
|
17345
17960
|
const moduleMetadata = routeManifestEntry || getClientModuleMetadata(route.modulePath, this.config.root);
|
|
17346
17961
|
const isClientComponent = moduleMetadata.isClientComponent;
|
|
17962
|
+
const renderedRouteSlots = await Promise.all(
|
|
17963
|
+
routeSlots.map(async (slot) => {
|
|
17964
|
+
const slotModule = await this.routeManager.loadRouteModule(slot.route.modulePath);
|
|
17965
|
+
if (!slotModule.default) {
|
|
17966
|
+
throw new Error(
|
|
17967
|
+
`Route slot "${slot.name}" module ${slot.route.modulePath} does not export a default component`
|
|
17968
|
+
);
|
|
17969
|
+
}
|
|
17970
|
+
const slotContext = await this.resolveRouteContext({
|
|
17971
|
+
request: currentRequest,
|
|
17972
|
+
rawRequest: req,
|
|
17973
|
+
params: slot.params,
|
|
17974
|
+
search: searchParamsObject,
|
|
17975
|
+
path: pathname
|
|
17976
|
+
});
|
|
17977
|
+
const rawSlotProps = withFarmRouteContext(
|
|
17978
|
+
{
|
|
17979
|
+
params: slot.params,
|
|
17980
|
+
searchParams: Promise.resolve(searchParamsObject),
|
|
17981
|
+
path: pathname,
|
|
17982
|
+
middleware: middlewareMap.size > 0 ? { data: middlewareMap } : void 0,
|
|
17983
|
+
context: pluginExposedContext.size > 0 ? { data: pluginExposedContext } : void 0
|
|
17984
|
+
},
|
|
17985
|
+
slotContext
|
|
17986
|
+
);
|
|
17987
|
+
const slotProps = await parseRouteModuleProps(slotModule, {
|
|
17988
|
+
props: rawSlotProps,
|
|
17989
|
+
search: searchParamsObject,
|
|
17990
|
+
routePath: slot.route.pattern
|
|
17991
|
+
});
|
|
17992
|
+
const metadata = getClientModuleMetadata(slot.route.modulePath, this.config.root);
|
|
17993
|
+
return {
|
|
17994
|
+
...slot,
|
|
17995
|
+
module: slotModule,
|
|
17996
|
+
props: slotProps,
|
|
17997
|
+
isClientComponent: metadata.isClientComponent,
|
|
17998
|
+
shouldHydrate: metadata.shouldHydrate
|
|
17999
|
+
};
|
|
18000
|
+
})
|
|
18001
|
+
);
|
|
17347
18002
|
const shouldHydrate = moduleMetadata.shouldHydrate;
|
|
18003
|
+
const hasHydratableRouteSlots = renderedRouteSlots.some(
|
|
18004
|
+
(slot) => slot.isClientComponent || slot.shouldHydrate
|
|
18005
|
+
);
|
|
17348
18006
|
req.__FARM_PAGE_PATH__ = route.modulePath;
|
|
17349
18007
|
req.__FARM_ROUTE__ = pathname;
|
|
17350
18008
|
req.__FARM_IS_CLIENT_COMPONENT__ = isClientComponent;
|
|
17351
18009
|
req.__FARM_SHOULD_HYDRATE__ = shouldHydrate;
|
|
18010
|
+
req.__FARM_HAS_HYDRATABLE_ROUTE_SLOTS__ = hasHydratableRouteSlots;
|
|
17352
18011
|
req.__FARM_LOADING_MODULE_PATH__ = loadingBoundaryEntry?.modulePath ? loadingBoundaryEntry.modulePath.substring(
|
|
17353
18012
|
loadingBoundaryEntry.modulePath.indexOf("/src/app/")
|
|
17354
18013
|
) : null;
|
|
18014
|
+
req.__FARM_ROUTE_SLOTS__ = renderedRouteSlots.map((slot) => ({
|
|
18015
|
+
name: slot.name,
|
|
18016
|
+
ownerPattern: slot.ownerPattern,
|
|
18017
|
+
containerId: slot.containerId,
|
|
18018
|
+
interception: slot.interception,
|
|
18019
|
+
fallback: slot.fallback,
|
|
18020
|
+
modulePath: slot.route.modulePath,
|
|
18021
|
+
isClientComponent: slot.isClientComponent,
|
|
18022
|
+
shouldHydrate: slot.shouldHydrate,
|
|
18023
|
+
props: {
|
|
18024
|
+
params: slot.props.params,
|
|
18025
|
+
search: slot.props.search,
|
|
18026
|
+
searchParams: slot.props.search,
|
|
18027
|
+
..."data" in slot.props ? { data: slot.props.data } : {},
|
|
18028
|
+
...slot.props.__farmCanonicalPath ? { __farmCanonicalPath: slot.props.__farmCanonicalPath } : {},
|
|
18029
|
+
...slot.props.__farmRoutePropsResolved ? { __farmRoutePropsResolved: true } : {},
|
|
18030
|
+
path: pathname
|
|
18031
|
+
}
|
|
18032
|
+
}));
|
|
17355
18033
|
req.__FARM_PROPS__ = {
|
|
17356
18034
|
params: pageProps.params,
|
|
17357
18035
|
search: pageProps.search,
|
|
@@ -17411,12 +18089,32 @@ var _ServerRenderer = class _ServerRenderer {
|
|
|
17411
18089
|
let wrappedElement = pageElement;
|
|
17412
18090
|
for (let i = layoutModules.length - 1; i >= 0; i--) {
|
|
17413
18091
|
const layoutModule = layoutModules[i];
|
|
18092
|
+
const layoutEntry = layouts[i];
|
|
17414
18093
|
const LayoutComponent = layoutModule.default;
|
|
18094
|
+
const slotProps = {};
|
|
18095
|
+
for (const slot of renderedRouteSlots) {
|
|
18096
|
+
if (slot.ownerPattern !== layoutEntry.pattern) continue;
|
|
18097
|
+
let slotElement = import_react4.default.createElement(
|
|
18098
|
+
slot.module.default,
|
|
18099
|
+
slot.props
|
|
18100
|
+
);
|
|
18101
|
+
slotElement = import_react4.default.createElement(
|
|
18102
|
+
"div",
|
|
18103
|
+
{
|
|
18104
|
+
id: slot.containerId,
|
|
18105
|
+
"data-farm-route-slot": slot.name,
|
|
18106
|
+
"data-farm-slot-owner": slot.ownerPattern
|
|
18107
|
+
},
|
|
18108
|
+
slotElement
|
|
18109
|
+
);
|
|
18110
|
+
slotProps[slot.name] = slotElement;
|
|
18111
|
+
}
|
|
17415
18112
|
wrappedElement = import_react4.default.createElement(
|
|
17416
18113
|
LayoutComponent,
|
|
17417
18114
|
{
|
|
17418
18115
|
children: wrappedElement,
|
|
17419
|
-
params
|
|
18116
|
+
params,
|
|
18117
|
+
...slotProps
|
|
17420
18118
|
}
|
|
17421
18119
|
);
|
|
17422
18120
|
}
|
|
@@ -17453,7 +18151,10 @@ var _ServerRenderer = class _ServerRenderer {
|
|
|
17453
18151
|
routeManifest,
|
|
17454
18152
|
captureStaticShell: Boolean(pprShellOptions),
|
|
17455
18153
|
observabilityRoute: pathname,
|
|
17456
|
-
onSuspenseHoleDetected: pprShellOptions ? () => emitFarmEvent({
|
|
18154
|
+
onSuspenseHoleDetected: pprShellOptions ? () => emitFarmEvent({
|
|
18155
|
+
type: "ppr.suspense.holeDetected",
|
|
18156
|
+
route: pathname
|
|
18157
|
+
}) : void 0,
|
|
17457
18158
|
onComplete: pprShellOptions && req.method !== "HEAD" ? (html) => this.cachePPRShell(pprShellOptions, html) : void 0
|
|
17458
18159
|
}
|
|
17459
18160
|
);
|
|
@@ -17501,7 +18202,11 @@ var _ServerRenderer = class _ServerRenderer {
|
|
|
17501
18202
|
}
|
|
17502
18203
|
emitFarmEvent({ type: "render.error", route: pathname, error });
|
|
17503
18204
|
if (pprRefreshRoute) {
|
|
17504
|
-
emitFarmEvent({
|
|
18205
|
+
emitFarmEvent({
|
|
18206
|
+
type: "ppr.refresh.error",
|
|
18207
|
+
route: pprRefreshRoute,
|
|
18208
|
+
error
|
|
18209
|
+
});
|
|
17505
18210
|
}
|
|
17506
18211
|
logger.error(`Error rendering page: ${error}`);
|
|
17507
18212
|
if (res.headersSent || res.writableEnded) {
|
|
@@ -17554,7 +18259,9 @@ var _ServerRenderer = class _ServerRenderer {
|
|
|
17554
18259
|
if (typeof layoutModule.generateMetadata === "function") {
|
|
17555
18260
|
metadata = mergeMetadata(
|
|
17556
18261
|
metadata,
|
|
17557
|
-
await layoutModule.generateMetadata({
|
|
18262
|
+
await layoutModule.generateMetadata({
|
|
18263
|
+
params: options.pageProps.params
|
|
18264
|
+
})
|
|
17558
18265
|
);
|
|
17559
18266
|
}
|
|
17560
18267
|
}
|
|
@@ -17785,7 +18492,13 @@ var _ServerRenderer = class _ServerRenderer {
|
|
|
17785
18492
|
clientEntry: "/@farm/client.js",
|
|
17786
18493
|
routes: {},
|
|
17787
18494
|
layouts: {},
|
|
17788
|
-
|
|
18495
|
+
slots: [],
|
|
18496
|
+
sharedAssets: [
|
|
18497
|
+
{
|
|
18498
|
+
tag: "link",
|
|
18499
|
+
attrs: { rel: "stylesheet", href: "/src/app/globals.css" }
|
|
18500
|
+
}
|
|
18501
|
+
]
|
|
17789
18502
|
};
|
|
17790
18503
|
for (const routeEntry of manifest.routes) {
|
|
17791
18504
|
clientManifest.routes[routeEntry.pattern] = {
|
|
@@ -17807,9 +18520,26 @@ var _ServerRenderer = class _ServerRenderer {
|
|
|
17807
18520
|
assets: []
|
|
17808
18521
|
};
|
|
17809
18522
|
}
|
|
17810
|
-
const
|
|
18523
|
+
for (const slotEntry of manifest.slots ?? []) {
|
|
18524
|
+
clientManifest.slots.push({
|
|
18525
|
+
...slotEntry,
|
|
18526
|
+
preloads: [slotEntry.modulePath],
|
|
18527
|
+
assets: []
|
|
18528
|
+
});
|
|
18529
|
+
}
|
|
18530
|
+
const routeSlotPayload = (req.__FARM_ROUTE_SLOTS__ || []).map(
|
|
18531
|
+
(slot) => ({
|
|
18532
|
+
...slot,
|
|
18533
|
+
modulePath: typeof slot.modulePath === "string" && slot.modulePath.startsWith(this.config.root) ? slot.modulePath.slice(this.config.root.length) : slot.modulePath
|
|
18534
|
+
})
|
|
18535
|
+
);
|
|
18536
|
+
const deferredProps = prepareDeferredData({
|
|
18537
|
+
page: req.__FARM_PROPS__ || {},
|
|
18538
|
+
slots: routeSlotPayload
|
|
18539
|
+
});
|
|
17811
18540
|
const propsScript = `<script>
|
|
17812
|
-
window.__FARM_PROPS__ = ${serializeInlineValue(deferredProps.data)};
|
|
18541
|
+
window.__FARM_PROPS__ = ${serializeInlineValue(deferredProps.data.page)};
|
|
18542
|
+
window.__FARM_ROUTE_SLOTS__ = ${serializeInlineValue(deferredProps.data.slots)};
|
|
17813
18543
|
window.__FARM_DEPLOYMENT_ID__ = ${serializeInlineValue(deploymentId)};
|
|
17814
18544
|
window.__FARM_PATH__ = ${JSON.stringify(req.__FARM_ROUTE__ || req.url || "/")};
|
|
17815
18545
|
window.__FARM_IS_CLIENT__ = ${JSON.stringify(isClientComponent)};
|
|
@@ -17822,7 +18552,7 @@ window.__FARM_MANIFEST__ = ${JSON.stringify(clientManifest)};
|
|
|
17822
18552
|
window.__FARM_INTEGRATION_API_MANIFEST__ = ${JSON.stringify(getRegisteredIntegrationAPIManifest())};
|
|
17823
18553
|
${getFarmI18nClientSnapshot() ? `window.__FARM_I18N__ = ${serializeInlineValue(getFarmI18nClientSnapshot())};` : ""}
|
|
17824
18554
|
</script>`;
|
|
17825
|
-
const hydrationClickQueueScript = isClientComponent || req.__FARM_SHOULD_HYDRATE__ === true ? createPreHydrationClickQueueScript() : "";
|
|
18555
|
+
const hydrationClickQueueScript = isClientComponent || req.__FARM_SHOULD_HYDRATE__ === true || req.__FARM_HAS_HYDRATABLE_ROUTE_SLOTS__ === true ? createPreHydrationClickQueueScript() : "";
|
|
17826
18556
|
const {
|
|
17827
18557
|
title,
|
|
17828
18558
|
tags: metaTags,
|
|
@@ -17933,7 +18663,11 @@ ${getFarmI18nClientSnapshot() ? `window.__FARM_I18N__ = ${serializeInlineValue(g
|
|
|
17933
18663
|
didError = true;
|
|
17934
18664
|
if (!isFarmRedirectError(error) && !isFarmNotFoundError(error)) {
|
|
17935
18665
|
logger.error(`SSR shell error: ${error}`);
|
|
17936
|
-
emitFarmEvent({
|
|
18666
|
+
emitFarmEvent({
|
|
18667
|
+
type: "render.error",
|
|
18668
|
+
route: observabilityRoute,
|
|
18669
|
+
error
|
|
18670
|
+
});
|
|
17937
18671
|
}
|
|
17938
18672
|
if (clearMiddlewareData) {
|
|
17939
18673
|
clearMiddlewareData();
|
|
@@ -17944,7 +18678,11 @@ ${getFarmI18nClientSnapshot() ? `window.__FARM_I18N__ = ${serializeInlineValue(g
|
|
|
17944
18678
|
didError = true;
|
|
17945
18679
|
if (!isFarmRedirectError(error) && !isFarmNotFoundError(error)) {
|
|
17946
18680
|
logger.error(`SSR streaming error: ${error}`);
|
|
17947
|
-
emitFarmEvent({
|
|
18681
|
+
emitFarmEvent({
|
|
18682
|
+
type: "render.error",
|
|
18683
|
+
route: observabilityRoute,
|
|
18684
|
+
error
|
|
18685
|
+
});
|
|
17948
18686
|
}
|
|
17949
18687
|
}
|
|
17950
18688
|
});
|
|
@@ -18120,6 +18858,7 @@ var _FarmApp = class _FarmApp {
|
|
|
18120
18858
|
logger.info("Initializing Farm.js application...");
|
|
18121
18859
|
}
|
|
18122
18860
|
await initStorage(this.config.storage);
|
|
18861
|
+
await configureFarmCache(this.config.cache);
|
|
18123
18862
|
await this.i18nRuntime.initialize();
|
|
18124
18863
|
await this.verifyAppStructure();
|
|
18125
18864
|
await this.routeManager.discoverRoutes();
|
|
@@ -18151,6 +18890,7 @@ var _FarmApp = class _FarmApp {
|
|
|
18151
18890
|
preset: config.preset ?? "node-server",
|
|
18152
18891
|
deploy: config.deploy || {},
|
|
18153
18892
|
storage: config.storage || {},
|
|
18893
|
+
cache: config.cache || {},
|
|
18154
18894
|
integrations: config.integrations || {},
|
|
18155
18895
|
plugins: config.plugins || [],
|
|
18156
18896
|
migrations: config.migrations || { commands: [] },
|
|
@@ -18629,7 +19369,7 @@ async function invokeAPIRouteEndpointInContext(endpoint, request, params) {
|
|
|
18629
19369
|
});
|
|
18630
19370
|
let body = void 0;
|
|
18631
19371
|
if (request.method.toUpperCase() !== "GET" && request.method.toUpperCase() !== "HEAD") {
|
|
18632
|
-
body = await
|
|
19372
|
+
body = await readRequestBody2(request);
|
|
18633
19373
|
}
|
|
18634
19374
|
const headers = Object.fromEntries(request.headers.entries());
|
|
18635
19375
|
const types = endpoint.__types || {};
|
|
@@ -18733,17 +19473,50 @@ function isFarmContextHandler(endpoint) {
|
|
|
18733
19473
|
return firstParameter === "ctx" || firstParameter === "context" || firstParameter.startsWith("{");
|
|
18734
19474
|
}
|
|
18735
19475
|
__name(isFarmContextHandler, "isFarmContextHandler");
|
|
18736
|
-
async function
|
|
19476
|
+
async function readRequestBody2(request) {
|
|
19477
|
+
const contentType = request.headers.get("content-type")?.split(";", 1)[0]?.trim().toLowerCase();
|
|
18737
19478
|
try {
|
|
19479
|
+
if (contentType === "multipart/form-data") {
|
|
19480
|
+
return formDataToObject(await request.clone().formData());
|
|
19481
|
+
}
|
|
18738
19482
|
const text2 = await request.clone().text();
|
|
18739
|
-
if (text2)
|
|
19483
|
+
if (!text2) return void 0;
|
|
19484
|
+
if (contentType === "application/x-www-form-urlencoded") {
|
|
19485
|
+
return searchParamsToObject2(new URLSearchParams(text2));
|
|
19486
|
+
}
|
|
19487
|
+
if (contentType === "application/json" || contentType?.endsWith("+json")) {
|
|
18740
19488
|
return JSON.parse(text2);
|
|
18741
19489
|
}
|
|
19490
|
+
return JSON.parse(text2);
|
|
18742
19491
|
} catch {
|
|
18743
19492
|
}
|
|
18744
19493
|
return void 0;
|
|
18745
19494
|
}
|
|
18746
|
-
__name(
|
|
19495
|
+
__name(readRequestBody2, "readRequestBody");
|
|
19496
|
+
function formDataToObject(formData) {
|
|
19497
|
+
return entriesToObject(formData.entries());
|
|
19498
|
+
}
|
|
19499
|
+
__name(formDataToObject, "formDataToObject");
|
|
19500
|
+
function searchParamsToObject2(searchParams) {
|
|
19501
|
+
return entriesToObject(searchParams.entries());
|
|
19502
|
+
}
|
|
19503
|
+
__name(searchParamsToObject2, "searchParamsToObject");
|
|
19504
|
+
function entriesToObject(entries) {
|
|
19505
|
+
const output = /* @__PURE__ */ Object.create(null);
|
|
19506
|
+
for (const [key, value] of entries) {
|
|
19507
|
+
if (key === "__proto__" || key === "constructor" || key === "prototype") continue;
|
|
19508
|
+
const current = output[key];
|
|
19509
|
+
if (current === void 0) {
|
|
19510
|
+
output[key] = value;
|
|
19511
|
+
} else if (Array.isArray(current)) {
|
|
19512
|
+
current.push(value);
|
|
19513
|
+
} else {
|
|
19514
|
+
output[key] = [current, value];
|
|
19515
|
+
}
|
|
19516
|
+
}
|
|
19517
|
+
return output;
|
|
19518
|
+
}
|
|
19519
|
+
__name(entriesToObject, "entriesToObject");
|
|
18747
19520
|
function validateInput(schema, value, error) {
|
|
18748
19521
|
if (!schema || typeof schema.parse !== "function") {
|
|
18749
19522
|
return value;
|
|
@@ -19898,6 +20671,7 @@ async function generateRouteTypes(options) {
|
|
|
19898
20671
|
absolute: false
|
|
19899
20672
|
});
|
|
19900
20673
|
for (const file of pageFiles) {
|
|
20674
|
+
if (parseRouteSlotFile(file)) continue;
|
|
19901
20675
|
const route = parseRoutePath(file);
|
|
19902
20676
|
if (route.type === "page") {
|
|
19903
20677
|
const pattern = createRoutePattern(route);
|
|
@@ -20633,7 +21407,7 @@ function transformError(id, message) {
|
|
|
20633
21407
|
__name(transformError, "transformError");
|
|
20634
21408
|
|
|
20635
21409
|
// package.json
|
|
20636
|
-
var version = "0.1.0-beta.
|
|
21410
|
+
var version = "0.1.0-beta.5";
|
|
20637
21411
|
|
|
20638
21412
|
// src/version.ts
|
|
20639
21413
|
var FARM_VERSION = version;
|
|
@@ -21352,7 +22126,7 @@ function farmPlugin(options = {}, initialPluginManager) {
|
|
|
21352
22126
|
}, "isProgrammaticRouteSourceFile");
|
|
21353
22127
|
const isAppRuntimeFile = /* @__PURE__ */ __name((file) => {
|
|
21354
22128
|
const normalized = file.replace(/\\/g, "/");
|
|
21355
|
-
return appDirSlugs.some((appDir) => normalized.startsWith(`${appDir}/`)) && /\/(?:page|layout|loading|error|middleware|route)\.(?:ts|tsx|js|jsx|md|mdx)$|\/(?:opengraph-image|twitter-image)(?:\.(?:ts|tsx|js|jsx|png|jpg|jpeg|gif|webp)|\.alt\.txt)$/.test(
|
|
22129
|
+
return appDirSlugs.some((appDir) => normalized.startsWith(`${appDir}/`)) && /\/(?:page|default|layout|loading|error|middleware|route)\.(?:ts|tsx|js|jsx|md|mdx)$|\/(?:opengraph-image|twitter-image)(?:\.(?:ts|tsx|js|jsx|png|jpg|jpeg|gif|webp)|\.alt\.txt)$/.test(
|
|
21356
22130
|
normalized
|
|
21357
22131
|
);
|
|
21358
22132
|
}, "isAppRuntimeFile");
|
|
@@ -22043,7 +22817,10 @@ function farmPlugin(options = {}, initialPluginManager) {
|
|
|
22043
22817
|
method: req.method || "GET"
|
|
22044
22818
|
});
|
|
22045
22819
|
}
|
|
22046
|
-
const
|
|
22820
|
+
const interceptFromHeader = request.headers.get("x-farm-intercept-from") || void 0;
|
|
22821
|
+
const match = routeManager3.matchRoute(targetRequestUrl.pathname, {
|
|
22822
|
+
interceptFrom: interceptFromHeader
|
|
22823
|
+
});
|
|
22047
22824
|
if (pm) {
|
|
22048
22825
|
await pm.runHookParallel("afterRouteMatch", {
|
|
22049
22826
|
pathname: targetPath,
|
|
@@ -22059,7 +22836,7 @@ function farmPlugin(options = {}, initialPluginManager) {
|
|
|
22059
22836
|
res.end(JSON.stringify({ error: "Route not found" }));
|
|
22060
22837
|
return;
|
|
22061
22838
|
}
|
|
22062
|
-
const { route, params, layouts } = match;
|
|
22839
|
+
const { route, params, layouts, slots } = match;
|
|
22063
22840
|
if (!route) {
|
|
22064
22841
|
res.statusCode = 404;
|
|
22065
22842
|
res.setHeader("Content-Type", "application/json");
|
|
@@ -22114,6 +22891,54 @@ function farmPlugin(options = {}, initialPluginManager) {
|
|
|
22114
22891
|
search: searchParams,
|
|
22115
22892
|
routePath: route.pattern
|
|
22116
22893
|
});
|
|
22894
|
+
const routeSlots = await Promise.all(
|
|
22895
|
+
slots.map(async (slot) => {
|
|
22896
|
+
const slotModule = await routeManager3.loadRouteModule(slot.route.modulePath);
|
|
22897
|
+
const slotMetadata = getClientModuleMetadata(
|
|
22898
|
+
slot.route.modulePath,
|
|
22899
|
+
server.config.root
|
|
22900
|
+
);
|
|
22901
|
+
const slotContext = await resolveFarmRouteContext(farmApp.getConfig(), {
|
|
22902
|
+
request,
|
|
22903
|
+
params: slot.params,
|
|
22904
|
+
search: searchParams,
|
|
22905
|
+
path: targetUrl.pathname
|
|
22906
|
+
});
|
|
22907
|
+
const slotProps = await parseRouteModuleProps2(slotModule, {
|
|
22908
|
+
props: withFarmRouteContext(
|
|
22909
|
+
{
|
|
22910
|
+
params: slot.params,
|
|
22911
|
+
searchParams: Promise.resolve(searchParams),
|
|
22912
|
+
path: targetUrl.pathname
|
|
22913
|
+
},
|
|
22914
|
+
slotContext
|
|
22915
|
+
),
|
|
22916
|
+
search: searchParams,
|
|
22917
|
+
routePath: slot.route.pattern
|
|
22918
|
+
});
|
|
22919
|
+
return {
|
|
22920
|
+
name: slot.name,
|
|
22921
|
+
ownerPattern: slot.ownerPattern,
|
|
22922
|
+
containerId: slot.containerId,
|
|
22923
|
+
interception: slot.interception,
|
|
22924
|
+
fallback: slot.fallback,
|
|
22925
|
+
modulePath: slot.route.modulePath,
|
|
22926
|
+
isClientComponent: slotMetadata.isClientComponent,
|
|
22927
|
+
shouldHydrate: slotMetadata.shouldHydrate,
|
|
22928
|
+
props: {
|
|
22929
|
+
params: slotProps.params,
|
|
22930
|
+
search: slotProps.search,
|
|
22931
|
+
searchParams: slotProps.search,
|
|
22932
|
+
..."data" in slotProps ? { data: slotProps.data } : {},
|
|
22933
|
+
...slotProps.__farmCanonicalPath ? {
|
|
22934
|
+
__farmCanonicalPath: slotProps.__farmCanonicalPath
|
|
22935
|
+
} : {},
|
|
22936
|
+
...slotProps.__farmRoutePropsResolved ? { __farmRoutePropsResolved: true } : {},
|
|
22937
|
+
path: targetUrl.pathname
|
|
22938
|
+
}
|
|
22939
|
+
};
|
|
22940
|
+
})
|
|
22941
|
+
);
|
|
22117
22942
|
const projectRoot = server.config.root;
|
|
22118
22943
|
const toUrlPath = /* @__PURE__ */ __name((absolutePath) => {
|
|
22119
22944
|
if (absolutePath.startsWith(projectRoot)) {
|
|
@@ -22134,13 +22959,21 @@ function farmPlugin(options = {}, initialPluginManager) {
|
|
|
22134
22959
|
},
|
|
22135
22960
|
canonicalPath: routeProps.__farmCanonicalPath,
|
|
22136
22961
|
modulePath: toUrlPath(route.modulePath),
|
|
22137
|
-
isClientComponent,
|
|
22138
|
-
shouldHydrate,
|
|
22962
|
+
isClientComponent: routeSlots.length > 0 ? false : isClientComponent,
|
|
22963
|
+
shouldHydrate: shouldHydrate || routeSlots.some((slot) => slot.isClientComponent || slot.shouldHydrate),
|
|
22139
22964
|
metadata: {
|
|
22140
22965
|
title: mergedMetadata.title,
|
|
22141
22966
|
description: mergedMetadata.description
|
|
22142
22967
|
},
|
|
22143
22968
|
layoutModules: layouts.map((l) => toUrlPath(l.modulePath)),
|
|
22969
|
+
routeSlots: routeSlots.map((slot) => ({
|
|
22970
|
+
...slot,
|
|
22971
|
+
modulePath: toUrlPath(slot.modulePath)
|
|
22972
|
+
})),
|
|
22973
|
+
interception: routeSlots.some((slot) => slot.interception) ? {
|
|
22974
|
+
from: interceptFromHeader,
|
|
22975
|
+
slots: routeSlots.filter((slot) => slot.interception).map((slot) => slot.name)
|
|
22976
|
+
} : void 0,
|
|
22144
22977
|
i18n: getFarmI18nClientSnapshot()
|
|
22145
22978
|
};
|
|
22146
22979
|
await sendWebResponse(
|
|
@@ -22476,6 +23309,7 @@ function farmPlugin(options = {}, initialPluginManager) {
|
|
|
22476
23309
|
export const getManifest = () => ({
|
|
22477
23310
|
routes: {},
|
|
22478
23311
|
layouts: {},
|
|
23312
|
+
slots: [],
|
|
22479
23313
|
clientEntry: "/@farm/client.js",
|
|
22480
23314
|
sharedAssets: []
|
|
22481
23315
|
});
|
|
@@ -22486,6 +23320,7 @@ export const getManifest = () => ({
|
|
|
22486
23320
|
clientEntry: "/@farm/client.js",
|
|
22487
23321
|
routes: {},
|
|
22488
23322
|
layouts: {},
|
|
23323
|
+
slots: [],
|
|
22489
23324
|
sharedAssets: [
|
|
22490
23325
|
{
|
|
22491
23326
|
tag: "link",
|
|
@@ -22515,6 +23350,13 @@ export const getManifest = () => ({
|
|
|
22515
23350
|
assets: []
|
|
22516
23351
|
};
|
|
22517
23352
|
}
|
|
23353
|
+
for (const slot of manifest.slots) {
|
|
23354
|
+
fullManifest.slots.push({
|
|
23355
|
+
...slot,
|
|
23356
|
+
preloads: [slot.modulePath],
|
|
23357
|
+
assets: []
|
|
23358
|
+
});
|
|
23359
|
+
}
|
|
22518
23360
|
return `
|
|
22519
23361
|
// Auto-generated manifest for SPA navigation (TanStack Start pattern)
|
|
22520
23362
|
// This manifest is inlined in the server bundle - no file on disk
|
|
@@ -23157,7 +23999,7 @@ window.__FARM_WRAP_PROVIDERS__ = wrapWithIntegrationProviders;
|
|
|
23157
23999
|
|
|
23158
24000
|
// Get manifest from window (inlined by server in HTML)
|
|
23159
24001
|
// Fallback to empty manifest if not available yet
|
|
23160
|
-
const getManifest = () => window.__FARM_MANIFEST__ || { routes: {}, layouts: {}, clientEntry: '', sharedAssets: [] };
|
|
24002
|
+
const getManifest = () => window.__FARM_MANIFEST__ || { routes: {}, layouts: {}, slots: [], clientEntry: '', sharedAssets: [] };
|
|
23161
24003
|
|
|
23162
24004
|
// ====== CLIENT-SIDE ROUTE MATCHING ======
|
|
23163
24005
|
// Matches URL to route using manifest (no server request!)
|
|
@@ -23496,6 +24338,9 @@ let LayoutComponent = null;
|
|
|
23496
24338
|
|
|
23497
24339
|
// Track if we've taken over rendering from SSR
|
|
23498
24340
|
let hasClientTakenOver = false;
|
|
24341
|
+
const routeSlotRoots = new Map();
|
|
24342
|
+
const routeSlotDefinitions = new Map();
|
|
24343
|
+
let activeRouteInterception = null;
|
|
23499
24344
|
|
|
23500
24345
|
function normalizeServerProps(rawProps) {
|
|
23501
24346
|
const props = rawProps && typeof rawProps === 'object' ? { ...rawProps } : {};
|
|
@@ -23508,6 +24353,123 @@ function normalizeServerProps(rawProps) {
|
|
|
23508
24353
|
return props;
|
|
23509
24354
|
}
|
|
23510
24355
|
|
|
24356
|
+
function getRouteSlotKey(slot) {
|
|
24357
|
+
return slot.ownerPattern + ':' + slot.name;
|
|
24358
|
+
}
|
|
24359
|
+
|
|
24360
|
+
async function renderRouteSlot(slot, mode = 'render') {
|
|
24361
|
+
const container = document.getElementById(slot.containerId);
|
|
24362
|
+
if (!container || !slot.modulePath) return false;
|
|
24363
|
+
if (mode === 'intercept' && !slot.isClientComponent && !slot.shouldHydrate) {
|
|
24364
|
+
return false;
|
|
24365
|
+
}
|
|
24366
|
+
|
|
24367
|
+
let slotModule = pageModuleCache.get(slot.modulePath);
|
|
24368
|
+
if (!slotModule) {
|
|
24369
|
+
slotModule = await import(/* @vite-ignore */ slot.modulePath);
|
|
24370
|
+
pageModuleCache.set(slot.modulePath, slotModule);
|
|
24371
|
+
}
|
|
24372
|
+
const SlotComponent = slotModule?.default;
|
|
24373
|
+
if (!SlotComponent) return false;
|
|
24374
|
+
|
|
24375
|
+
const props = reviveDeferredData(
|
|
24376
|
+
normalizeServerProps(slot.props || {}),
|
|
24377
|
+
window.__FARM_DEFERRED_DATA__ || {},
|
|
24378
|
+
);
|
|
24379
|
+
const element = wrapWithIntegrationProviders(
|
|
24380
|
+
React.createElement(SlotComponent, props),
|
|
24381
|
+
);
|
|
24382
|
+
const key = getRouteSlotKey(slot);
|
|
24383
|
+
const existingRoot = routeSlotRoots.get(key);
|
|
24384
|
+
|
|
24385
|
+
if (mode === 'hydrate') {
|
|
24386
|
+
if (existingRoot) return true;
|
|
24387
|
+
const root = hydrateRoot(container, element);
|
|
24388
|
+
routeSlotRoots.set(key, root);
|
|
24389
|
+
} else {
|
|
24390
|
+
if (existingRoot) {
|
|
24391
|
+
try { existingRoot.unmount(); } catch (error) {}
|
|
24392
|
+
}
|
|
24393
|
+
const root = createRoot(container);
|
|
24394
|
+
root.render(element);
|
|
24395
|
+
routeSlotRoots.set(key, root);
|
|
24396
|
+
}
|
|
24397
|
+
|
|
24398
|
+
routeSlotDefinitions.set(key, slot);
|
|
24399
|
+
return true;
|
|
24400
|
+
}
|
|
24401
|
+
|
|
24402
|
+
async function hydrateInitialRouteSlots() {
|
|
24403
|
+
const slots = Array.isArray(window.__FARM_ROUTE_SLOTS__)
|
|
24404
|
+
? window.__FARM_ROUTE_SLOTS__
|
|
24405
|
+
: [];
|
|
24406
|
+
let hydrated = false;
|
|
24407
|
+
|
|
24408
|
+
for (const slot of slots) {
|
|
24409
|
+
routeSlotDefinitions.set(getRouteSlotKey(slot), slot);
|
|
24410
|
+
if (!slot.isClientComponent && !slot.shouldHydrate) continue;
|
|
24411
|
+
try {
|
|
24412
|
+
hydrated = (await renderRouteSlot(slot, 'hydrate')) || hydrated;
|
|
24413
|
+
} catch (error) {
|
|
24414
|
+
console.warn('[Farm.js] Could not hydrate route slot:', slot.name, error);
|
|
24415
|
+
}
|
|
24416
|
+
}
|
|
24417
|
+
|
|
24418
|
+
return hydrated;
|
|
24419
|
+
}
|
|
24420
|
+
|
|
24421
|
+
async function renderRouteInterception(pageData) {
|
|
24422
|
+
const slots = Array.isArray(pageData.routeSlots)
|
|
24423
|
+
? pageData.routeSlots.filter((slot) => slot.interception)
|
|
24424
|
+
: [];
|
|
24425
|
+
if (!pageData.interception || slots.length === 0) return false;
|
|
24426
|
+
|
|
24427
|
+
const previous = new Map();
|
|
24428
|
+
for (const slot of slots) {
|
|
24429
|
+
const key = getRouteSlotKey(slot);
|
|
24430
|
+
previous.set(key, routeSlotDefinitions.get(key) || null);
|
|
24431
|
+
if (!(await renderRouteSlot(slot, 'intercept'))) {
|
|
24432
|
+
return false;
|
|
24433
|
+
}
|
|
24434
|
+
}
|
|
24435
|
+
|
|
24436
|
+
activeRouteInterception = {
|
|
24437
|
+
from: pageData.interception.from,
|
|
24438
|
+
slots,
|
|
24439
|
+
previous,
|
|
24440
|
+
};
|
|
24441
|
+
return true;
|
|
24442
|
+
}
|
|
24443
|
+
|
|
24444
|
+
async function clearRouteInterception(destination) {
|
|
24445
|
+
if (!activeRouteInterception) return false;
|
|
24446
|
+
const active = activeRouteInterception;
|
|
24447
|
+
activeRouteInterception = null;
|
|
24448
|
+
|
|
24449
|
+
for (const slot of active.slots) {
|
|
24450
|
+
const key = getRouteSlotKey(slot);
|
|
24451
|
+
const root = routeSlotRoots.get(key);
|
|
24452
|
+
if (root) {
|
|
24453
|
+
try { root.unmount(); } catch (error) {}
|
|
24454
|
+
routeSlotRoots.delete(key);
|
|
24455
|
+
}
|
|
24456
|
+
|
|
24457
|
+
const previous = active.previous.get(key);
|
|
24458
|
+
if (previous && (previous.isClientComponent || previous.shouldHydrate)) {
|
|
24459
|
+
await renderRouteSlot(previous, 'render');
|
|
24460
|
+
} else {
|
|
24461
|
+
const container = document.getElementById(slot.containerId);
|
|
24462
|
+
if (container) container.replaceChildren();
|
|
24463
|
+
if (previous) routeSlotDefinitions.set(key, previous);
|
|
24464
|
+
else routeSlotDefinitions.delete(key);
|
|
24465
|
+
}
|
|
24466
|
+
}
|
|
24467
|
+
|
|
24468
|
+
if (!active.from) return false;
|
|
24469
|
+
const background = new URL(active.from, window.location.origin);
|
|
24470
|
+
return destination === background.pathname + background.search;
|
|
24471
|
+
}
|
|
24472
|
+
|
|
23511
24473
|
function applyCanonicalPathFromProps(props) {
|
|
23512
24474
|
const canonicalPath = props && typeof props.__farmCanonicalPath === 'string'
|
|
23513
24475
|
? props.__farmCanonicalPath
|
|
@@ -23742,6 +24704,17 @@ async function tryHydrateImportedPage(
|
|
|
23742
24704
|
async function renderPage(pageData) {
|
|
23743
24705
|
const container = document.getElementById('root');
|
|
23744
24706
|
if (!container) return;
|
|
24707
|
+
const destination = window.location.pathname + window.location.search;
|
|
24708
|
+
|
|
24709
|
+
if (pageData.interception) {
|
|
24710
|
+
if (await renderRouteInterception(pageData)) return;
|
|
24711
|
+
window.location.assign(destination);
|
|
24712
|
+
return;
|
|
24713
|
+
}
|
|
24714
|
+
|
|
24715
|
+
if (await clearRouteInterception(destination)) {
|
|
24716
|
+
return;
|
|
24717
|
+
}
|
|
23745
24718
|
|
|
23746
24719
|
const route = {
|
|
23747
24720
|
modulePath: pageData.modulePath,
|
|
@@ -23970,7 +24943,9 @@ async function hydrate() {
|
|
|
23970
24943
|
window.__FARM_SHOULD_HYDRATE__ === true ||
|
|
23971
24944
|
isClientComponent ||
|
|
23972
24945
|
await moduleLooksClient(modulePath);
|
|
24946
|
+
const hydratedSlots = await hydrateInitialRouteSlots();
|
|
23973
24947
|
if (!shouldHydrate) {
|
|
24948
|
+
if (hydratedSlots) replayPreHydrationClicks();
|
|
23974
24949
|
console.log('[Farm.js] Server component - SPA router ready')
|
|
23975
24950
|
return
|
|
23976
24951
|
}
|
|
@@ -24354,7 +25329,7 @@ function createServerFn(options) {
|
|
|
24354
25329
|
const middleware = resolveServerFnMiddleware(options.middleware);
|
|
24355
25330
|
const serverFn = /* @__PURE__ */ __name(async (value) => {
|
|
24356
25331
|
const formData = isFormData(value) ? value : void 0;
|
|
24357
|
-
const rawInput = formData ?
|
|
25332
|
+
const rawInput = formData ? formDataToObject2(formData) : value;
|
|
24358
25333
|
const input = await _parseServerFnSchema(options.input, rawInput, "input");
|
|
24359
25334
|
const executionContext = getServerActionExecutionContext();
|
|
24360
25335
|
const request = executionContext?.request ?? _resolveCurrentRequest();
|
|
@@ -24366,8 +25341,21 @@ function createServerFn(options) {
|
|
|
24366
25341
|
request,
|
|
24367
25342
|
signal
|
|
24368
25343
|
};
|
|
24369
|
-
|
|
24370
|
-
|
|
25344
|
+
let resolvedContext = Object.freeze(/* @__PURE__ */ Object.create(null));
|
|
25345
|
+
const result = await runServerFnMiddleware(middleware, handlerContext, async (context) => {
|
|
25346
|
+
resolvedContext = context.context;
|
|
25347
|
+
return options.handler(context);
|
|
25348
|
+
});
|
|
25349
|
+
const parsedResult = await _parseServerFnSchema(options.output, result, "output");
|
|
25350
|
+
if (options.invalidates) {
|
|
25351
|
+
const declaration = typeof options.invalidates === "function" ? await options.invalidates({
|
|
25352
|
+
...handlerContext,
|
|
25353
|
+
context: resolvedContext,
|
|
25354
|
+
result: parsedResult
|
|
25355
|
+
}) : options.invalidates;
|
|
25356
|
+
await applyFarmCacheInvalidationTargets(declaration);
|
|
25357
|
+
}
|
|
25358
|
+
return parsedResult;
|
|
24371
25359
|
}, "serverFn");
|
|
24372
25360
|
Object.defineProperties(serverFn, {
|
|
24373
25361
|
[FARM_SERVER_FN_SYMBOL]: {
|
|
@@ -24389,6 +25377,10 @@ function createServerFn(options) {
|
|
|
24389
25377
|
__farmServerFnMiddleware: {
|
|
24390
25378
|
value: middleware,
|
|
24391
25379
|
enumerable: false
|
|
25380
|
+
},
|
|
25381
|
+
__farmServerFnInvalidates: {
|
|
25382
|
+
value: options.invalidates,
|
|
25383
|
+
enumerable: false
|
|
24392
25384
|
}
|
|
24393
25385
|
});
|
|
24394
25386
|
return serverFn;
|
|
@@ -24486,7 +25478,7 @@ function unwrapSafeParseResult(result) {
|
|
|
24486
25478
|
return result;
|
|
24487
25479
|
}
|
|
24488
25480
|
__name(unwrapSafeParseResult, "unwrapSafeParseResult");
|
|
24489
|
-
function
|
|
25481
|
+
function formDataToObject2(formData) {
|
|
24490
25482
|
const output = /* @__PURE__ */ Object.create(null);
|
|
24491
25483
|
for (const [key, value] of formData.entries()) {
|
|
24492
25484
|
if (!isSafeFormKey(key)) continue;
|
|
@@ -24501,7 +25493,7 @@ function formDataToObject(formData) {
|
|
|
24501
25493
|
}
|
|
24502
25494
|
return output;
|
|
24503
25495
|
}
|
|
24504
|
-
__name(
|
|
25496
|
+
__name(formDataToObject2, "formDataToObject");
|
|
24505
25497
|
function isSafeFormKey(key) {
|
|
24506
25498
|
return !key.startsWith("$ACTION_") && !UNSAFE_FORM_KEYS.has(key);
|
|
24507
25499
|
}
|
|
@@ -24563,7 +25555,7 @@ function createServerQuery(options) {
|
|
|
24563
25555
|
tags: [createRouteDataCacheTag(routeKey)],
|
|
24564
25556
|
revalidate: staleTime === false ? false : Math.max(1, Math.ceil(staleTime / 1e3))
|
|
24565
25557
|
});
|
|
24566
|
-
updatedAt = cache.
|
|
25558
|
+
updatedAt = (await cache.getEntryAsync(cacheKey, { allowStale: true }))?.createdAt ?? Date.now();
|
|
24567
25559
|
}
|
|
24568
25560
|
return createFarmServerQueryResult(data, {
|
|
24569
25561
|
key: clientKey,
|
|
@@ -25412,6 +26404,13 @@ function mergeFarmViteConfig(farmConfig, userConfig = {}) {
|
|
|
25412
26404
|
...farmConfig.server,
|
|
25413
26405
|
...userConfig.server
|
|
25414
26406
|
},
|
|
26407
|
+
resolve: {
|
|
26408
|
+
...farmConfig.resolve,
|
|
26409
|
+
...userConfig.resolve,
|
|
26410
|
+
dedupe: Array.from(
|
|
26411
|
+
/* @__PURE__ */ new Set([...farmConfig.resolve?.dedupe || [], ...userConfig.resolve?.dedupe || []])
|
|
26412
|
+
)
|
|
26413
|
+
},
|
|
25415
26414
|
optimizeDeps: {
|
|
25416
26415
|
...farmConfig.optimizeDeps,
|
|
25417
26416
|
...userConfig.optimizeDeps,
|
|
@@ -25438,6 +26437,7 @@ function mergeFarmViteConfig(farmConfig, userConfig = {}) {
|
|
|
25438
26437
|
__name(mergeFarmViteConfig, "mergeFarmViteConfig");
|
|
25439
26438
|
|
|
25440
26439
|
// src/server/create-server.ts
|
|
26440
|
+
var DEFAULT_FARM_DEV_SERVER_PORT = 3e3;
|
|
25441
26441
|
function createBrandingPlugin() {
|
|
25442
26442
|
let serverStarted = false;
|
|
25443
26443
|
let startTime = Date.now();
|
|
@@ -25599,7 +26599,13 @@ async function createServer(config = {}) {
|
|
|
25599
26599
|
createBrandingPlugin()
|
|
25600
26600
|
],
|
|
25601
26601
|
server: {
|
|
25602
|
-
middlewareMode: false
|
|
26602
|
+
middlewareMode: false,
|
|
26603
|
+
port: DEFAULT_FARM_DEV_SERVER_PORT,
|
|
26604
|
+
strictPort: true
|
|
26605
|
+
},
|
|
26606
|
+
resolve: {
|
|
26607
|
+
// Keep framework and application modules on one React runtime.
|
|
26608
|
+
dedupe: ["react", "react-dom"]
|
|
25603
26609
|
},
|
|
25604
26610
|
optimizeDeps: {
|
|
25605
26611
|
// Avoid Vite scanning server/native-only deps from framework internals.
|
|
@@ -25674,7 +26680,7 @@ async function createServer(config = {}) {
|
|
|
25674
26680
|
}
|
|
25675
26681
|
}
|
|
25676
26682
|
__name(createServer, "createServer");
|
|
25677
|
-
async function startDevServer(config = {}, port
|
|
26683
|
+
async function startDevServer(config = {}, port) {
|
|
25678
26684
|
const server = await createServer(config);
|
|
25679
26685
|
await server.listen(port);
|
|
25680
26686
|
const pluginManager = server.__farmPluginManager;
|
|
@@ -25755,6 +26761,7 @@ function assertFunction(value, label) {
|
|
|
25755
26761
|
__name(assertFunction, "assertFunction");
|
|
25756
26762
|
// Annotate the CommonJS export names for ESM import in node:
|
|
25757
26763
|
0 && (module.exports = {
|
|
26764
|
+
DEFAULT_FARM_DEV_SERVER_PORT,
|
|
25758
26765
|
DEFAULT_SERVER_ACTION_BODY_SIZE_LIMIT,
|
|
25759
26766
|
FARM_SERVER_QUERY_SYMBOL,
|
|
25760
26767
|
FarmApp,
|
|
@@ -25767,7 +26774,9 @@ __name(assertFunction, "assertFunction");
|
|
|
25767
26774
|
_runWithAfterRequest,
|
|
25768
26775
|
_withAfterNodeMiddleware,
|
|
25769
26776
|
after,
|
|
26777
|
+
applyFarmCacheInvalidationTargets,
|
|
25770
26778
|
applyFarmCacheInvalidations,
|
|
26779
|
+
configureFarmCache,
|
|
25771
26780
|
createClientOnlyFn,
|
|
25772
26781
|
createFarmApp,
|
|
25773
26782
|
createFarmCacheKey,
|
|
@@ -25833,6 +26842,7 @@ __name(assertFunction, "assertFunction");
|
|
|
25833
26842
|
segmentsToPattern,
|
|
25834
26843
|
sqliteStorage,
|
|
25835
26844
|
startDevServer,
|
|
26845
|
+
storageCacheAdapter,
|
|
25836
26846
|
toViteModuleId,
|
|
25837
26847
|
unstable_cache,
|
|
25838
26848
|
updateTag,
|