@farm.js/core 0.1.0-beta.3 → 0.1.0-beta.4
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-5QH4IKY3.mjs → chunk-3U3ZUQAQ.mjs} +2 -2
- 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-OHC6VCDI.mjs → chunk-AJWRO5WE.mjs} +521 -42
- package/dist/chunk-AJWRO5WE.mjs.map +1 -0
- package/dist/chunk-ALCLXXTY.mjs +187 -0
- package/dist/chunk-ALCLXXTY.mjs.map +1 -0
- package/dist/{chunk-XJSHJN4M.mjs → chunk-AOBXKNS5.mjs} +593 -49
- package/dist/chunk-AOBXKNS5.mjs.map +1 -0
- package/dist/{chunk-CSU4KJJF.mjs → chunk-C2ROET2V.mjs} +2 -2
- package/dist/{chunk-BIOIOWXZ.mjs → chunk-HNIQFZKB.mjs} +2 -2
- 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-SHRJG6OG.mjs → chunk-RBRLLZL5.mjs} +18 -3
- package/dist/chunk-RBRLLZL5.mjs.map +1 -0
- package/dist/{chunk-MH6FKW2I.mjs → chunk-SADGIRS2.mjs} +3 -3
- 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-5FW6PQ3J.mjs → chunk-VVKWFZAH.mjs} +41 -16
- package/dist/chunk-VVKWFZAH.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-JNYVN7YP.mjs → chunk-W4UIVMVI.mjs} +2 -2
- package/dist/{chunk-JNYVN7YP.mjs.map → chunk-W4UIVMVI.mjs.map} +1 -1
- 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 +70 -4
- package/dist/client.d.ts +70 -4
- 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 +2112 -197
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +12 -11
- package/dist/index.d.ts +12 -11
- 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 +278 -7
- 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-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-3U3ZUQAQ.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-MH6FKW2I.mjs.map → chunk-SADGIRS2.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/index.cjs
CHANGED
|
@@ -4705,7 +4705,8 @@ var init_route_rules = __esm({
|
|
|
4705
4705
|
// src/cache-invalidation.ts
|
|
4706
4706
|
function getFarmCacheInvalidationState() {
|
|
4707
4707
|
return globalState[FARM_CACHE_INVALIDATION_STATE] ?? (globalState[FARM_CACHE_INVALIDATION_STATE] = {
|
|
4708
|
-
listeners: /* @__PURE__ */ new Set()
|
|
4708
|
+
listeners: /* @__PURE__ */ new Set(),
|
|
4709
|
+
taskListeners: /* @__PURE__ */ new Set()
|
|
4709
4710
|
});
|
|
4710
4711
|
}
|
|
4711
4712
|
function notifyFarmCacheInvalidation(key) {
|
|
@@ -4714,6 +4715,11 @@ function notifyFarmCacheInvalidation(key) {
|
|
|
4714
4715
|
listener(key);
|
|
4715
4716
|
}
|
|
4716
4717
|
}
|
|
4718
|
+
function notifyFarmCacheTask(task) {
|
|
4719
|
+
for (const listener of getFarmCacheInvalidationState().taskListeners) {
|
|
4720
|
+
listener(task);
|
|
4721
|
+
}
|
|
4722
|
+
}
|
|
4717
4723
|
function applyFarmCacheInvalidations(keys) {
|
|
4718
4724
|
if (!Array.isArray(keys)) return;
|
|
4719
4725
|
for (const key of keys) {
|
|
@@ -4745,6 +4751,11 @@ function subscribeFarmCacheInvalidation(listener) {
|
|
|
4745
4751
|
state.listeners.add(listener);
|
|
4746
4752
|
return () => state.listeners.delete(listener);
|
|
4747
4753
|
}
|
|
4754
|
+
function subscribeFarmCacheTask(listener) {
|
|
4755
|
+
const state = getFarmCacheInvalidationState();
|
|
4756
|
+
state.taskListeners.add(listener);
|
|
4757
|
+
return () => state.taskListeners.delete(listener);
|
|
4758
|
+
}
|
|
4748
4759
|
var FARM_CACHE_INVALIDATION_HEADER, FARM_CACHE_INVALIDATION_STATE, globalState;
|
|
4749
4760
|
var init_cache_invalidation = __esm({
|
|
4750
4761
|
"src/cache-invalidation.ts"() {
|
|
@@ -4754,10 +4765,12 @@ var init_cache_invalidation = __esm({
|
|
|
4754
4765
|
globalState = globalThis;
|
|
4755
4766
|
__name(getFarmCacheInvalidationState, "getFarmCacheInvalidationState");
|
|
4756
4767
|
__name(notifyFarmCacheInvalidation, "notifyFarmCacheInvalidation");
|
|
4768
|
+
__name(notifyFarmCacheTask, "notifyFarmCacheTask");
|
|
4757
4769
|
__name(applyFarmCacheInvalidations, "applyFarmCacheInvalidations");
|
|
4758
4770
|
__name(encodeFarmCacheInvalidations, "encodeFarmCacheInvalidations");
|
|
4759
4771
|
__name(decodeFarmCacheInvalidations, "decodeFarmCacheInvalidations");
|
|
4760
4772
|
__name(subscribeFarmCacheInvalidation, "subscribeFarmCacheInvalidation");
|
|
4773
|
+
__name(subscribeFarmCacheTask, "subscribeFarmCacheTask");
|
|
4761
4774
|
}
|
|
4762
4775
|
});
|
|
4763
4776
|
|
|
@@ -4853,16 +4866,24 @@ function sanitizeServerActionError(_error) {
|
|
|
4853
4866
|
message: "Server function failed"
|
|
4854
4867
|
};
|
|
4855
4868
|
}
|
|
4856
|
-
function runWithServerActionRequest(request, callback) {
|
|
4869
|
+
async function runWithServerActionRequest(request, callback) {
|
|
4857
4870
|
throwIfAborted(request.signal);
|
|
4858
|
-
|
|
4859
|
-
|
|
4860
|
-
|
|
4861
|
-
|
|
4862
|
-
|
|
4863
|
-
|
|
4864
|
-
|
|
4865
|
-
|
|
4871
|
+
const context = {
|
|
4872
|
+
request,
|
|
4873
|
+
signal: request.signal,
|
|
4874
|
+
invalidations: /* @__PURE__ */ new Set(),
|
|
4875
|
+
cacheTasks: /* @__PURE__ */ new Set()
|
|
4876
|
+
};
|
|
4877
|
+
return getServerActionStorage().run(context, async () => {
|
|
4878
|
+
try {
|
|
4879
|
+
const result = await callback();
|
|
4880
|
+
await Promise.all(context.cacheTasks);
|
|
4881
|
+
return result;
|
|
4882
|
+
} catch (error) {
|
|
4883
|
+
await Promise.allSettled(context.cacheTasks);
|
|
4884
|
+
throw error;
|
|
4885
|
+
}
|
|
4886
|
+
});
|
|
4866
4887
|
}
|
|
4867
4888
|
function getServerActionExecutionContext() {
|
|
4868
4889
|
return getServerActionStorage().getStore();
|
|
@@ -5173,6 +5194,9 @@ var init_server_action_security = __esm({
|
|
|
5173
5194
|
subscribeFarmCacheInvalidation((key) => {
|
|
5174
5195
|
getServerActionExecutionContext()?.invalidations.add(key);
|
|
5175
5196
|
});
|
|
5197
|
+
subscribeFarmCacheTask((task) => {
|
|
5198
|
+
getServerActionExecutionContext()?.cacheTasks.add(task);
|
|
5199
|
+
});
|
|
5176
5200
|
__name(getServerActionStorage, "getServerActionStorage");
|
|
5177
5201
|
__name(getFallbackAbortController, "getFallbackAbortController");
|
|
5178
5202
|
__name(parseBodySizeLimit, "parseBodySizeLimit");
|
|
@@ -6231,9 +6255,51 @@ function defineCacheKey() {
|
|
|
6231
6255
|
});
|
|
6232
6256
|
};
|
|
6233
6257
|
}
|
|
6258
|
+
function storageCacheAdapter(storage, options = {}) {
|
|
6259
|
+
if (!storage || typeof storage.getItem !== "function" || typeof storage.setItem !== "function") {
|
|
6260
|
+
throw new TypeError("storageCacheAdapter expects a compatible storage client.");
|
|
6261
|
+
}
|
|
6262
|
+
const base = normalizeCacheNamespace(options.base || "farm-cache");
|
|
6263
|
+
const entryKey = /* @__PURE__ */ __name((key) => `${base}:entry:${key}`, "entryKey");
|
|
6264
|
+
const tagKey = /* @__PURE__ */ __name((tag) => `${base}:tag:${tag}`, "tagKey");
|
|
6265
|
+
return {
|
|
6266
|
+
name: "storage",
|
|
6267
|
+
get: /* @__PURE__ */ __name((key) => storage.getItem(entryKey(key)), "get"),
|
|
6268
|
+
set: /* @__PURE__ */ __name(async (key, entry) => {
|
|
6269
|
+
await storage.setItem(entryKey(key), entry);
|
|
6270
|
+
}, "set"),
|
|
6271
|
+
delete: /* @__PURE__ */ __name(async (key) => {
|
|
6272
|
+
await storage.removeItem(entryKey(key));
|
|
6273
|
+
}, "delete"),
|
|
6274
|
+
clear: storage.clear ? async () => {
|
|
6275
|
+
await storage.clear(base);
|
|
6276
|
+
} : void 0,
|
|
6277
|
+
getTagVersions: /* @__PURE__ */ __name(async (tags) => {
|
|
6278
|
+
const versions = await Promise.all(
|
|
6279
|
+
tags.map(async (tag) => {
|
|
6280
|
+
const value = await storage.getItem(tagKey(tag));
|
|
6281
|
+
return [tag, normalizeAdapterVersion(value)];
|
|
6282
|
+
})
|
|
6283
|
+
);
|
|
6284
|
+
return Object.fromEntries(versions);
|
|
6285
|
+
}, "getTagVersions"),
|
|
6286
|
+
invalidateTags: /* @__PURE__ */ __name(async (tags) => {
|
|
6287
|
+
await Promise.all(
|
|
6288
|
+
tags.map(async (tag) => {
|
|
6289
|
+
const key = tagKey(tag);
|
|
6290
|
+
const current = normalizeAdapterVersion(await storage.getItem(key));
|
|
6291
|
+
await storage.setItem(key, Math.max(Date.now(), current + 1));
|
|
6292
|
+
})
|
|
6293
|
+
);
|
|
6294
|
+
}, "invalidateTags")
|
|
6295
|
+
};
|
|
6296
|
+
}
|
|
6234
6297
|
function getFarmDataCache() {
|
|
6235
6298
|
return sharedFarmDataCache;
|
|
6236
6299
|
}
|
|
6300
|
+
function configureFarmCache(config) {
|
|
6301
|
+
sharedFarmDataCache.configure(config);
|
|
6302
|
+
}
|
|
6237
6303
|
function unstable_cache(fn, keyParts = [], options = {}) {
|
|
6238
6304
|
return async (...args) => {
|
|
6239
6305
|
const locale = getActiveFarmI18nSnapshot()?.locale;
|
|
@@ -6248,24 +6314,64 @@ function unstable_cache(fn, keyParts = [], options = {}) {
|
|
|
6248
6314
|
};
|
|
6249
6315
|
}
|
|
6250
6316
|
function revalidateTag(_tag, _profile) {
|
|
6251
|
-
getFarmDataCache()
|
|
6317
|
+
const cache = getFarmDataCache();
|
|
6318
|
+
if (cache.hasAdapter) {
|
|
6319
|
+
const task = cache.revalidateTagAsync(_tag, {
|
|
6320
|
+
source: "revalidateTag",
|
|
6321
|
+
profile: _profile
|
|
6322
|
+
}).then(() => void 0);
|
|
6323
|
+
notifyFarmCacheTask(task);
|
|
6324
|
+
return task;
|
|
6325
|
+
}
|
|
6326
|
+
cache.revalidateTag(_tag, {
|
|
6252
6327
|
source: "revalidateTag",
|
|
6253
6328
|
profile: _profile
|
|
6254
6329
|
});
|
|
6255
6330
|
}
|
|
6256
6331
|
function updateTag(tag) {
|
|
6257
|
-
|
|
6332
|
+
const cache = getFarmDataCache();
|
|
6333
|
+
if (cache.hasAdapter) {
|
|
6334
|
+
const task = cache.revalidateTagAsync(tag, { source: "updateTag" }).then(() => void 0);
|
|
6335
|
+
notifyFarmCacheTask(task);
|
|
6336
|
+
return task;
|
|
6337
|
+
}
|
|
6338
|
+
cache.revalidateTag(tag, { source: "updateTag" });
|
|
6258
6339
|
}
|
|
6259
6340
|
function revalidatePath(routePath) {
|
|
6260
|
-
getFarmDataCache()
|
|
6341
|
+
const cache = getFarmDataCache();
|
|
6342
|
+
if (cache.hasAdapter) {
|
|
6343
|
+
const task = cache.revalidatePathAsync(routePath).then(() => void 0);
|
|
6344
|
+
notifyFarmCacheTask(task);
|
|
6345
|
+
return task;
|
|
6346
|
+
}
|
|
6347
|
+
cache.revalidatePath(routePath);
|
|
6261
6348
|
}
|
|
6262
6349
|
function invalidate(key) {
|
|
6263
6350
|
const clientKey = createRouteDataCacheKey(key);
|
|
6264
|
-
|
|
6351
|
+
const task = updateTag(createRouteDataCacheTag(key));
|
|
6265
6352
|
notifyFarmCacheInvalidation(clientKey);
|
|
6353
|
+
return task;
|
|
6266
6354
|
}
|
|
6267
6355
|
function invalidateRouteData(key) {
|
|
6268
|
-
invalidate(key);
|
|
6356
|
+
return invalidate(key);
|
|
6357
|
+
}
|
|
6358
|
+
async function applyFarmCacheInvalidationTargets(targets) {
|
|
6359
|
+
if (!Array.isArray(targets)) {
|
|
6360
|
+
throw new TypeError("Cache invalidations must resolve to an array of targets.");
|
|
6361
|
+
}
|
|
6362
|
+
const clientKeys = [];
|
|
6363
|
+
for (const target of targets) {
|
|
6364
|
+
assertFarmCacheInvalidationTarget(target);
|
|
6365
|
+
if ("key" in target) {
|
|
6366
|
+
await invalidate(target.key);
|
|
6367
|
+
clientKeys.push(createRouteDataCacheKey(target.key));
|
|
6368
|
+
} else if ("path" in target) {
|
|
6369
|
+
await revalidatePath(target.path);
|
|
6370
|
+
} else {
|
|
6371
|
+
await updateTag(target.tag);
|
|
6372
|
+
}
|
|
6373
|
+
}
|
|
6374
|
+
return Array.from(new Set(clientKeys));
|
|
6269
6375
|
}
|
|
6270
6376
|
function createPathCacheTag(routePath) {
|
|
6271
6377
|
return `path:${normalizeRevalidatePath(routePath)}`;
|
|
@@ -6320,6 +6426,60 @@ function normalizeCacheTag(tag) {
|
|
|
6320
6426
|
}
|
|
6321
6427
|
return normalized;
|
|
6322
6428
|
}
|
|
6429
|
+
function normalizeCacheNamespace(namespace) {
|
|
6430
|
+
if (typeof namespace !== "string") {
|
|
6431
|
+
throw new TypeError("Cache namespace must be a string.");
|
|
6432
|
+
}
|
|
6433
|
+
const normalized = namespace.trim().replace(/:+$/g, "");
|
|
6434
|
+
if (!normalized) {
|
|
6435
|
+
throw new Error("Cache namespace cannot be empty.");
|
|
6436
|
+
}
|
|
6437
|
+
return normalized;
|
|
6438
|
+
}
|
|
6439
|
+
function normalizeAdapterVersion(value) {
|
|
6440
|
+
return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : 0;
|
|
6441
|
+
}
|
|
6442
|
+
function normalizePositiveDuration(value, fallback, name) {
|
|
6443
|
+
if (value === void 0) return fallback;
|
|
6444
|
+
if (!Number.isFinite(value) || value <= 0) {
|
|
6445
|
+
throw new TypeError(`${name} must be a positive number of milliseconds.`);
|
|
6446
|
+
}
|
|
6447
|
+
return Math.floor(value);
|
|
6448
|
+
}
|
|
6449
|
+
function delay(ms) {
|
|
6450
|
+
return new Promise((resolve5) => setTimeout(resolve5, ms));
|
|
6451
|
+
}
|
|
6452
|
+
function normalizeCacheOptionsTags(options) {
|
|
6453
|
+
const tags = /* @__PURE__ */ new Set();
|
|
6454
|
+
for (const tag of options.tags ?? []) {
|
|
6455
|
+
tags.add(normalizeCacheTag(tag));
|
|
6456
|
+
}
|
|
6457
|
+
for (const routePath of options.paths ?? []) {
|
|
6458
|
+
tags.add(createPathCacheTag(routePath));
|
|
6459
|
+
}
|
|
6460
|
+
return tags;
|
|
6461
|
+
}
|
|
6462
|
+
function assertFarmCacheEntry(entry, expectedKey) {
|
|
6463
|
+
if (!entry || typeof entry !== "object" || entry.key !== expectedKey || !Array.isArray(entry.tags) || typeof entry.createdAt !== "number") {
|
|
6464
|
+
throw new TypeError(
|
|
6465
|
+
`Cache adapter returned an invalid entry for ${JSON.stringify(expectedKey)}.`
|
|
6466
|
+
);
|
|
6467
|
+
}
|
|
6468
|
+
}
|
|
6469
|
+
function assertFarmCacheInvalidationTarget(target) {
|
|
6470
|
+
if (!target || typeof target !== "object") {
|
|
6471
|
+
throw new TypeError("Cache invalidation targets must be { key }, { path }, or { tag }.");
|
|
6472
|
+
}
|
|
6473
|
+
if ("key" in target) {
|
|
6474
|
+
const key = target.key;
|
|
6475
|
+
if (typeof key === "string" || Array.isArray(key)) return;
|
|
6476
|
+
} else if ("path" in target && typeof target.path === "string") {
|
|
6477
|
+
return;
|
|
6478
|
+
} else if ("tag" in target && typeof target.tag === "string") {
|
|
6479
|
+
return;
|
|
6480
|
+
}
|
|
6481
|
+
throw new TypeError("Cache invalidation targets must contain a string/array key, path, or tag.");
|
|
6482
|
+
}
|
|
6323
6483
|
function getFunctionCacheIdentity(fn) {
|
|
6324
6484
|
if (fn.name) {
|
|
6325
6485
|
return `name:${fn.name}`;
|
|
@@ -6380,12 +6540,53 @@ var init_cache = __esm({
|
|
|
6380
6540
|
init_bridge();
|
|
6381
6541
|
init_cache_invalidation();
|
|
6382
6542
|
__name(defineCacheKey, "defineCacheKey");
|
|
6543
|
+
__name(storageCacheAdapter, "storageCacheAdapter");
|
|
6383
6544
|
_FarmDataCache = class _FarmDataCache {
|
|
6384
|
-
constructor() {
|
|
6545
|
+
constructor(config = {}) {
|
|
6385
6546
|
this.entries = /* @__PURE__ */ new Map();
|
|
6386
6547
|
this.inflight = /* @__PURE__ */ new Map();
|
|
6387
6548
|
this.invalidatedTagVersions = /* @__PURE__ */ new Map();
|
|
6388
6549
|
this.version = 0;
|
|
6550
|
+
this.namespace = "farm";
|
|
6551
|
+
this.local = true;
|
|
6552
|
+
this.lease = {
|
|
6553
|
+
enabled: true,
|
|
6554
|
+
ttlMs: 1e4,
|
|
6555
|
+
waitTimeoutMs: 1e4,
|
|
6556
|
+
pollIntervalMs: 25
|
|
6557
|
+
};
|
|
6558
|
+
this.configure(config);
|
|
6559
|
+
}
|
|
6560
|
+
configure(config = {}) {
|
|
6561
|
+
this.adapter = config.adapter;
|
|
6562
|
+
this.namespace = normalizeCacheNamespace(config.namespace || "farm");
|
|
6563
|
+
this.local = !config.adapter;
|
|
6564
|
+
this.lease = config.lease === false ? { ...this.lease, enabled: false } : {
|
|
6565
|
+
enabled: true,
|
|
6566
|
+
ttlMs: normalizePositiveDuration(config.lease?.ttlMs, 1e4, "cache.lease.ttlMs"),
|
|
6567
|
+
waitTimeoutMs: normalizePositiveDuration(
|
|
6568
|
+
config.lease?.waitTimeoutMs,
|
|
6569
|
+
1e4,
|
|
6570
|
+
"cache.lease.waitTimeoutMs"
|
|
6571
|
+
),
|
|
6572
|
+
pollIntervalMs: normalizePositiveDuration(
|
|
6573
|
+
config.lease?.pollIntervalMs,
|
|
6574
|
+
25,
|
|
6575
|
+
"cache.lease.pollIntervalMs"
|
|
6576
|
+
)
|
|
6577
|
+
};
|
|
6578
|
+
if (!this.local) {
|
|
6579
|
+
this.entries.clear();
|
|
6580
|
+
this.inflight.clear();
|
|
6581
|
+
this.invalidatedTagVersions.clear();
|
|
6582
|
+
this.version = 0;
|
|
6583
|
+
}
|
|
6584
|
+
}
|
|
6585
|
+
get adapterName() {
|
|
6586
|
+
return this.adapter?.name || (this.adapter ? "custom" : "memory");
|
|
6587
|
+
}
|
|
6588
|
+
get hasAdapter() {
|
|
6589
|
+
return this.adapter !== void 0;
|
|
6389
6590
|
}
|
|
6390
6591
|
get size() {
|
|
6391
6592
|
return this.entries.size;
|
|
@@ -6421,6 +6622,45 @@ var init_cache = __esm({
|
|
|
6421
6622
|
});
|
|
6422
6623
|
return this.toPublicEntry(entry);
|
|
6423
6624
|
}
|
|
6625
|
+
async getEntryAsync(key, options = {}) {
|
|
6626
|
+
if (this.local) {
|
|
6627
|
+
const localEntry = this.getEntry(key, options);
|
|
6628
|
+
if (localEntry) return localEntry;
|
|
6629
|
+
}
|
|
6630
|
+
if (!this.adapter) {
|
|
6631
|
+
return this.local ? void 0 : this.getEntry(key, options);
|
|
6632
|
+
}
|
|
6633
|
+
const entry = await this.adapter.get(this.createAdapterKey(key));
|
|
6634
|
+
if (!entry) {
|
|
6635
|
+
emitFarmEvent({ type: "cache.miss", key });
|
|
6636
|
+
return void 0;
|
|
6637
|
+
}
|
|
6638
|
+
assertFarmCacheEntry(entry, key);
|
|
6639
|
+
const stale = await this.isAdapterEntryStale(entry, options.now);
|
|
6640
|
+
if (stale) {
|
|
6641
|
+
emitFarmEvent({
|
|
6642
|
+
type: "cache.stale",
|
|
6643
|
+
key,
|
|
6644
|
+
tags: [...entry.tags],
|
|
6645
|
+
revalidate: entry.revalidate
|
|
6646
|
+
});
|
|
6647
|
+
if (!options.allowStale) {
|
|
6648
|
+
emitFarmEvent({ type: "cache.miss", key, reason: "stale" });
|
|
6649
|
+
return void 0;
|
|
6650
|
+
}
|
|
6651
|
+
}
|
|
6652
|
+
emitFarmEvent({
|
|
6653
|
+
type: "cache.hit",
|
|
6654
|
+
key,
|
|
6655
|
+
tags: [...entry.tags],
|
|
6656
|
+
revalidate: entry.revalidate,
|
|
6657
|
+
stale
|
|
6658
|
+
});
|
|
6659
|
+
if (this.local && !stale) {
|
|
6660
|
+
this.hydrateLocalEntry(entry);
|
|
6661
|
+
}
|
|
6662
|
+
return { ...entry, key };
|
|
6663
|
+
}
|
|
6424
6664
|
set(key, value, options = {}) {
|
|
6425
6665
|
const tags = /* @__PURE__ */ new Set();
|
|
6426
6666
|
for (const tag of options.tags ?? []) {
|
|
@@ -6433,6 +6673,7 @@ var init_cache = __esm({
|
|
|
6433
6673
|
key,
|
|
6434
6674
|
value,
|
|
6435
6675
|
tags,
|
|
6676
|
+
tagVersions: void 0,
|
|
6436
6677
|
createdAt: options.createdAt ?? Date.now(),
|
|
6437
6678
|
createdVersion: ++this.version,
|
|
6438
6679
|
revalidate: normalizeRevalidate(options.revalidate)
|
|
@@ -6446,11 +6687,45 @@ var init_cache = __esm({
|
|
|
6446
6687
|
});
|
|
6447
6688
|
return this.toPublicEntry(entry);
|
|
6448
6689
|
}
|
|
6690
|
+
async setAsync(key, value, options = {}, tagVersions) {
|
|
6691
|
+
const tags = normalizeCacheOptionsTags(options);
|
|
6692
|
+
const capturedVersions = tagVersions ?? await this.getAdapterTagVersions(Array.from(tags.values()));
|
|
6693
|
+
const entry = {
|
|
6694
|
+
key,
|
|
6695
|
+
value,
|
|
6696
|
+
tags: Array.from(tags),
|
|
6697
|
+
tagVersions: capturedVersions,
|
|
6698
|
+
createdAt: options.createdAt ?? Date.now(),
|
|
6699
|
+
createdVersion: ++this.version,
|
|
6700
|
+
revalidate: normalizeRevalidate(options.revalidate)
|
|
6701
|
+
};
|
|
6702
|
+
if (this.local) {
|
|
6703
|
+
this.hydrateLocalEntry(entry);
|
|
6704
|
+
}
|
|
6705
|
+
if (this.adapter) {
|
|
6706
|
+
await this.adapter.set(this.createAdapterKey(key), entry);
|
|
6707
|
+
}
|
|
6708
|
+
emitFarmEvent({
|
|
6709
|
+
type: "cache.set",
|
|
6710
|
+
key,
|
|
6711
|
+
tags: [...entry.tags],
|
|
6712
|
+
revalidate: entry.revalidate
|
|
6713
|
+
});
|
|
6714
|
+
return entry;
|
|
6715
|
+
}
|
|
6449
6716
|
delete(key) {
|
|
6450
6717
|
const deleted = this.entries.delete(key);
|
|
6451
6718
|
emitFarmEvent({ type: "cache.delete", key, deleted });
|
|
6452
6719
|
return deleted;
|
|
6453
6720
|
}
|
|
6721
|
+
async deleteAsync(key) {
|
|
6722
|
+
const deleted = this.entries.delete(key);
|
|
6723
|
+
if (this.adapter) {
|
|
6724
|
+
await this.adapter.delete(this.createAdapterKey(key));
|
|
6725
|
+
}
|
|
6726
|
+
emitFarmEvent({ type: "cache.delete", key, deleted: this.adapter ? true : deleted });
|
|
6727
|
+
return this.adapter ? true : deleted;
|
|
6728
|
+
}
|
|
6454
6729
|
clear() {
|
|
6455
6730
|
const count = this.entries.size;
|
|
6456
6731
|
this.entries.clear();
|
|
@@ -6459,6 +6734,10 @@ var init_cache = __esm({
|
|
|
6459
6734
|
this.version = 0;
|
|
6460
6735
|
emitFarmEvent({ type: "cache.clear", count });
|
|
6461
6736
|
}
|
|
6737
|
+
async clearAsync() {
|
|
6738
|
+
this.clear();
|
|
6739
|
+
await this.adapter?.clear?.();
|
|
6740
|
+
}
|
|
6462
6741
|
isStale(entry, now2 = Date.now()) {
|
|
6463
6742
|
if (typeof entry.revalidate === "number" && entry.revalidate > 0 && now2 - entry.createdAt >= entry.revalidate * 1e3) {
|
|
6464
6743
|
return true;
|
|
@@ -6471,6 +6750,12 @@ var init_cache = __esm({
|
|
|
6471
6750
|
}
|
|
6472
6751
|
return false;
|
|
6473
6752
|
}
|
|
6753
|
+
async isStaleAsync(entry, now2 = Date.now()) {
|
|
6754
|
+
if (this.adapter) {
|
|
6755
|
+
return this.isAdapterEntryStale(entry, now2);
|
|
6756
|
+
}
|
|
6757
|
+
return this.isStale(entry, now2);
|
|
6758
|
+
}
|
|
6474
6759
|
revalidateTag(tag, options = {}) {
|
|
6475
6760
|
const normalized = normalizeCacheTag(tag);
|
|
6476
6761
|
const count = this.invalidateTag(normalized);
|
|
@@ -6479,6 +6764,15 @@ var init_cache = __esm({
|
|
|
6479
6764
|
);
|
|
6480
6765
|
return count;
|
|
6481
6766
|
}
|
|
6767
|
+
async revalidateTagAsync(tag, options = {}) {
|
|
6768
|
+
const normalized = normalizeCacheTag(tag);
|
|
6769
|
+
const count = this.invalidateTag(normalized);
|
|
6770
|
+
await this.adapter?.invalidateTags?.([this.createAdapterTag(normalized)]);
|
|
6771
|
+
emitFarmEvent(
|
|
6772
|
+
options.source === "updateTag" ? { type: "cache.updateTag", tag: normalized, count } : { type: "cache.revalidateTag", tag: normalized, profile: options.profile, count }
|
|
6773
|
+
);
|
|
6774
|
+
return count;
|
|
6775
|
+
}
|
|
6482
6776
|
revalidatePath(routePath) {
|
|
6483
6777
|
const normalizedPath = normalizeRevalidatePath(routePath);
|
|
6484
6778
|
const pathTag = createPathCacheTag(normalizedPath);
|
|
@@ -6495,8 +6789,25 @@ var init_cache = __esm({
|
|
|
6495
6789
|
}
|
|
6496
6790
|
return count;
|
|
6497
6791
|
}
|
|
6792
|
+
async revalidatePathAsync(routePath) {
|
|
6793
|
+
const normalizedPath = normalizeRevalidatePath(routePath);
|
|
6794
|
+
const pathTag = createPathCacheTag(normalizedPath);
|
|
6795
|
+
const pprCount = this.countEntriesForTags([pathTag, "ppr"]);
|
|
6796
|
+
const count = this.invalidateTag(pathTag);
|
|
6797
|
+
await this.adapter?.invalidateTags?.([this.createAdapterTag(pathTag)]);
|
|
6798
|
+
emitFarmEvent({ type: "cache.revalidatePath", path: normalizedPath, count });
|
|
6799
|
+
if (pprCount > 0) {
|
|
6800
|
+
emitFarmEvent({
|
|
6801
|
+
type: "ppr.shell.invalidated",
|
|
6802
|
+
route: normalizedPath,
|
|
6803
|
+
reason: "revalidatePath",
|
|
6804
|
+
count: pprCount
|
|
6805
|
+
});
|
|
6806
|
+
}
|
|
6807
|
+
return count;
|
|
6808
|
+
}
|
|
6498
6809
|
async getOrSet(key, producer, options = {}) {
|
|
6499
|
-
const cached = this.
|
|
6810
|
+
const cached = await this.getEntryAsync(key);
|
|
6500
6811
|
if (cached) {
|
|
6501
6812
|
return cached.value;
|
|
6502
6813
|
}
|
|
@@ -6505,10 +6816,8 @@ var init_cache = __esm({
|
|
|
6505
6816
|
emitFarmEvent({ type: "cache.dedupe", key });
|
|
6506
6817
|
return inflight;
|
|
6507
6818
|
}
|
|
6508
|
-
const
|
|
6509
|
-
|
|
6510
|
-
return value;
|
|
6511
|
-
}).catch((error) => {
|
|
6819
|
+
const tags = Array.from(normalizeCacheOptionsTags(options));
|
|
6820
|
+
const promise = this.fillCacheEntry(key, producer, options, tags).catch((error) => {
|
|
6512
6821
|
emitFarmEvent({ type: "cache.error", key, operation: "set", error });
|
|
6513
6822
|
throw error;
|
|
6514
6823
|
}).finally(() => {
|
|
@@ -6517,6 +6826,40 @@ var init_cache = __esm({
|
|
|
6517
6826
|
this.inflight.set(key, promise);
|
|
6518
6827
|
return promise;
|
|
6519
6828
|
}
|
|
6829
|
+
async fillCacheEntry(key, producer, options, tags) {
|
|
6830
|
+
const leaseKey = `${this.namespace}:lease:${key}`;
|
|
6831
|
+
let leaseToken;
|
|
6832
|
+
if (this.adapter?.acquireLease && this.adapter.releaseLease && this.lease.enabled) {
|
|
6833
|
+
leaseToken = await this.adapter.acquireLease(leaseKey, this.lease.ttlMs);
|
|
6834
|
+
if (!leaseToken) {
|
|
6835
|
+
const shared = await this.waitForAdapterEntry(key);
|
|
6836
|
+
if (shared) {
|
|
6837
|
+
emitFarmEvent({ type: "cache.dedupe", key });
|
|
6838
|
+
return shared.value;
|
|
6839
|
+
}
|
|
6840
|
+
leaseToken = await this.adapter.acquireLease(leaseKey, this.lease.ttlMs);
|
|
6841
|
+
}
|
|
6842
|
+
}
|
|
6843
|
+
try {
|
|
6844
|
+
const initialTagVersions = await this.getAdapterTagVersions(tags);
|
|
6845
|
+
const value = await producer();
|
|
6846
|
+
await this.setAsync(key, value, options, initialTagVersions);
|
|
6847
|
+
return value;
|
|
6848
|
+
} finally {
|
|
6849
|
+
if (leaseToken && this.adapter?.releaseLease) {
|
|
6850
|
+
await this.adapter.releaseLease(leaseKey, leaseToken);
|
|
6851
|
+
}
|
|
6852
|
+
}
|
|
6853
|
+
}
|
|
6854
|
+
async waitForAdapterEntry(key) {
|
|
6855
|
+
const deadline = Date.now() + this.lease.waitTimeoutMs;
|
|
6856
|
+
while (Date.now() < deadline) {
|
|
6857
|
+
await delay(this.lease.pollIntervalMs);
|
|
6858
|
+
const entry = await this.getEntryAsync(key);
|
|
6859
|
+
if (entry) return entry;
|
|
6860
|
+
}
|
|
6861
|
+
return void 0;
|
|
6862
|
+
}
|
|
6520
6863
|
countEntriesForTag(tag) {
|
|
6521
6864
|
let count = 0;
|
|
6522
6865
|
for (const entry of this.entries.values()) {
|
|
@@ -6544,11 +6887,53 @@ var init_cache = __esm({
|
|
|
6544
6887
|
key: entry.key,
|
|
6545
6888
|
value: entry.value,
|
|
6546
6889
|
tags: Array.from(entry.tags),
|
|
6890
|
+
tagVersions: entry.tagVersions,
|
|
6547
6891
|
createdAt: entry.createdAt,
|
|
6548
6892
|
createdVersion: entry.createdVersion,
|
|
6549
6893
|
revalidate: entry.revalidate
|
|
6550
6894
|
};
|
|
6551
6895
|
}
|
|
6896
|
+
hydrateLocalEntry(entry) {
|
|
6897
|
+
this.entries.set(entry.key, {
|
|
6898
|
+
key: entry.key,
|
|
6899
|
+
value: entry.value,
|
|
6900
|
+
tags: new Set(entry.tags.map(normalizeCacheTag)),
|
|
6901
|
+
tagVersions: entry.tagVersions,
|
|
6902
|
+
createdAt: entry.createdAt,
|
|
6903
|
+
createdVersion: entry.createdVersion ?? ++this.version,
|
|
6904
|
+
revalidate: normalizeRevalidate(entry.revalidate)
|
|
6905
|
+
});
|
|
6906
|
+
}
|
|
6907
|
+
createAdapterKey(key) {
|
|
6908
|
+
return `${this.namespace}:entry:${key}`;
|
|
6909
|
+
}
|
|
6910
|
+
createAdapterTag(tag) {
|
|
6911
|
+
return `${this.namespace}:tag:${tag}`;
|
|
6912
|
+
}
|
|
6913
|
+
async getAdapterTagVersions(tags) {
|
|
6914
|
+
if (!this.adapter?.getTagVersions || tags.length === 0) return {};
|
|
6915
|
+
const normalized = tags.map(normalizeCacheTag);
|
|
6916
|
+
const physicalTags = normalized.map((tag) => this.createAdapterTag(tag));
|
|
6917
|
+
const versions = await this.adapter.getTagVersions(physicalTags);
|
|
6918
|
+
return Object.fromEntries(
|
|
6919
|
+
normalized.map((tag, index) => [
|
|
6920
|
+
tag,
|
|
6921
|
+
normalizeAdapterVersion(versions[physicalTags[index]])
|
|
6922
|
+
])
|
|
6923
|
+
);
|
|
6924
|
+
}
|
|
6925
|
+
async isAdapterEntryStale(entry, now2 = Date.now()) {
|
|
6926
|
+
if (typeof entry.revalidate === "number" && entry.revalidate > 0 && now2 - entry.createdAt >= entry.revalidate * 1e3) {
|
|
6927
|
+
return true;
|
|
6928
|
+
}
|
|
6929
|
+
const currentVersions = await this.getAdapterTagVersions(entry.tags);
|
|
6930
|
+
for (const tag of entry.tags) {
|
|
6931
|
+
if (normalizeAdapterVersion(currentVersions[tag]) > normalizeAdapterVersion(entry.tagVersions?.[tag])) {
|
|
6932
|
+
return true;
|
|
6933
|
+
}
|
|
6934
|
+
}
|
|
6935
|
+
return false;
|
|
6936
|
+
}
|
|
6552
6937
|
};
|
|
6553
6938
|
__name(_FarmDataCache, "FarmDataCache");
|
|
6554
6939
|
FarmDataCache = _FarmDataCache;
|
|
@@ -6558,12 +6943,14 @@ var init_cache = __esm({
|
|
|
6558
6943
|
functionIds = /* @__PURE__ */ new WeakMap();
|
|
6559
6944
|
nextFunctionId = 0;
|
|
6560
6945
|
__name(getFarmDataCache, "getFarmDataCache");
|
|
6946
|
+
__name(configureFarmCache, "configureFarmCache");
|
|
6561
6947
|
__name(unstable_cache, "unstable_cache");
|
|
6562
6948
|
__name(revalidateTag, "revalidateTag");
|
|
6563
6949
|
__name(updateTag, "updateTag");
|
|
6564
6950
|
__name(revalidatePath, "revalidatePath");
|
|
6565
6951
|
__name(invalidate, "invalidate");
|
|
6566
6952
|
__name(invalidateRouteData, "invalidateRouteData");
|
|
6953
|
+
__name(applyFarmCacheInvalidationTargets, "applyFarmCacheInvalidationTargets");
|
|
6567
6954
|
__name(createPathCacheTag, "createPathCacheTag");
|
|
6568
6955
|
__name(createRouteDataCacheTag, "createRouteDataCacheTag");
|
|
6569
6956
|
__name(createRouteDataCacheKey, "createRouteDataCacheKey");
|
|
@@ -6571,6 +6958,13 @@ var init_cache = __esm({
|
|
|
6571
6958
|
__name(createFarmCacheKey, "createFarmCacheKey");
|
|
6572
6959
|
__name(normalizeRevalidate, "normalizeRevalidate");
|
|
6573
6960
|
__name(normalizeCacheTag, "normalizeCacheTag");
|
|
6961
|
+
__name(normalizeCacheNamespace, "normalizeCacheNamespace");
|
|
6962
|
+
__name(normalizeAdapterVersion, "normalizeAdapterVersion");
|
|
6963
|
+
__name(normalizePositiveDuration, "normalizePositiveDuration");
|
|
6964
|
+
__name(delay, "delay");
|
|
6965
|
+
__name(normalizeCacheOptionsTags, "normalizeCacheOptionsTags");
|
|
6966
|
+
__name(assertFarmCacheEntry, "assertFarmCacheEntry");
|
|
6967
|
+
__name(assertFarmCacheInvalidationTarget, "assertFarmCacheInvalidationTarget");
|
|
6574
6968
|
__name(getFunctionCacheIdentity, "getFunctionCacheIdentity");
|
|
6575
6969
|
__name(stableSerialize, "stableSerialize");
|
|
6576
6970
|
}
|
|
@@ -7696,6 +8090,83 @@ var init_routing = __esm({
|
|
|
7696
8090
|
}
|
|
7697
8091
|
});
|
|
7698
8092
|
|
|
8093
|
+
// src/routing/route-slots.ts
|
|
8094
|
+
function parseRouteSlotFile(filePath) {
|
|
8095
|
+
const normalized = filePath.replace(/\\/g, "/");
|
|
8096
|
+
const parts = normalized.split("/").filter(Boolean);
|
|
8097
|
+
const fileName = parts.at(-1) ?? "";
|
|
8098
|
+
const baseName = fileName.replace(/\.(tsx?|jsx?)$/, "");
|
|
8099
|
+
if (baseName !== "page" && baseName !== "default") return null;
|
|
8100
|
+
const slotIndex = parts.findIndex((part) => SLOT_SEGMENT.test(part));
|
|
8101
|
+
if (slotIndex < 0) return null;
|
|
8102
|
+
if (parts.slice(slotIndex + 1, -1).some((part) => SLOT_SEGMENT.test(part))) {
|
|
8103
|
+
throw new Error(`Nested route slots are not supported in "${filePath}"`);
|
|
8104
|
+
}
|
|
8105
|
+
const slotMatch = parts[slotIndex].match(SLOT_SEGMENT);
|
|
8106
|
+
const name = slotMatch?.[1];
|
|
8107
|
+
if (!name) return null;
|
|
8108
|
+
const ownerParts = parts.slice(0, slotIndex);
|
|
8109
|
+
const contentParts = parts.slice(slotIndex + 1, -1);
|
|
8110
|
+
const marker = parseInterceptionMarker(contentParts[0]);
|
|
8111
|
+
let targetBase = ownerParts;
|
|
8112
|
+
let targetParts = contentParts;
|
|
8113
|
+
if (marker) {
|
|
8114
|
+
targetBase = marker.root === true ? [] : ownerParts.slice(0, Math.max(0, ownerParts.length - marker.up));
|
|
8115
|
+
targetParts = [...marker.remainder ? [marker.remainder] : [], ...contentParts.slice(1)];
|
|
8116
|
+
}
|
|
8117
|
+
const ownerFile = [...ownerParts, "layout.tsx"].join("/");
|
|
8118
|
+
const routeFile = [
|
|
8119
|
+
...baseName === "default" ? ownerParts : targetBase,
|
|
8120
|
+
...baseName === "default" ? [] : targetParts,
|
|
8121
|
+
"page.tsx"
|
|
8122
|
+
].join("/");
|
|
8123
|
+
return {
|
|
8124
|
+
name,
|
|
8125
|
+
ownerRoute: parseRoutePath(ownerFile || "layout.tsx"),
|
|
8126
|
+
route: parseRoutePath(routeFile || "page.tsx"),
|
|
8127
|
+
interception: marker !== null,
|
|
8128
|
+
fallback: baseName === "default"
|
|
8129
|
+
};
|
|
8130
|
+
}
|
|
8131
|
+
function createRouteSlotContainerId(name, ownerPattern) {
|
|
8132
|
+
const owner = ownerPattern === "/" ? "root" : ownerPattern.replace(/^\//, "").replace(/[^A-Za-z0-9_-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
8133
|
+
return `__farm_slot_${name}_${owner || "root"}__`;
|
|
8134
|
+
}
|
|
8135
|
+
function parseInterceptionMarker(segment) {
|
|
8136
|
+
if (!segment) return null;
|
|
8137
|
+
if (segment.startsWith("(...)")) {
|
|
8138
|
+
return {
|
|
8139
|
+
up: 0,
|
|
8140
|
+
root: true,
|
|
8141
|
+
remainder: segment.slice(5)
|
|
8142
|
+
};
|
|
8143
|
+
}
|
|
8144
|
+
if (segment.startsWith("(.)")) {
|
|
8145
|
+
return {
|
|
8146
|
+
up: 0,
|
|
8147
|
+
remainder: segment.slice(3)
|
|
8148
|
+
};
|
|
8149
|
+
}
|
|
8150
|
+
let remainder = segment;
|
|
8151
|
+
let up = 0;
|
|
8152
|
+
while (remainder.startsWith("(..)")) {
|
|
8153
|
+
up += 1;
|
|
8154
|
+
remainder = remainder.slice(4);
|
|
8155
|
+
}
|
|
8156
|
+
return up > 0 ? { up, remainder } : null;
|
|
8157
|
+
}
|
|
8158
|
+
var SLOT_SEGMENT;
|
|
8159
|
+
var init_route_slots = __esm({
|
|
8160
|
+
"src/routing/route-slots.ts"() {
|
|
8161
|
+
"use strict";
|
|
8162
|
+
init_utils();
|
|
8163
|
+
SLOT_SEGMENT = /^@([A-Za-z][A-Za-z0-9_-]*)$/;
|
|
8164
|
+
__name(parseRouteSlotFile, "parseRouteSlotFile");
|
|
8165
|
+
__name(createRouteSlotContainerId, "createRouteSlotContainerId");
|
|
8166
|
+
__name(parseInterceptionMarker, "parseInterceptionMarker");
|
|
8167
|
+
}
|
|
8168
|
+
});
|
|
8169
|
+
|
|
7699
8170
|
// src/routing/route-manager.ts
|
|
7700
8171
|
function routeSpecificity(entry) {
|
|
7701
8172
|
return entry.route.segments.reduce((score, segment) => {
|
|
@@ -7767,11 +8238,13 @@ var init_route_manager = __esm({
|
|
|
7767
8238
|
init_static_metadata_image();
|
|
7768
8239
|
init_route_runtime();
|
|
7769
8240
|
init_routing();
|
|
8241
|
+
init_route_slots();
|
|
7770
8242
|
__name(routeSpecificity, "routeSpecificity");
|
|
7771
8243
|
_RouteManager = class _RouteManager {
|
|
7772
8244
|
constructor(config, viteServer) {
|
|
7773
8245
|
this.routes = /* @__PURE__ */ new Map();
|
|
7774
8246
|
this.layouts = /* @__PURE__ */ new Map();
|
|
8247
|
+
this.routeSlots = /* @__PURE__ */ new Map();
|
|
7775
8248
|
this.loadings = /* @__PURE__ */ new Map();
|
|
7776
8249
|
this.errors = /* @__PURE__ */ new Map();
|
|
7777
8250
|
this.metadataImages = /* @__PURE__ */ new Map();
|
|
@@ -7787,6 +8260,7 @@ var init_route_manager = __esm({
|
|
|
7787
8260
|
async discoverRoutes() {
|
|
7788
8261
|
this.routes.clear();
|
|
7789
8262
|
this.layouts.clear();
|
|
8263
|
+
this.routeSlots.clear();
|
|
7790
8264
|
this.loadings.clear();
|
|
7791
8265
|
this.errors.clear();
|
|
7792
8266
|
this.metadataImages.clear();
|
|
@@ -7797,6 +8271,13 @@ var init_route_manager = __esm({
|
|
|
7797
8271
|
await this.discoverFileRoutes(source);
|
|
7798
8272
|
await this.discoverProgrammaticRoutes(source);
|
|
7799
8273
|
}
|
|
8274
|
+
for (const slot of this.routeSlots.values()) {
|
|
8275
|
+
if (slot.interception && !this.routes.has(slot.pattern)) {
|
|
8276
|
+
throw new Error(
|
|
8277
|
+
`Intercepting route slot "${slot.name}" targets "${slot.pattern}", but no canonical page exists for that URL`
|
|
8278
|
+
);
|
|
8279
|
+
}
|
|
8280
|
+
}
|
|
7800
8281
|
this.routes = new Map(
|
|
7801
8282
|
Array.from(this.routes.entries()).sort(
|
|
7802
8283
|
([, left], [, right]) => routeSpecificity(right) - routeSpecificity(left)
|
|
@@ -7812,7 +8293,7 @@ var init_route_manager = __esm({
|
|
|
7812
8293
|
/**
|
|
7813
8294
|
* Find matching route for a given URL path
|
|
7814
8295
|
*/
|
|
7815
|
-
matchRoute(pathname) {
|
|
8296
|
+
matchRoute(pathname, options = {}) {
|
|
7816
8297
|
const routePathname = this.toRoutePathname(pathname);
|
|
7817
8298
|
const normalizedPath = routePathname === "/" ? "/" : routePathname.replace(/\/$/, "");
|
|
7818
8299
|
let matchedRoute = null;
|
|
@@ -7826,10 +8307,12 @@ var init_route_manager = __esm({
|
|
|
7826
8307
|
}
|
|
7827
8308
|
}
|
|
7828
8309
|
const layouts = this.findMatchingLayouts(normalizedPath);
|
|
8310
|
+
const slots = this.findMatchingRouteSlots(normalizedPath, options.interceptFrom);
|
|
7829
8311
|
return {
|
|
7830
8312
|
route: matchedRoute,
|
|
7831
8313
|
params,
|
|
7832
|
-
layouts
|
|
8314
|
+
layouts,
|
|
8315
|
+
slots
|
|
7833
8316
|
};
|
|
7834
8317
|
}
|
|
7835
8318
|
/**
|
|
@@ -7844,6 +8327,9 @@ var init_route_manager = __esm({
|
|
|
7844
8327
|
getLayouts() {
|
|
7845
8328
|
return new Map(this.layouts);
|
|
7846
8329
|
}
|
|
8330
|
+
getRouteSlots() {
|
|
8331
|
+
return new Map(this.routeSlots);
|
|
8332
|
+
}
|
|
7847
8333
|
/** Resolve route rules, inherited layouts, and the page export in precedence order. */
|
|
7848
8334
|
async resolveRouteRuntimeConfig(pattern) {
|
|
7849
8335
|
const routeEntry = this.routes.get(pattern);
|
|
@@ -8002,7 +8488,22 @@ var init_route_manager = __esm({
|
|
|
8002
8488
|
pattern: entry.pattern,
|
|
8003
8489
|
modulePath: toUrlPath(entry.modulePath)
|
|
8004
8490
|
}));
|
|
8005
|
-
|
|
8491
|
+
const slots = Array.from(this.routeSlots.values()).map((entry) => {
|
|
8492
|
+
const metadata = getClientModuleMetadata(entry.modulePath, projectRoot);
|
|
8493
|
+
return {
|
|
8494
|
+
name: entry.name,
|
|
8495
|
+
ownerPattern: entry.ownerPattern,
|
|
8496
|
+
pattern: entry.pattern,
|
|
8497
|
+
modulePath: toUrlPath(entry.modulePath),
|
|
8498
|
+
containerId: entry.containerId,
|
|
8499
|
+
interception: entry.interception,
|
|
8500
|
+
fallback: entry.fallback,
|
|
8501
|
+
shouldHydrate: metadata.shouldHydrate,
|
|
8502
|
+
isClientComponent: metadata.isClientComponent,
|
|
8503
|
+
segments: entry.route.segments
|
|
8504
|
+
};
|
|
8505
|
+
});
|
|
8506
|
+
return { routes, layouts, slots };
|
|
8006
8507
|
}
|
|
8007
8508
|
/**
|
|
8008
8509
|
* Load a route module dynamically
|
|
@@ -8079,6 +8580,7 @@ var init_route_manager = __esm({
|
|
|
8079
8580
|
async discoverFileRoutes(source) {
|
|
8080
8581
|
const appDir = resolveAppPath(source.root, source.srcDir, "app");
|
|
8081
8582
|
const pageFiles = await safeGlobFiles("**/page.{ts,tsx,js,jsx,md,mdx}", appDir);
|
|
8583
|
+
const slotDefaultFiles = await safeGlobFiles("**/@*/**/default.{ts,tsx,js,jsx}", appDir);
|
|
8082
8584
|
const layoutFiles = await safeGlobFiles("**/layout.{ts,tsx,js,jsx}", appDir);
|
|
8083
8585
|
const loadingFiles = await safeGlobFiles("**/loading.{ts,tsx,js,jsx}", appDir);
|
|
8084
8586
|
const errorFiles = await safeGlobFiles("**/error.{ts,tsx,js,jsx}", appDir);
|
|
@@ -8087,7 +8589,7 @@ var init_route_manager = __esm({
|
|
|
8087
8589
|
appDir
|
|
8088
8590
|
);
|
|
8089
8591
|
for (const [kind, files, target] of [
|
|
8090
|
-
["page", pageFiles, this.routes],
|
|
8592
|
+
["page", pageFiles.filter((file) => parseRouteSlotFile(file) === null), this.routes],
|
|
8091
8593
|
["layout", layoutFiles, this.layouts],
|
|
8092
8594
|
["loading", loadingFiles, this.loadings],
|
|
8093
8595
|
["error", errorFiles, this.errors]
|
|
@@ -8111,6 +8613,32 @@ var init_route_manager = __esm({
|
|
|
8111
8613
|
});
|
|
8112
8614
|
}
|
|
8113
8615
|
}
|
|
8616
|
+
for (const file of [...pageFiles, ...slotDefaultFiles]) {
|
|
8617
|
+
const slot = parseRouteSlotFile(file);
|
|
8618
|
+
if (!slot) continue;
|
|
8619
|
+
const modulePath = import_path5.default.join(appDir, file);
|
|
8620
|
+
const pattern = this.createRoutePattern(slot.route);
|
|
8621
|
+
const ownerPattern = this.createRoutePattern(slot.ownerRoute);
|
|
8622
|
+
const key = `${ownerPattern}:${slot.name}:${slot.interception ? "intercept" : "slot"}:${slot.fallback ? "default" : pattern}`;
|
|
8623
|
+
const existing = this.routeSlots.get(key);
|
|
8624
|
+
if (existing?.sourceRoot === source.root) {
|
|
8625
|
+
throw new Error(
|
|
8626
|
+
`Duplicate route slot "${slot.name}" for "${pattern}". Found both ${existing.modulePath} and ${modulePath}.`
|
|
8627
|
+
);
|
|
8628
|
+
}
|
|
8629
|
+
this.routeSlots.set(key, {
|
|
8630
|
+
route: slot.route,
|
|
8631
|
+
modulePath,
|
|
8632
|
+
pattern,
|
|
8633
|
+
source: "file",
|
|
8634
|
+
sourceRoot: source.root,
|
|
8635
|
+
name: slot.name,
|
|
8636
|
+
ownerPattern,
|
|
8637
|
+
interception: slot.interception,
|
|
8638
|
+
fallback: slot.fallback,
|
|
8639
|
+
containerId: createRouteSlotContainerId(slot.name, ownerPattern)
|
|
8640
|
+
});
|
|
8641
|
+
}
|
|
8114
8642
|
for (const file of metadataImageFiles) {
|
|
8115
8643
|
const fileBase = import_path5.default.basename(file, import_path5.default.extname(file));
|
|
8116
8644
|
const kind = fileBase === "twitter-image" ? "twitter" : "opengraph";
|
|
@@ -8236,6 +8764,71 @@ var init_route_manager = __esm({
|
|
|
8236
8764
|
}
|
|
8237
8765
|
return matchingLayouts;
|
|
8238
8766
|
}
|
|
8767
|
+
findMatchingRouteSlots(pathname, interceptFrom) {
|
|
8768
|
+
const groups = /* @__PURE__ */ new Map();
|
|
8769
|
+
for (const entry of this.routeSlots.values()) {
|
|
8770
|
+
if (!this.matchesRoutePrefix(pathname, entry.ownerPattern)) continue;
|
|
8771
|
+
const key = `${entry.ownerPattern}:${entry.name}`;
|
|
8772
|
+
const entries = groups.get(key) ?? [];
|
|
8773
|
+
entries.push(entry);
|
|
8774
|
+
groups.set(key, entries);
|
|
8775
|
+
}
|
|
8776
|
+
const normalizedFrom = interceptFrom ? this.toRoutePathname(new URL(interceptFrom, "http://farm.local").pathname) : void 0;
|
|
8777
|
+
const matches = [];
|
|
8778
|
+
for (const entries of groups.values()) {
|
|
8779
|
+
const candidates = entries.filter((entry) => !entry.fallback).filter(
|
|
8780
|
+
(entry) => !entry.interception || normalizedFrom !== void 0 && this.matchesRoutePrefix(normalizedFrom, entry.ownerPattern)
|
|
8781
|
+
).map((entry) => ({
|
|
8782
|
+
entry,
|
|
8783
|
+
match: matchRoute(pathname, entry.route.segments)
|
|
8784
|
+
})).filter((candidate) => candidate.match.matches).sort((left, right) => {
|
|
8785
|
+
if (left.entry.interception !== right.entry.interception) {
|
|
8786
|
+
return left.entry.interception ? -1 : 1;
|
|
8787
|
+
}
|
|
8788
|
+
return routeSpecificity(right.entry) - routeSpecificity(left.entry);
|
|
8789
|
+
});
|
|
8790
|
+
const selected = candidates[0];
|
|
8791
|
+
if (selected) {
|
|
8792
|
+
matches.push({
|
|
8793
|
+
name: selected.entry.name,
|
|
8794
|
+
ownerPattern: selected.entry.ownerPattern,
|
|
8795
|
+
containerId: selected.entry.containerId,
|
|
8796
|
+
interception: selected.entry.interception,
|
|
8797
|
+
fallback: false,
|
|
8798
|
+
route: selected.entry,
|
|
8799
|
+
params: selected.match.params
|
|
8800
|
+
});
|
|
8801
|
+
continue;
|
|
8802
|
+
}
|
|
8803
|
+
const fallback = entries.find((entry) => entry.fallback);
|
|
8804
|
+
if (fallback) {
|
|
8805
|
+
matches.push({
|
|
8806
|
+
name: fallback.name,
|
|
8807
|
+
ownerPattern: fallback.ownerPattern,
|
|
8808
|
+
containerId: fallback.containerId,
|
|
8809
|
+
interception: false,
|
|
8810
|
+
fallback: true,
|
|
8811
|
+
route: fallback,
|
|
8812
|
+
params: {}
|
|
8813
|
+
});
|
|
8814
|
+
}
|
|
8815
|
+
}
|
|
8816
|
+
return matches.sort((left, right) => {
|
|
8817
|
+
const ownerDifference = left.route.route.segments.length - right.route.route.segments.length;
|
|
8818
|
+
return ownerDifference || left.name.localeCompare(right.name);
|
|
8819
|
+
});
|
|
8820
|
+
}
|
|
8821
|
+
matchesRoutePrefix(pathname, pattern) {
|
|
8822
|
+
if (pattern === "/") return true;
|
|
8823
|
+
const patternSegments = parseRoutePath(`${pattern}/page.tsx`).segments;
|
|
8824
|
+
const pathSegments = pathname.split("/").filter(Boolean);
|
|
8825
|
+
if (patternSegments.length > pathSegments.length) return false;
|
|
8826
|
+
for (let index = 0; index < patternSegments.length; index++) {
|
|
8827
|
+
const segment = patternSegments[index];
|
|
8828
|
+
if (!segment.isDynamic && segment.segment !== pathSegments[index]) return false;
|
|
8829
|
+
}
|
|
8830
|
+
return true;
|
|
8831
|
+
}
|
|
8239
8832
|
findNearestBoundary(pathname, boundaries) {
|
|
8240
8833
|
const normalizedPath = pathname === "/" ? "/" : pathname.replace(/\/$/, "");
|
|
8241
8834
|
const pathSegments = normalizedPath.split("/").filter(Boolean);
|
|
@@ -9408,13 +10001,23 @@ function readPageState() {
|
|
|
9408
10001
|
if (!state || typeof state !== "object") return null;
|
|
9409
10002
|
return state[FARM_PAGE_STATE_KEY] ?? null;
|
|
9410
10003
|
}
|
|
9411
|
-
function createHistoryState(path28, pageState, currentState) {
|
|
10004
|
+
function createHistoryState(path28, pageState, currentState, interceptFrom) {
|
|
9412
10005
|
const base = currentState && typeof currentState === "object" ? { ...currentState } : {};
|
|
9413
|
-
|
|
10006
|
+
const nextState = {
|
|
9414
10007
|
...base,
|
|
9415
10008
|
path: path28,
|
|
9416
10009
|
[FARM_PAGE_STATE_KEY]: pageState
|
|
9417
10010
|
};
|
|
10011
|
+
if (interceptFrom === null) {
|
|
10012
|
+
delete nextState[FARM_INTERCEPT_FROM_KEY];
|
|
10013
|
+
} else if (interceptFrom) {
|
|
10014
|
+
nextState[FARM_INTERCEPT_FROM_KEY] = interceptFrom;
|
|
10015
|
+
}
|
|
10016
|
+
return nextState;
|
|
10017
|
+
}
|
|
10018
|
+
function getPageDataCacheKey(path28, interceptFrom) {
|
|
10019
|
+
return interceptFrom ? `${path28}
|
|
10020
|
+
intercept:${interceptFrom}` : path28;
|
|
9418
10021
|
}
|
|
9419
10022
|
function createNavigationLocation(url) {
|
|
9420
10023
|
return {
|
|
@@ -9427,7 +10030,7 @@ function createNavigationLocation(url) {
|
|
|
9427
10030
|
function getScrollElementStorageKey(path28, key) {
|
|
9428
10031
|
return `farm-scroll-${path28}:${key}`;
|
|
9429
10032
|
}
|
|
9430
|
-
var FARM_PAGE_STATE_KEY, IDLE_NAVIGATION_STATE, routerInstance, _SPARouter, SPARouter;
|
|
10033
|
+
var FARM_PAGE_STATE_KEY, FARM_INTERCEPT_FROM_KEY, IDLE_NAVIGATION_STATE, routerInstance, _SPARouter, SPARouter;
|
|
9431
10034
|
var init_spa_router = __esm({
|
|
9432
10035
|
"src/client/spa-router.ts"() {
|
|
9433
10036
|
"use strict";
|
|
@@ -9436,6 +10039,7 @@ var init_spa_router = __esm({
|
|
|
9436
10039
|
init_deployment();
|
|
9437
10040
|
init_client_runtime();
|
|
9438
10041
|
FARM_PAGE_STATE_KEY = "__farmPageState";
|
|
10042
|
+
FARM_INTERCEPT_FROM_KEY = "__farmInterceptFrom";
|
|
9439
10043
|
IDLE_NAVIGATION_STATE = {
|
|
9440
10044
|
state: "idle",
|
|
9441
10045
|
pending: false,
|
|
@@ -9506,7 +10110,11 @@ var init_spa_router = __esm({
|
|
|
9506
10110
|
return;
|
|
9507
10111
|
}
|
|
9508
10112
|
const from = window.location.pathname + window.location.search;
|
|
9509
|
-
if (await this.shouldBlockNavigation({
|
|
10113
|
+
if (await this.shouldBlockNavigation({
|
|
10114
|
+
from,
|
|
10115
|
+
to: fullPath,
|
|
10116
|
+
action: replace ? "replace" : "push"
|
|
10117
|
+
})) {
|
|
9510
10118
|
return;
|
|
9511
10119
|
}
|
|
9512
10120
|
if (this.options.scrollRestoration) {
|
|
@@ -9524,11 +10132,11 @@ var init_spa_router = __esm({
|
|
|
9524
10132
|
to: url,
|
|
9525
10133
|
action: replace ? "replace" : "push"
|
|
9526
10134
|
});
|
|
9527
|
-
const pageData = await this.fetchPageData(fullPath);
|
|
10135
|
+
const pageData = await this.fetchPageData(fullPath, true, from);
|
|
9528
10136
|
if (clientNavigation) {
|
|
9529
10137
|
await this.clientPlugins?.markNavigationLoaded(clientNavigation, pageData);
|
|
9530
10138
|
}
|
|
9531
|
-
if (pageData.isClientComponent === false) {
|
|
10139
|
+
if (pageData.isClientComponent === false && !pageData.interception) {
|
|
9532
10140
|
this.finishNavigation();
|
|
9533
10141
|
window.location.assign(pageData.canonicalPath || fullPath);
|
|
9534
10142
|
return;
|
|
@@ -9566,11 +10174,12 @@ var init_spa_router = __esm({
|
|
|
9566
10174
|
if (isFarmLocaleChangeHref(href)) return;
|
|
9567
10175
|
const url = new URL(href, window.location.origin);
|
|
9568
10176
|
const fullPath = url.pathname + url.search;
|
|
10177
|
+
const interceptFrom = window.location.pathname + window.location.search;
|
|
9569
10178
|
if (this.prefetchingUrls.has(fullPath)) return;
|
|
9570
|
-
if (this.isCached(fullPath)) return;
|
|
10179
|
+
if (this.isCached(fullPath, interceptFrom)) return;
|
|
9571
10180
|
this.prefetchingUrls.add(fullPath);
|
|
9572
10181
|
try {
|
|
9573
|
-
await this.fetchPageData(fullPath, false);
|
|
10182
|
+
await this.fetchPageData(fullPath, false, interceptFrom);
|
|
9574
10183
|
} catch (error) {
|
|
9575
10184
|
console.warn("[Farm.js] Prefetch failed:", href, error);
|
|
9576
10185
|
} finally {
|
|
@@ -9645,7 +10254,12 @@ var init_spa_router = __esm({
|
|
|
9645
10254
|
}
|
|
9646
10255
|
async commitNavigation(options) {
|
|
9647
10256
|
const historyPath = options.pageData.canonicalPath || options.fullPath;
|
|
9648
|
-
const historyState = createHistoryState(
|
|
10257
|
+
const historyState = createHistoryState(
|
|
10258
|
+
historyPath,
|
|
10259
|
+
options.state,
|
|
10260
|
+
void 0,
|
|
10261
|
+
options.pageData.interception?.from ?? null
|
|
10262
|
+
);
|
|
9649
10263
|
if (options.replace) {
|
|
9650
10264
|
window.history.replaceState(historyState, "", historyPath);
|
|
9651
10265
|
} else {
|
|
@@ -9700,15 +10314,17 @@ var init_spa_router = __esm({
|
|
|
9700
10314
|
/**
|
|
9701
10315
|
* Fetch page data from cache or server
|
|
9702
10316
|
*/
|
|
9703
|
-
async fetchPageData(path28, recover = true) {
|
|
9704
|
-
const
|
|
10317
|
+
async fetchPageData(path28, recover = true, interceptFrom) {
|
|
10318
|
+
const cacheKey = getPageDataCacheKey(path28, interceptFrom);
|
|
10319
|
+
const cached = this.cache.get(cacheKey);
|
|
9705
10320
|
if (cached && Date.now() - cached.timestamp < this.options.cacheMaxAge) {
|
|
9706
10321
|
return cached.data;
|
|
9707
10322
|
}
|
|
9708
10323
|
const response = await fetch(`/__farm/page-data?path=${encodeURIComponent(path28)}`, {
|
|
9709
10324
|
headers: createFarmDeploymentRequestHeaders(this.options.deploymentId, {
|
|
9710
10325
|
Accept: "application/x-farm-deferred+json, application/json",
|
|
9711
|
-
"X-Farm-SPA": "1"
|
|
10326
|
+
"X-Farm-SPA": "1",
|
|
10327
|
+
...interceptFrom ? { "X-Farm-Intercept-From": interceptFrom } : {}
|
|
9712
10328
|
})
|
|
9713
10329
|
});
|
|
9714
10330
|
if (isFarmDeploymentMismatchResponse(response, this.options.deploymentId)) {
|
|
@@ -9726,7 +10342,7 @@ var init_spa_router = __esm({
|
|
|
9726
10342
|
throw new Error(`Failed to fetch page data: ${response.status}`);
|
|
9727
10343
|
}
|
|
9728
10344
|
const data = await readDeferredDataResponse(response);
|
|
9729
|
-
this.cache.set(
|
|
10345
|
+
this.cache.set(cacheKey, {
|
|
9730
10346
|
data,
|
|
9731
10347
|
timestamp: Date.now()
|
|
9732
10348
|
});
|
|
@@ -9757,7 +10373,8 @@ var init_spa_router = __esm({
|
|
|
9757
10373
|
to: window.location.href,
|
|
9758
10374
|
action: "pop"
|
|
9759
10375
|
});
|
|
9760
|
-
const
|
|
10376
|
+
const interceptFrom = typeof event.state?.[FARM_INTERCEPT_FROM_KEY] === "string" ? event.state[FARM_INTERCEPT_FROM_KEY] : void 0;
|
|
10377
|
+
const pageData = await this.fetchPageData(path28, true, interceptFrom);
|
|
9761
10378
|
if (clientNavigation) {
|
|
9762
10379
|
await this.clientPlugins?.markNavigationLoaded(clientNavigation, pageData);
|
|
9763
10380
|
}
|
|
@@ -9788,8 +10405,8 @@ var init_spa_router = __esm({
|
|
|
9788
10405
|
/**
|
|
9789
10406
|
* Check if URL is cached
|
|
9790
10407
|
*/
|
|
9791
|
-
isCached(path28) {
|
|
9792
|
-
const cached = this.cache.get(path28);
|
|
10408
|
+
isCached(path28, interceptFrom) {
|
|
10409
|
+
const cached = this.cache.get(getPageDataCacheKey(path28, interceptFrom));
|
|
9793
10410
|
return cached !== void 0 && Date.now() - cached.timestamp < this.options.cacheMaxAge;
|
|
9794
10411
|
}
|
|
9795
10412
|
/**
|
|
@@ -9904,6 +10521,7 @@ var init_spa_router = __esm({
|
|
|
9904
10521
|
__name(replaceState, "replaceState");
|
|
9905
10522
|
__name(readPageState, "readPageState");
|
|
9906
10523
|
__name(createHistoryState, "createHistoryState");
|
|
10524
|
+
__name(getPageDataCacheKey, "getPageDataCacheKey");
|
|
9907
10525
|
__name(createNavigationLocation, "createNavigationLocation");
|
|
9908
10526
|
__name(getScrollElementStorageKey, "getScrollElementStorageKey");
|
|
9909
10527
|
}
|
|
@@ -11279,7 +11897,9 @@ var init_renderer = __esm({
|
|
|
11279
11897
|
async runWithRequestContext(request, fn) {
|
|
11280
11898
|
return _runWithCurrentRequest(
|
|
11281
11899
|
request,
|
|
11282
|
-
() => this.i18nRuntime?.config.enabled ? _runWithFarmI18nRequest(this.i18nRuntime, request, fn, {
|
|
11900
|
+
() => this.i18nRuntime?.config.enabled ? _runWithFarmI18nRequest(this.i18nRuntime, request, fn, {
|
|
11901
|
+
redirect: false
|
|
11902
|
+
}) : fn()
|
|
11283
11903
|
);
|
|
11284
11904
|
}
|
|
11285
11905
|
async resolveRouteContext(input) {
|
|
@@ -11302,11 +11922,11 @@ var init_renderer = __esm({
|
|
|
11302
11922
|
/**
|
|
11303
11923
|
* Check if a path should be served from SSG cache
|
|
11304
11924
|
*/
|
|
11305
|
-
shouldServeSSG(pathname) {
|
|
11925
|
+
async shouldServeSSG(pathname) {
|
|
11306
11926
|
const ssgPage = matchSSGPage(pathname, this.ssgManifest);
|
|
11307
11927
|
if (!ssgPage) return null;
|
|
11308
|
-
const cached = this.getCachedSSGPage(pathname);
|
|
11309
|
-
if (cached && this.dataCache.
|
|
11928
|
+
const cached = await this.getCachedSSGPage(pathname);
|
|
11929
|
+
if (cached && await this.dataCache.isStaleAsync(cached)) {
|
|
11310
11930
|
this.regenerateSSGPage(ssgPage);
|
|
11311
11931
|
}
|
|
11312
11932
|
return ssgPage;
|
|
@@ -11318,12 +11938,12 @@ var init_renderer = __esm({
|
|
|
11318
11938
|
return createFarmCacheKey(["ppr", normalizeRevalidatePath(pathname), search]);
|
|
11319
11939
|
}
|
|
11320
11940
|
getCachedSSGPage(urlPath) {
|
|
11321
|
-
return this.dataCache.
|
|
11941
|
+
return this.dataCache.getEntryAsync(this.getSSGCacheKey(urlPath), {
|
|
11322
11942
|
allowStale: true
|
|
11323
11943
|
});
|
|
11324
11944
|
}
|
|
11325
|
-
cacheSSGPage(page2, html, options) {
|
|
11326
|
-
this.dataCache.
|
|
11945
|
+
async cacheSSGPage(page2, html, options) {
|
|
11946
|
+
await this.dataCache.setAsync(
|
|
11327
11947
|
this.getSSGCacheKey(page2.urlPath),
|
|
11328
11948
|
{ html, document: options.document },
|
|
11329
11949
|
{
|
|
@@ -11335,11 +11955,11 @@ var init_renderer = __esm({
|
|
|
11335
11955
|
);
|
|
11336
11956
|
}
|
|
11337
11957
|
getCachedPPRShell(pathname, search) {
|
|
11338
|
-
return this.dataCache.
|
|
11958
|
+
return this.dataCache.getEntryAsync(this.getPPRCacheKey(pathname, search));
|
|
11339
11959
|
}
|
|
11340
|
-
cachePPRShell(options, html) {
|
|
11960
|
+
async cachePPRShell(options, html) {
|
|
11341
11961
|
const key = this.getPPRCacheKey(options.pathname, options.search);
|
|
11342
|
-
this.dataCache.
|
|
11962
|
+
await this.dataCache.setAsync(
|
|
11343
11963
|
key,
|
|
11344
11964
|
{ html },
|
|
11345
11965
|
{
|
|
@@ -11437,7 +12057,7 @@ var init_renderer = __esm({
|
|
|
11437
12057
|
}
|
|
11438
12058
|
const { renderToString } = await import("react-dom/server");
|
|
11439
12059
|
const html = renderToString(await this.wrapWithIntegrationProviders(pageElement));
|
|
11440
|
-
this.cacheSSGPage(page2, html, { document: false });
|
|
12060
|
+
await this.cacheSSGPage(page2, html, { document: false });
|
|
11441
12061
|
logger.info(`ISR: Regenerated ${page2.urlPath}`);
|
|
11442
12062
|
} catch (error) {
|
|
11443
12063
|
logger.error(`ISR regeneration failed for ${page2.urlPath}: ${error}`);
|
|
@@ -11451,7 +12071,7 @@ var init_renderer = __esm({
|
|
|
11451
12071
|
* Serve a pre-rendered SSG page
|
|
11452
12072
|
*/
|
|
11453
12073
|
async serveSSGPage(req, res, page2) {
|
|
11454
|
-
const cached = this.getCachedSSGPage(page2.urlPath);
|
|
12074
|
+
const cached = await this.getCachedSSGPage(page2.urlPath);
|
|
11455
12075
|
if (cached) {
|
|
11456
12076
|
res.setHeader("Content-Type", "text/html; charset=utf-8");
|
|
11457
12077
|
res.setHeader("X-Farm-SSG", "cached");
|
|
@@ -11469,9 +12089,12 @@ var init_renderer = __esm({
|
|
|
11469
12089
|
if (fs2.existsSync(htmlPath)) {
|
|
11470
12090
|
const stat = fs2.statSync(htmlPath);
|
|
11471
12091
|
const html = fs2.readFileSync(htmlPath, "utf-8");
|
|
11472
|
-
this.cacheSSGPage(page2, html, {
|
|
11473
|
-
|
|
11474
|
-
|
|
12092
|
+
await this.cacheSSGPage(page2, html, {
|
|
12093
|
+
document: true,
|
|
12094
|
+
createdAt: stat.mtimeMs
|
|
12095
|
+
});
|
|
12096
|
+
const fileCacheEntry = await this.getCachedSSGPage(page2.urlPath);
|
|
12097
|
+
if (fileCacheEntry && await this.dataCache.isStaleAsync(fileCacheEntry)) {
|
|
11475
12098
|
this.regenerateSSGPage(page2);
|
|
11476
12099
|
}
|
|
11477
12100
|
res.setHeader("Content-Type", "text/html; charset=utf-8");
|
|
@@ -11517,6 +12140,7 @@ var init_renderer = __esm({
|
|
|
11517
12140
|
let pathname = "/";
|
|
11518
12141
|
let params = {};
|
|
11519
12142
|
let layouts = [];
|
|
12143
|
+
let routeSlots = [];
|
|
11520
12144
|
let searchParamsObject = {};
|
|
11521
12145
|
let middlewareMap = /* @__PURE__ */ new Map();
|
|
11522
12146
|
let middlewareContext = /* @__PURE__ */ new Map();
|
|
@@ -11549,7 +12173,7 @@ var init_renderer = __esm({
|
|
|
11549
12173
|
}
|
|
11550
12174
|
this.applyDeploymentHeaders(req, res);
|
|
11551
12175
|
if (process.env.NODE_ENV === "production") {
|
|
11552
|
-
const ssgPage = this.shouldServeSSG(pathname);
|
|
12176
|
+
const ssgPage = await this.shouldServeSSG(pathname);
|
|
11553
12177
|
if (ssgPage) {
|
|
11554
12178
|
const served = await this.serveSSGPage(req, res, ssgPage);
|
|
11555
12179
|
if (served) {
|
|
@@ -11562,6 +12186,7 @@ var init_renderer = __esm({
|
|
|
11562
12186
|
const route2 = match.route;
|
|
11563
12187
|
params = match.params;
|
|
11564
12188
|
layouts = match.layouts;
|
|
12189
|
+
routeSlots = match.slots ?? [];
|
|
11565
12190
|
if (!route2) {
|
|
11566
12191
|
emitFarmEvent({ type: "route.notFound", pathname });
|
|
11567
12192
|
await this.render404(req, res);
|
|
@@ -11578,7 +12203,9 @@ var init_renderer = __esm({
|
|
|
11578
12203
|
errorBoundaryEntry = this.routeManager.getMatchingError(pathname);
|
|
11579
12204
|
middlewareMap = toMiddlewareMap2(req.__FARM_MIDDLEWARE_DATA__);
|
|
11580
12205
|
middlewareContext = toMiddlewareMap2(req.__FARM_MIDDLEWARE_CONTEXT__);
|
|
11581
|
-
pluginExposedContext = getRequestContextSnapshot(req, {
|
|
12206
|
+
pluginExposedContext = getRequestContextSnapshot(req, {
|
|
12207
|
+
exposedOnly: true
|
|
12208
|
+
});
|
|
11582
12209
|
const currentRequest = createWebRequestFromFarmRequest(req);
|
|
11583
12210
|
const routeContext = await this.resolveRouteContext({
|
|
11584
12211
|
request: currentRequest,
|
|
@@ -11642,8 +12269,16 @@ var init_renderer = __esm({
|
|
|
11642
12269
|
revalidate: renderingConfig.revalidate
|
|
11643
12270
|
} : void 0;
|
|
11644
12271
|
if (renderingConfig.ppr && pprBypassReason) {
|
|
11645
|
-
emitFarmEvent({
|
|
11646
|
-
|
|
12272
|
+
emitFarmEvent({
|
|
12273
|
+
type: "ppr.shell.bypass",
|
|
12274
|
+
route: pathname,
|
|
12275
|
+
reason: pprBypassReason
|
|
12276
|
+
});
|
|
12277
|
+
emitFarmEvent({
|
|
12278
|
+
type: "cache.bypass",
|
|
12279
|
+
route: pathname,
|
|
12280
|
+
reason: pprBypassReason
|
|
12281
|
+
});
|
|
11647
12282
|
if (pprBypassReason === "refresh") {
|
|
11648
12283
|
pprRefreshRoute = pathname;
|
|
11649
12284
|
emitFarmEvent({ type: "ppr.refresh.start", route: pathname });
|
|
@@ -11651,14 +12286,22 @@ var init_renderer = __esm({
|
|
|
11651
12286
|
}
|
|
11652
12287
|
if (pprShellOptions) {
|
|
11653
12288
|
const pprCacheKey = this.getPPRCacheKey(pathname, url.search);
|
|
11654
|
-
const cachedPPRShell = this.getCachedPPRShell(pathname, url.search);
|
|
12289
|
+
const cachedPPRShell = await this.getCachedPPRShell(pathname, url.search);
|
|
11655
12290
|
if (cachedPPRShell) {
|
|
11656
|
-
emitFarmEvent({
|
|
12291
|
+
emitFarmEvent({
|
|
12292
|
+
type: "ppr.shell.hit",
|
|
12293
|
+
route: pathname,
|
|
12294
|
+
key: pprCacheKey
|
|
12295
|
+
});
|
|
11657
12296
|
this.serveCachedPPRShell(res, cachedPPRShell.value, renderingConfig.revalidate);
|
|
11658
12297
|
completeRender(res.statusCode || 200, pathname);
|
|
11659
12298
|
return;
|
|
11660
12299
|
}
|
|
11661
|
-
emitFarmEvent({
|
|
12300
|
+
emitFarmEvent({
|
|
12301
|
+
type: "ppr.shell.miss",
|
|
12302
|
+
route: pathname,
|
|
12303
|
+
key: pprCacheKey
|
|
12304
|
+
});
|
|
11662
12305
|
}
|
|
11663
12306
|
let LoadingFallbackComponent = null;
|
|
11664
12307
|
if (loadingBoundaryEntry) {
|
|
@@ -11682,14 +12325,77 @@ var init_renderer = __esm({
|
|
|
11682
12325
|
);
|
|
11683
12326
|
const moduleMetadata = routeManifestEntry || getClientModuleMetadata(route2.modulePath, this.config.root);
|
|
11684
12327
|
const isClientComponent = moduleMetadata.isClientComponent;
|
|
12328
|
+
const renderedRouteSlots = await Promise.all(
|
|
12329
|
+
routeSlots.map(async (slot) => {
|
|
12330
|
+
const slotModule = await this.routeManager.loadRouteModule(slot.route.modulePath);
|
|
12331
|
+
if (!slotModule.default) {
|
|
12332
|
+
throw new Error(
|
|
12333
|
+
`Route slot "${slot.name}" module ${slot.route.modulePath} does not export a default component`
|
|
12334
|
+
);
|
|
12335
|
+
}
|
|
12336
|
+
const slotContext = await this.resolveRouteContext({
|
|
12337
|
+
request: currentRequest,
|
|
12338
|
+
rawRequest: req,
|
|
12339
|
+
params: slot.params,
|
|
12340
|
+
search: searchParamsObject,
|
|
12341
|
+
path: pathname
|
|
12342
|
+
});
|
|
12343
|
+
const rawSlotProps = withFarmRouteContext(
|
|
12344
|
+
{
|
|
12345
|
+
params: slot.params,
|
|
12346
|
+
searchParams: Promise.resolve(searchParamsObject),
|
|
12347
|
+
path: pathname,
|
|
12348
|
+
middleware: middlewareMap.size > 0 ? { data: middlewareMap } : void 0,
|
|
12349
|
+
context: pluginExposedContext.size > 0 ? { data: pluginExposedContext } : void 0
|
|
12350
|
+
},
|
|
12351
|
+
slotContext
|
|
12352
|
+
);
|
|
12353
|
+
const slotProps = await parseRouteModuleProps(slotModule, {
|
|
12354
|
+
props: rawSlotProps,
|
|
12355
|
+
search: searchParamsObject,
|
|
12356
|
+
routePath: slot.route.pattern
|
|
12357
|
+
});
|
|
12358
|
+
const metadata = getClientModuleMetadata(slot.route.modulePath, this.config.root);
|
|
12359
|
+
return {
|
|
12360
|
+
...slot,
|
|
12361
|
+
module: slotModule,
|
|
12362
|
+
props: slotProps,
|
|
12363
|
+
isClientComponent: metadata.isClientComponent,
|
|
12364
|
+
shouldHydrate: metadata.shouldHydrate
|
|
12365
|
+
};
|
|
12366
|
+
})
|
|
12367
|
+
);
|
|
11685
12368
|
const shouldHydrate = moduleMetadata.shouldHydrate;
|
|
12369
|
+
const hasHydratableRouteSlots = renderedRouteSlots.some(
|
|
12370
|
+
(slot) => slot.isClientComponent || slot.shouldHydrate
|
|
12371
|
+
);
|
|
11686
12372
|
req.__FARM_PAGE_PATH__ = route2.modulePath;
|
|
11687
12373
|
req.__FARM_ROUTE__ = pathname;
|
|
11688
12374
|
req.__FARM_IS_CLIENT_COMPONENT__ = isClientComponent;
|
|
11689
12375
|
req.__FARM_SHOULD_HYDRATE__ = shouldHydrate;
|
|
12376
|
+
req.__FARM_HAS_HYDRATABLE_ROUTE_SLOTS__ = hasHydratableRouteSlots;
|
|
11690
12377
|
req.__FARM_LOADING_MODULE_PATH__ = loadingBoundaryEntry?.modulePath ? loadingBoundaryEntry.modulePath.substring(
|
|
11691
12378
|
loadingBoundaryEntry.modulePath.indexOf("/src/app/")
|
|
11692
12379
|
) : null;
|
|
12380
|
+
req.__FARM_ROUTE_SLOTS__ = renderedRouteSlots.map((slot) => ({
|
|
12381
|
+
name: slot.name,
|
|
12382
|
+
ownerPattern: slot.ownerPattern,
|
|
12383
|
+
containerId: slot.containerId,
|
|
12384
|
+
interception: slot.interception,
|
|
12385
|
+
fallback: slot.fallback,
|
|
12386
|
+
modulePath: slot.route.modulePath,
|
|
12387
|
+
isClientComponent: slot.isClientComponent,
|
|
12388
|
+
shouldHydrate: slot.shouldHydrate,
|
|
12389
|
+
props: {
|
|
12390
|
+
params: slot.props.params,
|
|
12391
|
+
search: slot.props.search,
|
|
12392
|
+
searchParams: slot.props.search,
|
|
12393
|
+
..."data" in slot.props ? { data: slot.props.data } : {},
|
|
12394
|
+
...slot.props.__farmCanonicalPath ? { __farmCanonicalPath: slot.props.__farmCanonicalPath } : {},
|
|
12395
|
+
...slot.props.__farmRoutePropsResolved ? { __farmRoutePropsResolved: true } : {},
|
|
12396
|
+
path: pathname
|
|
12397
|
+
}
|
|
12398
|
+
}));
|
|
11693
12399
|
req.__FARM_PROPS__ = {
|
|
11694
12400
|
params: pageProps.params,
|
|
11695
12401
|
search: pageProps.search,
|
|
@@ -11749,12 +12455,32 @@ var init_renderer = __esm({
|
|
|
11749
12455
|
let wrappedElement = pageElement;
|
|
11750
12456
|
for (let i = layoutModules.length - 1; i >= 0; i--) {
|
|
11751
12457
|
const layoutModule = layoutModules[i];
|
|
12458
|
+
const layoutEntry = layouts[i];
|
|
11752
12459
|
const LayoutComponent = layoutModule.default;
|
|
12460
|
+
const slotProps = {};
|
|
12461
|
+
for (const slot of renderedRouteSlots) {
|
|
12462
|
+
if (slot.ownerPattern !== layoutEntry.pattern) continue;
|
|
12463
|
+
let slotElement = import_react4.default.createElement(
|
|
12464
|
+
slot.module.default,
|
|
12465
|
+
slot.props
|
|
12466
|
+
);
|
|
12467
|
+
slotElement = import_react4.default.createElement(
|
|
12468
|
+
"div",
|
|
12469
|
+
{
|
|
12470
|
+
id: slot.containerId,
|
|
12471
|
+
"data-farm-route-slot": slot.name,
|
|
12472
|
+
"data-farm-slot-owner": slot.ownerPattern
|
|
12473
|
+
},
|
|
12474
|
+
slotElement
|
|
12475
|
+
);
|
|
12476
|
+
slotProps[slot.name] = slotElement;
|
|
12477
|
+
}
|
|
11753
12478
|
wrappedElement = import_react4.default.createElement(
|
|
11754
12479
|
LayoutComponent,
|
|
11755
12480
|
{
|
|
11756
12481
|
children: wrappedElement,
|
|
11757
|
-
params
|
|
12482
|
+
params,
|
|
12483
|
+
...slotProps
|
|
11758
12484
|
}
|
|
11759
12485
|
);
|
|
11760
12486
|
}
|
|
@@ -11791,7 +12517,10 @@ var init_renderer = __esm({
|
|
|
11791
12517
|
routeManifest,
|
|
11792
12518
|
captureStaticShell: Boolean(pprShellOptions),
|
|
11793
12519
|
observabilityRoute: pathname,
|
|
11794
|
-
onSuspenseHoleDetected: pprShellOptions ? () => emitFarmEvent({
|
|
12520
|
+
onSuspenseHoleDetected: pprShellOptions ? () => emitFarmEvent({
|
|
12521
|
+
type: "ppr.suspense.holeDetected",
|
|
12522
|
+
route: pathname
|
|
12523
|
+
}) : void 0,
|
|
11795
12524
|
onComplete: pprShellOptions && req.method !== "HEAD" ? (html) => this.cachePPRShell(pprShellOptions, html) : void 0
|
|
11796
12525
|
}
|
|
11797
12526
|
);
|
|
@@ -11839,7 +12568,11 @@ var init_renderer = __esm({
|
|
|
11839
12568
|
}
|
|
11840
12569
|
emitFarmEvent({ type: "render.error", route: pathname, error });
|
|
11841
12570
|
if (pprRefreshRoute) {
|
|
11842
|
-
emitFarmEvent({
|
|
12571
|
+
emitFarmEvent({
|
|
12572
|
+
type: "ppr.refresh.error",
|
|
12573
|
+
route: pprRefreshRoute,
|
|
12574
|
+
error
|
|
12575
|
+
});
|
|
11843
12576
|
}
|
|
11844
12577
|
logger.error(`Error rendering page: ${error}`);
|
|
11845
12578
|
if (res.headersSent || res.writableEnded) {
|
|
@@ -11892,7 +12625,9 @@ var init_renderer = __esm({
|
|
|
11892
12625
|
if (typeof layoutModule.generateMetadata === "function") {
|
|
11893
12626
|
metadata = mergeMetadata(
|
|
11894
12627
|
metadata,
|
|
11895
|
-
await layoutModule.generateMetadata({
|
|
12628
|
+
await layoutModule.generateMetadata({
|
|
12629
|
+
params: options.pageProps.params
|
|
12630
|
+
})
|
|
11896
12631
|
);
|
|
11897
12632
|
}
|
|
11898
12633
|
}
|
|
@@ -12123,7 +12858,13 @@ var init_renderer = __esm({
|
|
|
12123
12858
|
clientEntry: "/@farm/client.js",
|
|
12124
12859
|
routes: {},
|
|
12125
12860
|
layouts: {},
|
|
12126
|
-
|
|
12861
|
+
slots: [],
|
|
12862
|
+
sharedAssets: [
|
|
12863
|
+
{
|
|
12864
|
+
tag: "link",
|
|
12865
|
+
attrs: { rel: "stylesheet", href: "/src/app/globals.css" }
|
|
12866
|
+
}
|
|
12867
|
+
]
|
|
12127
12868
|
};
|
|
12128
12869
|
for (const routeEntry of manifest.routes) {
|
|
12129
12870
|
clientManifest.routes[routeEntry.pattern] = {
|
|
@@ -12145,9 +12886,26 @@ var init_renderer = __esm({
|
|
|
12145
12886
|
assets: []
|
|
12146
12887
|
};
|
|
12147
12888
|
}
|
|
12148
|
-
const
|
|
12889
|
+
for (const slotEntry of manifest.slots ?? []) {
|
|
12890
|
+
clientManifest.slots.push({
|
|
12891
|
+
...slotEntry,
|
|
12892
|
+
preloads: [slotEntry.modulePath],
|
|
12893
|
+
assets: []
|
|
12894
|
+
});
|
|
12895
|
+
}
|
|
12896
|
+
const routeSlotPayload = (req.__FARM_ROUTE_SLOTS__ || []).map(
|
|
12897
|
+
(slot) => ({
|
|
12898
|
+
...slot,
|
|
12899
|
+
modulePath: typeof slot.modulePath === "string" && slot.modulePath.startsWith(this.config.root) ? slot.modulePath.slice(this.config.root.length) : slot.modulePath
|
|
12900
|
+
})
|
|
12901
|
+
);
|
|
12902
|
+
const deferredProps = prepareDeferredData({
|
|
12903
|
+
page: req.__FARM_PROPS__ || {},
|
|
12904
|
+
slots: routeSlotPayload
|
|
12905
|
+
});
|
|
12149
12906
|
const propsScript = `<script>
|
|
12150
|
-
window.__FARM_PROPS__ = ${serializeInlineValue(deferredProps.data)};
|
|
12907
|
+
window.__FARM_PROPS__ = ${serializeInlineValue(deferredProps.data.page)};
|
|
12908
|
+
window.__FARM_ROUTE_SLOTS__ = ${serializeInlineValue(deferredProps.data.slots)};
|
|
12151
12909
|
window.__FARM_DEPLOYMENT_ID__ = ${serializeInlineValue(deploymentId)};
|
|
12152
12910
|
window.__FARM_PATH__ = ${JSON.stringify(req.__FARM_ROUTE__ || req.url || "/")};
|
|
12153
12911
|
window.__FARM_IS_CLIENT__ = ${JSON.stringify(isClientComponent)};
|
|
@@ -12160,7 +12918,7 @@ window.__FARM_MANIFEST__ = ${JSON.stringify(clientManifest)};
|
|
|
12160
12918
|
window.__FARM_INTEGRATION_API_MANIFEST__ = ${JSON.stringify(getRegisteredIntegrationAPIManifest())};
|
|
12161
12919
|
${getFarmI18nClientSnapshot() ? `window.__FARM_I18N__ = ${serializeInlineValue(getFarmI18nClientSnapshot())};` : ""}
|
|
12162
12920
|
</script>`;
|
|
12163
|
-
const hydrationClickQueueScript = isClientComponent || req.__FARM_SHOULD_HYDRATE__ === true ? createPreHydrationClickQueueScript() : "";
|
|
12921
|
+
const hydrationClickQueueScript = isClientComponent || req.__FARM_SHOULD_HYDRATE__ === true || req.__FARM_HAS_HYDRATABLE_ROUTE_SLOTS__ === true ? createPreHydrationClickQueueScript() : "";
|
|
12164
12922
|
const {
|
|
12165
12923
|
title,
|
|
12166
12924
|
tags: metaTags,
|
|
@@ -12271,7 +13029,11 @@ ${getFarmI18nClientSnapshot() ? `window.__FARM_I18N__ = ${serializeInlineValue(g
|
|
|
12271
13029
|
didError = true;
|
|
12272
13030
|
if (!isFarmRedirectError(error) && !isFarmNotFoundError(error)) {
|
|
12273
13031
|
logger.error(`SSR shell error: ${error}`);
|
|
12274
|
-
emitFarmEvent({
|
|
13032
|
+
emitFarmEvent({
|
|
13033
|
+
type: "render.error",
|
|
13034
|
+
route: observabilityRoute,
|
|
13035
|
+
error
|
|
13036
|
+
});
|
|
12275
13037
|
}
|
|
12276
13038
|
if (clearMiddlewareData) {
|
|
12277
13039
|
clearMiddlewareData();
|
|
@@ -12282,7 +13044,11 @@ ${getFarmI18nClientSnapshot() ? `window.__FARM_I18N__ = ${serializeInlineValue(g
|
|
|
12282
13044
|
didError = true;
|
|
12283
13045
|
if (!isFarmRedirectError(error) && !isFarmNotFoundError(error)) {
|
|
12284
13046
|
logger.error(`SSR streaming error: ${error}`);
|
|
12285
|
-
emitFarmEvent({
|
|
13047
|
+
emitFarmEvent({
|
|
13048
|
+
type: "render.error",
|
|
13049
|
+
route: observabilityRoute,
|
|
13050
|
+
error
|
|
13051
|
+
});
|
|
12286
13052
|
}
|
|
12287
13053
|
}
|
|
12288
13054
|
});
|
|
@@ -12488,6 +13254,7 @@ var init_app = __esm({
|
|
|
12488
13254
|
init_devtools_config();
|
|
12489
13255
|
init_config();
|
|
12490
13256
|
init_server2();
|
|
13257
|
+
init_cache();
|
|
12491
13258
|
defaultDocsConfig = {
|
|
12492
13259
|
enabled: false,
|
|
12493
13260
|
entry: "/docs",
|
|
@@ -12509,6 +13276,7 @@ var init_app = __esm({
|
|
|
12509
13276
|
logger.info("Initializing Farm.js application...");
|
|
12510
13277
|
}
|
|
12511
13278
|
await initStorage(this.config.storage);
|
|
13279
|
+
await configureFarmCache(this.config.cache);
|
|
12512
13280
|
await this.i18nRuntime.initialize();
|
|
12513
13281
|
await this.verifyAppStructure();
|
|
12514
13282
|
await this.routeManager.discoverRoutes();
|
|
@@ -12540,6 +13308,7 @@ var init_app = __esm({
|
|
|
12540
13308
|
preset: config.preset ?? "node-server",
|
|
12541
13309
|
deploy: config.deploy || {},
|
|
12542
13310
|
storage: config.storage || {},
|
|
13311
|
+
cache: config.cache || {},
|
|
12543
13312
|
integrations: config.integrations || {},
|
|
12544
13313
|
plugins: config.plugins || [],
|
|
12545
13314
|
migrations: config.migrations || { commands: [] },
|
|
@@ -13138,6 +13907,184 @@ var init_hmr = __esm({
|
|
|
13138
13907
|
}
|
|
13139
13908
|
});
|
|
13140
13909
|
|
|
13910
|
+
// src/api/transport.ts
|
|
13911
|
+
function multipart(schema) {
|
|
13912
|
+
if (!Object.isExtensible(schema) && !isMultipartSchema(schema)) {
|
|
13913
|
+
throw new TypeError("multipart() requires an extensible schema object");
|
|
13914
|
+
}
|
|
13915
|
+
if (!isMultipartSchema(schema)) {
|
|
13916
|
+
Object.defineProperty(schema, "__farmMultipartSchema", {
|
|
13917
|
+
value: true,
|
|
13918
|
+
configurable: false,
|
|
13919
|
+
enumerable: false,
|
|
13920
|
+
writable: false
|
|
13921
|
+
});
|
|
13922
|
+
}
|
|
13923
|
+
return schema;
|
|
13924
|
+
}
|
|
13925
|
+
function isMultipartSchema(value) {
|
|
13926
|
+
return typeof value === "object" && value !== null && value.__farmMultipartSchema === true && typeof value.parse === "function";
|
|
13927
|
+
}
|
|
13928
|
+
function toFormData(values) {
|
|
13929
|
+
const formData = new FormData();
|
|
13930
|
+
for (const [key, value] of Object.entries(values)) {
|
|
13931
|
+
if (isUnsafeFormKey(key)) continue;
|
|
13932
|
+
if (Array.isArray(value)) {
|
|
13933
|
+
for (const entry of value) appendFormValue(formData, key, entry);
|
|
13934
|
+
continue;
|
|
13935
|
+
}
|
|
13936
|
+
appendFormValue(formData, key, value);
|
|
13937
|
+
}
|
|
13938
|
+
return formData;
|
|
13939
|
+
}
|
|
13940
|
+
function jsonStream(source, init = {}) {
|
|
13941
|
+
const iterator = toAsyncIterator(source);
|
|
13942
|
+
const encoder = new TextEncoder();
|
|
13943
|
+
let finished = false;
|
|
13944
|
+
const body = new ReadableStream(
|
|
13945
|
+
{
|
|
13946
|
+
async pull(controller) {
|
|
13947
|
+
if (finished) return;
|
|
13948
|
+
try {
|
|
13949
|
+
const next = await iterator.next();
|
|
13950
|
+
if (next.done) {
|
|
13951
|
+
finished = true;
|
|
13952
|
+
controller.close();
|
|
13953
|
+
return;
|
|
13954
|
+
}
|
|
13955
|
+
controller.enqueue(encoder.encode(`${JSON.stringify(next.value)}
|
|
13956
|
+
`));
|
|
13957
|
+
} catch (error) {
|
|
13958
|
+
finished = true;
|
|
13959
|
+
controller.error(error);
|
|
13960
|
+
}
|
|
13961
|
+
},
|
|
13962
|
+
async cancel(reason) {
|
|
13963
|
+
finished = true;
|
|
13964
|
+
await iterator.return?.(reason);
|
|
13965
|
+
}
|
|
13966
|
+
},
|
|
13967
|
+
{
|
|
13968
|
+
// Do not read the next application event until the response consumer
|
|
13969
|
+
// requests another chunk.
|
|
13970
|
+
highWaterMark: 0
|
|
13971
|
+
}
|
|
13972
|
+
);
|
|
13973
|
+
const headers2 = new Headers(init.headers);
|
|
13974
|
+
if (!headers2.has("content-type")) {
|
|
13975
|
+
headers2.set("content-type", "application/x-ndjson; charset=utf-8");
|
|
13976
|
+
}
|
|
13977
|
+
headers2.set("cache-control", headers2.get("cache-control") ?? "no-store");
|
|
13978
|
+
return new Response(body, {
|
|
13979
|
+
...init,
|
|
13980
|
+
headers: headers2
|
|
13981
|
+
});
|
|
13982
|
+
}
|
|
13983
|
+
function isJSONStreamResponse(response) {
|
|
13984
|
+
const contentType = response.headers?.get?.("content-type")?.toLowerCase() ?? "";
|
|
13985
|
+
return contentType.includes("application/x-ndjson") || contentType.includes("application/ndjson");
|
|
13986
|
+
}
|
|
13987
|
+
function readJSONStream(response) {
|
|
13988
|
+
if (!response.body) {
|
|
13989
|
+
throw new TypeError("Cannot read a JSON stream response without a body");
|
|
13990
|
+
}
|
|
13991
|
+
const reader = response.body.getReader();
|
|
13992
|
+
const decoder = new TextDecoder();
|
|
13993
|
+
let buffer = "";
|
|
13994
|
+
let completed = false;
|
|
13995
|
+
let claimed = false;
|
|
13996
|
+
const iterator = {
|
|
13997
|
+
async next() {
|
|
13998
|
+
while (true) {
|
|
13999
|
+
const lineEnd = buffer.indexOf("\n");
|
|
14000
|
+
if (lineEnd >= 0) {
|
|
14001
|
+
const line = buffer.slice(0, lineEnd).trim();
|
|
14002
|
+
buffer = buffer.slice(lineEnd + 1);
|
|
14003
|
+
if (!line) continue;
|
|
14004
|
+
return { done: false, value: JSON.parse(line) };
|
|
14005
|
+
}
|
|
14006
|
+
if (completed) {
|
|
14007
|
+
const line = buffer.trim();
|
|
14008
|
+
buffer = "";
|
|
14009
|
+
if (!line) return { done: true, value: void 0 };
|
|
14010
|
+
return { done: false, value: JSON.parse(line) };
|
|
14011
|
+
}
|
|
14012
|
+
const chunk = await reader.read();
|
|
14013
|
+
completed = chunk.done;
|
|
14014
|
+
buffer += decoder.decode(chunk.value, { stream: !chunk.done });
|
|
14015
|
+
}
|
|
14016
|
+
},
|
|
14017
|
+
async return() {
|
|
14018
|
+
completed = true;
|
|
14019
|
+
buffer = "";
|
|
14020
|
+
await reader.cancel();
|
|
14021
|
+
return { done: true, value: void 0 };
|
|
14022
|
+
}
|
|
14023
|
+
};
|
|
14024
|
+
return {
|
|
14025
|
+
response,
|
|
14026
|
+
async cancel(reason) {
|
|
14027
|
+
completed = true;
|
|
14028
|
+
buffer = "";
|
|
14029
|
+
await reader.cancel(reason);
|
|
14030
|
+
},
|
|
14031
|
+
[Symbol.asyncIterator]() {
|
|
14032
|
+
if (claimed) {
|
|
14033
|
+
throw new TypeError("Farm API streams can only be consumed once");
|
|
14034
|
+
}
|
|
14035
|
+
claimed = true;
|
|
14036
|
+
return iterator;
|
|
14037
|
+
}
|
|
14038
|
+
};
|
|
14039
|
+
}
|
|
14040
|
+
function isFarmAPIStream(value) {
|
|
14041
|
+
return typeof value === "object" && value !== null && "response" in value && typeof value.cancel === "function" && typeof value[Symbol.asyncIterator] === "function";
|
|
14042
|
+
}
|
|
14043
|
+
function appendFormValue(formData, key, value) {
|
|
14044
|
+
if (value === void 0) return;
|
|
14045
|
+
if (value === null) {
|
|
14046
|
+
formData.append(key, "");
|
|
14047
|
+
return;
|
|
14048
|
+
}
|
|
14049
|
+
if (value instanceof Blob) {
|
|
14050
|
+
formData.append(key, value);
|
|
14051
|
+
return;
|
|
14052
|
+
}
|
|
14053
|
+
if (value instanceof Date) {
|
|
14054
|
+
formData.append(key, value.toISOString());
|
|
14055
|
+
return;
|
|
14056
|
+
}
|
|
14057
|
+
formData.append(key, String(value));
|
|
14058
|
+
}
|
|
14059
|
+
function isUnsafeFormKey(key) {
|
|
14060
|
+
return key === "__proto__" || key === "constructor" || key === "prototype";
|
|
14061
|
+
}
|
|
14062
|
+
function toAsyncIterator(source) {
|
|
14063
|
+
if (Symbol.asyncIterator in Object(source)) {
|
|
14064
|
+
return source[Symbol.asyncIterator]();
|
|
14065
|
+
}
|
|
14066
|
+
const iterator = source[Symbol.iterator]();
|
|
14067
|
+
return {
|
|
14068
|
+
next: /* @__PURE__ */ __name(async () => iterator.next(), "next"),
|
|
14069
|
+
return: iterator.return ? async (value) => iterator.return(value) : void 0
|
|
14070
|
+
};
|
|
14071
|
+
}
|
|
14072
|
+
var init_transport = __esm({
|
|
14073
|
+
"src/api/transport.ts"() {
|
|
14074
|
+
"use strict";
|
|
14075
|
+
__name(multipart, "multipart");
|
|
14076
|
+
__name(isMultipartSchema, "isMultipartSchema");
|
|
14077
|
+
__name(toFormData, "toFormData");
|
|
14078
|
+
__name(jsonStream, "jsonStream");
|
|
14079
|
+
__name(isJSONStreamResponse, "isJSONStreamResponse");
|
|
14080
|
+
__name(readJSONStream, "readJSONStream");
|
|
14081
|
+
__name(isFarmAPIStream, "isFarmAPIStream");
|
|
14082
|
+
__name(appendFormValue, "appendFormValue");
|
|
14083
|
+
__name(isUnsafeFormKey, "isUnsafeFormKey");
|
|
14084
|
+
__name(toAsyncIterator, "toAsyncIterator");
|
|
14085
|
+
}
|
|
14086
|
+
});
|
|
14087
|
+
|
|
13141
14088
|
// src/api/endpoint.ts
|
|
13142
14089
|
function isEndpointFailure(value) {
|
|
13143
14090
|
return value instanceof EndpointFailure;
|
|
@@ -13193,6 +14140,7 @@ function createEndpoint(pathOrOptions, optionsOrHandler, maybeHandler) {
|
|
|
13193
14140
|
endpoint2.__errors = errors;
|
|
13194
14141
|
endpoint2.__types = {
|
|
13195
14142
|
body: options.body,
|
|
14143
|
+
inputBody: isMultipartSchema(options.body) ? "form-data" : options.body,
|
|
13196
14144
|
query: options.query,
|
|
13197
14145
|
headers: options.headers,
|
|
13198
14146
|
response: null,
|
|
@@ -13303,34 +14251,10 @@ async function applyEndpointInvalidations(declaration, context, result) {
|
|
|
13303
14251
|
const targets = typeof declaration === "function" ? await declaration(context) : declaration;
|
|
13304
14252
|
if (!Array.isArray(targets)) {
|
|
13305
14253
|
throw new TypeError(
|
|
13306
|
-
"Endpoint invalidates must resolve to an array of { key } or {
|
|
14254
|
+
"Endpoint invalidates must resolve to an array of { key }, { path }, or { tag } targets"
|
|
13307
14255
|
);
|
|
13308
14256
|
}
|
|
13309
|
-
|
|
13310
|
-
for (const target of targets) {
|
|
13311
|
-
assertEndpointInvalidationTarget(target);
|
|
13312
|
-
if ("key" in target) {
|
|
13313
|
-
invalidate(target.key);
|
|
13314
|
-
clientKeys.push(createRouteDataCacheKey(target.key));
|
|
13315
|
-
} else {
|
|
13316
|
-
revalidatePath(target.path);
|
|
13317
|
-
}
|
|
13318
|
-
}
|
|
13319
|
-
return Array.from(new Set(clientKeys));
|
|
13320
|
-
}
|
|
13321
|
-
function assertEndpointInvalidationTarget(target) {
|
|
13322
|
-
if (!target || typeof target !== "object") {
|
|
13323
|
-
throw new TypeError("Endpoint invalidation targets must be { key } or { path } objects");
|
|
13324
|
-
}
|
|
13325
|
-
if ("key" in target) {
|
|
13326
|
-
const key = target.key;
|
|
13327
|
-
if (typeof key === "string" || Array.isArray(key)) return;
|
|
13328
|
-
} else if ("path" in target && typeof target.path === "string") {
|
|
13329
|
-
return;
|
|
13330
|
-
}
|
|
13331
|
-
throw new TypeError(
|
|
13332
|
-
"Endpoint invalidation targets must contain a string/array key or a path string"
|
|
13333
|
-
);
|
|
14257
|
+
return applyFarmCacheInvalidationTargets(targets);
|
|
13334
14258
|
}
|
|
13335
14259
|
function createInitialEndpointContext(value) {
|
|
13336
14260
|
if (value === void 0 || value === null) return EMPTY_ENDPOINT_CONTEXT;
|
|
@@ -13416,6 +14340,7 @@ var init_endpoint = __esm({
|
|
|
13416
14340
|
"use strict";
|
|
13417
14341
|
import_better_call = require("better-call");
|
|
13418
14342
|
init_cache();
|
|
14343
|
+
init_transport();
|
|
13419
14344
|
_EndpointFailure = class _EndpointFailure extends Error {
|
|
13420
14345
|
constructor(code, data, options) {
|
|
13421
14346
|
super(options.message);
|
|
@@ -13437,7 +14362,6 @@ var init_endpoint = __esm({
|
|
|
13437
14362
|
__name(normalizeEndpointMiddleware, "normalizeEndpointMiddleware");
|
|
13438
14363
|
__name(runEndpointMiddleware, "runEndpointMiddleware");
|
|
13439
14364
|
__name(applyEndpointInvalidations, "applyEndpointInvalidations");
|
|
13440
|
-
__name(assertEndpointInvalidationTarget, "assertEndpointInvalidationTarget");
|
|
13441
14365
|
__name(createInitialEndpointContext, "createInitialEndpointContext");
|
|
13442
14366
|
__name(mergeEndpointContext, "mergeEndpointContext");
|
|
13443
14367
|
__name(isPlainEndpointContext, "isPlainEndpointContext");
|
|
@@ -13495,7 +14419,7 @@ async function invokeAPIRouteEndpointInContext(endpoint2, request, params) {
|
|
|
13495
14419
|
});
|
|
13496
14420
|
let body = void 0;
|
|
13497
14421
|
if (request.method.toUpperCase() !== "GET" && request.method.toUpperCase() !== "HEAD") {
|
|
13498
|
-
body = await
|
|
14422
|
+
body = await readRequestBody2(request);
|
|
13499
14423
|
}
|
|
13500
14424
|
const headers2 = Object.fromEntries(request.headers.entries());
|
|
13501
14425
|
const types = endpoint2.__types || {};
|
|
@@ -13593,16 +14517,46 @@ function isFarmContextHandler(endpoint2) {
|
|
|
13593
14517
|
const firstParameter = (arrowMatch?.[1] || arrowMatch?.[2] || functionMatch?.[1] || "").split(",")[0].trim();
|
|
13594
14518
|
return firstParameter === "ctx" || firstParameter === "context" || firstParameter.startsWith("{");
|
|
13595
14519
|
}
|
|
13596
|
-
async function
|
|
14520
|
+
async function readRequestBody2(request) {
|
|
14521
|
+
const contentType = request.headers.get("content-type")?.split(";", 1)[0]?.trim().toLowerCase();
|
|
13597
14522
|
try {
|
|
14523
|
+
if (contentType === "multipart/form-data") {
|
|
14524
|
+
return formDataToObject(await request.clone().formData());
|
|
14525
|
+
}
|
|
13598
14526
|
const text2 = await request.clone().text();
|
|
13599
|
-
if (text2)
|
|
14527
|
+
if (!text2) return void 0;
|
|
14528
|
+
if (contentType === "application/x-www-form-urlencoded") {
|
|
14529
|
+
return searchParamsToObject2(new URLSearchParams(text2));
|
|
14530
|
+
}
|
|
14531
|
+
if (contentType === "application/json" || contentType?.endsWith("+json")) {
|
|
13600
14532
|
return JSON.parse(text2);
|
|
13601
14533
|
}
|
|
14534
|
+
return JSON.parse(text2);
|
|
13602
14535
|
} catch {
|
|
13603
14536
|
}
|
|
13604
14537
|
return void 0;
|
|
13605
14538
|
}
|
|
14539
|
+
function formDataToObject(formData) {
|
|
14540
|
+
return entriesToObject(formData.entries());
|
|
14541
|
+
}
|
|
14542
|
+
function searchParamsToObject2(searchParams) {
|
|
14543
|
+
return entriesToObject(searchParams.entries());
|
|
14544
|
+
}
|
|
14545
|
+
function entriesToObject(entries) {
|
|
14546
|
+
const output = /* @__PURE__ */ Object.create(null);
|
|
14547
|
+
for (const [key, value] of entries) {
|
|
14548
|
+
if (key === "__proto__" || key === "constructor" || key === "prototype") continue;
|
|
14549
|
+
const current = output[key];
|
|
14550
|
+
if (current === void 0) {
|
|
14551
|
+
output[key] = value;
|
|
14552
|
+
} else if (Array.isArray(current)) {
|
|
14553
|
+
current.push(value);
|
|
14554
|
+
} else {
|
|
14555
|
+
output[key] = [current, value];
|
|
14556
|
+
}
|
|
14557
|
+
}
|
|
14558
|
+
return output;
|
|
14559
|
+
}
|
|
13606
14560
|
function validateInput(schema, value, error) {
|
|
13607
14561
|
if (!schema || typeof schema.parse !== "function") {
|
|
13608
14562
|
return value;
|
|
@@ -13701,7 +14655,10 @@ var init_runtime2 = __esm({
|
|
|
13701
14655
|
__name(attachEndpointInvalidations, "attachEndpointInvalidations");
|
|
13702
14656
|
__name(createEndpointFailureResponse, "createEndpointFailureResponse");
|
|
13703
14657
|
__name(isFarmContextHandler, "isFarmContextHandler");
|
|
13704
|
-
__name(
|
|
14658
|
+
__name(readRequestBody2, "readRequestBody");
|
|
14659
|
+
__name(formDataToObject, "formDataToObject");
|
|
14660
|
+
__name(searchParamsToObject2, "searchParamsToObject");
|
|
14661
|
+
__name(entriesToObject, "entriesToObject");
|
|
13705
14662
|
__name(validateInput, "validateInput");
|
|
13706
14663
|
__name(matchRoutePath, "matchRoutePath");
|
|
13707
14664
|
__name(getPathSegments, "getPathSegments");
|
|
@@ -15034,6 +15991,7 @@ async function generateRouteTypes(options) {
|
|
|
15034
15991
|
absolute: false
|
|
15035
15992
|
});
|
|
15036
15993
|
for (const file of pageFiles) {
|
|
15994
|
+
if (parseRouteSlotFile(file)) continue;
|
|
15037
15995
|
const route2 = parseRoutePath(file);
|
|
15038
15996
|
if (route2.type === "page") {
|
|
15039
15997
|
const pattern = createRoutePattern(route2);
|
|
@@ -15099,6 +16057,7 @@ var init_generate_route_types = __esm({
|
|
|
15099
16057
|
path12 = __toESM(require("path"));
|
|
15100
16058
|
fs5 = __toESM(require("fs"));
|
|
15101
16059
|
init_utils();
|
|
16060
|
+
init_route_slots();
|
|
15102
16061
|
init_routes_server();
|
|
15103
16062
|
init_write_file_if_changed();
|
|
15104
16063
|
__name(routeSegmentsToTsTypeLiteral, "routeSegmentsToTsTypeLiteral");
|
|
@@ -15816,7 +16775,7 @@ var init_environment_vite = __esm({
|
|
|
15816
16775
|
var version;
|
|
15817
16776
|
var init_package = __esm({
|
|
15818
16777
|
"package.json"() {
|
|
15819
|
-
version = "0.1.0-beta.
|
|
16778
|
+
version = "0.1.0-beta.4";
|
|
15820
16779
|
}
|
|
15821
16780
|
});
|
|
15822
16781
|
|
|
@@ -20003,6 +20962,7 @@ async function resolveConfig(userConfig, mode) {
|
|
|
20003
20962
|
observability: userConfig.observability ?? false,
|
|
20004
20963
|
devtools: resolveFarmDevtoolsConfig(userConfig.devtools, mode),
|
|
20005
20964
|
storage: userConfig.storage || {},
|
|
20965
|
+
cache: userConfig.cache || {},
|
|
20006
20966
|
suppressLintOnLink: userConfig.suppressLintOnLink ?? false,
|
|
20007
20967
|
experimental: {
|
|
20008
20968
|
serverComponents: false,
|
|
@@ -23644,7 +24604,7 @@ function farmPlugin(options = {}, initialPluginManager) {
|
|
|
23644
24604
|
}, "isProgrammaticRouteSourceFile");
|
|
23645
24605
|
const isAppRuntimeFile = /* @__PURE__ */ __name((file) => {
|
|
23646
24606
|
const normalized = file.replace(/\\/g, "/");
|
|
23647
|
-
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(
|
|
24607
|
+
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(
|
|
23648
24608
|
normalized
|
|
23649
24609
|
);
|
|
23650
24610
|
}, "isAppRuntimeFile");
|
|
@@ -24335,7 +25295,10 @@ function farmPlugin(options = {}, initialPluginManager) {
|
|
|
24335
25295
|
method: req.method || "GET"
|
|
24336
25296
|
});
|
|
24337
25297
|
}
|
|
24338
|
-
const
|
|
25298
|
+
const interceptFromHeader = request.headers.get("x-farm-intercept-from") || void 0;
|
|
25299
|
+
const match = routeManager3.matchRoute(targetRequestUrl.pathname, {
|
|
25300
|
+
interceptFrom: interceptFromHeader
|
|
25301
|
+
});
|
|
24339
25302
|
if (pm) {
|
|
24340
25303
|
await pm.runHookParallel("afterRouteMatch", {
|
|
24341
25304
|
pathname: targetPath,
|
|
@@ -24351,7 +25314,7 @@ function farmPlugin(options = {}, initialPluginManager) {
|
|
|
24351
25314
|
res.end(JSON.stringify({ error: "Route not found" }));
|
|
24352
25315
|
return;
|
|
24353
25316
|
}
|
|
24354
|
-
const { route: route2, params, layouts } = match;
|
|
25317
|
+
const { route: route2, params, layouts, slots } = match;
|
|
24355
25318
|
if (!route2) {
|
|
24356
25319
|
res.statusCode = 404;
|
|
24357
25320
|
res.setHeader("Content-Type", "application/json");
|
|
@@ -24406,6 +25369,54 @@ function farmPlugin(options = {}, initialPluginManager) {
|
|
|
24406
25369
|
search: searchParams,
|
|
24407
25370
|
routePath: route2.pattern
|
|
24408
25371
|
});
|
|
25372
|
+
const routeSlots = await Promise.all(
|
|
25373
|
+
slots.map(async (slot) => {
|
|
25374
|
+
const slotModule = await routeManager3.loadRouteModule(slot.route.modulePath);
|
|
25375
|
+
const slotMetadata = getClientModuleMetadata(
|
|
25376
|
+
slot.route.modulePath,
|
|
25377
|
+
server.config.root
|
|
25378
|
+
);
|
|
25379
|
+
const slotContext = await resolveFarmRouteContext(farmApp.getConfig(), {
|
|
25380
|
+
request,
|
|
25381
|
+
params: slot.params,
|
|
25382
|
+
search: searchParams,
|
|
25383
|
+
path: targetUrl.pathname
|
|
25384
|
+
});
|
|
25385
|
+
const slotProps = await parseRouteModuleProps2(slotModule, {
|
|
25386
|
+
props: withFarmRouteContext(
|
|
25387
|
+
{
|
|
25388
|
+
params: slot.params,
|
|
25389
|
+
searchParams: Promise.resolve(searchParams),
|
|
25390
|
+
path: targetUrl.pathname
|
|
25391
|
+
},
|
|
25392
|
+
slotContext
|
|
25393
|
+
),
|
|
25394
|
+
search: searchParams,
|
|
25395
|
+
routePath: slot.route.pattern
|
|
25396
|
+
});
|
|
25397
|
+
return {
|
|
25398
|
+
name: slot.name,
|
|
25399
|
+
ownerPattern: slot.ownerPattern,
|
|
25400
|
+
containerId: slot.containerId,
|
|
25401
|
+
interception: slot.interception,
|
|
25402
|
+
fallback: slot.fallback,
|
|
25403
|
+
modulePath: slot.route.modulePath,
|
|
25404
|
+
isClientComponent: slotMetadata.isClientComponent,
|
|
25405
|
+
shouldHydrate: slotMetadata.shouldHydrate,
|
|
25406
|
+
props: {
|
|
25407
|
+
params: slotProps.params,
|
|
25408
|
+
search: slotProps.search,
|
|
25409
|
+
searchParams: slotProps.search,
|
|
25410
|
+
..."data" in slotProps ? { data: slotProps.data } : {},
|
|
25411
|
+
...slotProps.__farmCanonicalPath ? {
|
|
25412
|
+
__farmCanonicalPath: slotProps.__farmCanonicalPath
|
|
25413
|
+
} : {},
|
|
25414
|
+
...slotProps.__farmRoutePropsResolved ? { __farmRoutePropsResolved: true } : {},
|
|
25415
|
+
path: targetUrl.pathname
|
|
25416
|
+
}
|
|
25417
|
+
};
|
|
25418
|
+
})
|
|
25419
|
+
);
|
|
24409
25420
|
const projectRoot = server.config.root;
|
|
24410
25421
|
const toUrlPath = /* @__PURE__ */ __name((absolutePath) => {
|
|
24411
25422
|
if (absolutePath.startsWith(projectRoot)) {
|
|
@@ -24426,13 +25437,21 @@ function farmPlugin(options = {}, initialPluginManager) {
|
|
|
24426
25437
|
},
|
|
24427
25438
|
canonicalPath: routeProps.__farmCanonicalPath,
|
|
24428
25439
|
modulePath: toUrlPath(route2.modulePath),
|
|
24429
|
-
isClientComponent,
|
|
24430
|
-
shouldHydrate,
|
|
25440
|
+
isClientComponent: routeSlots.length > 0 ? false : isClientComponent,
|
|
25441
|
+
shouldHydrate: shouldHydrate || routeSlots.some((slot) => slot.isClientComponent || slot.shouldHydrate),
|
|
24431
25442
|
metadata: {
|
|
24432
25443
|
title: mergedMetadata.title,
|
|
24433
25444
|
description: mergedMetadata.description
|
|
24434
25445
|
},
|
|
24435
25446
|
layoutModules: layouts.map((l) => toUrlPath(l.modulePath)),
|
|
25447
|
+
routeSlots: routeSlots.map((slot) => ({
|
|
25448
|
+
...slot,
|
|
25449
|
+
modulePath: toUrlPath(slot.modulePath)
|
|
25450
|
+
})),
|
|
25451
|
+
interception: routeSlots.some((slot) => slot.interception) ? {
|
|
25452
|
+
from: interceptFromHeader,
|
|
25453
|
+
slots: routeSlots.filter((slot) => slot.interception).map((slot) => slot.name)
|
|
25454
|
+
} : void 0,
|
|
24436
25455
|
i18n: getFarmI18nClientSnapshot()
|
|
24437
25456
|
};
|
|
24438
25457
|
await sendWebResponse(
|
|
@@ -24768,6 +25787,7 @@ function farmPlugin(options = {}, initialPluginManager) {
|
|
|
24768
25787
|
export const getManifest = () => ({
|
|
24769
25788
|
routes: {},
|
|
24770
25789
|
layouts: {},
|
|
25790
|
+
slots: [],
|
|
24771
25791
|
clientEntry: "/@farm/client.js",
|
|
24772
25792
|
sharedAssets: []
|
|
24773
25793
|
});
|
|
@@ -24778,6 +25798,7 @@ export const getManifest = () => ({
|
|
|
24778
25798
|
clientEntry: "/@farm/client.js",
|
|
24779
25799
|
routes: {},
|
|
24780
25800
|
layouts: {},
|
|
25801
|
+
slots: [],
|
|
24781
25802
|
sharedAssets: [
|
|
24782
25803
|
{
|
|
24783
25804
|
tag: "link",
|
|
@@ -24807,6 +25828,13 @@ export const getManifest = () => ({
|
|
|
24807
25828
|
assets: []
|
|
24808
25829
|
};
|
|
24809
25830
|
}
|
|
25831
|
+
for (const slot of manifest.slots) {
|
|
25832
|
+
fullManifest.slots.push({
|
|
25833
|
+
...slot,
|
|
25834
|
+
preloads: [slot.modulePath],
|
|
25835
|
+
assets: []
|
|
25836
|
+
});
|
|
25837
|
+
}
|
|
24810
25838
|
return `
|
|
24811
25839
|
// Auto-generated manifest for SPA navigation (TanStack Start pattern)
|
|
24812
25840
|
// This manifest is inlined in the server bundle - no file on disk
|
|
@@ -25443,7 +26471,7 @@ window.__FARM_WRAP_PROVIDERS__ = wrapWithIntegrationProviders;
|
|
|
25443
26471
|
|
|
25444
26472
|
// Get manifest from window (inlined by server in HTML)
|
|
25445
26473
|
// Fallback to empty manifest if not available yet
|
|
25446
|
-
const getManifest = () => window.__FARM_MANIFEST__ || { routes: {}, layouts: {}, clientEntry: '', sharedAssets: [] };
|
|
26474
|
+
const getManifest = () => window.__FARM_MANIFEST__ || { routes: {}, layouts: {}, slots: [], clientEntry: '', sharedAssets: [] };
|
|
25447
26475
|
|
|
25448
26476
|
// ====== CLIENT-SIDE ROUTE MATCHING ======
|
|
25449
26477
|
// Matches URL to route using manifest (no server request!)
|
|
@@ -25782,6 +26810,9 @@ let LayoutComponent = null;
|
|
|
25782
26810
|
|
|
25783
26811
|
// Track if we've taken over rendering from SSR
|
|
25784
26812
|
let hasClientTakenOver = false;
|
|
26813
|
+
const routeSlotRoots = new Map();
|
|
26814
|
+
const routeSlotDefinitions = new Map();
|
|
26815
|
+
let activeRouteInterception = null;
|
|
25785
26816
|
|
|
25786
26817
|
function normalizeServerProps(rawProps) {
|
|
25787
26818
|
const props = rawProps && typeof rawProps === 'object' ? { ...rawProps } : {};
|
|
@@ -25794,6 +26825,123 @@ function normalizeServerProps(rawProps) {
|
|
|
25794
26825
|
return props;
|
|
25795
26826
|
}
|
|
25796
26827
|
|
|
26828
|
+
function getRouteSlotKey(slot) {
|
|
26829
|
+
return slot.ownerPattern + ':' + slot.name;
|
|
26830
|
+
}
|
|
26831
|
+
|
|
26832
|
+
async function renderRouteSlot(slot, mode = 'render') {
|
|
26833
|
+
const container = document.getElementById(slot.containerId);
|
|
26834
|
+
if (!container || !slot.modulePath) return false;
|
|
26835
|
+
if (mode === 'intercept' && !slot.isClientComponent && !slot.shouldHydrate) {
|
|
26836
|
+
return false;
|
|
26837
|
+
}
|
|
26838
|
+
|
|
26839
|
+
let slotModule = pageModuleCache.get(slot.modulePath);
|
|
26840
|
+
if (!slotModule) {
|
|
26841
|
+
slotModule = await import(/* @vite-ignore */ slot.modulePath);
|
|
26842
|
+
pageModuleCache.set(slot.modulePath, slotModule);
|
|
26843
|
+
}
|
|
26844
|
+
const SlotComponent = slotModule?.default;
|
|
26845
|
+
if (!SlotComponent) return false;
|
|
26846
|
+
|
|
26847
|
+
const props = reviveDeferredData(
|
|
26848
|
+
normalizeServerProps(slot.props || {}),
|
|
26849
|
+
window.__FARM_DEFERRED_DATA__ || {},
|
|
26850
|
+
);
|
|
26851
|
+
const element = wrapWithIntegrationProviders(
|
|
26852
|
+
React.createElement(SlotComponent, props),
|
|
26853
|
+
);
|
|
26854
|
+
const key = getRouteSlotKey(slot);
|
|
26855
|
+
const existingRoot = routeSlotRoots.get(key);
|
|
26856
|
+
|
|
26857
|
+
if (mode === 'hydrate') {
|
|
26858
|
+
if (existingRoot) return true;
|
|
26859
|
+
const root = hydrateRoot(container, element);
|
|
26860
|
+
routeSlotRoots.set(key, root);
|
|
26861
|
+
} else {
|
|
26862
|
+
if (existingRoot) {
|
|
26863
|
+
try { existingRoot.unmount(); } catch (error) {}
|
|
26864
|
+
}
|
|
26865
|
+
const root = createRoot(container);
|
|
26866
|
+
root.render(element);
|
|
26867
|
+
routeSlotRoots.set(key, root);
|
|
26868
|
+
}
|
|
26869
|
+
|
|
26870
|
+
routeSlotDefinitions.set(key, slot);
|
|
26871
|
+
return true;
|
|
26872
|
+
}
|
|
26873
|
+
|
|
26874
|
+
async function hydrateInitialRouteSlots() {
|
|
26875
|
+
const slots = Array.isArray(window.__FARM_ROUTE_SLOTS__)
|
|
26876
|
+
? window.__FARM_ROUTE_SLOTS__
|
|
26877
|
+
: [];
|
|
26878
|
+
let hydrated = false;
|
|
26879
|
+
|
|
26880
|
+
for (const slot of slots) {
|
|
26881
|
+
routeSlotDefinitions.set(getRouteSlotKey(slot), slot);
|
|
26882
|
+
if (!slot.isClientComponent && !slot.shouldHydrate) continue;
|
|
26883
|
+
try {
|
|
26884
|
+
hydrated = (await renderRouteSlot(slot, 'hydrate')) || hydrated;
|
|
26885
|
+
} catch (error) {
|
|
26886
|
+
console.warn('[Farm.js] Could not hydrate route slot:', slot.name, error);
|
|
26887
|
+
}
|
|
26888
|
+
}
|
|
26889
|
+
|
|
26890
|
+
return hydrated;
|
|
26891
|
+
}
|
|
26892
|
+
|
|
26893
|
+
async function renderRouteInterception(pageData) {
|
|
26894
|
+
const slots = Array.isArray(pageData.routeSlots)
|
|
26895
|
+
? pageData.routeSlots.filter((slot) => slot.interception)
|
|
26896
|
+
: [];
|
|
26897
|
+
if (!pageData.interception || slots.length === 0) return false;
|
|
26898
|
+
|
|
26899
|
+
const previous = new Map();
|
|
26900
|
+
for (const slot of slots) {
|
|
26901
|
+
const key = getRouteSlotKey(slot);
|
|
26902
|
+
previous.set(key, routeSlotDefinitions.get(key) || null);
|
|
26903
|
+
if (!(await renderRouteSlot(slot, 'intercept'))) {
|
|
26904
|
+
return false;
|
|
26905
|
+
}
|
|
26906
|
+
}
|
|
26907
|
+
|
|
26908
|
+
activeRouteInterception = {
|
|
26909
|
+
from: pageData.interception.from,
|
|
26910
|
+
slots,
|
|
26911
|
+
previous,
|
|
26912
|
+
};
|
|
26913
|
+
return true;
|
|
26914
|
+
}
|
|
26915
|
+
|
|
26916
|
+
async function clearRouteInterception(destination) {
|
|
26917
|
+
if (!activeRouteInterception) return false;
|
|
26918
|
+
const active = activeRouteInterception;
|
|
26919
|
+
activeRouteInterception = null;
|
|
26920
|
+
|
|
26921
|
+
for (const slot of active.slots) {
|
|
26922
|
+
const key = getRouteSlotKey(slot);
|
|
26923
|
+
const root = routeSlotRoots.get(key);
|
|
26924
|
+
if (root) {
|
|
26925
|
+
try { root.unmount(); } catch (error) {}
|
|
26926
|
+
routeSlotRoots.delete(key);
|
|
26927
|
+
}
|
|
26928
|
+
|
|
26929
|
+
const previous = active.previous.get(key);
|
|
26930
|
+
if (previous && (previous.isClientComponent || previous.shouldHydrate)) {
|
|
26931
|
+
await renderRouteSlot(previous, 'render');
|
|
26932
|
+
} else {
|
|
26933
|
+
const container = document.getElementById(slot.containerId);
|
|
26934
|
+
if (container) container.replaceChildren();
|
|
26935
|
+
if (previous) routeSlotDefinitions.set(key, previous);
|
|
26936
|
+
else routeSlotDefinitions.delete(key);
|
|
26937
|
+
}
|
|
26938
|
+
}
|
|
26939
|
+
|
|
26940
|
+
if (!active.from) return false;
|
|
26941
|
+
const background = new URL(active.from, window.location.origin);
|
|
26942
|
+
return destination === background.pathname + background.search;
|
|
26943
|
+
}
|
|
26944
|
+
|
|
25797
26945
|
function applyCanonicalPathFromProps(props) {
|
|
25798
26946
|
const canonicalPath = props && typeof props.__farmCanonicalPath === 'string'
|
|
25799
26947
|
? props.__farmCanonicalPath
|
|
@@ -26028,6 +27176,17 @@ async function tryHydrateImportedPage(
|
|
|
26028
27176
|
async function renderPage(pageData) {
|
|
26029
27177
|
const container = document.getElementById('root');
|
|
26030
27178
|
if (!container) return;
|
|
27179
|
+
const destination = window.location.pathname + window.location.search;
|
|
27180
|
+
|
|
27181
|
+
if (pageData.interception) {
|
|
27182
|
+
if (await renderRouteInterception(pageData)) return;
|
|
27183
|
+
window.location.assign(destination);
|
|
27184
|
+
return;
|
|
27185
|
+
}
|
|
27186
|
+
|
|
27187
|
+
if (await clearRouteInterception(destination)) {
|
|
27188
|
+
return;
|
|
27189
|
+
}
|
|
26031
27190
|
|
|
26032
27191
|
const route = {
|
|
26033
27192
|
modulePath: pageData.modulePath,
|
|
@@ -26256,7 +27415,9 @@ async function hydrate() {
|
|
|
26256
27415
|
window.__FARM_SHOULD_HYDRATE__ === true ||
|
|
26257
27416
|
isClientComponent ||
|
|
26258
27417
|
await moduleLooksClient(modulePath);
|
|
27418
|
+
const hydratedSlots = await hydrateInitialRouteSlots();
|
|
26259
27419
|
if (!shouldHydrate) {
|
|
27420
|
+
if (hydratedSlots) replayPreHydrationClicks();
|
|
26260
27421
|
console.log('[Farm.js] Server component - SPA router ready')
|
|
26261
27422
|
return
|
|
26262
27423
|
}
|
|
@@ -28023,6 +29184,7 @@ __export(src_exports, {
|
|
|
28023
29184
|
DeferredDataError: () => DeferredDataError,
|
|
28024
29185
|
DocsRoute: () => DocsRoute,
|
|
28025
29186
|
EndpointFailure: () => EndpointFailure,
|
|
29187
|
+
FARM_API_ROUTE_META_SYMBOL: () => FARM_API_ROUTE_META_SYMBOL,
|
|
28026
29188
|
FARM_API_ROUTE_REF_SYMBOL: () => FARM_API_ROUTE_REF_SYMBOL,
|
|
28027
29189
|
FARM_CRON_MANIFEST: () => FARM_CRON_MANIFEST,
|
|
28028
29190
|
FARM_DEFERRED_BRAND: () => FARM_DEFERRED_BRAND,
|
|
@@ -28067,6 +29229,7 @@ __export(src_exports, {
|
|
|
28067
29229
|
_withAfterNodeMiddleware: () => _withAfterNodeMiddleware,
|
|
28068
29230
|
after: () => after,
|
|
28069
29231
|
api: () => api,
|
|
29232
|
+
applyFarmCacheInvalidationTargets: () => applyFarmCacheInvalidationTargets,
|
|
28070
29233
|
applyFarmCacheInvalidations: () => applyFarmCacheInvalidations,
|
|
28071
29234
|
applyFarmCronVercelCrons: () => applyFarmCronVercelCrons,
|
|
28072
29235
|
applyFarmWorkflowVercelCrons: () => applyFarmWorkflowVercelCrons,
|
|
@@ -28084,6 +29247,7 @@ __export(src_exports, {
|
|
|
28084
29247
|
buildFarmRoutePath: () => buildFarmRoutePath,
|
|
28085
29248
|
collectSSGPages: () => collectSSGPages,
|
|
28086
29249
|
completeFarmServerQueryAction: () => completeFarmServerQueryAction,
|
|
29250
|
+
configureFarmCache: () => configureFarmCache,
|
|
28087
29251
|
configureFarmObservability: () => configureFarmObservability,
|
|
28088
29252
|
cookies: () => cookies,
|
|
28089
29253
|
createAPIClient: () => createAPIClient,
|
|
@@ -28183,6 +29347,7 @@ __export(src_exports, {
|
|
|
28183
29347
|
generateFarmTypeArtifacts: () => generateFarmTypeArtifacts,
|
|
28184
29348
|
generateRouteTypes: () => generateRouteTypes,
|
|
28185
29349
|
generateSSGManifest: () => generateSSGManifest,
|
|
29350
|
+
getAPIRouteRefMetadata: () => getAPIRouteRefMetadata,
|
|
28186
29351
|
getCurrentRequest: () => getCurrentRequest,
|
|
28187
29352
|
getDeployTargetForPreset: () => getDeployTargetForPreset,
|
|
28188
29353
|
getEnv: () => getEnv,
|
|
@@ -28242,6 +29407,7 @@ __export(src_exports, {
|
|
|
28242
29407
|
isCronRequestAuthorized: () => isCronRequestAuthorized,
|
|
28243
29408
|
isDeferred: () => isDeferred,
|
|
28244
29409
|
isEndpointFailure: () => isEndpointFailure,
|
|
29410
|
+
isFarmAPIStream: () => isFarmAPIStream,
|
|
28245
29411
|
isFarmDeploymentMismatchResponse: () => isFarmDeploymentMismatchResponse,
|
|
28246
29412
|
isFarmDocsAPIRequest: () => isFarmDocsAPIRequest,
|
|
28247
29413
|
isFarmDocsRequest: () => isFarmDocsRequest,
|
|
@@ -28250,10 +29416,13 @@ __export(src_exports, {
|
|
|
28250
29416
|
isFarmNotFoundError: () => isFarmNotFoundError,
|
|
28251
29417
|
isFarmRedirectError: () => isFarmRedirectError,
|
|
28252
29418
|
isFarmRouteActive: () => isFarmRouteActive,
|
|
29419
|
+
isJSONStreamResponse: () => isJSONStreamResponse,
|
|
29420
|
+
isMultipartSchema: () => isMultipartSchema,
|
|
28253
29421
|
isProgrammaticRouteManifest: () => isProgrammaticRouteManifest,
|
|
28254
29422
|
isProgrammaticRoutesFileName: () => isProgrammaticRoutesFileName,
|
|
28255
29423
|
isSSGModule: () => isSSGModule,
|
|
28256
29424
|
isWebResponse: () => isWebResponse2,
|
|
29425
|
+
jsonStream: () => jsonStream,
|
|
28257
29426
|
layout: () => layout,
|
|
28258
29427
|
libsqlStorage: () => libsqlStorage,
|
|
28259
29428
|
loadConfig: () => loadConfig,
|
|
@@ -28273,6 +29442,7 @@ __export(src_exports, {
|
|
|
28273
29442
|
mergeScheduledTasks: () => mergeScheduledTasks,
|
|
28274
29443
|
middleware: () => middleware,
|
|
28275
29444
|
mongodbStorage: () => mongodbStorage,
|
|
29445
|
+
multipart: () => multipart,
|
|
28276
29446
|
mysql2Storage: () => mysql2Storage,
|
|
28277
29447
|
mysqlStorage: () => mysqlStorage,
|
|
28278
29448
|
navigateTo: () => navigateTo,
|
|
@@ -28309,6 +29479,7 @@ __export(src_exports, {
|
|
|
28309
29479
|
publicEnv: () => publicEnv,
|
|
28310
29480
|
pushState: () => pushState,
|
|
28311
29481
|
readDeferredDataResponse: () => readDeferredDataResponse,
|
|
29482
|
+
readJSONStream: () => readJSONStream,
|
|
28312
29483
|
readPageState: () => readPageState,
|
|
28313
29484
|
redirect: () => redirect2,
|
|
28314
29485
|
redisStorage: () => redisStorage,
|
|
@@ -28353,13 +29524,16 @@ __export(src_exports, {
|
|
|
28353
29524
|
setEnv: () => setEnv,
|
|
28354
29525
|
snapshotDeferredData: () => snapshotDeferredData,
|
|
28355
29526
|
sqliteStorage: () => sqliteStorage,
|
|
29527
|
+
storageCacheAdapter: () => storageCacheAdapter,
|
|
28356
29528
|
titleFromMarkdown: () => titleFromMarkdown,
|
|
29529
|
+
toFormData: () => toFormData,
|
|
28357
29530
|
toViteModuleId: () => toViteModuleId,
|
|
28358
29531
|
unstable_cache: () => unstable_cache,
|
|
28359
29532
|
unwrapMiddleware: () => unwrapMiddleware,
|
|
28360
29533
|
updateTag: () => updateTag,
|
|
28361
29534
|
upstashStorage: () => upstashStorage,
|
|
28362
29535
|
useBlocker: () => useBlocker,
|
|
29536
|
+
useFetcher: () => useFetcher,
|
|
28363
29537
|
useMutation: () => useMutation,
|
|
28364
29538
|
useNavigation: () => useNavigation,
|
|
28365
29539
|
usePageState: () => usePageState,
|
|
@@ -29540,7 +30714,9 @@ __name(normalizeFarmClientCacheKey, "normalizeFarmClientCacheKey");
|
|
|
29540
30714
|
|
|
29541
30715
|
// src/api/client.ts
|
|
29542
30716
|
init_cache_invalidation();
|
|
30717
|
+
init_transport();
|
|
29543
30718
|
var FARM_API_ROUTE_REF_SYMBOL = /* @__PURE__ */ Symbol.for("farm.api.route-ref");
|
|
30719
|
+
var FARM_API_ROUTE_META_SYMBOL = /* @__PURE__ */ Symbol.for("farm.api.route-meta");
|
|
29544
30720
|
var _APIClientError = class _APIClientError extends Error {
|
|
29545
30721
|
constructor(code, data, options) {
|
|
29546
30722
|
super(options.message);
|
|
@@ -29578,16 +30754,22 @@ function createAPIClient(options = {}) {
|
|
|
29578
30754
|
}
|
|
29579
30755
|
});
|
|
29580
30756
|
}
|
|
30757
|
+
const headers2 = {
|
|
30758
|
+
"Content-Type": "application/json",
|
|
30759
|
+
...options.headers,
|
|
30760
|
+
...requestOptions.headers
|
|
30761
|
+
};
|
|
29581
30762
|
const fetchOptions = {
|
|
29582
30763
|
method: requestOptions.method || "GET",
|
|
29583
|
-
headers:
|
|
29584
|
-
"Content-Type": "application/json",
|
|
29585
|
-
...options.headers,
|
|
29586
|
-
...requestOptions.headers
|
|
29587
|
-
}
|
|
30764
|
+
headers: headers2
|
|
29588
30765
|
};
|
|
29589
|
-
if (requestOptions.body) {
|
|
29590
|
-
|
|
30766
|
+
if (requestOptions.body !== void 0) {
|
|
30767
|
+
if (isFormData(requestOptions.body)) {
|
|
30768
|
+
deleteHeader(headers2, "content-type");
|
|
30769
|
+
fetchOptions.body = requestOptions.body;
|
|
30770
|
+
} else {
|
|
30771
|
+
fetchOptions.body = JSON.stringify(requestOptions.body);
|
|
30772
|
+
}
|
|
29591
30773
|
}
|
|
29592
30774
|
const response = await fetch(url.toString(), fetchOptions);
|
|
29593
30775
|
applyFarmCacheInvalidations(
|
|
@@ -29595,7 +30777,7 @@ function createAPIClient(options = {}) {
|
|
|
29595
30777
|
);
|
|
29596
30778
|
let data = void 0;
|
|
29597
30779
|
if (response.status !== 204 && response.status !== 205) {
|
|
29598
|
-
data = await response.json();
|
|
30780
|
+
data = isJSONStreamResponse(response) ? readJSONStream(response) : await response.json();
|
|
29599
30781
|
}
|
|
29600
30782
|
return { response, data };
|
|
29601
30783
|
}, "fetchClient");
|
|
@@ -29741,16 +30923,16 @@ function createAPIClient(options = {}) {
|
|
|
29741
30923
|
}
|
|
29742
30924
|
}
|
|
29743
30925
|
attempt += 1;
|
|
29744
|
-
const
|
|
29745
|
-
if (
|
|
29746
|
-
await new Promise((resolve5) => setTimeout(resolve5,
|
|
30926
|
+
const delay2 = typeof clientOptions?.retry?.delay === "function" ? clientOptions.retry.delay(attempt) : clientOptions?.retry?.delay ?? 0;
|
|
30927
|
+
if (delay2 > 0) {
|
|
30928
|
+
await new Promise((resolve5) => setTimeout(resolve5, delay2));
|
|
29747
30929
|
}
|
|
29748
30930
|
}
|
|
29749
30931
|
})();
|
|
29750
30932
|
inflightState.set(cacheKey, { promise, startedAt: now2 });
|
|
29751
30933
|
try {
|
|
29752
30934
|
const result2 = await promise;
|
|
29753
|
-
if (!result2.error && isCacheEnabled) {
|
|
30935
|
+
if (!result2.error && isCacheEnabled && !isFarmAPIStream(result2.data)) {
|
|
29754
30936
|
const updatedAt = Date.now();
|
|
29755
30937
|
cacheState.set(cacheKey, {
|
|
29756
30938
|
data: result2.data,
|
|
@@ -29823,10 +31005,17 @@ function createAPIClient(options = {}) {
|
|
|
29823
31005
|
clientOptions?.onSettled?.(result.data, result.error);
|
|
29824
31006
|
return result;
|
|
29825
31007
|
}, "request");
|
|
29826
|
-
return createNestedProxy(
|
|
31008
|
+
return createNestedProxy(
|
|
31009
|
+
[],
|
|
31010
|
+
request,
|
|
31011
|
+
routeMeta,
|
|
31012
|
+
baseURL,
|
|
31013
|
+
options.baseURL === void 0,
|
|
31014
|
+
rootAliases
|
|
31015
|
+
);
|
|
29827
31016
|
}
|
|
29828
31017
|
__name(createAPIClient, "createAPIClient");
|
|
29829
|
-
function createNestedProxy(path28, client, routeMeta, baseURL, rootAliases) {
|
|
31018
|
+
function createNestedProxy(path28, client, routeMeta, baseURL, sameOrigin, rootAliases) {
|
|
29830
31019
|
const target = /* @__PURE__ */ __name(() => {
|
|
29831
31020
|
}, "target");
|
|
29832
31021
|
const proxy = new Proxy(target, {
|
|
@@ -29835,13 +31024,29 @@ function createNestedProxy(path28, client, routeMeta, baseURL, rootAliases) {
|
|
|
29835
31024
|
if (prop === FARM_API_ROUTE_REF_SYMBOL) {
|
|
29836
31025
|
return path28.length > 0;
|
|
29837
31026
|
}
|
|
31027
|
+
if (prop === FARM_API_ROUTE_META_SYMBOL) {
|
|
31028
|
+
const metadata = resolveRouteMeta({ path: path28, baseURL });
|
|
31029
|
+
return Object.freeze({
|
|
31030
|
+
path: metadata.routePath,
|
|
31031
|
+
method: metadata.method,
|
|
31032
|
+
baseURL,
|
|
31033
|
+
sameOrigin
|
|
31034
|
+
});
|
|
31035
|
+
}
|
|
29838
31036
|
if (path28.length === 0 && typeof prop === "string" && rootAliases && prop in rootAliases) {
|
|
29839
31037
|
return rootAliases[prop];
|
|
29840
31038
|
}
|
|
29841
31039
|
if (typeof prop !== "string") {
|
|
29842
31040
|
return Reflect.get(_target, prop);
|
|
29843
31041
|
}
|
|
29844
|
-
return createNestedProxy(
|
|
31042
|
+
return createNestedProxy(
|
|
31043
|
+
[...path28, prop],
|
|
31044
|
+
client,
|
|
31045
|
+
routeMeta,
|
|
31046
|
+
baseURL,
|
|
31047
|
+
sameOrigin,
|
|
31048
|
+
rootAliases
|
|
31049
|
+
);
|
|
29845
31050
|
},
|
|
29846
31051
|
// When calling as a function
|
|
29847
31052
|
apply(_target, _thisArg, args) {
|
|
@@ -29867,6 +31072,22 @@ function isAPIRouteRef(value) {
|
|
|
29867
31072
|
return typeof value === "function" && value[FARM_API_ROUTE_REF_SYMBOL] === true;
|
|
29868
31073
|
}
|
|
29869
31074
|
__name(isAPIRouteRef, "isAPIRouteRef");
|
|
31075
|
+
function getAPIRouteRefMetadata(value) {
|
|
31076
|
+
if (!isAPIRouteRef(value)) return null;
|
|
31077
|
+
const metadata = value[FARM_API_ROUTE_META_SYMBOL];
|
|
31078
|
+
if (!metadata || typeof metadata !== "object") return null;
|
|
31079
|
+
const candidate = metadata;
|
|
31080
|
+
if (typeof candidate.path !== "string" || typeof candidate.method !== "string" || typeof candidate.baseURL !== "string" || typeof candidate.sameOrigin !== "boolean") {
|
|
31081
|
+
return null;
|
|
31082
|
+
}
|
|
31083
|
+
return {
|
|
31084
|
+
path: candidate.path,
|
|
31085
|
+
method: candidate.method,
|
|
31086
|
+
baseURL: candidate.baseURL,
|
|
31087
|
+
sameOrigin: candidate.sameOrigin
|
|
31088
|
+
};
|
|
31089
|
+
}
|
|
31090
|
+
__name(getAPIRouteRefMetadata, "getAPIRouteRefMetadata");
|
|
29870
31091
|
function createServerAPIClient(endpoints, options = {}) {
|
|
29871
31092
|
if (options.integrations === false || Object.prototype.hasOwnProperty.call(endpoints, "integrations")) {
|
|
29872
31093
|
return endpoints;
|
|
@@ -29971,6 +31192,17 @@ function normalizeError(error) {
|
|
|
29971
31192
|
return normalized;
|
|
29972
31193
|
}
|
|
29973
31194
|
__name(normalizeError, "normalizeError");
|
|
31195
|
+
function isFormData(value) {
|
|
31196
|
+
return typeof value === "object" && value !== null && (typeof FormData !== "undefined" && value instanceof FormData || Object.prototype.toString.call(value) === "[object FormData]" && typeof value.entries === "function");
|
|
31197
|
+
}
|
|
31198
|
+
__name(isFormData, "isFormData");
|
|
31199
|
+
function deleteHeader(headers2, name) {
|
|
31200
|
+
const normalized = name.toLowerCase();
|
|
31201
|
+
for (const key of Object.keys(headers2)) {
|
|
31202
|
+
if (key.toLowerCase() === normalized) delete headers2[key];
|
|
31203
|
+
}
|
|
31204
|
+
}
|
|
31205
|
+
__name(deleteHeader, "deleteHeader");
|
|
29974
31206
|
function createResponseError2(response, data) {
|
|
29975
31207
|
const expected = readEndpointErrorEnvelope(data);
|
|
29976
31208
|
if (expected) {
|
|
@@ -30002,6 +31234,9 @@ function readEndpointErrorEnvelope(data) {
|
|
|
30002
31234
|
}
|
|
30003
31235
|
__name(readEndpointErrorEnvelope, "readEndpointErrorEnvelope");
|
|
30004
31236
|
|
|
31237
|
+
// src/api/index.ts
|
|
31238
|
+
init_transport();
|
|
31239
|
+
|
|
30005
31240
|
// src/api/vite-plugin.ts
|
|
30006
31241
|
init_route_manager2();
|
|
30007
31242
|
init_response();
|
|
@@ -31728,6 +32963,7 @@ init_image_types();
|
|
|
31728
32963
|
// src/server-fn.ts
|
|
31729
32964
|
init_server_action_security();
|
|
31730
32965
|
init_request_bridge();
|
|
32966
|
+
init_cache();
|
|
31731
32967
|
var FARM_SERVER_FN_SYMBOL = /* @__PURE__ */ Symbol.for("farm.server-fn");
|
|
31732
32968
|
var UNSAFE_FORM_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
|
|
31733
32969
|
function createServerMiddleware(options) {
|
|
@@ -31751,8 +32987,8 @@ function createServerFn(options) {
|
|
|
31751
32987
|
}
|
|
31752
32988
|
const middleware2 = resolveServerFnMiddleware(options.middleware);
|
|
31753
32989
|
const serverFn = /* @__PURE__ */ __name(async (value) => {
|
|
31754
|
-
const formData =
|
|
31755
|
-
const rawInput = formData ?
|
|
32990
|
+
const formData = isFormData2(value) ? value : void 0;
|
|
32991
|
+
const rawInput = formData ? formDataToObject2(formData) : value;
|
|
31756
32992
|
const input = await _parseServerFnSchema(options.input, rawInput, "input");
|
|
31757
32993
|
const executionContext = getServerActionExecutionContext();
|
|
31758
32994
|
const request = executionContext?.request ?? _resolveCurrentRequest();
|
|
@@ -31764,8 +33000,21 @@ function createServerFn(options) {
|
|
|
31764
33000
|
request,
|
|
31765
33001
|
signal
|
|
31766
33002
|
};
|
|
31767
|
-
|
|
31768
|
-
|
|
33003
|
+
let resolvedContext = Object.freeze(/* @__PURE__ */ Object.create(null));
|
|
33004
|
+
const result = await runServerFnMiddleware(middleware2, handlerContext, async (context) => {
|
|
33005
|
+
resolvedContext = context.context;
|
|
33006
|
+
return options.handler(context);
|
|
33007
|
+
});
|
|
33008
|
+
const parsedResult = await _parseServerFnSchema(options.output, result, "output");
|
|
33009
|
+
if (options.invalidates) {
|
|
33010
|
+
const declaration = typeof options.invalidates === "function" ? await options.invalidates({
|
|
33011
|
+
...handlerContext,
|
|
33012
|
+
context: resolvedContext,
|
|
33013
|
+
result: parsedResult
|
|
33014
|
+
}) : options.invalidates;
|
|
33015
|
+
await applyFarmCacheInvalidationTargets(declaration);
|
|
33016
|
+
}
|
|
33017
|
+
return parsedResult;
|
|
31769
33018
|
}, "serverFn");
|
|
31770
33019
|
Object.defineProperties(serverFn, {
|
|
31771
33020
|
[FARM_SERVER_FN_SYMBOL]: {
|
|
@@ -31787,6 +33036,10 @@ function createServerFn(options) {
|
|
|
31787
33036
|
__farmServerFnMiddleware: {
|
|
31788
33037
|
value: middleware2,
|
|
31789
33038
|
enumerable: false
|
|
33039
|
+
},
|
|
33040
|
+
__farmServerFnInvalidates: {
|
|
33041
|
+
value: options.invalidates,
|
|
33042
|
+
enumerable: false
|
|
31790
33043
|
}
|
|
31791
33044
|
});
|
|
31792
33045
|
return serverFn;
|
|
@@ -31884,7 +33137,7 @@ function unwrapSafeParseResult(result) {
|
|
|
31884
33137
|
return result;
|
|
31885
33138
|
}
|
|
31886
33139
|
__name(unwrapSafeParseResult, "unwrapSafeParseResult");
|
|
31887
|
-
function
|
|
33140
|
+
function formDataToObject2(formData) {
|
|
31888
33141
|
const output = /* @__PURE__ */ Object.create(null);
|
|
31889
33142
|
for (const [key, value] of formData.entries()) {
|
|
31890
33143
|
if (!isSafeFormKey(key)) continue;
|
|
@@ -31899,19 +33152,19 @@ function formDataToObject(formData) {
|
|
|
31899
33152
|
}
|
|
31900
33153
|
return output;
|
|
31901
33154
|
}
|
|
31902
|
-
__name(
|
|
33155
|
+
__name(formDataToObject2, "formDataToObject");
|
|
31903
33156
|
function isSafeFormKey(key) {
|
|
31904
33157
|
return !key.startsWith("$ACTION_") && !UNSAFE_FORM_KEYS.has(key);
|
|
31905
33158
|
}
|
|
31906
33159
|
__name(isSafeFormKey, "isSafeFormKey");
|
|
31907
|
-
function
|
|
33160
|
+
function isFormData2(value) {
|
|
31908
33161
|
if (!value || typeof value !== "object") return false;
|
|
31909
33162
|
if (typeof FormData !== "undefined" && value instanceof FormData) {
|
|
31910
33163
|
return true;
|
|
31911
33164
|
}
|
|
31912
33165
|
return Object.prototype.toString.call(value) === "[object FormData]" && typeof value.entries === "function";
|
|
31913
33166
|
}
|
|
31914
|
-
__name(
|
|
33167
|
+
__name(isFormData2, "isFormData");
|
|
31915
33168
|
|
|
31916
33169
|
// src/server-fn-client.ts
|
|
31917
33170
|
var import_react7 = require("react");
|
|
@@ -31946,7 +33199,7 @@ function useServerFn(serverFn, options = {}) {
|
|
|
31946
33199
|
const submit = (0, import_react7.useCallback)(
|
|
31947
33200
|
async (input) => {
|
|
31948
33201
|
const requestId = ++requestIdRef.current;
|
|
31949
|
-
const formData =
|
|
33202
|
+
const formData = isFormData3(input) ? input : void 0;
|
|
31950
33203
|
const previousResult = stateRef.current.result;
|
|
31951
33204
|
const optimisticResult = options.optimistic?.({
|
|
31952
33205
|
input,
|
|
@@ -32054,14 +33307,14 @@ function normalizeServerFnError(error) {
|
|
|
32054
33307
|
return normalized;
|
|
32055
33308
|
}
|
|
32056
33309
|
__name(normalizeServerFnError, "normalizeServerFnError");
|
|
32057
|
-
function
|
|
33310
|
+
function isFormData3(value) {
|
|
32058
33311
|
if (!value || typeof value !== "object") return false;
|
|
32059
33312
|
if (typeof FormData !== "undefined" && value instanceof FormData) {
|
|
32060
33313
|
return true;
|
|
32061
33314
|
}
|
|
32062
33315
|
return Object.prototype.toString.call(value) === "[object FormData]" && typeof value.entries === "function";
|
|
32063
33316
|
}
|
|
32064
|
-
__name(
|
|
33317
|
+
__name(isFormData3, "isFormData");
|
|
32065
33318
|
|
|
32066
33319
|
// src/server-query.ts
|
|
32067
33320
|
init_cache();
|
|
@@ -32121,7 +33374,7 @@ function createServerQuery(options) {
|
|
|
32121
33374
|
tags: [createRouteDataCacheTag(routeKey)],
|
|
32122
33375
|
revalidate: staleTime === false ? false : Math.max(1, Math.ceil(staleTime / 1e3))
|
|
32123
33376
|
});
|
|
32124
|
-
updatedAt = cache.
|
|
33377
|
+
updatedAt = (await cache.getEntryAsync(cacheKey, { allowStale: true }))?.createdAt ?? Date.now();
|
|
32125
33378
|
}
|
|
32126
33379
|
return createFarmServerQueryResult(data, {
|
|
32127
33380
|
key: clientKey,
|
|
@@ -33151,6 +34404,18 @@ async function buildUniversal(config, routeManager, apiRouteManager, serverRende
|
|
|
33151
34404
|
...isFarmMarkdownPageFile(entry.modulePath) ? { source: (0, import_fs5.readFileSync)(entry.modulePath, "utf8") } : {}
|
|
33152
34405
|
});
|
|
33153
34406
|
}
|
|
34407
|
+
const routeSlots = Array.from(
|
|
34408
|
+
routeManager.getRouteSlots().values(),
|
|
34409
|
+
(entry) => ({
|
|
34410
|
+
name: entry.name,
|
|
34411
|
+
ownerPattern: entry.ownerPattern,
|
|
34412
|
+
pattern: entry.pattern,
|
|
34413
|
+
modulePath: entry.modulePath,
|
|
34414
|
+
containerId: entry.containerId,
|
|
34415
|
+
interception: entry.interception,
|
|
34416
|
+
fallback: entry.fallback
|
|
34417
|
+
})
|
|
34418
|
+
);
|
|
33154
34419
|
logger.info(`\u{1F4CB} Found ${pageRoutes.length} page routes`);
|
|
33155
34420
|
const fs9 = await import("fs/promises");
|
|
33156
34421
|
const layoutRoutes = [];
|
|
@@ -33194,7 +34459,16 @@ async function buildUniversal(config, routeManager, apiRouteManager, serverRende
|
|
|
33194
34459
|
logger.info("\u{1F4E6} Building client and SSR bundles in parallel...");
|
|
33195
34460
|
const [clientBuildResult, ssrBuildResult] = await Promise.allSettled([
|
|
33196
34461
|
// Client build (to disk)
|
|
33197
|
-
buildClient(
|
|
34462
|
+
buildClient(
|
|
34463
|
+
productionVite,
|
|
34464
|
+
config,
|
|
34465
|
+
root,
|
|
34466
|
+
srcDir,
|
|
34467
|
+
clientOutputDir,
|
|
34468
|
+
pageRoutes,
|
|
34469
|
+
layoutRoutes,
|
|
34470
|
+
routeSlots
|
|
34471
|
+
),
|
|
33198
34472
|
// SSR build (in memory)
|
|
33199
34473
|
buildSSRInMemory(
|
|
33200
34474
|
productionVite,
|
|
@@ -33205,7 +34479,8 @@ async function buildUniversal(config, routeManager, apiRouteManager, serverRende
|
|
|
33205
34479
|
serverRenderer,
|
|
33206
34480
|
preset,
|
|
33207
34481
|
pageRoutes,
|
|
33208
|
-
layoutRoutes
|
|
34482
|
+
layoutRoutes,
|
|
34483
|
+
routeSlots
|
|
33209
34484
|
)
|
|
33210
34485
|
]);
|
|
33211
34486
|
const [routeRuntimeManifestResult] = await routeRuntimeManifestResultPromise;
|
|
@@ -33225,7 +34500,8 @@ async function buildUniversal(config, routeManager, apiRouteManager, serverRende
|
|
|
33225
34500
|
srcDir,
|
|
33226
34501
|
clientOutputDir,
|
|
33227
34502
|
pageRoutes,
|
|
33228
|
-
layoutRoutes
|
|
34503
|
+
layoutRoutes,
|
|
34504
|
+
routeSlots
|
|
33229
34505
|
);
|
|
33230
34506
|
}
|
|
33231
34507
|
const ssrResult = ssrBuildResult.value;
|
|
@@ -33328,7 +34604,7 @@ async function validateClientBuildOutput(root, srcDir, outputDir) {
|
|
|
33328
34604
|
}
|
|
33329
34605
|
}
|
|
33330
34606
|
__name(validateClientBuildOutput, "validateClientBuildOutput");
|
|
33331
|
-
async function buildClient(productionVite, config, root, srcDir, outputDir, pageRoutes, layoutRoutes = []) {
|
|
34607
|
+
async function buildClient(productionVite, config, root, srcDir, outputDir, pageRoutes, layoutRoutes = [], routeSlots = []) {
|
|
33332
34608
|
const viteBuild = productionVite.build;
|
|
33333
34609
|
const { farmPlugin: farmPlugin2 } = await Promise.resolve().then(() => (init_vite(), vite_exports));
|
|
33334
34610
|
const { PluginManager: PluginManager2 } = await Promise.resolve().then(() => (init_plugin(), plugin_exports));
|
|
@@ -33355,8 +34631,16 @@ async function buildClient(productionVite, config, root, srcDir, outputDir, page
|
|
|
33355
34631
|
logger.warn(`\u26A0\uFE0F Could not inspect route file ${route2.modulePath}: ${error}`);
|
|
33356
34632
|
}
|
|
33357
34633
|
}
|
|
34634
|
+
const clientRouteSlots = routeSlots.filter((slot) => {
|
|
34635
|
+
try {
|
|
34636
|
+
return getClientModuleMetadata(slot.modulePath, root).shouldHydrate;
|
|
34637
|
+
} catch (error) {
|
|
34638
|
+
logger.warn(`\u26A0\uFE0F Could not inspect route slot ${slot.modulePath}: ${error}`);
|
|
34639
|
+
return false;
|
|
34640
|
+
}
|
|
34641
|
+
});
|
|
33358
34642
|
logger.info(
|
|
33359
|
-
`\u{1F4F1} Total hydratable routes detected: ${clientPages.length}
|
|
34643
|
+
`\u{1F4F1} Total hydratable routes detected: ${clientPages.length} pages and ${clientRouteSlots.length} slots`
|
|
33360
34644
|
);
|
|
33361
34645
|
const clientEntryRoot = import_path12.default.join(root, ".farm", "tmp");
|
|
33362
34646
|
await fs9.mkdir(clientEntryRoot, { recursive: true });
|
|
@@ -33365,6 +34649,7 @@ async function buildClient(productionVite, config, root, srcDir, outputDir, page
|
|
|
33365
34649
|
const clientHydrationCode = generateClientHydrationEntry(
|
|
33366
34650
|
clientPages,
|
|
33367
34651
|
layoutRoutes,
|
|
34652
|
+
clientRouteSlots,
|
|
33368
34653
|
root,
|
|
33369
34654
|
srcDir,
|
|
33370
34655
|
isFarmDocsSearchEnabled(config.docs),
|
|
@@ -33697,7 +34982,7 @@ function generateUniversalRouterStateProperties() {
|
|
|
33697
34982
|
`.trim();
|
|
33698
34983
|
}
|
|
33699
34984
|
__name(generateUniversalRouterStateProperties, "generateUniversalRouterStateProperties");
|
|
33700
|
-
function generateClientHydrationEntry(clientPages, layoutRoutes, root, srcDir, docsSearchEnabled, docsSearchModuleId, i18nConfig = {
|
|
34985
|
+
function generateClientHydrationEntry(clientPages, layoutRoutes, clientRouteSlots, root, srcDir, docsSearchEnabled, docsSearchModuleId, i18nConfig = {
|
|
33701
34986
|
enabled: false,
|
|
33702
34987
|
locales: ["en"],
|
|
33703
34988
|
defaultLocale: "en",
|
|
@@ -33765,7 +35050,7 @@ function isFarmLocaleDocumentChange() {
|
|
|
33765
35050
|
return false;
|
|
33766
35051
|
}
|
|
33767
35052
|
`;
|
|
33768
|
-
if (clientPages.length === 0) {
|
|
35053
|
+
if (clientPages.length === 0 && clientRouteSlots.length === 0) {
|
|
33769
35054
|
return `
|
|
33770
35055
|
// Farm.js Client Runtime (no client components)
|
|
33771
35056
|
${cssImport}
|
|
@@ -34015,11 +35300,25 @@ document.addEventListener("click", function(e) {
|
|
|
34015
35300
|
}
|
|
34016
35301
|
const imports = [];
|
|
34017
35302
|
const routeEntries = [];
|
|
35303
|
+
const routeSlotEntries = [];
|
|
34018
35304
|
clientPages.forEach((page2, index) => {
|
|
34019
35305
|
const importPath = toImportPath(page2.modulePath);
|
|
34020
35306
|
imports.push(`import Page${index} from "${importPath}";`);
|
|
34021
35307
|
routeEntries.push(` { pattern: ${JSON.stringify(page2.pattern)}, Component: Page${index} }`);
|
|
34022
35308
|
});
|
|
35309
|
+
clientRouteSlots.forEach((slot, index) => {
|
|
35310
|
+
const importPath = toImportPath(slot.modulePath);
|
|
35311
|
+
imports.push(`import RouteSlot${index} from "${importPath}";`);
|
|
35312
|
+
routeSlotEntries.push(` {
|
|
35313
|
+
name: ${JSON.stringify(slot.name)},
|
|
35314
|
+
ownerPattern: ${JSON.stringify(slot.ownerPattern)},
|
|
35315
|
+
pattern: ${JSON.stringify(slot.pattern)},
|
|
35316
|
+
containerId: ${JSON.stringify(slot.containerId)},
|
|
35317
|
+
interception: ${JSON.stringify(slot.interception)},
|
|
35318
|
+
fallback: ${JSON.stringify(slot.fallback)},
|
|
35319
|
+
Component: RouteSlot${index},
|
|
35320
|
+
}`);
|
|
35321
|
+
});
|
|
34023
35322
|
return `
|
|
34024
35323
|
// Farm.js Client Runtime - SPA with Hydration
|
|
34025
35324
|
${cssImport}
|
|
@@ -34041,6 +35340,10 @@ const clientRoutes = [
|
|
|
34041
35340
|
${routeEntries.join(",\n")}
|
|
34042
35341
|
];
|
|
34043
35342
|
|
|
35343
|
+
const clientRouteSlots = [
|
|
35344
|
+
${routeSlotEntries.join(",\n")}
|
|
35345
|
+
];
|
|
35346
|
+
|
|
34044
35347
|
// Layout routes for wrapping client components
|
|
34045
35348
|
const layoutRoutes = [
|
|
34046
35349
|
${layoutRegistrations.join(",\n")}
|
|
@@ -34095,6 +35398,146 @@ function matchRoute(pathname) {
|
|
|
34095
35398
|
return null;
|
|
34096
35399
|
}
|
|
34097
35400
|
|
|
35401
|
+
function matchesRoutePrefix(pathname, pattern) {
|
|
35402
|
+
if (pattern === "/") return true;
|
|
35403
|
+
const pathSegments = getFarmRoutePathname(pathname).split("/").filter(Boolean);
|
|
35404
|
+
const patternSegments = pattern.split("/").filter(Boolean);
|
|
35405
|
+
if (patternSegments.length > pathSegments.length) return false;
|
|
35406
|
+
const candidate = "/" + pathSegments.slice(0, patternSegments.length).join("/");
|
|
35407
|
+
return matchFarmRoute(pattern, candidate) !== null;
|
|
35408
|
+
}
|
|
35409
|
+
|
|
35410
|
+
function matchInterceptedRouteSlot(pathname, from) {
|
|
35411
|
+
for (const slot of clientRouteSlots) {
|
|
35412
|
+
if (!slot.interception || !matchesRoutePrefix(from, slot.ownerPattern)) continue;
|
|
35413
|
+
const params = matchFarmRoute(slot.pattern, getFarmRoutePathname(pathname));
|
|
35414
|
+
if (params !== null) return { slot: slot, params: params };
|
|
35415
|
+
}
|
|
35416
|
+
return null;
|
|
35417
|
+
}
|
|
35418
|
+
|
|
35419
|
+
function routeSlotKey(slot) {
|
|
35420
|
+
return slot.ownerPattern + ":" + slot.name;
|
|
35421
|
+
}
|
|
35422
|
+
|
|
35423
|
+
function findClientRouteSlot(slot) {
|
|
35424
|
+
return clientRouteSlots.find(function(candidate) {
|
|
35425
|
+
return candidate.name === slot.name &&
|
|
35426
|
+
candidate.ownerPattern === slot.ownerPattern &&
|
|
35427
|
+
candidate.pattern === slot.pattern &&
|
|
35428
|
+
candidate.interception === slot.interception &&
|
|
35429
|
+
candidate.fallback === slot.fallback;
|
|
35430
|
+
});
|
|
35431
|
+
}
|
|
35432
|
+
|
|
35433
|
+
function readRouteSlotPayload(doc) {
|
|
35434
|
+
const script = doc.getElementById("__farm_route_slots_data__");
|
|
35435
|
+
if (!script?.textContent) return [];
|
|
35436
|
+
try {
|
|
35437
|
+
const parsed = JSON.parse(script.textContent);
|
|
35438
|
+
return Array.isArray(parsed) ? parsed : [];
|
|
35439
|
+
} catch {
|
|
35440
|
+
return [];
|
|
35441
|
+
}
|
|
35442
|
+
}
|
|
35443
|
+
|
|
35444
|
+
const routeSlotRoots = new Map();
|
|
35445
|
+
let activeRouteInterception = null;
|
|
35446
|
+
|
|
35447
|
+
function resetRouteSlotRoots() {
|
|
35448
|
+
for (const root of routeSlotRoots.values()) {
|
|
35449
|
+
try { root.unmount(); } catch {}
|
|
35450
|
+
}
|
|
35451
|
+
routeSlotRoots.clear();
|
|
35452
|
+
activeRouteInterception = null;
|
|
35453
|
+
}
|
|
35454
|
+
|
|
35455
|
+
function renderClientRouteSlot(slot, registration, mode) {
|
|
35456
|
+
const container = document.getElementById(slot.containerId);
|
|
35457
|
+
if (!container || !registration?.Component) return false;
|
|
35458
|
+
const key = routeSlotKey(slot);
|
|
35459
|
+
const existingRoot = routeSlotRoots.get(key);
|
|
35460
|
+
const props = slot.props && typeof slot.props === "object" ? slot.props : {};
|
|
35461
|
+
const element = React.createElement(registration.Component, props);
|
|
35462
|
+
|
|
35463
|
+
if (mode === "hydrate") {
|
|
35464
|
+
if (existingRoot) return true;
|
|
35465
|
+
const root = hydrateRoot(container, element);
|
|
35466
|
+
routeSlotRoots.set(key, root);
|
|
35467
|
+
return true;
|
|
35468
|
+
}
|
|
35469
|
+
|
|
35470
|
+
if (existingRoot) {
|
|
35471
|
+
try { existingRoot.unmount(); } catch {}
|
|
35472
|
+
routeSlotRoots.delete(key);
|
|
35473
|
+
} else {
|
|
35474
|
+
container.replaceChildren();
|
|
35475
|
+
}
|
|
35476
|
+
const root = createRoot(container);
|
|
35477
|
+
root.render(element);
|
|
35478
|
+
routeSlotRoots.set(key, root);
|
|
35479
|
+
return true;
|
|
35480
|
+
}
|
|
35481
|
+
|
|
35482
|
+
function hydrateInitialRouteSlots() {
|
|
35483
|
+
const slots = Array.isArray(window.__FARM_ROUTE_SLOTS__)
|
|
35484
|
+
? window.__FARM_ROUTE_SLOTS__
|
|
35485
|
+
: [];
|
|
35486
|
+
for (const slot of slots) {
|
|
35487
|
+
const registration = findClientRouteSlot(slot);
|
|
35488
|
+
if (!registration) continue;
|
|
35489
|
+
try {
|
|
35490
|
+
renderClientRouteSlot(slot, registration, "hydrate");
|
|
35491
|
+
} catch (error) {
|
|
35492
|
+
console.warn("[Farm.js] Could not hydrate route slot:", slot.name, error);
|
|
35493
|
+
}
|
|
35494
|
+
}
|
|
35495
|
+
}
|
|
35496
|
+
|
|
35497
|
+
function renderRouteInterception(slot, registration, from) {
|
|
35498
|
+
const container = document.getElementById(slot.containerId);
|
|
35499
|
+
if (!container) return false;
|
|
35500
|
+
const key = routeSlotKey(slot);
|
|
35501
|
+
const previousSlot = (window.__FARM_ROUTE_SLOTS__ || []).find(function(candidate) {
|
|
35502
|
+
return routeSlotKey(candidate) === key;
|
|
35503
|
+
}) || null;
|
|
35504
|
+
const previousHtml = container.innerHTML;
|
|
35505
|
+
|
|
35506
|
+
if (!renderClientRouteSlot(slot, registration, "render")) return false;
|
|
35507
|
+
activeRouteInterception = {
|
|
35508
|
+
from: from,
|
|
35509
|
+
key: key,
|
|
35510
|
+
slot: slot,
|
|
35511
|
+
previousSlot: previousSlot,
|
|
35512
|
+
previousHtml: previousHtml,
|
|
35513
|
+
};
|
|
35514
|
+
return true;
|
|
35515
|
+
}
|
|
35516
|
+
|
|
35517
|
+
function clearRouteInterception(destination) {
|
|
35518
|
+
if (!activeRouteInterception) return false;
|
|
35519
|
+
const active = activeRouteInterception;
|
|
35520
|
+
activeRouteInterception = null;
|
|
35521
|
+
const root = routeSlotRoots.get(active.key);
|
|
35522
|
+
if (root) {
|
|
35523
|
+
try { root.unmount(); } catch {}
|
|
35524
|
+
routeSlotRoots.delete(active.key);
|
|
35525
|
+
}
|
|
35526
|
+
const container = document.getElementById(active.slot.containerId);
|
|
35527
|
+
if (container) {
|
|
35528
|
+
container.innerHTML = active.previousHtml;
|
|
35529
|
+
if (active.previousSlot) {
|
|
35530
|
+
const registration = findClientRouteSlot(active.previousSlot);
|
|
35531
|
+
if (registration) {
|
|
35532
|
+
try {
|
|
35533
|
+
renderClientRouteSlot(active.previousSlot, registration, "hydrate");
|
|
35534
|
+
} catch {}
|
|
35535
|
+
}
|
|
35536
|
+
}
|
|
35537
|
+
}
|
|
35538
|
+
return destination === active.from;
|
|
35539
|
+
}
|
|
35540
|
+
|
|
34098
35541
|
// State
|
|
34099
35542
|
let reactRoot = null;
|
|
34100
35543
|
let currentPathname = null;
|
|
@@ -34113,12 +35556,17 @@ function resetReactRoot() {
|
|
|
34113
35556
|
async function hydrate() {
|
|
34114
35557
|
const pathname = window.location.pathname;
|
|
34115
35558
|
const matched = matchRoute(pathname);
|
|
34116
|
-
|
|
35559
|
+
hydrateInitialRouteSlots();
|
|
35560
|
+
|
|
34117
35561
|
if (!matched) {
|
|
34118
35562
|
return;
|
|
34119
35563
|
}
|
|
34120
35564
|
|
|
34121
|
-
const
|
|
35565
|
+
const hasRouteSlots =
|
|
35566
|
+
Array.isArray(window.__FARM_ROUTE_SLOTS__) && window.__FARM_ROUTE_SLOTS__.length > 0;
|
|
35567
|
+
const container =
|
|
35568
|
+
(hasRouteSlots ? document.getElementById("__farm_page__") : null) ||
|
|
35569
|
+
document.getElementById("root");
|
|
34122
35570
|
if (!container) {
|
|
34123
35571
|
console.error("[Farm.js] No root element found");
|
|
34124
35572
|
return;
|
|
@@ -34132,7 +35580,9 @@ async function hydrate() {
|
|
|
34132
35580
|
|
|
34133
35581
|
// Create page element and wrap with layouts
|
|
34134
35582
|
const pageElement = React.createElement(Component, props);
|
|
34135
|
-
const wrappedElement =
|
|
35583
|
+
const wrappedElement = hasRouteSlots
|
|
35584
|
+
? pageElement
|
|
35585
|
+
: wrapWithLayouts(pageElement, pathname, params);
|
|
34136
35586
|
|
|
34137
35587
|
const shouldHydrate = !isHydrated && Boolean(container.innerHTML.trim());
|
|
34138
35588
|
const hydrationSession = await farmClientRuntime.beginHydration({
|
|
@@ -34197,6 +35647,57 @@ ${generateUniversalRouterStateProperties()}
|
|
|
34197
35647
|
: undefined,
|
|
34198
35648
|
});
|
|
34199
35649
|
|
|
35650
|
+
if (activeRouteInterception && clearRouteInterception(to)) {
|
|
35651
|
+
await farmClientRuntime.markNavigationLoaded(clientNavigation, {
|
|
35652
|
+
routeSlots: "restored",
|
|
35653
|
+
});
|
|
35654
|
+
await farmClientRuntime.resolveNavigation(clientNavigation);
|
|
35655
|
+
void farmClientRuntime.scheduleNavigationRendered(clientNavigation);
|
|
35656
|
+
this.currentPath = to;
|
|
35657
|
+
this.finishNavigation();
|
|
35658
|
+
return;
|
|
35659
|
+
}
|
|
35660
|
+
if (activeRouteInterception) {
|
|
35661
|
+
clearRouteInterception(to);
|
|
35662
|
+
}
|
|
35663
|
+
|
|
35664
|
+
const intercepted = matchInterceptedRouteSlot(pathname, from);
|
|
35665
|
+
if (intercepted) {
|
|
35666
|
+
const html = await this.fetchPage(to, from);
|
|
35667
|
+
const doc = new DOMParser().parseFromString(html, "text/html");
|
|
35668
|
+
const slotPayload = readRouteSlotPayload(doc);
|
|
35669
|
+
const selectedSlot = slotPayload.find(function(slot) {
|
|
35670
|
+
return slot.interception &&
|
|
35671
|
+
slot.name === intercepted.slot.name &&
|
|
35672
|
+
slot.ownerPattern === intercepted.slot.ownerPattern;
|
|
35673
|
+
});
|
|
35674
|
+
|
|
35675
|
+
if (
|
|
35676
|
+
selectedSlot &&
|
|
35677
|
+
renderRouteInterception(selectedSlot, intercepted.slot, from)
|
|
35678
|
+
) {
|
|
35679
|
+
await farmClientRuntime.markNavigationLoaded(clientNavigation, {
|
|
35680
|
+
route: intercepted.slot.pattern,
|
|
35681
|
+
params: intercepted.params,
|
|
35682
|
+
});
|
|
35683
|
+
const historyState = createHistoryState(
|
|
35684
|
+
to,
|
|
35685
|
+
options.state,
|
|
35686
|
+
window.history.state,
|
|
35687
|
+
);
|
|
35688
|
+
if (action === "replace") {
|
|
35689
|
+
window.history.replaceState(historyState, "", url);
|
|
35690
|
+
} else if (action !== "pop") {
|
|
35691
|
+
window.history.pushState(historyState, "", url);
|
|
35692
|
+
}
|
|
35693
|
+
await farmClientRuntime.resolveNavigation(clientNavigation);
|
|
35694
|
+
void farmClientRuntime.scheduleNavigationRendered(clientNavigation);
|
|
35695
|
+
this.currentPath = to;
|
|
35696
|
+
this.finishNavigation();
|
|
35697
|
+
return;
|
|
35698
|
+
}
|
|
35699
|
+
}
|
|
35700
|
+
|
|
34200
35701
|
if (matched) {
|
|
34201
35702
|
const Component = matched.route.Component;
|
|
34202
35703
|
const params = matched.params;
|
|
@@ -34273,21 +35774,28 @@ ${generateUniversalRouterStateProperties()}
|
|
|
34273
35774
|
}
|
|
34274
35775
|
},
|
|
34275
35776
|
|
|
34276
|
-
fetchPage: async function(url) {
|
|
34277
|
-
const
|
|
35777
|
+
fetchPage: async function(url, interceptFrom) {
|
|
35778
|
+
const cacheKey = interceptFrom ? url + "\\nintercept:" + interceptFrom : url;
|
|
35779
|
+
const cached = this.prefetchCache.get(cacheKey);
|
|
34278
35780
|
if (cached) return cached;
|
|
34279
35781
|
|
|
34280
35782
|
const response = await fetch(url, {
|
|
34281
|
-
headers: {
|
|
35783
|
+
headers: {
|
|
35784
|
+
"Accept": "text/html",
|
|
35785
|
+
...(interceptFrom ? { "X-Farm-Intercept-From": interceptFrom } : {}),
|
|
35786
|
+
}
|
|
34282
35787
|
});
|
|
34283
35788
|
if (!response.ok) throw new Error("Failed to fetch page");
|
|
34284
|
-
|
|
35789
|
+
const html = await response.text();
|
|
35790
|
+
this.prefetchCache.set(cacheKey, html);
|
|
35791
|
+
return html;
|
|
34285
35792
|
},
|
|
34286
35793
|
|
|
34287
35794
|
swapContent: function(html, targetPath) {
|
|
34288
35795
|
const parser = new DOMParser();
|
|
34289
35796
|
const doc = parser.parseFromString(html, "text/html");
|
|
34290
35797
|
if (isFarmLocaleDocumentChange(doc)) return false;
|
|
35798
|
+
const nextRouteSlots = readRouteSlotPayload(doc);
|
|
34291
35799
|
|
|
34292
35800
|
// Update title
|
|
34293
35801
|
const newTitle = doc.querySelector("title");
|
|
@@ -34312,7 +35820,10 @@ ${generateUniversalRouterStateProperties()}
|
|
|
34312
35820
|
const currentRoot = document.getElementById("root");
|
|
34313
35821
|
if (!newRoot || !currentRoot) return this.swapDocument(doc);
|
|
34314
35822
|
resetReactRoot();
|
|
35823
|
+
resetRouteSlotRoots();
|
|
34315
35824
|
currentRoot.innerHTML = newRoot.innerHTML;
|
|
35825
|
+
window.__FARM_ROUTE_SLOTS__ = nextRouteSlots;
|
|
35826
|
+
hydrateInitialRouteSlots();
|
|
34316
35827
|
|
|
34317
35828
|
// Check if new page has a client component
|
|
34318
35829
|
const targetUrl = new URL(targetPath || window.location.href, window.location.origin);
|
|
@@ -34324,13 +35835,15 @@ ${generateUniversalRouterStateProperties()}
|
|
|
34324
35835
|
const params = matched.params;
|
|
34325
35836
|
const searchParams = Object.fromEntries(targetUrl.searchParams);
|
|
34326
35837
|
const props = { params: params, searchParams: Promise.resolve(searchParams) };
|
|
34327
|
-
|
|
34328
|
-
if (!reactRoot) {
|
|
34329
|
-
reactRoot = createRoot(currentRoot);
|
|
34330
|
-
}
|
|
34331
35838
|
const pageElement = React.createElement(Component, props);
|
|
34332
|
-
const
|
|
34333
|
-
|
|
35839
|
+
const hasRouteSlots = nextRouteSlots.length > 0;
|
|
35840
|
+
const pageContainer =
|
|
35841
|
+
(hasRouteSlots ? document.getElementById("__farm_page__") : null) || currentRoot;
|
|
35842
|
+
const wrappedElement = hasRouteSlots
|
|
35843
|
+
? pageElement
|
|
35844
|
+
: wrapWithLayouts(pageElement, newPathname, params);
|
|
35845
|
+
reactRoot = hydrateRoot(pageContainer, wrappedElement);
|
|
35846
|
+
isHydrated = true;
|
|
34334
35847
|
}
|
|
34335
35848
|
return true;
|
|
34336
35849
|
},
|
|
@@ -34339,6 +35852,7 @@ ${generateUniversalRouterStateProperties()}
|
|
|
34339
35852
|
if (!doc.documentElement || !doc.body) return false;
|
|
34340
35853
|
|
|
34341
35854
|
resetReactRoot();
|
|
35855
|
+
resetRouteSlotRoots();
|
|
34342
35856
|
|
|
34343
35857
|
Array.from(document.documentElement.attributes).forEach(function(attr) {
|
|
34344
35858
|
if (!doc.documentElement.hasAttribute(attr.name)) {
|
|
@@ -34372,10 +35886,12 @@ ${generateUniversalRouterStateProperties()}
|
|
|
34372
35886
|
if (url.origin !== window.location.origin) return;
|
|
34373
35887
|
|
|
34374
35888
|
const pathname = url.pathname + url.search;
|
|
34375
|
-
|
|
35889
|
+
const interceptFrom = this.currentPath;
|
|
35890
|
+
const cacheKey = pathname + "\\nintercept:" + interceptFrom;
|
|
35891
|
+
if (this.prefetchCache.has(cacheKey)) return;
|
|
34376
35892
|
|
|
34377
|
-
this.fetchPage(pathname)
|
|
34378
|
-
.then(function(html) { spaRouter.prefetchCache.set(
|
|
35893
|
+
this.fetchPage(pathname, interceptFrom)
|
|
35894
|
+
.then(function(html) { spaRouter.prefetchCache.set(cacheKey, html); })
|
|
34379
35895
|
.catch(function() {});
|
|
34380
35896
|
},
|
|
34381
35897
|
|
|
@@ -34466,7 +35982,7 @@ if (isFarmDocsSearchPage()) {
|
|
|
34466
35982
|
`.trim();
|
|
34467
35983
|
}
|
|
34468
35984
|
__name(generateClientHydrationEntry, "generateClientHydrationEntry");
|
|
34469
|
-
async function buildSSRInMemory(productionVite, config, root, routeManager, apiRouteManager, serverRenderer, preset, collectedPageRoutes, collectedLayoutRoutes) {
|
|
35985
|
+
async function buildSSRInMemory(productionVite, config, root, routeManager, apiRouteManager, serverRenderer, preset, collectedPageRoutes, collectedLayoutRoutes, collectedRouteSlots) {
|
|
34470
35986
|
const viteBuild = productionVite.build;
|
|
34471
35987
|
const { farmPlugin: farmPlugin2 } = await Promise.resolve().then(() => (init_vite(), vite_exports));
|
|
34472
35988
|
const { PluginManager: PluginManager2 } = await Promise.resolve().then(() => (init_plugin(), plugin_exports));
|
|
@@ -34499,6 +36015,7 @@ async function buildSSRInMemory(productionVite, config, root, routeManager, apiR
|
|
|
34499
36015
|
let ssrEntryFile;
|
|
34500
36016
|
const pageRoutes = collectedPageRoutes.map((route2) => ({ ...route2 }));
|
|
34501
36017
|
const layoutRoutes = collectedLayoutRoutes.map((route2) => ({ ...route2 }));
|
|
36018
|
+
const routeSlots = collectedRouteSlots.map((slot) => ({ ...slot }));
|
|
34502
36019
|
const metadataImageRoutes = [];
|
|
34503
36020
|
for (const entry of routeManager.getMetadataImages().values()) {
|
|
34504
36021
|
if (entry.sourceType === "static") {
|
|
@@ -34599,6 +36116,7 @@ async function buildSSRInMemory(productionVite, config, root, routeManager, apiR
|
|
|
34599
36116
|
apiRoutes,
|
|
34600
36117
|
pageRoutes,
|
|
34601
36118
|
layoutRoutes,
|
|
36119
|
+
routeSlots,
|
|
34602
36120
|
errorRoutes,
|
|
34603
36121
|
metadataImageRoutes,
|
|
34604
36122
|
middlewareRoutes,
|
|
@@ -34769,10 +36287,14 @@ async function buildSSRInMemory(productionVite, config, root, routeManager, apiR
|
|
|
34769
36287
|
}
|
|
34770
36288
|
}
|
|
34771
36289
|
}
|
|
34772
|
-
return {
|
|
36290
|
+
return {
|
|
36291
|
+
bundle: ssrBundle,
|
|
36292
|
+
entryFile: ssrEntryFile,
|
|
36293
|
+
configuredHeaderRoutes
|
|
36294
|
+
};
|
|
34773
36295
|
}
|
|
34774
36296
|
__name(buildSSRInMemory, "buildSSRInMemory");
|
|
34775
|
-
function generateVirtualEntryCode(apiRoutes, pageRoutes, layoutRoutes, errorRoutes, metadataImageRoutes, middlewareRoutes, redirectRoutes, configuredRewriteRoutes, configuredHeaderRoutes, notFoundPath, config, configModulePath, hasServerRuntimeIntegrations, hasRuntimeIntegrationConfig, hasConfiguredRuntimePlugins, preset, i18nCatalogs) {
|
|
36297
|
+
function generateVirtualEntryCode(apiRoutes, pageRoutes, layoutRoutes, routeSlots, errorRoutes, metadataImageRoutes, middlewareRoutes, redirectRoutes, configuredRewriteRoutes, configuredHeaderRoutes, notFoundPath, config, configModulePath, hasServerRuntimeIntegrations, hasRuntimeIntegrationConfig, hasConfiguredRuntimePlugins, preset, i18nCatalogs) {
|
|
34776
36298
|
const hasPluginRuntime = hasRuntimeIntegrationConfig || hasConfiguredRuntimePlugins;
|
|
34777
36299
|
const hasMiddlewareRuntime = middlewareRoutes.length > 0 || hasFarmMiddlewareConfig(config.middleware);
|
|
34778
36300
|
const farmDocsBaseConfig = config.docs?.enabled ? { ...config.docs, config: void 0 } : void 0;
|
|
@@ -34816,10 +36338,12 @@ function generateVirtualEntryCode(apiRoutes, pageRoutes, layoutRoutes, errorRout
|
|
|
34816
36338
|
return;
|
|
34817
36339
|
}
|
|
34818
36340
|
pageImports.push(`import * as ${varName} from "${route2.modulePath}";`);
|
|
36341
|
+
const shouldHydrate = getClientModuleMetadata(route2.modulePath, config.root).shouldHydrate;
|
|
34819
36342
|
pageRegistrations.push(`
|
|
34820
36343
|
{
|
|
34821
36344
|
pattern: ${JSON.stringify(route2.pattern)},
|
|
34822
36345
|
module: ${varName},
|
|
36346
|
+
shouldHydrate: ${JSON.stringify(shouldHydrate)},
|
|
34823
36347
|
}`);
|
|
34824
36348
|
});
|
|
34825
36349
|
const layoutImports = [];
|
|
@@ -34833,6 +36357,22 @@ function generateVirtualEntryCode(apiRoutes, pageRoutes, layoutRoutes, errorRout
|
|
|
34833
36357
|
module: ${varName},
|
|
34834
36358
|
}`);
|
|
34835
36359
|
});
|
|
36360
|
+
const routeSlotImports = [];
|
|
36361
|
+
const routeSlotRegistrations = [];
|
|
36362
|
+
routeSlots.forEach((slot, index) => {
|
|
36363
|
+
const varName = `routeSlot${index}`;
|
|
36364
|
+
routeSlotImports.push(`import * as ${varName} from "${slot.modulePath}";`);
|
|
36365
|
+
routeSlotRegistrations.push(`
|
|
36366
|
+
{
|
|
36367
|
+
name: ${JSON.stringify(slot.name)},
|
|
36368
|
+
ownerPattern: ${JSON.stringify(slot.ownerPattern)},
|
|
36369
|
+
pattern: ${JSON.stringify(slot.pattern)},
|
|
36370
|
+
containerId: ${JSON.stringify(slot.containerId)},
|
|
36371
|
+
interception: ${JSON.stringify(slot.interception)},
|
|
36372
|
+
fallback: ${JSON.stringify(slot.fallback)},
|
|
36373
|
+
module: ${varName},
|
|
36374
|
+
}`);
|
|
36375
|
+
});
|
|
34836
36376
|
const errorImports = [];
|
|
34837
36377
|
const errorRegistrations = [];
|
|
34838
36378
|
errorRoutes.forEach((errorRoute, index) => {
|
|
@@ -34883,6 +36423,7 @@ function generateVirtualEntryCode(apiRoutes, pageRoutes, layoutRoutes, errorRout
|
|
|
34883
36423
|
_runWithMiddlewareData,
|
|
34884
36424
|
addMetadataImageReference,
|
|
34885
36425
|
applyProductionMiddlewareHeaders,
|
|
36426
|
+
configureFarmCache,
|
|
34886
36427
|
configureFarmObservability,
|
|
34887
36428
|
createFarmCacheKey,
|
|
34888
36429
|
createFarmLocaleCookie,
|
|
@@ -34985,6 +36526,7 @@ async function handleAPIRequest(request) {
|
|
|
34985
36526
|
${apiImports.join("\n")}
|
|
34986
36527
|
${pageImports.join("\n")}
|
|
34987
36528
|
${layoutImports.join("\n")}
|
|
36529
|
+
${routeSlotImports.join("\n")}
|
|
34988
36530
|
${errorImports.join("\n")}
|
|
34989
36531
|
${metadataImageImports.join("\n")}
|
|
34990
36532
|
${middlewareImports.join("\n")}
|
|
@@ -35062,6 +36604,7 @@ const farmObservabilityConfig = farmUserConfig?.observability ?? ${JSON.stringif
|
|
|
35062
36604
|
config.observability ?? false
|
|
35063
36605
|
)};
|
|
35064
36606
|
configureFarmObservability(farmObservabilityConfig);
|
|
36607
|
+
configureFarmCache(farmResolvedRuntimeConfig.cache);
|
|
35065
36608
|
const farmI18nConfig = ${JSON.stringify(config.i18n)};
|
|
35066
36609
|
const farmI18nRuntime = ${config.i18n.enabled ? `createFarmI18nRuntime(farmI18nConfig, ${JSON.stringify(i18nCatalogs)})` : "null"};
|
|
35067
36610
|
${config.i18n.enabled ? "_setDefaultFarmI18nRuntime(farmI18nRuntime);" : ""}
|
|
@@ -35119,6 +36662,9 @@ for (const route of pageRoutes) {
|
|
|
35119
36662
|
const layoutRoutes = [${layoutRegistrations.join(",")}
|
|
35120
36663
|
];
|
|
35121
36664
|
|
|
36665
|
+
const routeSlots = [${routeSlotRegistrations.join(",")}
|
|
36666
|
+
];
|
|
36667
|
+
|
|
35122
36668
|
// Route-level error boundaries bundled at build time.
|
|
35123
36669
|
const errorRoutes = [${errorRegistrations.join(",")}
|
|
35124
36670
|
];
|
|
@@ -35153,18 +36699,21 @@ function serializeFarmInlineValue(value) {
|
|
|
35153
36699
|
.replace(/\\u2029/g, "\\\\u2029");
|
|
35154
36700
|
}
|
|
35155
36701
|
|
|
35156
|
-
function renderFarmClientBootstrapScript(canonicalPath) {
|
|
36702
|
+
function renderFarmClientBootstrapScript(canonicalPath, selectedRouteSlots) {
|
|
35157
36703
|
const integrationManifest = ${hasRuntimeIntegrationConfig ? "getRegisteredIntegrationAPIManifest()" : "{}"};
|
|
36704
|
+
const serializedRouteSlots = serializeFarmInlineValue(selectedRouteSlots || []);
|
|
35158
36705
|
let source = 'window.__FARM_INTEGRATION_API_MANIFEST__=' +
|
|
35159
36706
|
serializeFarmInlineValue(integrationManifest) +
|
|
35160
|
-
';';
|
|
36707
|
+
';window.__FARM_ROUTE_SLOTS__=' + serializedRouteSlots + ';';
|
|
35161
36708
|
if (typeof canonicalPath === "string" && canonicalPath.startsWith("/")) {
|
|
35162
36709
|
const serializedPath = serializeFarmInlineValue(canonicalPath);
|
|
35163
36710
|
source += 'if(location.pathname+location.search!==' + serializedPath + '){' +
|
|
35164
36711
|
'history.replaceState(Object.assign({},history.state||{},{path:' + serializedPath + '}),"",' +
|
|
35165
36712
|
serializedPath + ');}';
|
|
35166
36713
|
}
|
|
35167
|
-
return '<script>' +
|
|
36714
|
+
return '<script id="__farm_route_slots_data__" type="application/json">' +
|
|
36715
|
+
serializedRouteSlots +
|
|
36716
|
+
'</script><script>' + source + '</script>';
|
|
35168
36717
|
}
|
|
35169
36718
|
|
|
35170
36719
|
function escapeFarmHtmlAttribute(value) {
|
|
@@ -35914,6 +37463,79 @@ function matchPageRoute(pathname) {
|
|
|
35914
37463
|
return null;
|
|
35915
37464
|
}
|
|
35916
37465
|
|
|
37466
|
+
function matchesRoutePrefix(pathname, pattern) {
|
|
37467
|
+
if (pattern === "/") return true;
|
|
37468
|
+
const pathSegments = normalizeRuntimePath(pathname).split("/").filter(Boolean);
|
|
37469
|
+
const patternSegments = normalizeRuntimePath(pattern).split("/").filter(Boolean);
|
|
37470
|
+
if (patternSegments.length > pathSegments.length) return false;
|
|
37471
|
+
const candidate = "/" + pathSegments.slice(0, patternSegments.length).join("/");
|
|
37472
|
+
return matchRuntimePathPattern(pattern, candidate) !== null;
|
|
37473
|
+
}
|
|
37474
|
+
|
|
37475
|
+
function routeSlotSpecificity(slot) {
|
|
37476
|
+
return slot.pattern.split("/").reduce(function(score, segment) {
|
|
37477
|
+
if (!segment) return score;
|
|
37478
|
+
if (segment.startsWith("[[...")) return score + 1;
|
|
37479
|
+
if (segment.startsWith("[...")) return score + 2;
|
|
37480
|
+
if (segment.startsWith("[")) return score + 3;
|
|
37481
|
+
return score + 10;
|
|
37482
|
+
}, 0);
|
|
37483
|
+
}
|
|
37484
|
+
|
|
37485
|
+
function matchRouteSlots(pathname, interceptFrom) {
|
|
37486
|
+
const groups = new Map();
|
|
37487
|
+
for (const slot of routeSlots) {
|
|
37488
|
+
if (!matchesRoutePrefix(pathname, slot.ownerPattern)) continue;
|
|
37489
|
+
const key = slot.ownerPattern + ":" + slot.name;
|
|
37490
|
+
const entries = groups.get(key) || [];
|
|
37491
|
+
entries.push(slot);
|
|
37492
|
+
groups.set(key, entries);
|
|
37493
|
+
}
|
|
37494
|
+
|
|
37495
|
+
const normalizedFrom =
|
|
37496
|
+
typeof interceptFrom === "string" && interceptFrom.startsWith("/")
|
|
37497
|
+
? new URL(interceptFrom, "http://farm.local").pathname
|
|
37498
|
+
: null;
|
|
37499
|
+
const matches = [];
|
|
37500
|
+
|
|
37501
|
+
for (const entries of groups.values()) {
|
|
37502
|
+
const candidates = entries
|
|
37503
|
+
.filter(function(entry) { return !entry.fallback; })
|
|
37504
|
+
.filter(function(entry) {
|
|
37505
|
+
return !entry.interception ||
|
|
37506
|
+
(normalizedFrom && matchesRoutePrefix(normalizedFrom, entry.ownerPattern));
|
|
37507
|
+
})
|
|
37508
|
+
.map(function(entry) {
|
|
37509
|
+
return {
|
|
37510
|
+
entry: entry,
|
|
37511
|
+
params: matchRuntimePathPattern(entry.pattern, pathname),
|
|
37512
|
+
};
|
|
37513
|
+
})
|
|
37514
|
+
.filter(function(candidate) { return candidate.params !== null; })
|
|
37515
|
+
.sort(function(left, right) {
|
|
37516
|
+
if (left.entry.interception !== right.entry.interception) {
|
|
37517
|
+
return left.entry.interception ? -1 : 1;
|
|
37518
|
+
}
|
|
37519
|
+
return routeSlotSpecificity(right.entry) - routeSlotSpecificity(left.entry);
|
|
37520
|
+
});
|
|
37521
|
+
|
|
37522
|
+
if (candidates[0]) {
|
|
37523
|
+
matches.push({ ...candidates[0].entry, params: candidates[0].params });
|
|
37524
|
+
continue;
|
|
37525
|
+
}
|
|
37526
|
+
|
|
37527
|
+
const fallback = entries.find(function(entry) { return entry.fallback; });
|
|
37528
|
+
if (fallback) matches.push({ ...fallback, params: {} });
|
|
37529
|
+
}
|
|
37530
|
+
|
|
37531
|
+
return matches.sort(function(left, right) {
|
|
37532
|
+
const ownerDepth =
|
|
37533
|
+
left.ownerPattern.split("/").filter(Boolean).length -
|
|
37534
|
+
right.ownerPattern.split("/").filter(Boolean).length;
|
|
37535
|
+
return ownerDepth || left.name.localeCompare(right.name);
|
|
37536
|
+
});
|
|
37537
|
+
}
|
|
37538
|
+
|
|
35917
37539
|
function hasLocalRequestRoute(request, routePathname) {
|
|
35918
37540
|
const pathname = new URL(request.url).pathname;
|
|
35919
37541
|
if (matchLocalAPIRequest(request) || matchLocalIntegrationRequest(request)) {
|
|
@@ -36064,6 +37686,7 @@ function getPPRShellBypassReason(request, middlewareData, middlewareContext) {
|
|
|
36064
37686
|
if (method !== "GET" && method !== "HEAD") return "method";
|
|
36065
37687
|
if (request.headers.get("cookie")) return "cookie";
|
|
36066
37688
|
if (request.headers.get("authorization")) return "authorization";
|
|
37689
|
+
if (request.headers.get("x-farm-intercept-from")) return "route-interception";
|
|
36067
37690
|
if (request.headers.get("x-farm-ppr-refresh")) return "refresh";
|
|
36068
37691
|
if (hasConfiguredRouteContext) return "route-context";
|
|
36069
37692
|
if (middlewareData?.size) return "middleware-data";
|
|
@@ -36117,8 +37740,8 @@ function getRouteSharedCacheControl(routeModule, pprCanCache) {
|
|
|
36117
37740
|
return "public, s-maxage=" + revalidate + ", stale-while-revalidate=300";
|
|
36118
37741
|
}
|
|
36119
37742
|
|
|
36120
|
-
function getCachedPPRShell(cacheKey) {
|
|
36121
|
-
const entry = pprShellCache.
|
|
37743
|
+
async function getCachedPPRShell(cacheKey) {
|
|
37744
|
+
const entry = await pprShellCache.getEntryAsync(cacheKey);
|
|
36122
37745
|
if (!entry) {
|
|
36123
37746
|
return null;
|
|
36124
37747
|
}
|
|
@@ -36333,7 +37956,7 @@ async function handleFarmRequestInContext(
|
|
|
36333
37956
|
}
|
|
36334
37957
|
}
|
|
36335
37958
|
if (pprCacheKey) {
|
|
36336
|
-
const cachedPPRShell = getCachedPPRShell(pprCacheKey);
|
|
37959
|
+
const cachedPPRShell = await getCachedPPRShell(pprCacheKey);
|
|
36337
37960
|
if (cachedPPRShell) {
|
|
36338
37961
|
emitFarmEvent({ type: "ppr.shell.hit", route: pathname, key: pprCacheKey });
|
|
36339
37962
|
emitFarmEvent({
|
|
@@ -36361,6 +37984,10 @@ async function handleFarmRequestInContext(
|
|
|
36361
37984
|
|
|
36362
37985
|
// Get applicable layouts for this page
|
|
36363
37986
|
const applicableLayouts = getApplicableLayouts(routePathname);
|
|
37987
|
+
const selectedRouteSlots = matchRouteSlots(
|
|
37988
|
+
routePathname,
|
|
37989
|
+
request.headers.get("x-farm-intercept-from"),
|
|
37990
|
+
);
|
|
36364
37991
|
|
|
36365
37992
|
if (PageComponent) {
|
|
36366
37993
|
// Parse search params - make it a resolved Promise for async components
|
|
@@ -36448,6 +38075,82 @@ async function handleFarmRequestInContext(
|
|
|
36448
38075
|
throw routeStateError;
|
|
36449
38076
|
}
|
|
36450
38077
|
}
|
|
38078
|
+
|
|
38079
|
+
const renderedRouteSlots = await Promise.all(
|
|
38080
|
+
selectedRouteSlots.map(async function(slot) {
|
|
38081
|
+
const slotContext = hasConfiguredRouteContext
|
|
38082
|
+
? await resolveFarmRouteContext(farmResolvedRuntimeConfig, {
|
|
38083
|
+
request,
|
|
38084
|
+
params: slot.params,
|
|
38085
|
+
search: searchParamsObj,
|
|
38086
|
+
path: pathname,
|
|
38087
|
+
})
|
|
38088
|
+
: undefined;
|
|
38089
|
+
const rawSlotProps = withFarmRouteContext(
|
|
38090
|
+
{
|
|
38091
|
+
params: slot.params,
|
|
38092
|
+
searchParams: Promise.resolve(searchParamsObj),
|
|
38093
|
+
path: pathname,
|
|
38094
|
+
...(middlewareData?.size ? { middleware: { data: middlewareData } } : {}),
|
|
38095
|
+
},
|
|
38096
|
+
slotContext,
|
|
38097
|
+
);
|
|
38098
|
+
if (slot.module.__farmResolveRouteProps && slotContext !== undefined) {
|
|
38099
|
+
Object.defineProperty(rawSlotProps, "context", {
|
|
38100
|
+
value: slotContext,
|
|
38101
|
+
enumerable: true,
|
|
38102
|
+
configurable: true,
|
|
38103
|
+
});
|
|
38104
|
+
}
|
|
38105
|
+
|
|
38106
|
+
const slotSchemas = slot.module.__farmRouteParsesProps
|
|
38107
|
+
? {}
|
|
38108
|
+
: slot.module.__farmRouteSchemas || {};
|
|
38109
|
+
let slotProps = slot.module.__farmResolveRouteProps
|
|
38110
|
+
? await slot.module.__farmResolveRouteProps(rawSlotProps)
|
|
38111
|
+
: {
|
|
38112
|
+
...rawSlotProps,
|
|
38113
|
+
params: slotSchemas.params?.parse
|
|
38114
|
+
? slotSchemas.params.parse(slot.params)
|
|
38115
|
+
: slot.params,
|
|
38116
|
+
search: slotSchemas.search?.parse
|
|
38117
|
+
? slotSchemas.search.parse(searchParamsObj)
|
|
38118
|
+
: searchParamsObj,
|
|
38119
|
+
searchParams: Promise.resolve(
|
|
38120
|
+
slotSchemas.search?.parse
|
|
38121
|
+
? slotSchemas.search.parse(searchParamsObj)
|
|
38122
|
+
: searchParamsObj,
|
|
38123
|
+
),
|
|
38124
|
+
};
|
|
38125
|
+
if (
|
|
38126
|
+
slot.module.__farmResolveRouteProps &&
|
|
38127
|
+
slotContext !== undefined &&
|
|
38128
|
+
slotProps.context === slotContext
|
|
38129
|
+
) {
|
|
38130
|
+
const { context: _slotContext, ...renderSlotProps } = slotProps;
|
|
38131
|
+
slotProps = renderSlotProps;
|
|
38132
|
+
}
|
|
38133
|
+
|
|
38134
|
+
return { ...slot, props: slotProps };
|
|
38135
|
+
}),
|
|
38136
|
+
);
|
|
38137
|
+
const routeSlotPayload = renderedRouteSlots.map(function(slot) {
|
|
38138
|
+
return {
|
|
38139
|
+
name: slot.name,
|
|
38140
|
+
ownerPattern: slot.ownerPattern,
|
|
38141
|
+
pattern: slot.pattern,
|
|
38142
|
+
containerId: slot.containerId,
|
|
38143
|
+
interception: slot.interception,
|
|
38144
|
+
fallback: slot.fallback,
|
|
38145
|
+
props: {
|
|
38146
|
+
params: slot.props.params,
|
|
38147
|
+
search: slot.props.search || searchParamsObj,
|
|
38148
|
+
searchParams: slot.props.search || searchParamsObj,
|
|
38149
|
+
...("data" in slot.props ? { data: slot.props.data } : {}),
|
|
38150
|
+
path: pathname,
|
|
38151
|
+
},
|
|
38152
|
+
};
|
|
38153
|
+
});
|
|
36451
38154
|
|
|
36452
38155
|
const renderPageElement = async () => {
|
|
36453
38156
|
// First, render the page content
|
|
@@ -36475,6 +38178,14 @@ async function handleFarmRequestInContext(
|
|
|
36475
38178
|
pageElement = React.createElement(PageComponent, pageProps);
|
|
36476
38179
|
}
|
|
36477
38180
|
|
|
38181
|
+
if (route.shouldHydrate && renderedRouteSlots.length > 0) {
|
|
38182
|
+
pageElement = React.createElement(
|
|
38183
|
+
"div",
|
|
38184
|
+
{ id: "__farm_page__", "data-farm-client": "true" },
|
|
38185
|
+
pageElement,
|
|
38186
|
+
);
|
|
38187
|
+
}
|
|
38188
|
+
|
|
36478
38189
|
// Wrap with layouts (from innermost to outermost)
|
|
36479
38190
|
// Layouts are sorted by depth (root first), so we process in reverse
|
|
36480
38191
|
let wrappedElement = pageElement;
|
|
@@ -36482,9 +38193,23 @@ async function handleFarmRequestInContext(
|
|
|
36482
38193
|
const layout = applicableLayouts[i];
|
|
36483
38194
|
const LayoutComponent = layout.module.default;
|
|
36484
38195
|
if (LayoutComponent) {
|
|
38196
|
+
const slotProps = {};
|
|
38197
|
+
for (const slot of renderedRouteSlots) {
|
|
38198
|
+
if (slot.ownerPattern !== layout.pattern) continue;
|
|
38199
|
+
slotProps[slot.name] = React.createElement(
|
|
38200
|
+
"div",
|
|
38201
|
+
{
|
|
38202
|
+
id: slot.containerId,
|
|
38203
|
+
"data-farm-route-slot": slot.name,
|
|
38204
|
+
"data-farm-slot-owner": slot.ownerPattern,
|
|
38205
|
+
},
|
|
38206
|
+
React.createElement(slot.module.default, slot.props),
|
|
38207
|
+
);
|
|
38208
|
+
}
|
|
36485
38209
|
wrappedElement = React.createElement(LayoutComponent, {
|
|
36486
38210
|
children: wrappedElement,
|
|
36487
38211
|
params,
|
|
38212
|
+
...slotProps,
|
|
36488
38213
|
});
|
|
36489
38214
|
}
|
|
36490
38215
|
}
|
|
@@ -36536,6 +38261,7 @@ async function handleFarmRequestInContext(
|
|
|
36536
38261
|
);
|
|
36537
38262
|
const hasRequestScopedRender = Boolean(
|
|
36538
38263
|
pageStatus >= 400 ||
|
|
38264
|
+
request.headers.get("x-farm-intercept-from") ||
|
|
36539
38265
|
hasPrivateRequestHeaders ||
|
|
36540
38266
|
hasConfiguredRouteContext ||
|
|
36541
38267
|
middlewareData?.size ||
|
|
@@ -36575,7 +38301,10 @@ async function handleFarmRequestInContext(
|
|
|
36575
38301
|
' <link rel="modulepreload" href="/farm-client.js">\\n' +
|
|
36576
38302
|
'</head>\\n<body>\\n <div id="root">';
|
|
36577
38303
|
const streamSuffix = '</div>\\n' +
|
|
36578
|
-
' ' + renderFarmClientBootstrapScript(
|
|
38304
|
+
' ' + renderFarmClientBootstrapScript(
|
|
38305
|
+
pageProps.__farmCanonicalPath,
|
|
38306
|
+
routeSlotPayload
|
|
38307
|
+
) + '\\n' +
|
|
36579
38308
|
' <script type="module" src="/farm-client.js"></script>\\n' +
|
|
36580
38309
|
'</body>\\n</html>';
|
|
36581
38310
|
const streamedDocument = createFarmDocumentStream(
|
|
@@ -36632,7 +38361,10 @@ async function handleFarmRequestInContext(
|
|
|
36632
38361
|
// Inject client script before closing body tag
|
|
36633
38362
|
.replace(
|
|
36634
38363
|
/<\\/body>/i,
|
|
36635
|
-
' ' + renderFarmClientBootstrapScript(
|
|
38364
|
+
' ' + renderFarmClientBootstrapScript(
|
|
38365
|
+
pageProps.__farmCanonicalPath,
|
|
38366
|
+
routeSlotPayload
|
|
38367
|
+
) + '\\n' +
|
|
36636
38368
|
' <script type="module" src="/farm-client.js"></script>\\n</body>',
|
|
36637
38369
|
);
|
|
36638
38370
|
|
|
@@ -36653,7 +38385,7 @@ async function handleFarmRequestInContext(
|
|
|
36653
38385
|
</head>
|
|
36654
38386
|
<body>
|
|
36655
38387
|
<div id="root">\${html}</div>
|
|
36656
|
-
\${renderFarmClientBootstrapScript(pageProps.__farmCanonicalPath)}
|
|
38388
|
+
\${renderFarmClientBootstrapScript(pageProps.__farmCanonicalPath, routeSlotPayload)}
|
|
36657
38389
|
<script type="module" src="/farm-client.js"></script>
|
|
36658
38390
|
</body>
|
|
36659
38391
|
</html>\`;
|
|
@@ -36661,7 +38393,7 @@ async function handleFarmRequestInContext(
|
|
|
36661
38393
|
fullHtml = applyFarmI18nDocument(fullHtml, pathname, farmI18nSnapshot);
|
|
36662
38394
|
|
|
36663
38395
|
if (pageStatus === 200 && pprCacheKey && request.method.toUpperCase() !== "HEAD") {
|
|
36664
|
-
pprShellCache.
|
|
38396
|
+
await pprShellCache.setAsync(
|
|
36665
38397
|
pprCacheKey,
|
|
36666
38398
|
{ html: fullHtml },
|
|
36667
38399
|
{
|
|
@@ -37854,6 +39586,13 @@ function mergeFarmViteConfig(farmConfig, userConfig = {}) {
|
|
|
37854
39586
|
...farmConfig.server,
|
|
37855
39587
|
...userConfig.server
|
|
37856
39588
|
},
|
|
39589
|
+
resolve: {
|
|
39590
|
+
...farmConfig.resolve,
|
|
39591
|
+
...userConfig.resolve,
|
|
39592
|
+
dedupe: Array.from(
|
|
39593
|
+
/* @__PURE__ */ new Set([...farmConfig.resolve?.dedupe || [], ...userConfig.resolve?.dedupe || []])
|
|
39594
|
+
)
|
|
39595
|
+
},
|
|
37857
39596
|
optimizeDeps: {
|
|
37858
39597
|
...farmConfig.optimizeDeps,
|
|
37859
39598
|
...userConfig.optimizeDeps,
|
|
@@ -38400,11 +40139,174 @@ function normalizeMutationError(error) {
|
|
|
38400
40139
|
}
|
|
38401
40140
|
__name(normalizeMutationError, "normalizeMutationError");
|
|
38402
40141
|
|
|
40142
|
+
// src/fetcher-client.tsx
|
|
40143
|
+
var import_react10 = require("react");
|
|
40144
|
+
var formDataContexts = /* @__PURE__ */ new WeakMap();
|
|
40145
|
+
function useFetcher(target, options = {}) {
|
|
40146
|
+
const targetRef = (0, import_react10.useRef)(target);
|
|
40147
|
+
const optionsRef = (0, import_react10.useRef)(options);
|
|
40148
|
+
const submissionIdRef = (0, import_react10.useRef)(0);
|
|
40149
|
+
const [formData, setFormData] = (0, import_react10.useState)(null);
|
|
40150
|
+
const mutation = useMutation(target, options);
|
|
40151
|
+
targetRef.current = target;
|
|
40152
|
+
optionsRef.current = options;
|
|
40153
|
+
const submitAsync = (0, import_react10.useCallback)(
|
|
40154
|
+
async (input) => {
|
|
40155
|
+
const submissionId = ++submissionIdRef.current;
|
|
40156
|
+
const submittedFormData = isFormData4(input) ? input : null;
|
|
40157
|
+
setFormData(submittedFormData);
|
|
40158
|
+
try {
|
|
40159
|
+
const variables = submittedFormData ? mapFetcherFormData(targetRef.current, submittedFormData, optionsRef.current) : input;
|
|
40160
|
+
return await mutation.mutateAsync(variables);
|
|
40161
|
+
} finally {
|
|
40162
|
+
if (submissionId === submissionIdRef.current) {
|
|
40163
|
+
setFormData(null);
|
|
40164
|
+
}
|
|
40165
|
+
}
|
|
40166
|
+
},
|
|
40167
|
+
[mutation.mutateAsync]
|
|
40168
|
+
);
|
|
40169
|
+
const submit = (0, import_react10.useCallback)(
|
|
40170
|
+
(input) => {
|
|
40171
|
+
void submitAsync(input).catch(() => {
|
|
40172
|
+
});
|
|
40173
|
+
},
|
|
40174
|
+
[submitAsync]
|
|
40175
|
+
);
|
|
40176
|
+
const Form = (0, import_react10.useMemo)(() => {
|
|
40177
|
+
const FetcherForm = /* @__PURE__ */ __name(({ action, method, encType, onSubmit, ...props }) => {
|
|
40178
|
+
const targetValue = targetRef.current;
|
|
40179
|
+
const metadata = getAPIRouteRefMetadata(targetValue);
|
|
40180
|
+
const nativeAction = action ?? resolveFetcherFormAction(targetValue, metadata);
|
|
40181
|
+
const nativeMethod = method ?? (metadata && (metadata.method === "GET" || metadata.method === "POST") ? metadata.method.toLowerCase() : metadata ? "post" : void 0);
|
|
40182
|
+
const functionAction = typeof nativeAction === "function";
|
|
40183
|
+
const handleSubmit = /* @__PURE__ */ __name((event) => {
|
|
40184
|
+
onSubmit?.(event);
|
|
40185
|
+
if (event.defaultPrevented) return;
|
|
40186
|
+
event.preventDefault();
|
|
40187
|
+
const submitter = getSubmitter(event);
|
|
40188
|
+
const nextFormData = createSubmitterFormData(event.currentTarget, submitter);
|
|
40189
|
+
formDataContexts.set(nextFormData, {
|
|
40190
|
+
form: event.currentTarget,
|
|
40191
|
+
submitter
|
|
40192
|
+
});
|
|
40193
|
+
void submitAsync(nextFormData).catch(() => {
|
|
40194
|
+
});
|
|
40195
|
+
}, "handleSubmit");
|
|
40196
|
+
return (0, import_react10.createElement)("form", {
|
|
40197
|
+
...props,
|
|
40198
|
+
action: nativeAction,
|
|
40199
|
+
method: functionAction ? void 0 : nativeMethod,
|
|
40200
|
+
encType: functionAction ? void 0 : encType,
|
|
40201
|
+
onSubmit: handleSubmit
|
|
40202
|
+
});
|
|
40203
|
+
}, "FetcherForm");
|
|
40204
|
+
FetcherForm.displayName = "FetcherForm";
|
|
40205
|
+
return FetcherForm;
|
|
40206
|
+
}, [submitAsync]);
|
|
40207
|
+
const reset = (0, import_react10.useCallback)(() => {
|
|
40208
|
+
submissionIdRef.current += 1;
|
|
40209
|
+
setFormData(null);
|
|
40210
|
+
mutation.reset();
|
|
40211
|
+
}, [mutation.reset]);
|
|
40212
|
+
return (0, import_react10.useMemo)(
|
|
40213
|
+
() => ({
|
|
40214
|
+
state: mutation.pending ? "submitting" : "idle",
|
|
40215
|
+
status: mutation.status,
|
|
40216
|
+
pending: mutation.pending,
|
|
40217
|
+
data: mutation.data,
|
|
40218
|
+
error: mutation.error,
|
|
40219
|
+
variables: mutation.variables,
|
|
40220
|
+
formData,
|
|
40221
|
+
submit,
|
|
40222
|
+
submitAsync,
|
|
40223
|
+
Form,
|
|
40224
|
+
reset
|
|
40225
|
+
}),
|
|
40226
|
+
[
|
|
40227
|
+
Form,
|
|
40228
|
+
formData,
|
|
40229
|
+
mutation.data,
|
|
40230
|
+
mutation.error,
|
|
40231
|
+
mutation.pending,
|
|
40232
|
+
mutation.status,
|
|
40233
|
+
mutation.variables,
|
|
40234
|
+
reset,
|
|
40235
|
+
submit,
|
|
40236
|
+
submitAsync
|
|
40237
|
+
]
|
|
40238
|
+
);
|
|
40239
|
+
}
|
|
40240
|
+
__name(useFetcher, "useFetcher");
|
|
40241
|
+
function mapFetcherFormData(target, formData, options) {
|
|
40242
|
+
const context = formDataContexts.get(formData) ?? { form: null, submitter: null };
|
|
40243
|
+
if (options.mapFormData) {
|
|
40244
|
+
return options.mapFormData(formData, context);
|
|
40245
|
+
}
|
|
40246
|
+
if (!isAPIRouteRef(target)) {
|
|
40247
|
+
return formData;
|
|
40248
|
+
}
|
|
40249
|
+
const values = formDataToObject3(formData);
|
|
40250
|
+
const method = getAPIRouteRefMetadata(target)?.method;
|
|
40251
|
+
return method === "GET" || method === "HEAD" ? { query: values } : { body: values };
|
|
40252
|
+
}
|
|
40253
|
+
__name(mapFetcherFormData, "mapFetcherFormData");
|
|
40254
|
+
function resolveFetcherFormAction(target, metadata) {
|
|
40255
|
+
if (!metadata) return isProgressiveFormAction(target) ? target : void 0;
|
|
40256
|
+
if (metadata.sameOrigin) return metadata.path;
|
|
40257
|
+
return new URL(metadata.path, metadata.baseURL).href;
|
|
40258
|
+
}
|
|
40259
|
+
__name(resolveFetcherFormAction, "resolveFetcherFormAction");
|
|
40260
|
+
function formDataToObject3(formData) {
|
|
40261
|
+
const output = /* @__PURE__ */ Object.create(null);
|
|
40262
|
+
for (const [key, value] of formData.entries()) {
|
|
40263
|
+
if (key === "__proto__" || key === "constructor" || key === "prototype") continue;
|
|
40264
|
+
const current = output[key];
|
|
40265
|
+
if (current === void 0) {
|
|
40266
|
+
output[key] = value;
|
|
40267
|
+
} else if (Array.isArray(current)) {
|
|
40268
|
+
current.push(value);
|
|
40269
|
+
} else {
|
|
40270
|
+
output[key] = [current, value];
|
|
40271
|
+
}
|
|
40272
|
+
}
|
|
40273
|
+
return output;
|
|
40274
|
+
}
|
|
40275
|
+
__name(formDataToObject3, "formDataToObject");
|
|
40276
|
+
function createSubmitterFormData(form, submitter) {
|
|
40277
|
+
try {
|
|
40278
|
+
return new FormData(form, submitter);
|
|
40279
|
+
} catch {
|
|
40280
|
+
const formData = new FormData(form);
|
|
40281
|
+
const candidate = submitter;
|
|
40282
|
+
if (candidate && !candidate.disabled && candidate.name) {
|
|
40283
|
+
formData.append(candidate.name, candidate.value ?? "");
|
|
40284
|
+
}
|
|
40285
|
+
return formData;
|
|
40286
|
+
}
|
|
40287
|
+
}
|
|
40288
|
+
__name(createSubmitterFormData, "createSubmitterFormData");
|
|
40289
|
+
function getSubmitter(event) {
|
|
40290
|
+
const nativeEvent = event.nativeEvent;
|
|
40291
|
+
return nativeEvent.submitter instanceof HTMLElement ? nativeEvent.submitter : null;
|
|
40292
|
+
}
|
|
40293
|
+
__name(getSubmitter, "getSubmitter");
|
|
40294
|
+
function isProgressiveFormAction(target) {
|
|
40295
|
+
const candidate = target;
|
|
40296
|
+
return candidate.__farmServerFn === true || typeof candidate.$$FORM_ACTION === "function" || candidate.$$typeof === /* @__PURE__ */ Symbol.for("react.server.reference");
|
|
40297
|
+
}
|
|
40298
|
+
__name(isProgressiveFormAction, "isProgressiveFormAction");
|
|
40299
|
+
function isFormData4(value) {
|
|
40300
|
+
if (!value || typeof value !== "object") return false;
|
|
40301
|
+
return typeof FormData !== "undefined" && value instanceof FormData || Object.prototype.toString.call(value) === "[object FormData]" && typeof value.entries === "function";
|
|
40302
|
+
}
|
|
40303
|
+
__name(isFormData4, "isFormData");
|
|
40304
|
+
|
|
38403
40305
|
// src/client.ts
|
|
38404
40306
|
init_integration_api();
|
|
38405
40307
|
|
|
38406
40308
|
// src/store.ts
|
|
38407
|
-
var
|
|
40309
|
+
var import_react11 = require("react");
|
|
38408
40310
|
var RESERVED_STORE_KEYS = /* @__PURE__ */ new Set([
|
|
38409
40311
|
"use",
|
|
38410
40312
|
"get",
|
|
@@ -38536,20 +40438,20 @@ function createStore(initialState, extend) {
|
|
|
38536
40438
|
}
|
|
38537
40439
|
return lastSlice;
|
|
38538
40440
|
}, "getSnapshot");
|
|
38539
|
-
return (0,
|
|
40441
|
+
return (0, import_react11.useSyncExternalStore)(
|
|
38540
40442
|
(notify) => addSubscription(keys, () => notify()),
|
|
38541
40443
|
getSnapshot,
|
|
38542
40444
|
getSnapshot
|
|
38543
40445
|
);
|
|
38544
40446
|
}
|
|
38545
40447
|
if (typeof keyOrKeys === "string") {
|
|
38546
|
-
return (0,
|
|
40448
|
+
return (0, import_react11.useSyncExternalStore)(
|
|
38547
40449
|
(notify) => addSubscription([keyOrKeys], () => notify()),
|
|
38548
40450
|
() => state[keyOrKeys],
|
|
38549
40451
|
() => state[keyOrKeys]
|
|
38550
40452
|
);
|
|
38551
40453
|
}
|
|
38552
|
-
return (0,
|
|
40454
|
+
return (0, import_react11.useSyncExternalStore)(
|
|
38553
40455
|
(notify) => addSubscription(null, () => notify()),
|
|
38554
40456
|
() => state,
|
|
38555
40457
|
() => state
|
|
@@ -38601,7 +40503,7 @@ function createStore(initialState, extend) {
|
|
|
38601
40503
|
__name(createStore, "createStore");
|
|
38602
40504
|
|
|
38603
40505
|
// src/client/link.tsx
|
|
38604
|
-
var
|
|
40506
|
+
var import_react12 = require("react");
|
|
38605
40507
|
init_router();
|
|
38606
40508
|
init_client_runtime();
|
|
38607
40509
|
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
@@ -38663,9 +40565,9 @@ function LinkInner({
|
|
|
38663
40565
|
onTouchStart,
|
|
38664
40566
|
...props
|
|
38665
40567
|
}, ref) {
|
|
38666
|
-
const elementRef = (0,
|
|
38667
|
-
const intentTimeoutRef = (0,
|
|
38668
|
-
const hasPrefetched = (0,
|
|
40568
|
+
const elementRef = (0, import_react12.useRef)(null);
|
|
40569
|
+
const intentTimeoutRef = (0, import_react12.useRef)(null);
|
|
40570
|
+
const hasPrefetched = (0, import_react12.useRef)(false);
|
|
38669
40571
|
const { intent, viewport, render } = normalizePrefetch(prefetch2);
|
|
38670
40572
|
const baseHref = resolveLinkHref(href, params, {
|
|
38671
40573
|
query,
|
|
@@ -38674,17 +40576,17 @@ function LinkInner({
|
|
|
38674
40576
|
});
|
|
38675
40577
|
const resolvedHref = localizeActiveFarmHref(baseHref, locale);
|
|
38676
40578
|
const isExternal = isExternalUrl(resolvedHref);
|
|
38677
|
-
const doPrefetch = (0,
|
|
40579
|
+
const doPrefetch = (0, import_react12.useCallback)(() => {
|
|
38678
40580
|
if (isExternal || hasPrefetched.current) return;
|
|
38679
40581
|
const router = getRouter2();
|
|
38680
40582
|
if (!router) return;
|
|
38681
40583
|
hasPrefetched.current = true;
|
|
38682
40584
|
router.prefetch(resolvedHref);
|
|
38683
40585
|
}, [resolvedHref, isExternal]);
|
|
38684
|
-
(0,
|
|
40586
|
+
(0, import_react12.useEffect)(() => {
|
|
38685
40587
|
hasPrefetched.current = false;
|
|
38686
40588
|
}, [resolvedHref]);
|
|
38687
|
-
(0,
|
|
40589
|
+
(0, import_react12.useEffect)(() => {
|
|
38688
40590
|
const element = elementRef.current;
|
|
38689
40591
|
if (!element || isExternal) return;
|
|
38690
40592
|
const router = getRouter2();
|
|
@@ -38694,7 +40596,7 @@ function LinkInner({
|
|
|
38694
40596
|
return () => router.unobserveForPrefetch(element);
|
|
38695
40597
|
}
|
|
38696
40598
|
}, [resolvedHref, viewport, isExternal]);
|
|
38697
|
-
(0,
|
|
40599
|
+
(0, import_react12.useEffect)(() => {
|
|
38698
40600
|
if (!render || isExternal) return;
|
|
38699
40601
|
let cancelled = false;
|
|
38700
40602
|
let timeoutId = null;
|
|
@@ -38716,7 +40618,7 @@ function LinkInner({
|
|
|
38716
40618
|
}
|
|
38717
40619
|
};
|
|
38718
40620
|
}, [render, isExternal, resolvedHref]);
|
|
38719
|
-
(0,
|
|
40621
|
+
(0, import_react12.useEffect)(() => {
|
|
38720
40622
|
return () => {
|
|
38721
40623
|
if (intentTimeoutRef.current) {
|
|
38722
40624
|
clearTimeout(intentTimeoutRef.current);
|
|
@@ -38724,13 +40626,13 @@ function LinkInner({
|
|
|
38724
40626
|
}
|
|
38725
40627
|
};
|
|
38726
40628
|
}, []);
|
|
38727
|
-
const cancelIntent = (0,
|
|
40629
|
+
const cancelIntent = (0, import_react12.useCallback)(() => {
|
|
38728
40630
|
if (intentTimeoutRef.current) {
|
|
38729
40631
|
clearTimeout(intentTimeoutRef.current);
|
|
38730
40632
|
intentTimeoutRef.current = null;
|
|
38731
40633
|
}
|
|
38732
40634
|
}, []);
|
|
38733
|
-
const scheduleIntentPrefetch = (0,
|
|
40635
|
+
const scheduleIntentPrefetch = (0, import_react12.useCallback)(() => {
|
|
38734
40636
|
if (isExternal || !intent || hasPrefetched.current) return;
|
|
38735
40637
|
cancelIntent();
|
|
38736
40638
|
intentTimeoutRef.current = setTimeout(() => {
|
|
@@ -38738,42 +40640,42 @@ function LinkInner({
|
|
|
38738
40640
|
doPrefetch();
|
|
38739
40641
|
}, prefetchDelay);
|
|
38740
40642
|
}, [intent, isExternal, prefetchDelay, doPrefetch, cancelIntent]);
|
|
38741
|
-
const handleMouseEnter = (0,
|
|
40643
|
+
const handleMouseEnter = (0, import_react12.useCallback)(
|
|
38742
40644
|
(event) => {
|
|
38743
40645
|
onMouseEnter?.(event);
|
|
38744
40646
|
scheduleIntentPrefetch();
|
|
38745
40647
|
},
|
|
38746
40648
|
[onMouseEnter, scheduleIntentPrefetch]
|
|
38747
40649
|
);
|
|
38748
|
-
const handleMouseLeave = (0,
|
|
40650
|
+
const handleMouseLeave = (0, import_react12.useCallback)(
|
|
38749
40651
|
(event) => {
|
|
38750
40652
|
onMouseLeave?.(event);
|
|
38751
40653
|
cancelIntent();
|
|
38752
40654
|
},
|
|
38753
40655
|
[onMouseLeave, cancelIntent]
|
|
38754
40656
|
);
|
|
38755
|
-
const handleTouchStart = (0,
|
|
40657
|
+
const handleTouchStart = (0, import_react12.useCallback)(
|
|
38756
40658
|
(event) => {
|
|
38757
40659
|
onTouchStart?.(event);
|
|
38758
40660
|
scheduleIntentPrefetch();
|
|
38759
40661
|
},
|
|
38760
40662
|
[onTouchStart, scheduleIntentPrefetch]
|
|
38761
40663
|
);
|
|
38762
|
-
const handleFocus = (0,
|
|
40664
|
+
const handleFocus = (0, import_react12.useCallback)(
|
|
38763
40665
|
(event) => {
|
|
38764
40666
|
onFocus?.(event);
|
|
38765
40667
|
scheduleIntentPrefetch();
|
|
38766
40668
|
},
|
|
38767
40669
|
[onFocus, scheduleIntentPrefetch]
|
|
38768
40670
|
);
|
|
38769
|
-
const handleBlur = (0,
|
|
40671
|
+
const handleBlur = (0, import_react12.useCallback)(
|
|
38770
40672
|
(event) => {
|
|
38771
40673
|
onBlur?.(event);
|
|
38772
40674
|
cancelIntent();
|
|
38773
40675
|
},
|
|
38774
40676
|
[onBlur, cancelIntent]
|
|
38775
40677
|
);
|
|
38776
|
-
const handleClick = (0,
|
|
40678
|
+
const handleClick = (0, import_react12.useCallback)(
|
|
38777
40679
|
(event) => {
|
|
38778
40680
|
onClick?.(event);
|
|
38779
40681
|
if (event.defaultPrevented) return;
|
|
@@ -38798,7 +40700,7 @@ function LinkInner({
|
|
|
38798
40700
|
},
|
|
38799
40701
|
[resolvedHref, replace, scroll, viewTransition, target, isExternal, onClick]
|
|
38800
40702
|
);
|
|
38801
|
-
const setRefs = (0,
|
|
40703
|
+
const setRefs = (0, import_react12.useCallback)(
|
|
38802
40704
|
(node) => {
|
|
38803
40705
|
elementRef.current = node;
|
|
38804
40706
|
if (typeof ref === "function") ref(node);
|
|
@@ -38827,7 +40729,7 @@ function LinkInner({
|
|
|
38827
40729
|
);
|
|
38828
40730
|
}
|
|
38829
40731
|
__name(LinkInner, "LinkInner");
|
|
38830
|
-
var LinkWithRef = (0,
|
|
40732
|
+
var LinkWithRef = (0, import_react12.forwardRef)(LinkInner);
|
|
38831
40733
|
LinkWithRef.displayName = "Link";
|
|
38832
40734
|
var Link = LinkWithRef;
|
|
38833
40735
|
function resolveLinkHref(href, params, options) {
|
|
@@ -39553,6 +41455,7 @@ __name(decodeCookiePart, "decodeCookiePart");
|
|
|
39553
41455
|
DeferredDataError,
|
|
39554
41456
|
DocsRoute,
|
|
39555
41457
|
EndpointFailure,
|
|
41458
|
+
FARM_API_ROUTE_META_SYMBOL,
|
|
39556
41459
|
FARM_API_ROUTE_REF_SYMBOL,
|
|
39557
41460
|
FARM_CRON_MANIFEST,
|
|
39558
41461
|
FARM_DEFERRED_BRAND,
|
|
@@ -39597,6 +41500,7 @@ __name(decodeCookiePart, "decodeCookiePart");
|
|
|
39597
41500
|
_withAfterNodeMiddleware,
|
|
39598
41501
|
after,
|
|
39599
41502
|
api,
|
|
41503
|
+
applyFarmCacheInvalidationTargets,
|
|
39600
41504
|
applyFarmCacheInvalidations,
|
|
39601
41505
|
applyFarmCronVercelCrons,
|
|
39602
41506
|
applyFarmWorkflowVercelCrons,
|
|
@@ -39614,6 +41518,7 @@ __name(decodeCookiePart, "decodeCookiePart");
|
|
|
39614
41518
|
buildFarmRoutePath,
|
|
39615
41519
|
collectSSGPages,
|
|
39616
41520
|
completeFarmServerQueryAction,
|
|
41521
|
+
configureFarmCache,
|
|
39617
41522
|
configureFarmObservability,
|
|
39618
41523
|
cookies,
|
|
39619
41524
|
createAPIClient,
|
|
@@ -39713,6 +41618,7 @@ __name(decodeCookiePart, "decodeCookiePart");
|
|
|
39713
41618
|
generateFarmTypeArtifacts,
|
|
39714
41619
|
generateRouteTypes,
|
|
39715
41620
|
generateSSGManifest,
|
|
41621
|
+
getAPIRouteRefMetadata,
|
|
39716
41622
|
getCurrentRequest,
|
|
39717
41623
|
getDeployTargetForPreset,
|
|
39718
41624
|
getEnv,
|
|
@@ -39772,6 +41678,7 @@ __name(decodeCookiePart, "decodeCookiePart");
|
|
|
39772
41678
|
isCronRequestAuthorized,
|
|
39773
41679
|
isDeferred,
|
|
39774
41680
|
isEndpointFailure,
|
|
41681
|
+
isFarmAPIStream,
|
|
39775
41682
|
isFarmDeploymentMismatchResponse,
|
|
39776
41683
|
isFarmDocsAPIRequest,
|
|
39777
41684
|
isFarmDocsRequest,
|
|
@@ -39780,10 +41687,13 @@ __name(decodeCookiePart, "decodeCookiePart");
|
|
|
39780
41687
|
isFarmNotFoundError,
|
|
39781
41688
|
isFarmRedirectError,
|
|
39782
41689
|
isFarmRouteActive,
|
|
41690
|
+
isJSONStreamResponse,
|
|
41691
|
+
isMultipartSchema,
|
|
39783
41692
|
isProgrammaticRouteManifest,
|
|
39784
41693
|
isProgrammaticRoutesFileName,
|
|
39785
41694
|
isSSGModule,
|
|
39786
41695
|
isWebResponse,
|
|
41696
|
+
jsonStream,
|
|
39787
41697
|
layout,
|
|
39788
41698
|
libsqlStorage,
|
|
39789
41699
|
loadConfig,
|
|
@@ -39803,6 +41713,7 @@ __name(decodeCookiePart, "decodeCookiePart");
|
|
|
39803
41713
|
mergeScheduledTasks,
|
|
39804
41714
|
middleware,
|
|
39805
41715
|
mongodbStorage,
|
|
41716
|
+
multipart,
|
|
39806
41717
|
mysql2Storage,
|
|
39807
41718
|
mysqlStorage,
|
|
39808
41719
|
navigateTo,
|
|
@@ -39839,6 +41750,7 @@ __name(decodeCookiePart, "decodeCookiePart");
|
|
|
39839
41750
|
publicEnv,
|
|
39840
41751
|
pushState,
|
|
39841
41752
|
readDeferredDataResponse,
|
|
41753
|
+
readJSONStream,
|
|
39842
41754
|
readPageState,
|
|
39843
41755
|
redirect,
|
|
39844
41756
|
redisStorage,
|
|
@@ -39883,13 +41795,16 @@ __name(decodeCookiePart, "decodeCookiePart");
|
|
|
39883
41795
|
setEnv,
|
|
39884
41796
|
snapshotDeferredData,
|
|
39885
41797
|
sqliteStorage,
|
|
41798
|
+
storageCacheAdapter,
|
|
39886
41799
|
titleFromMarkdown,
|
|
41800
|
+
toFormData,
|
|
39887
41801
|
toViteModuleId,
|
|
39888
41802
|
unstable_cache,
|
|
39889
41803
|
unwrapMiddleware,
|
|
39890
41804
|
updateTag,
|
|
39891
41805
|
upstashStorage,
|
|
39892
41806
|
useBlocker,
|
|
41807
|
+
useFetcher,
|
|
39893
41808
|
useMutation,
|
|
39894
41809
|
useNavigation,
|
|
39895
41810
|
usePageState,
|