@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
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cache.ts"],"sourcesContent":["import { emitFarmEvent } from \"./observability\";\nimport { notifyFarmCacheInvalidation, notifyFarmCacheTask } from \"./cache-invalidation\";\nimport { getActiveFarmI18nSnapshot } from \"./i18n/bridge\";\n\nexport { applyFarmCacheInvalidations } from \"./cache-invalidation\";\n\nexport type RevalidateTagProfile =\n | \"max\"\n | \"default\"\n | \"seconds\"\n | \"minutes\"\n | \"hours\"\n | \"days\"\n | \"weeks\"\n | \"months\"\n | { expire?: number };\n\nexport interface FarmCacheOptions {\n /**\n * Tag cached data so it can be invalidated with revalidateTag/updateTag.\n */\n tags?: readonly string[];\n /**\n * Path tags let revalidatePath invalidate data tied to a route.\n */\n paths?: readonly string[];\n /**\n * Time in seconds before the entry becomes stale. False means no TTL.\n */\n revalidate?: number | false;\n}\n\nexport interface FarmCacheSetOptions extends FarmCacheOptions {\n createdAt?: number;\n}\n\nexport type RouteDataCacheKey = string | readonly unknown[];\n\nexport type FarmCacheInvalidationTarget =\n | { key: RouteDataCacheKey }\n | { path: string }\n | { tag: string };\n\ndeclare const FARM_DEFINED_CACHE_KEY_DATA: unique symbol;\n\n/**\n * A regular Farm cache key carrying the data shape stored under that key.\n *\n * The brand exists only in TypeScript. At runtime the value remains the\n * original string or structured array, so all existing cache APIs continue to\n * accept untyped keys.\n */\nexport type DefinedCacheKey<TData, TKey extends RouteDataCacheKey = RouteDataCacheKey> = TKey & {\n readonly [FARM_DEFINED_CACHE_KEY_DATA]: TData;\n};\n\nexport type CacheKeyFactory<\n TData,\n TArguments extends readonly unknown[],\n TKey extends RouteDataCacheKey = RouteDataCacheKey,\n> = (...args: TArguments) => DefinedCacheKey<TData, TKey>;\n\nexport type InferCacheKeyData<TKey> =\n TKey extends DefinedCacheKey<infer TData, RouteDataCacheKey> ? TData : unknown;\n\n/**\n * Optionally add a data type to an existing string/array cache-key factory.\n *\n * This helper does not introduce a new runtime key representation. Calling the\n * returned factory produces the exact key returned by `factory`.\n */\nexport function defineCacheKey<TData>() {\n return <const TArguments extends readonly unknown[], const TKey extends RouteDataCacheKey>(\n factory: (...args: TArguments) => TKey,\n ): CacheKeyFactory<TData, TArguments, TKey> => {\n if (typeof factory !== \"function\") {\n throw new TypeError(\"defineCacheKey expects a key factory function.\");\n }\n\n return ((...args: TArguments) => {\n const key = factory(...args);\n if (typeof key !== \"string\" && !Array.isArray(key)) {\n throw new TypeError(\n \"A defined cache key factory must return a string or structured array.\",\n );\n }\n return key as DefinedCacheKey<TData, TKey>;\n }) as CacheKeyFactory<TData, TArguments, TKey>;\n };\n}\n\nexport interface FarmCacheEntry<T = unknown> {\n key: string;\n value: T;\n tags: readonly string[];\n /**\n * Adapter tag versions captured before the cached value was produced.\n * A later version makes the entry stale across every server instance.\n */\n tagVersions?: Readonly<Record<string, number>>;\n createdAt: number;\n createdVersion?: number;\n revalidate?: number | false;\n}\n\ninterface InternalFarmCacheEntry<T = unknown> {\n key: string;\n value: T;\n tags: Set<string>;\n tagVersions?: Readonly<Record<string, number>>;\n createdAt: number;\n createdVersion: number;\n revalidate?: number | false;\n}\n\n/**\n * Asynchronous persistence contract used by distributed Farm caches.\n *\n * Implementations are responsible for serializing cache entries and making\n * tag version updates atomic when the backing service supports it.\n */\nexport interface FarmCacheAdapter {\n readonly name?: string;\n get<T = unknown>(key: string): Promise<FarmCacheEntry<T> | null | undefined>;\n set<T = unknown>(key: string, entry: FarmCacheEntry<T>): Promise<void>;\n delete(key: string): Promise<void>;\n clear?(): Promise<void>;\n getTagVersions?(tags: readonly string[]): Promise<Readonly<Record<string, number>>>;\n invalidateTags?(tags: readonly string[]): Promise<void>;\n /** Atomically acquire a short-lived regeneration lease. */\n acquireLease?(key: string, ttlMs: number): Promise<string | null | undefined>;\n /** Release the lease only when the supplied ownership token still matches. */\n releaseLease?(key: string, token: string): Promise<void>;\n}\n\nexport interface FarmCacheUserConfig {\n /** Shared cache implementation, for example a Redis-backed adapter. */\n adapter?: FarmCacheAdapter;\n /** Prefix isolating applications and deployments sharing one adapter. */\n namespace?: string;\n /**\n * Coordinate cache fills across processes when the adapter implements\n * acquireLease/releaseLease. Set false to disable.\n */\n lease?:\n | false\n | {\n ttlMs?: number;\n waitTimeoutMs?: number;\n pollIntervalMs?: number;\n };\n}\n\nexport interface FarmCacheStorage {\n getItem<T = unknown>(key: string): Promise<T | null>;\n setItem<T = unknown>(key: string, value: T): Promise<unknown>;\n removeItem(key: string): Promise<unknown>;\n clear?(base?: string): Promise<unknown>;\n}\n\nexport interface StorageFarmCacheAdapterOptions {\n /** Prefix used inside the supplied storage client. */\n base?: string;\n}\n\n/**\n * Adapt a Farm/unstorage-compatible key-value client to the cache contract.\n *\n * This is a portable baseline adapter. Provider-specific adapters should use\n * their atomic increment/transaction primitives for tag invalidation.\n */\nexport function storageCacheAdapter(\n storage: FarmCacheStorage,\n options: StorageFarmCacheAdapterOptions = {},\n): FarmCacheAdapter {\n if (!storage || typeof storage.getItem !== \"function\" || typeof storage.setItem !== \"function\") {\n throw new TypeError(\"storageCacheAdapter expects a compatible storage client.\");\n }\n\n const base = normalizeCacheNamespace(options.base || \"farm-cache\");\n const entryKey = (key: string) => `${base}:entry:${key}`;\n const tagKey = (tag: string) => `${base}:tag:${tag}`;\n\n return {\n name: \"storage\",\n get: <T>(key: string) => storage.getItem<FarmCacheEntry<T>>(entryKey(key)),\n set: async <T>(key: string, entry: FarmCacheEntry<T>) => {\n await storage.setItem(entryKey(key), entry);\n },\n delete: async (key: string) => {\n await storage.removeItem(entryKey(key));\n },\n clear: storage.clear\n ? async () => {\n await storage.clear!(base);\n }\n : undefined,\n getTagVersions: async (tags) => {\n const versions = await Promise.all(\n tags.map(async (tag) => {\n const value = await storage.getItem<number>(tagKey(tag));\n return [tag, normalizeAdapterVersion(value)] as const;\n }),\n );\n return Object.fromEntries(versions);\n },\n invalidateTags: async (tags) => {\n await Promise.all(\n tags.map(async (tag) => {\n const key = tagKey(tag);\n const current = normalizeAdapterVersion(await storage.getItem<number>(key));\n await storage.setItem(key, Math.max(Date.now(), current + 1));\n }),\n );\n },\n };\n}\n\nexport interface GetFarmCacheEntryOptions {\n allowStale?: boolean;\n now?: number;\n}\n\ninterface FarmCacheStaleEntry {\n tags: Iterable<string>;\n createdAt: number;\n createdVersion?: number;\n revalidate?: number | false;\n}\n\nexport class FarmDataCache {\n private entries = new Map<string, InternalFarmCacheEntry>();\n private inflight = new Map<string, Promise<unknown>>();\n private invalidatedTagVersions = new Map<string, number>();\n private version = 0;\n private adapter?: FarmCacheAdapter;\n private namespace = \"farm\";\n private local = true;\n private lease = {\n enabled: true,\n ttlMs: 10_000,\n waitTimeoutMs: 10_000,\n pollIntervalMs: 25,\n };\n\n constructor(config: FarmCacheUserConfig = {}) {\n this.configure(config);\n }\n\n configure(config: FarmCacheUserConfig = {}): void {\n this.adapter = config.adapter;\n this.namespace = normalizeCacheNamespace(config.namespace || \"farm\");\n this.local = !config.adapter;\n this.lease =\n config.lease === false\n ? { ...this.lease, enabled: false }\n : {\n enabled: true,\n ttlMs: normalizePositiveDuration(config.lease?.ttlMs, 10_000, \"cache.lease.ttlMs\"),\n waitTimeoutMs: normalizePositiveDuration(\n config.lease?.waitTimeoutMs,\n 10_000,\n \"cache.lease.waitTimeoutMs\",\n ),\n pollIntervalMs: normalizePositiveDuration(\n config.lease?.pollIntervalMs,\n 25,\n \"cache.lease.pollIntervalMs\",\n ),\n };\n if (!this.local) {\n this.entries.clear();\n this.inflight.clear();\n this.invalidatedTagVersions.clear();\n this.version = 0;\n }\n }\n\n get adapterName(): string {\n return this.adapter?.name || (this.adapter ? \"custom\" : \"memory\");\n }\n\n get hasAdapter(): boolean {\n return this.adapter !== undefined;\n }\n\n get size(): number {\n return this.entries.size;\n }\n\n get<T>(key: string, options: GetFarmCacheEntryOptions = {}): T | undefined {\n return this.getEntry<T>(key, options)?.value;\n }\n\n getEntry<T = unknown>(\n key: string,\n options: GetFarmCacheEntryOptions = {},\n ): FarmCacheEntry<T> | undefined {\n const entry = this.entries.get(key) as InternalFarmCacheEntry<T> | undefined;\n if (!entry) {\n emitFarmEvent({ type: \"cache.miss\", key });\n return undefined;\n }\n\n const stale = this.isStale(entry, options.now);\n if (stale) {\n emitFarmEvent({\n type: \"cache.stale\",\n key,\n tags: Array.from(entry.tags),\n revalidate: entry.revalidate,\n });\n }\n\n if (!options.allowStale && stale) {\n emitFarmEvent({ type: \"cache.miss\", key, reason: \"stale\" });\n return undefined;\n }\n\n emitFarmEvent({\n type: \"cache.hit\",\n key,\n tags: Array.from(entry.tags),\n revalidate: entry.revalidate,\n stale,\n });\n\n return this.toPublicEntry(entry);\n }\n\n async getEntryAsync<T = unknown>(\n key: string,\n options: GetFarmCacheEntryOptions = {},\n ): Promise<FarmCacheEntry<T> | undefined> {\n if (this.local) {\n const localEntry = this.getEntry<T>(key, options);\n if (localEntry) return localEntry;\n }\n\n if (!this.adapter) {\n return this.local ? undefined : this.getEntry<T>(key, options);\n }\n\n const entry = await this.adapter.get<T>(this.createAdapterKey(key));\n if (!entry) {\n emitFarmEvent({ type: \"cache.miss\", key });\n return undefined;\n }\n\n assertFarmCacheEntry(entry, key);\n const stale = await this.isAdapterEntryStale(entry, options.now);\n if (stale) {\n emitFarmEvent({\n type: \"cache.stale\",\n key,\n tags: [...entry.tags],\n revalidate: entry.revalidate,\n });\n if (!options.allowStale) {\n emitFarmEvent({ type: \"cache.miss\", key, reason: \"stale\" });\n return undefined;\n }\n }\n\n emitFarmEvent({\n type: \"cache.hit\",\n key,\n tags: [...entry.tags],\n revalidate: entry.revalidate,\n stale,\n });\n\n if (this.local && !stale) {\n this.hydrateLocalEntry(entry);\n }\n return { ...entry, key };\n }\n\n set<T>(key: string, value: T, options: FarmCacheSetOptions = {}): FarmCacheEntry<T> {\n const tags = new Set<string>();\n for (const tag of options.tags ?? []) {\n tags.add(normalizeCacheTag(tag));\n }\n for (const routePath of options.paths ?? []) {\n tags.add(createPathCacheTag(routePath));\n }\n\n const entry: InternalFarmCacheEntry<T> = {\n key,\n value,\n tags,\n tagVersions: undefined,\n createdAt: options.createdAt ?? Date.now(),\n createdVersion: ++this.version,\n revalidate: normalizeRevalidate(options.revalidate),\n };\n\n this.entries.set(key, entry);\n emitFarmEvent({\n type: \"cache.set\",\n key,\n tags: Array.from(tags),\n revalidate: entry.revalidate,\n });\n return this.toPublicEntry(entry);\n }\n\n async setAsync<T>(\n key: string,\n value: T,\n options: FarmCacheSetOptions = {},\n tagVersions?: Readonly<Record<string, number>>,\n ): Promise<FarmCacheEntry<T>> {\n const tags = normalizeCacheOptionsTags(options);\n const capturedVersions =\n tagVersions ?? (await this.getAdapterTagVersions(Array.from(tags.values())));\n const entry: FarmCacheEntry<T> = {\n key,\n value,\n tags: Array.from(tags),\n tagVersions: capturedVersions,\n createdAt: options.createdAt ?? Date.now(),\n createdVersion: ++this.version,\n revalidate: normalizeRevalidate(options.revalidate),\n };\n\n if (this.local) {\n this.hydrateLocalEntry(entry);\n }\n if (this.adapter) {\n await this.adapter.set(this.createAdapterKey(key), entry);\n }\n\n emitFarmEvent({\n type: \"cache.set\",\n key,\n tags: [...entry.tags],\n revalidate: entry.revalidate,\n });\n return entry;\n }\n\n delete(key: string): boolean {\n const deleted = this.entries.delete(key);\n emitFarmEvent({ type: \"cache.delete\", key, deleted });\n return deleted;\n }\n\n async deleteAsync(key: string): Promise<boolean> {\n const deleted = this.entries.delete(key);\n if (this.adapter) {\n await this.adapter.delete(this.createAdapterKey(key));\n }\n emitFarmEvent({ type: \"cache.delete\", key, deleted: this.adapter ? true : deleted });\n return this.adapter ? true : deleted;\n }\n\n clear(): void {\n const count = this.entries.size;\n this.entries.clear();\n this.inflight.clear();\n this.invalidatedTagVersions.clear();\n this.version = 0;\n emitFarmEvent({ type: \"cache.clear\", count });\n }\n\n async clearAsync(): Promise<void> {\n this.clear();\n await this.adapter?.clear?.();\n }\n\n isStale(entry: FarmCacheStaleEntry, now = Date.now()): boolean {\n if (\n typeof entry.revalidate === \"number\" &&\n entry.revalidate > 0 &&\n now - entry.createdAt >= entry.revalidate * 1000\n ) {\n return true;\n }\n\n for (const tag of entry.tags) {\n const invalidatedVersion = this.invalidatedTagVersions.get(normalizeCacheTag(tag));\n if (\n typeof invalidatedVersion === \"number\" &&\n typeof entry.createdVersion === \"number\" &&\n invalidatedVersion > entry.createdVersion\n ) {\n return true;\n }\n }\n\n return false;\n }\n\n async isStaleAsync(entry: FarmCacheEntry, now = Date.now()): Promise<boolean> {\n if (this.adapter) {\n return this.isAdapterEntryStale(entry, now);\n }\n return this.isStale(entry, now);\n }\n\n revalidateTag(\n tag: string,\n options: { source?: \"revalidateTag\" | \"updateTag\"; profile?: RevalidateTagProfile } = {},\n ): number {\n const normalized = normalizeCacheTag(tag);\n const count = this.invalidateTag(normalized);\n emitFarmEvent(\n options.source === \"updateTag\"\n ? { type: \"cache.updateTag\", tag: normalized, count }\n : { type: \"cache.revalidateTag\", tag: normalized, profile: options.profile, count },\n );\n return count;\n }\n\n async revalidateTagAsync(\n tag: string,\n options: { source?: \"revalidateTag\" | \"updateTag\"; profile?: RevalidateTagProfile } = {},\n ): Promise<number> {\n const normalized = normalizeCacheTag(tag);\n const count = this.invalidateTag(normalized);\n await this.adapter?.invalidateTags?.([this.createAdapterTag(normalized)]);\n emitFarmEvent(\n options.source === \"updateTag\"\n ? { type: \"cache.updateTag\", tag: normalized, count }\n : { type: \"cache.revalidateTag\", tag: normalized, profile: options.profile, count },\n );\n return count;\n }\n\n revalidatePath(routePath: string): number {\n const normalizedPath = normalizeRevalidatePath(routePath);\n const pathTag = createPathCacheTag(normalizedPath);\n const pprCount = this.countEntriesForTags([pathTag, \"ppr\"]);\n const count = this.invalidateTag(pathTag);\n emitFarmEvent({ type: \"cache.revalidatePath\", path: normalizedPath, count });\n\n if (pprCount > 0) {\n emitFarmEvent({\n type: \"ppr.shell.invalidated\",\n route: normalizedPath,\n reason: \"revalidatePath\",\n count: pprCount,\n });\n }\n\n return count;\n }\n\n async revalidatePathAsync(routePath: string): Promise<number> {\n const normalizedPath = normalizeRevalidatePath(routePath);\n const pathTag = createPathCacheTag(normalizedPath);\n const pprCount = this.countEntriesForTags([pathTag, \"ppr\"]);\n const count = this.invalidateTag(pathTag);\n await this.adapter?.invalidateTags?.([this.createAdapterTag(pathTag)]);\n emitFarmEvent({ type: \"cache.revalidatePath\", path: normalizedPath, count });\n\n if (pprCount > 0) {\n emitFarmEvent({\n type: \"ppr.shell.invalidated\",\n route: normalizedPath,\n reason: \"revalidatePath\",\n count: pprCount,\n });\n }\n\n return count;\n }\n\n async getOrSet<T>(\n key: string,\n producer: () => Promise<T> | T,\n options: FarmCacheOptions = {},\n ): Promise<T> {\n const cached = await this.getEntryAsync<T>(key);\n if (cached) {\n return cached.value;\n }\n\n const inflight = this.inflight.get(key) as Promise<T> | undefined;\n if (inflight) {\n emitFarmEvent({ type: \"cache.dedupe\", key });\n return inflight;\n }\n\n const tags = Array.from(normalizeCacheOptionsTags(options));\n const promise = this.fillCacheEntry(key, producer, options, tags)\n .catch((error) => {\n emitFarmEvent({ type: \"cache.error\", key, operation: \"set\", error });\n throw error;\n })\n .finally(() => {\n this.inflight.delete(key);\n });\n\n this.inflight.set(key, promise);\n return promise;\n }\n\n private async fillCacheEntry<T>(\n key: string,\n producer: () => Promise<T> | T,\n options: FarmCacheOptions,\n tags: readonly string[],\n ): Promise<T> {\n const leaseKey = `${this.namespace}:lease:${key}`;\n let leaseToken: string | null | undefined;\n\n if (this.adapter?.acquireLease && this.adapter.releaseLease && this.lease.enabled) {\n leaseToken = await this.adapter.acquireLease(leaseKey, this.lease.ttlMs);\n if (!leaseToken) {\n const shared = await this.waitForAdapterEntry<T>(key);\n if (shared) {\n emitFarmEvent({ type: \"cache.dedupe\", key });\n return shared.value;\n }\n leaseToken = await this.adapter.acquireLease(leaseKey, this.lease.ttlMs);\n }\n }\n\n try {\n const initialTagVersions = await this.getAdapterTagVersions(tags);\n const value = await producer();\n await this.setAsync(key, value, options, initialTagVersions);\n return value;\n } finally {\n if (leaseToken && this.adapter?.releaseLease) {\n await this.adapter.releaseLease(leaseKey, leaseToken);\n }\n }\n }\n\n private async waitForAdapterEntry<T>(key: string): Promise<FarmCacheEntry<T> | undefined> {\n const deadline = Date.now() + this.lease.waitTimeoutMs;\n while (Date.now() < deadline) {\n await delay(this.lease.pollIntervalMs);\n const entry = await this.getEntryAsync<T>(key);\n if (entry) return entry;\n }\n return undefined;\n }\n\n private countEntriesForTag(tag: string): number {\n let count = 0;\n for (const entry of this.entries.values()) {\n if (entry.tags.has(tag)) {\n count++;\n }\n }\n return count;\n }\n\n private countEntriesForTags(tags: readonly string[]): number {\n let count = 0;\n for (const entry of this.entries.values()) {\n if (tags.every((tag) => entry.tags.has(tag))) {\n count++;\n }\n }\n return count;\n }\n\n private invalidateTag(normalizedTag: string): number {\n this.invalidatedTagVersions.set(normalizedTag, ++this.version);\n return this.countEntriesForTag(normalizedTag);\n }\n\n private toPublicEntry<T>(entry: InternalFarmCacheEntry<T>): FarmCacheEntry<T> {\n return {\n key: entry.key,\n value: entry.value,\n tags: Array.from(entry.tags),\n tagVersions: entry.tagVersions,\n createdAt: entry.createdAt,\n createdVersion: entry.createdVersion,\n revalidate: entry.revalidate,\n };\n }\n\n private hydrateLocalEntry<T>(entry: FarmCacheEntry<T>): void {\n this.entries.set(entry.key, {\n key: entry.key,\n value: entry.value,\n tags: new Set(entry.tags.map(normalizeCacheTag)),\n tagVersions: entry.tagVersions,\n createdAt: entry.createdAt,\n createdVersion: entry.createdVersion ?? ++this.version,\n revalidate: normalizeRevalidate(entry.revalidate),\n });\n }\n\n private createAdapterKey(key: string): string {\n return `${this.namespace}:entry:${key}`;\n }\n\n private createAdapterTag(tag: string): string {\n return `${this.namespace}:tag:${tag}`;\n }\n\n private async getAdapterTagVersions(\n tags: readonly string[],\n ): Promise<Readonly<Record<string, number>>> {\n if (!this.adapter?.getTagVersions || tags.length === 0) return {};\n\n const normalized = tags.map(normalizeCacheTag);\n const physicalTags = normalized.map((tag) => this.createAdapterTag(tag));\n const versions = await this.adapter.getTagVersions(physicalTags);\n return Object.fromEntries(\n normalized.map((tag, index) => [\n tag,\n normalizeAdapterVersion(versions[physicalTags[index]!]),\n ]),\n );\n }\n\n private async isAdapterEntryStale(entry: FarmCacheEntry, now = Date.now()): Promise<boolean> {\n if (\n typeof entry.revalidate === \"number\" &&\n entry.revalidate > 0 &&\n now - entry.createdAt >= entry.revalidate * 1000\n ) {\n return true;\n }\n\n const currentVersions = await this.getAdapterTagVersions(entry.tags);\n for (const tag of entry.tags) {\n if (\n normalizeAdapterVersion(currentVersions[tag]) >\n normalizeAdapterVersion(entry.tagVersions?.[tag])\n ) {\n return true;\n }\n }\n return false;\n }\n}\n\nconst FARM_DATA_CACHE_SYMBOL = Symbol.for(\"farm.dataCache\");\nconst farmDataCacheGlobal = globalThis as typeof globalThis & {\n [FARM_DATA_CACHE_SYMBOL]?: FarmDataCache;\n};\nconst sharedFarmDataCache = (farmDataCacheGlobal[FARM_DATA_CACHE_SYMBOL] ??= new FarmDataCache());\nconst functionIds = new WeakMap<Function, number>();\nlet nextFunctionId = 0;\n\nexport function getFarmDataCache(): FarmDataCache {\n return sharedFarmDataCache;\n}\n\nexport function configureFarmCache(config: FarmCacheUserConfig | undefined): void {\n sharedFarmDataCache.configure(config);\n}\n\nexport function unstable_cache<Args extends unknown[], Result>(\n fn: (...args: Args) => Result | Promise<Result>,\n keyParts: readonly unknown[] = [],\n options: FarmCacheOptions = {},\n): (...args: Args) => Promise<Result> {\n return async (...args: Args): Promise<Result> => {\n const locale = getActiveFarmI18nSnapshot()?.locale;\n const key = createFarmCacheKey([\n \"unstable_cache\",\n getFunctionCacheIdentity(fn),\n locale ? [\"locale\", locale] : null,\n keyParts,\n args,\n ]);\n return getFarmDataCache().getOrSet<Result>(key, () => fn(...args), options);\n };\n}\n\nexport function revalidateTag(_tag: string, _profile?: RevalidateTagProfile): void | Promise<void> {\n const cache = getFarmDataCache();\n if (cache.hasAdapter) {\n const task = cache\n .revalidateTagAsync(_tag, {\n source: \"revalidateTag\",\n profile: _profile,\n })\n .then(() => undefined);\n notifyFarmCacheTask(task);\n return task;\n }\n cache.revalidateTag(_tag, {\n source: \"revalidateTag\",\n profile: _profile,\n });\n}\n\nexport function updateTag(tag: string): void | Promise<void> {\n const cache = getFarmDataCache();\n if (cache.hasAdapter) {\n const task = cache.revalidateTagAsync(tag, { source: \"updateTag\" }).then(() => undefined);\n notifyFarmCacheTask(task);\n return task;\n }\n cache.revalidateTag(tag, { source: \"updateTag\" });\n}\n\nexport function revalidatePath(routePath: string): void | Promise<void> {\n const cache = getFarmDataCache();\n if (cache.hasAdapter) {\n const task = cache.revalidatePathAsync(routePath).then(() => undefined);\n notifyFarmCacheTask(task);\n return task;\n }\n cache.revalidatePath(routePath);\n}\n\nexport function invalidate(key: RouteDataCacheKey): void | Promise<void> {\n const clientKey = createRouteDataCacheKey(key);\n const task = updateTag(createRouteDataCacheTag(key));\n notifyFarmCacheInvalidation(clientKey);\n return task;\n}\n\nexport function invalidateRouteData(key: RouteDataCacheKey): void | Promise<void> {\n return invalidate(key);\n}\n\n/**\n * Apply a normalized set of invalidation targets and return browser cache keys\n * that should be carried with an action/endpoint response.\n */\nexport async function applyFarmCacheInvalidationTargets(\n targets: readonly FarmCacheInvalidationTarget[],\n): Promise<readonly string[]> {\n if (!Array.isArray(targets)) {\n throw new TypeError(\"Cache invalidations must resolve to an array of targets.\");\n }\n\n const clientKeys: string[] = [];\n for (const target of targets) {\n assertFarmCacheInvalidationTarget(target);\n if (\"key\" in target) {\n await invalidate(target.key);\n clientKeys.push(createRouteDataCacheKey(target.key));\n } else if (\"path\" in target) {\n await revalidatePath(target.path);\n } else {\n await updateTag(target.tag);\n }\n }\n return Array.from(new Set(clientKeys));\n}\n\nexport function createPathCacheTag(routePath: string): string {\n return `path:${normalizeRevalidatePath(routePath)}`;\n}\n\nexport function createRouteDataCacheTag(key: RouteDataCacheKey): string {\n return `route-data:${createRouteDataCacheKey(key)}`;\n}\n\nexport function createRouteDataCacheKey(key: RouteDataCacheKey): string {\n return createFarmCacheKey(Array.isArray(key) ? key : [key]);\n}\n\nexport function normalizeRevalidatePath(routePath: string): string {\n if (typeof routePath !== \"string\") {\n throw new TypeError(\"revalidatePath expects a path string.\");\n }\n\n let normalized = routePath.trim();\n if (!normalized) {\n throw new Error(\"revalidatePath expects a non-empty path.\");\n }\n\n try {\n if (/^https?:\\/\\//.test(normalized)) {\n normalized = new URL(normalized).pathname;\n }\n } catch {\n // Keep the original path if URL parsing fails.\n }\n\n normalized = normalized.split(\"?\")[0] ?? normalized;\n normalized = normalized.startsWith(\"/\") ? normalized : `/${normalized}`;\n normalized = normalized.replace(/\\/{2,}/g, \"/\");\n if (normalized.length > 1) {\n normalized = normalized.replace(/\\/+$/, \"\");\n }\n return normalized || \"/\";\n}\n\nexport function createFarmCacheKey(parts: readonly unknown[]): string {\n return stableSerialize(parts);\n}\n\nfunction normalizeRevalidate(revalidate: number | false | undefined): number | false | undefined {\n if (revalidate === false || revalidate === undefined) {\n return revalidate;\n }\n if (!Number.isFinite(revalidate) || revalidate <= 0) {\n return undefined;\n }\n return revalidate;\n}\n\nfunction normalizeCacheTag(tag: string): string {\n if (typeof tag !== \"string\") {\n throw new TypeError(\"Cache tags must be strings.\");\n }\n const normalized = tag.trim();\n if (!normalized) {\n throw new Error(\"Cache tags cannot be empty.\");\n }\n return normalized;\n}\n\nfunction normalizeCacheNamespace(namespace: string): string {\n if (typeof namespace !== \"string\") {\n throw new TypeError(\"Cache namespace must be a string.\");\n }\n const normalized = namespace.trim().replace(/:+$/g, \"\");\n if (!normalized) {\n throw new Error(\"Cache namespace cannot be empty.\");\n }\n return normalized;\n}\n\nfunction normalizeAdapterVersion(value: unknown): number {\n return typeof value === \"number\" && Number.isFinite(value) && value > 0 ? value : 0;\n}\n\nfunction normalizePositiveDuration(\n value: number | undefined,\n fallback: number,\n name: string,\n): number {\n if (value === undefined) return fallback;\n if (!Number.isFinite(value) || value <= 0) {\n throw new TypeError(`${name} must be a positive number of milliseconds.`);\n }\n return Math.floor(value);\n}\n\nfunction delay(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nfunction normalizeCacheOptionsTags(options: FarmCacheOptions): Set<string> {\n const tags = new Set<string>();\n for (const tag of options.tags ?? []) {\n tags.add(normalizeCacheTag(tag));\n }\n for (const routePath of options.paths ?? []) {\n tags.add(createPathCacheTag(routePath));\n }\n return tags;\n}\n\nfunction assertFarmCacheEntry(\n entry: FarmCacheEntry,\n expectedKey: string,\n): asserts entry is FarmCacheEntry {\n if (\n !entry ||\n typeof entry !== \"object\" ||\n entry.key !== expectedKey ||\n !Array.isArray(entry.tags) ||\n typeof entry.createdAt !== \"number\"\n ) {\n throw new TypeError(\n `Cache adapter returned an invalid entry for ${JSON.stringify(expectedKey)}.`,\n );\n }\n}\n\nfunction assertFarmCacheInvalidationTarget(\n target: unknown,\n): asserts target is FarmCacheInvalidationTarget {\n if (!target || typeof target !== \"object\") {\n throw new TypeError(\"Cache invalidation targets must be { key }, { path }, or { tag }.\");\n }\n\n if (\"key\" in target) {\n const key = (target as { key?: unknown }).key;\n if (typeof key === \"string\" || Array.isArray(key)) return;\n } else if (\"path\" in target && typeof (target as { path?: unknown }).path === \"string\") {\n return;\n } else if (\"tag\" in target && typeof (target as { tag?: unknown }).tag === \"string\") {\n return;\n }\n\n throw new TypeError(\"Cache invalidation targets must contain a string/array key, path, or tag.\");\n}\n\nfunction getFunctionCacheIdentity(fn: Function): string {\n if (fn.name) {\n return `name:${fn.name}`;\n }\n\n let id = functionIds.get(fn);\n if (!id) {\n id = ++nextFunctionId;\n functionIds.set(fn, id);\n }\n return `anonymous:${id}`;\n}\n\nfunction stableSerialize(value: unknown, seen = new WeakSet<object>()): string {\n if (value === null) return \"null\";\n if (value === undefined) return \"undefined\";\n\n const valueType = typeof value;\n if (valueType === \"string\") return JSON.stringify(value);\n if (valueType === \"number\" || valueType === \"boolean\" || valueType === \"bigint\") {\n return `${valueType}:${String(value)}`;\n }\n if (valueType === \"symbol\") {\n return `symbol:${String(value)}`;\n }\n if (valueType === \"function\") {\n return `function:${getFunctionCacheIdentity(value as Function)}`;\n }\n\n if (value instanceof Date) {\n return `date:${value.toISOString()}`;\n }\n if (value instanceof URL) {\n return `url:${value.toString()}`;\n }\n if (value instanceof RegExp) {\n return `regexp:${value.toString()}`;\n }\n\n if (Array.isArray(value)) {\n return `[${value.map((item) => stableSerialize(item, seen)).join(\",\")}]`;\n }\n\n if (value && typeof value === \"object\") {\n if (seen.has(value)) {\n return \"[Circular]\";\n }\n seen.add(value);\n\n const entries = Object.entries(value as Record<string, unknown>).sort(([a], [b]) =>\n a.localeCompare(b),\n );\n const serialized = entries\n .map(([key, item]) => `${JSON.stringify(key)}:${stableSerialize(item, seen)}`)\n .join(\",\");\n\n seen.delete(value);\n return `{${serialized}}`;\n }\n\n return String(value);\n}\n"],"mappings":"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","names":[]}
|
|
@@ -23,6 +23,7 @@ import {
|
|
|
23
23
|
|
|
24
24
|
// src/client/spa-router.ts
|
|
25
25
|
var FARM_PAGE_STATE_KEY = "__farmPageState";
|
|
26
|
+
var FARM_INTERCEPT_FROM_KEY = "__farmInterceptFrom";
|
|
26
27
|
var IDLE_NAVIGATION_STATE = {
|
|
27
28
|
state: "idle",
|
|
28
29
|
pending: false,
|
|
@@ -93,7 +94,11 @@ var _SPARouter = class _SPARouter {
|
|
|
93
94
|
return;
|
|
94
95
|
}
|
|
95
96
|
const from = window.location.pathname + window.location.search;
|
|
96
|
-
if (await this.shouldBlockNavigation({
|
|
97
|
+
if (await this.shouldBlockNavigation({
|
|
98
|
+
from,
|
|
99
|
+
to: fullPath,
|
|
100
|
+
action: replace ? "replace" : "push"
|
|
101
|
+
})) {
|
|
97
102
|
return;
|
|
98
103
|
}
|
|
99
104
|
if (this.options.scrollRestoration) {
|
|
@@ -111,11 +116,11 @@ var _SPARouter = class _SPARouter {
|
|
|
111
116
|
to: url,
|
|
112
117
|
action: replace ? "replace" : "push"
|
|
113
118
|
});
|
|
114
|
-
const pageData = await this.fetchPageData(fullPath);
|
|
119
|
+
const pageData = await this.fetchPageData(fullPath, true, from);
|
|
115
120
|
if (clientNavigation) {
|
|
116
121
|
await this.clientPlugins?.markNavigationLoaded(clientNavigation, pageData);
|
|
117
122
|
}
|
|
118
|
-
if (pageData.isClientComponent === false) {
|
|
123
|
+
if (pageData.isClientComponent === false && !pageData.interception) {
|
|
119
124
|
this.finishNavigation();
|
|
120
125
|
window.location.assign(pageData.canonicalPath || fullPath);
|
|
121
126
|
return;
|
|
@@ -153,11 +158,12 @@ var _SPARouter = class _SPARouter {
|
|
|
153
158
|
if (isFarmLocaleChangeHref(href)) return;
|
|
154
159
|
const url = new URL(href, window.location.origin);
|
|
155
160
|
const fullPath = url.pathname + url.search;
|
|
161
|
+
const interceptFrom = window.location.pathname + window.location.search;
|
|
156
162
|
if (this.prefetchingUrls.has(fullPath)) return;
|
|
157
|
-
if (this.isCached(fullPath)) return;
|
|
163
|
+
if (this.isCached(fullPath, interceptFrom)) return;
|
|
158
164
|
this.prefetchingUrls.add(fullPath);
|
|
159
165
|
try {
|
|
160
|
-
await this.fetchPageData(fullPath, false);
|
|
166
|
+
await this.fetchPageData(fullPath, false, interceptFrom);
|
|
161
167
|
} catch (error) {
|
|
162
168
|
console.warn("[Farm.js] Prefetch failed:", href, error);
|
|
163
169
|
} finally {
|
|
@@ -232,7 +238,12 @@ var _SPARouter = class _SPARouter {
|
|
|
232
238
|
}
|
|
233
239
|
async commitNavigation(options) {
|
|
234
240
|
const historyPath = options.pageData.canonicalPath || options.fullPath;
|
|
235
|
-
const historyState = createHistoryState(
|
|
241
|
+
const historyState = createHistoryState(
|
|
242
|
+
historyPath,
|
|
243
|
+
options.state,
|
|
244
|
+
void 0,
|
|
245
|
+
options.pageData.interception?.from ?? null
|
|
246
|
+
);
|
|
236
247
|
if (options.replace) {
|
|
237
248
|
window.history.replaceState(historyState, "", historyPath);
|
|
238
249
|
} else {
|
|
@@ -287,15 +298,17 @@ var _SPARouter = class _SPARouter {
|
|
|
287
298
|
/**
|
|
288
299
|
* Fetch page data from cache or server
|
|
289
300
|
*/
|
|
290
|
-
async fetchPageData(path, recover = true) {
|
|
291
|
-
const
|
|
301
|
+
async fetchPageData(path, recover = true, interceptFrom) {
|
|
302
|
+
const cacheKey = getPageDataCacheKey(path, interceptFrom);
|
|
303
|
+
const cached = this.cache.get(cacheKey);
|
|
292
304
|
if (cached && Date.now() - cached.timestamp < this.options.cacheMaxAge) {
|
|
293
305
|
return cached.data;
|
|
294
306
|
}
|
|
295
307
|
const response = await fetch(`/__farm/page-data?path=${encodeURIComponent(path)}`, {
|
|
296
308
|
headers: createFarmDeploymentRequestHeaders(this.options.deploymentId, {
|
|
297
309
|
Accept: "application/x-farm-deferred+json, application/json",
|
|
298
|
-
"X-Farm-SPA": "1"
|
|
310
|
+
"X-Farm-SPA": "1",
|
|
311
|
+
...interceptFrom ? { "X-Farm-Intercept-From": interceptFrom } : {}
|
|
299
312
|
})
|
|
300
313
|
});
|
|
301
314
|
if (isFarmDeploymentMismatchResponse(response, this.options.deploymentId)) {
|
|
@@ -313,7 +326,7 @@ var _SPARouter = class _SPARouter {
|
|
|
313
326
|
throw new Error(`Failed to fetch page data: ${response.status}`);
|
|
314
327
|
}
|
|
315
328
|
const data = await readDeferredDataResponse(response);
|
|
316
|
-
this.cache.set(
|
|
329
|
+
this.cache.set(cacheKey, {
|
|
317
330
|
data,
|
|
318
331
|
timestamp: Date.now()
|
|
319
332
|
});
|
|
@@ -344,7 +357,8 @@ var _SPARouter = class _SPARouter {
|
|
|
344
357
|
to: window.location.href,
|
|
345
358
|
action: "pop"
|
|
346
359
|
});
|
|
347
|
-
const
|
|
360
|
+
const interceptFrom = typeof event.state?.[FARM_INTERCEPT_FROM_KEY] === "string" ? event.state[FARM_INTERCEPT_FROM_KEY] : void 0;
|
|
361
|
+
const pageData = await this.fetchPageData(path, true, interceptFrom);
|
|
348
362
|
if (clientNavigation) {
|
|
349
363
|
await this.clientPlugins?.markNavigationLoaded(clientNavigation, pageData);
|
|
350
364
|
}
|
|
@@ -375,8 +389,8 @@ var _SPARouter = class _SPARouter {
|
|
|
375
389
|
/**
|
|
376
390
|
* Check if URL is cached
|
|
377
391
|
*/
|
|
378
|
-
isCached(path) {
|
|
379
|
-
const cached = this.cache.get(path);
|
|
392
|
+
isCached(path, interceptFrom) {
|
|
393
|
+
const cached = this.cache.get(getPageDataCacheKey(path, interceptFrom));
|
|
380
394
|
return cached !== void 0 && Date.now() - cached.timestamp < this.options.cacheMaxAge;
|
|
381
395
|
}
|
|
382
396
|
/**
|
|
@@ -532,15 +546,26 @@ function readPageState() {
|
|
|
532
546
|
return state[FARM_PAGE_STATE_KEY] ?? null;
|
|
533
547
|
}
|
|
534
548
|
__name(readPageState, "readPageState");
|
|
535
|
-
function createHistoryState(path, pageState, currentState) {
|
|
549
|
+
function createHistoryState(path, pageState, currentState, interceptFrom) {
|
|
536
550
|
const base = currentState && typeof currentState === "object" ? { ...currentState } : {};
|
|
537
|
-
|
|
551
|
+
const nextState = {
|
|
538
552
|
...base,
|
|
539
553
|
path,
|
|
540
554
|
[FARM_PAGE_STATE_KEY]: pageState
|
|
541
555
|
};
|
|
556
|
+
if (interceptFrom === null) {
|
|
557
|
+
delete nextState[FARM_INTERCEPT_FROM_KEY];
|
|
558
|
+
} else if (interceptFrom) {
|
|
559
|
+
nextState[FARM_INTERCEPT_FROM_KEY] = interceptFrom;
|
|
560
|
+
}
|
|
561
|
+
return nextState;
|
|
542
562
|
}
|
|
543
563
|
__name(createHistoryState, "createHistoryState");
|
|
564
|
+
function getPageDataCacheKey(path, interceptFrom) {
|
|
565
|
+
return interceptFrom ? `${path}
|
|
566
|
+
intercept:${interceptFrom}` : path;
|
|
567
|
+
}
|
|
568
|
+
__name(getPageDataCacheKey, "getPageDataCacheKey");
|
|
544
569
|
function createNavigationLocation(url) {
|
|
545
570
|
return {
|
|
546
571
|
href: url.href,
|
|
@@ -725,4 +750,4 @@ export {
|
|
|
725
750
|
useBlocker,
|
|
726
751
|
useScrollRestoration
|
|
727
752
|
};
|
|
728
|
-
//# sourceMappingURL=chunk-
|
|
753
|
+
//# sourceMappingURL=chunk-VVKWFZAH.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/client/spa-router.ts","../src/client/router.ts"],"sourcesContent":["\"use client\";\n\nimport { readDeferredDataResponse } from \"../deferred\";\nimport {\n createFarmDeploymentMismatchError,\n createFarmDeploymentRequestHeaders,\n isFarmDeploymentMismatchResponse,\n} from \"../deployment\";\nimport type { FarmClientNavigationSession, FarmClientPluginManager } from \"./plugin\";\nimport { _hydrateFarmI18n, isFarmLocaleChangeHref } from \"../i18n/client-runtime\";\nimport type { FarmI18nClientSnapshot } from \"../i18n/types\";\n\n/**\n * Farm.js SPA Router\n *\n * Provides client-side navigation without full page reloads.\n * Features:\n * - Prefetch on viewport intersection\n * - Prefetch on hover\n * - Page caching\n * - History API integration\n * - Scroll restoration\n */\n\ninterface PageData {\n props: Record<string, any>;\n modulePath: string;\n canonicalPath?: string;\n isClientComponent?: boolean;\n shouldHydrate?: boolean;\n metadata?: {\n title?: string;\n description?: string;\n };\n layoutModules?: string[];\n routeSlots?: RouteSlotPageData[];\n interception?: {\n from?: string;\n slots: string[];\n };\n i18n?: FarmI18nClientSnapshot;\n}\n\ninterface RouteSlotPageData {\n name: string;\n ownerPattern: string;\n containerId: string;\n interception: boolean;\n fallback: boolean;\n modulePath: string;\n isClientComponent: boolean;\n shouldHydrate: boolean;\n props: Record<string, any>;\n}\n\nexport interface RouterOptions {\n prefetchTimeout?: number;\n cacheMaxAge?: number;\n scrollRestoration?: boolean;\n shouldUseDocumentNavigation?: (pathname: string) => boolean;\n deploymentId?: string;\n}\n\ninterface CacheEntry {\n data: PageData;\n timestamp: number;\n}\n\nexport interface FarmNavigationBlockerContext {\n from: string;\n to: string;\n action: \"push\" | \"replace\" | \"pop\";\n}\n\nexport type FarmNavigationBlocker = (\n context: FarmNavigationBlockerContext,\n) => boolean | void | Promise<boolean | void>;\n\nexport type FarmViewTransitionMode = boolean | \"auto\";\n\nexport interface FarmNavigateOptions {\n replace?: boolean;\n scroll?: boolean;\n state?: unknown;\n viewTransition?: FarmViewTransitionMode;\n}\n\nexport interface FarmNavigationLocation {\n href: string;\n pathname: string;\n search: string;\n hash: string;\n}\n\nexport interface FarmNavigationState {\n state: \"idle\" | \"loading\";\n pending: boolean;\n from: string | null;\n to: FarmNavigationLocation | null;\n action: FarmNavigationBlockerContext[\"action\"] | null;\n startedAt: number | null;\n}\n\nexport type FarmNavigationListener = (state: FarmNavigationState) => void;\n\nconst FARM_PAGE_STATE_KEY = \"__farmPageState\";\nconst FARM_INTERCEPT_FROM_KEY = \"__farmInterceptFrom\";\nconst IDLE_NAVIGATION_STATE: FarmNavigationState = {\n state: \"idle\",\n pending: false,\n from: null,\n to: null,\n action: null,\n startedAt: null,\n};\n\n// Global router instance\nlet routerInstance: SPARouter | null = null;\n\nexport class SPARouter {\n private cache: Map<string, CacheEntry> = new Map();\n private prefetchingUrls: Set<string> = new Set();\n private observers: Map<Element, IntersectionObserver> = new Map();\n private blockers: Set<FarmNavigationBlocker> = new Set();\n private navigationListeners: Set<FarmNavigationListener> = new Set();\n private navigationState: FarmNavigationState = IDLE_NAVIGATION_STATE;\n private scrollElements: Map<string, HTMLElement> = new Map();\n private options: Required<Omit<RouterOptions, \"deploymentId\">> &\n Pick<RouterOptions, \"deploymentId\">;\n private onNavigate?: (data: PageData) => Promise<void>;\n private clientPlugins?: Pick<\n FarmClientPluginManager,\n | \"beginNavigation\"\n | \"markNavigationLoaded\"\n | \"resolveNavigation\"\n | \"scheduleNavigationRendered\"\n | \"failNavigation\"\n >;\n\n constructor(options: RouterOptions = {}) {\n this.options = {\n prefetchTimeout: options.prefetchTimeout ?? 100,\n cacheMaxAge: options.cacheMaxAge ?? 30000, // 30 seconds\n scrollRestoration: options.scrollRestoration ?? true,\n shouldUseDocumentNavigation: options.shouldUseDocumentNavigation ?? (() => false),\n deploymentId: options.deploymentId ?? readBrowserDeploymentId(),\n };\n\n if (typeof window !== \"undefined\") {\n // Listen for popstate (back/forward navigation)\n window.addEventListener(\"popstate\", this.handlePopState.bind(this));\n\n // Save scroll position before unload\n window.addEventListener(\"beforeunload\", (event) => {\n if (this.blockers.size > 0) {\n event.preventDefault();\n event.returnValue = \"\";\n }\n this.saveScrollPosition(window.location.pathname);\n });\n }\n }\n\n /**\n * Set the navigation handler that updates React\n */\n setNavigationHandler(handler: (data: PageData) => Promise<void>) {\n this.onNavigate = handler;\n }\n\n /**\n * Connect Farm's browser plugin lifecycle to SPA navigation.\n */\n setClientPluginManager(manager: FarmClientPluginManager) {\n this.clientPlugins = manager;\n }\n\n /**\n * Navigate to a new URL\n */\n async navigate(href: string, options: FarmNavigateOptions = {}): Promise<void> {\n const { replace = false, scroll = true, state, viewTransition = false } = options;\n\n // Parse the URL\n const url = new URL(href, window.location.origin);\n const pathname = url.pathname;\n const search = url.search;\n const fullPath = pathname + search;\n\n if (\n isFarmLocaleChangeHref(url.toString()) ||\n this.options.shouldUseDocumentNavigation(pathname)\n ) {\n if (replace) window.location.replace(url.toString());\n else window.location.assign(url.toString());\n return;\n }\n\n // Same page navigation - just update hash/scroll\n if (pathname === window.location.pathname && search === window.location.search) {\n if (url.hash) {\n window.location.hash = url.hash;\n }\n return;\n }\n\n const from = window.location.pathname + window.location.search;\n if (\n await this.shouldBlockNavigation({\n from,\n to: fullPath,\n action: replace ? \"replace\" : \"push\",\n })\n ) {\n return;\n }\n\n // Save current scroll position\n if (this.options.scrollRestoration) {\n this.saveScrollPosition(window.location.pathname);\n }\n\n this.startNavigation({\n from,\n to: createNavigationLocation(url),\n action: replace ? \"replace\" : \"push\",\n });\n\n let clientNavigation: FarmClientNavigationSession | undefined;\n try {\n clientNavigation = await this.clientPlugins?.beginNavigation({\n from,\n to: url,\n action: replace ? \"replace\" : \"push\",\n });\n\n // Fetch page data (from cache or server)\n const pageData = await this.fetchPageData(fullPath, true, from);\n if (clientNavigation) {\n await this.clientPlugins?.markNavigationLoaded(clientNavigation, pageData);\n }\n\n if (pageData.isClientComponent === false && !pageData.interception) {\n this.finishNavigation();\n window.location.assign(pageData.canonicalPath || fullPath);\n return;\n }\n\n await this.runViewTransition(viewTransition, () =>\n this.commitNavigation({\n fullPath,\n pageData,\n pathname,\n replace,\n scroll,\n state,\n url,\n }),\n );\n\n if (clientNavigation) {\n await this.clientPlugins?.resolveNavigation(clientNavigation);\n void this.clientPlugins?.scheduleNavigationRendered(clientNavigation);\n }\n this.finishNavigation();\n } catch (error) {\n if (clientNavigation) {\n await this.clientPlugins?.failNavigation(clientNavigation, error);\n }\n this.finishNavigation();\n console.error(\"[Farm.js] Navigation error:\", error);\n // Fall back to full page navigation\n window.location.href = href;\n }\n }\n\n /**\n * Prefetch a URL\n */\n async prefetch(href: string): Promise<void> {\n if (isFarmLocaleChangeHref(href)) return;\n const url = new URL(href, window.location.origin);\n const fullPath = url.pathname + url.search;\n const interceptFrom = window.location.pathname + window.location.search;\n\n // Skip if already prefetching or cached\n if (this.prefetchingUrls.has(fullPath)) return;\n if (this.isCached(fullPath, interceptFrom)) return;\n\n this.prefetchingUrls.add(fullPath);\n\n try {\n await this.fetchPageData(fullPath, false, interceptFrom);\n } catch (error) {\n console.warn(\"[Farm.js] Prefetch failed:\", href, error);\n } finally {\n this.prefetchingUrls.delete(fullPath);\n }\n }\n\n /**\n * Observe an element for viewport intersection (prefetch when visible)\n */\n observeForPrefetch(element: HTMLAnchorElement): void {\n if (typeof IntersectionObserver === \"undefined\") return;\n\n const href = element.getAttribute(\"href\");\n if (!href || this.isExternalUrl(href)) return;\n\n const observer = new IntersectionObserver(\n (entries) => {\n for (const entry of entries) {\n if (entry.isIntersecting) {\n // Delay prefetch slightly to avoid prefetching during scroll\n setTimeout(() => {\n this.prefetch(href);\n }, this.options.prefetchTimeout);\n\n // Stop observing after first intersection\n observer.unobserve(element);\n this.observers.delete(element);\n }\n }\n },\n { rootMargin: \"200px\" }, // Start prefetching when 200px from viewport\n );\n\n observer.observe(element);\n this.observers.set(element, observer);\n }\n\n /**\n * Stop observing an element\n */\n unobserveForPrefetch(element: HTMLAnchorElement): void {\n const observer = this.observers.get(element);\n if (observer) {\n observer.unobserve(element);\n this.observers.delete(element);\n }\n }\n\n addBlocker(blocker: FarmNavigationBlocker): () => void {\n this.blockers.add(blocker);\n return () => {\n this.blockers.delete(blocker);\n };\n }\n\n getNavigationState(): FarmNavigationState {\n return this.navigationState;\n }\n\n subscribeNavigation(listener: FarmNavigationListener): () => void {\n this.navigationListeners.add(listener);\n listener(this.navigationState);\n return () => {\n this.navigationListeners.delete(listener);\n };\n }\n\n registerScrollElement(key: string, element: HTMLElement): () => void {\n this.scrollElements.set(key, element);\n this.restoreScrollElement(window.location.pathname, key, element);\n return () => {\n if (this.scrollElements.get(key) === element) {\n this.scrollElements.delete(key);\n }\n };\n }\n\n pushState(state: unknown, href?: string): void {\n this.writePageState(\"push\", state, href);\n }\n\n replaceState(state: unknown, href?: string): void {\n this.writePageState(\"replace\", state, href);\n }\n\n private async commitNavigation(options: {\n fullPath: string;\n pageData: PageData;\n pathname: string;\n replace: boolean;\n scroll: boolean;\n state: unknown;\n url: URL;\n }): Promise<void> {\n const historyPath = options.pageData.canonicalPath || options.fullPath;\n const historyState = createHistoryState(\n historyPath,\n options.state,\n undefined,\n options.pageData.interception?.from ?? null,\n );\n if (options.replace) {\n window.history.replaceState(historyState, \"\", historyPath);\n } else {\n window.history.pushState(historyState, \"\", historyPath);\n }\n\n if (options.pageData.metadata?.title) {\n document.title = options.pageData.metadata.title;\n }\n\n if (options.pageData.metadata?.description) {\n let metaDesc = document.querySelector('meta[name=\"description\"]');\n if (!metaDesc) {\n metaDesc = document.createElement(\"meta\");\n metaDesc.setAttribute(\"name\", \"description\");\n document.head.appendChild(metaDesc);\n }\n metaDesc.setAttribute(\"content\", options.pageData.metadata.description);\n }\n\n _hydrateFarmI18n(options.pageData.i18n);\n\n if (this.onNavigate) {\n await this.onNavigate(options.pageData);\n }\n\n if (options.scroll) {\n if (options.url.hash) {\n const element = document.querySelector(options.url.hash);\n if (element) {\n element.scrollIntoView();\n }\n } else {\n window.scrollTo(0, 0);\n }\n } else if (this.options.scrollRestoration) {\n this.restoreScrollPosition(options.pathname);\n }\n }\n\n private async runViewTransition(\n mode: FarmViewTransitionMode,\n callback: () => Promise<void>,\n ): Promise<void> {\n if (!mode || typeof document === \"undefined\") {\n await callback();\n return;\n }\n\n const startViewTransition = (document as any).startViewTransition;\n if (typeof startViewTransition !== \"function\") {\n await callback();\n return;\n }\n\n const transition = startViewTransition.call(document, () => callback());\n const updateDone = transition?.updateCallbackDone || transition?.ready;\n if (updateDone && typeof updateDone.then === \"function\") {\n await updateDone;\n }\n transition?.finished?.catch?.(() => undefined);\n }\n\n /**\n * Fetch page data from cache or server\n */\n private async fetchPageData(\n path: string,\n recover = true,\n interceptFrom?: string,\n ): Promise<PageData> {\n const cacheKey = getPageDataCacheKey(path, interceptFrom);\n // Check cache first\n const cached = this.cache.get(cacheKey);\n if (cached && Date.now() - cached.timestamp < this.options.cacheMaxAge) {\n return cached.data;\n }\n\n // Fetch from server\n const response = await fetch(`/__farm/page-data?path=${encodeURIComponent(path)}`, {\n headers: createFarmDeploymentRequestHeaders(this.options.deploymentId, {\n Accept: \"application/x-farm-deferred+json, application/json\",\n \"X-Farm-SPA\": \"1\",\n ...(interceptFrom ? { \"X-Farm-Intercept-From\": interceptFrom } : {}),\n }),\n });\n\n if (isFarmDeploymentMismatchResponse(response, this.options.deploymentId)) {\n const error = createFarmDeploymentMismatchError(\n response,\n this.options.deploymentId || \"unknown\",\n );\n dispatchDeploymentMismatch(error);\n if (recover) {\n window.location.assign(path);\n }\n throw error;\n }\n\n if (!response.ok) {\n throw new Error(`Failed to fetch page data: ${response.status}`);\n }\n\n const data = await readDeferredDataResponse<PageData>(response);\n\n // Cache the result\n this.cache.set(cacheKey, {\n data,\n timestamp: Date.now(),\n });\n\n return data;\n }\n\n /**\n * Handle browser back/forward navigation\n */\n private async handlePopState(event: PopStateEvent): Promise<void> {\n if (document.documentElement.dataset.farmDocsRuntime === \"true\") return;\n\n const path = window.location.pathname + window.location.search;\n\n if (\n await this.shouldBlockNavigation({\n from: event.state?.path || path,\n to: path,\n action: \"pop\",\n })\n ) {\n return;\n }\n\n this.startNavigation({\n from: event.state?.path || path,\n to: createNavigationLocation(new URL(window.location.href)),\n action: \"pop\",\n });\n\n let clientNavigation: FarmClientNavigationSession | undefined;\n try {\n clientNavigation = await this.clientPlugins?.beginNavigation({\n from: null,\n to: window.location.href,\n action: \"pop\",\n });\n const interceptFrom =\n typeof event.state?.[FARM_INTERCEPT_FROM_KEY] === \"string\"\n ? event.state[FARM_INTERCEPT_FROM_KEY]\n : undefined;\n const pageData = await this.fetchPageData(path, true, interceptFrom);\n if (clientNavigation) {\n await this.clientPlugins?.markNavigationLoaded(clientNavigation, pageData);\n }\n\n // Update document title\n if (pageData.metadata?.title) {\n document.title = pageData.metadata.title;\n }\n\n _hydrateFarmI18n(pageData.i18n);\n\n // Call the navigation handler to update React\n if (this.onNavigate) {\n await this.onNavigate(pageData);\n }\n\n // Restore scroll position\n if (this.options.scrollRestoration) {\n this.restoreScrollPosition(window.location.pathname);\n }\n\n if (clientNavigation) {\n await this.clientPlugins?.resolveNavigation(clientNavigation);\n void this.clientPlugins?.scheduleNavigationRendered(clientNavigation);\n }\n this.finishNavigation();\n } catch (error) {\n if (clientNavigation) {\n await this.clientPlugins?.failNavigation(clientNavigation, error);\n }\n this.finishNavigation();\n console.error(\"[Farm.js] Popstate navigation error:\", error);\n // Reload the page as fallback\n window.location.reload();\n }\n }\n\n /**\n * Check if URL is cached\n */\n private isCached(path: string, interceptFrom?: string): boolean {\n const cached = this.cache.get(getPageDataCacheKey(path, interceptFrom));\n return cached !== undefined && Date.now() - cached.timestamp < this.options.cacheMaxAge;\n }\n\n /**\n * Check if URL is external\n */\n private isExternalUrl(href: string): boolean {\n return href.startsWith(\"http://\") || href.startsWith(\"https://\") || href.startsWith(\"//\");\n }\n\n private async shouldBlockNavigation(context: FarmNavigationBlockerContext): Promise<boolean> {\n for (const blocker of this.blockers) {\n if (await blocker(context)) {\n return true;\n }\n }\n return false;\n }\n\n private startNavigation(options: {\n from: string;\n to: FarmNavigationLocation;\n action: FarmNavigationBlockerContext[\"action\"];\n }): void {\n this.setNavigationState({\n state: \"loading\",\n pending: true,\n from: options.from,\n to: options.to,\n action: options.action,\n startedAt: Date.now(),\n });\n }\n\n private finishNavigation(): void {\n this.setNavigationState(IDLE_NAVIGATION_STATE);\n }\n\n private setNavigationState(state: FarmNavigationState): void {\n this.navigationState = state;\n for (const listener of this.navigationListeners) {\n listener(state);\n }\n }\n\n private writePageState(action: \"push\" | \"replace\", state: unknown, href?: string): void {\n if (typeof window === \"undefined\") return;\n\n const url = href ? new URL(href, window.location.origin).toString() : window.location.href;\n const nextState = createHistoryState(\n new URL(url).pathname + new URL(url).search,\n state,\n window.history.state,\n );\n\n if (action === \"replace\") {\n window.history.replaceState(nextState, \"\", url);\n } else {\n window.history.pushState(nextState, \"\", url);\n }\n\n window.dispatchEvent(new PopStateEvent(\"popstate\", { state: nextState }));\n }\n\n /**\n * Save scroll position for a path\n */\n private saveScrollPosition(path: string): void {\n try {\n sessionStorage.setItem(\n `farm-scroll-${path}`,\n JSON.stringify({ x: window.scrollX, y: window.scrollY }),\n );\n for (const [key, element] of this.scrollElements) {\n sessionStorage.setItem(\n getScrollElementStorageKey(path, key),\n JSON.stringify({ x: element.scrollLeft, y: element.scrollTop }),\n );\n }\n } catch {\n // Ignore storage errors\n }\n }\n\n /**\n * Restore scroll position for a path\n */\n private restoreScrollPosition(path: string): void {\n try {\n const saved = sessionStorage.getItem(`farm-scroll-${path}`);\n if (saved) {\n const { x, y } = JSON.parse(saved);\n setTimeout(() => window.scrollTo(x, y), 0);\n }\n for (const [key, element] of this.scrollElements) {\n this.restoreScrollElement(path, key, element);\n }\n } catch {\n // Ignore storage errors\n }\n }\n\n private restoreScrollElement(path: string, key: string, element: HTMLElement): void {\n try {\n const saved = sessionStorage.getItem(getScrollElementStorageKey(path, key));\n if (!saved) return;\n const { x, y } = JSON.parse(saved);\n setTimeout(() => {\n element.scrollLeft = x;\n element.scrollTop = y;\n }, 0);\n } catch {\n // Ignore storage errors\n }\n }\n\n /**\n * Clear the page cache\n */\n clearCache(): void {\n this.cache.clear();\n }\n}\n\nfunction readBrowserDeploymentId(): string | undefined {\n if (typeof window === \"undefined\") return undefined;\n\n const runtimeId = (window as Window & { __FARM_DEPLOYMENT_ID__?: unknown })\n .__FARM_DEPLOYMENT_ID__;\n if (typeof runtimeId === \"string\" && runtimeId) return runtimeId;\n\n return document.querySelector<HTMLMetaElement>('meta[name=\"farm-deployment-id\"]')?.content;\n}\n\nfunction dispatchDeploymentMismatch(error: Error): void {\n if (typeof window === \"undefined\" || typeof CustomEvent === \"undefined\") return;\n window.dispatchEvent(new CustomEvent(\"farm:deployment-mismatch\", { detail: error }));\n}\n\n/**\n * Get or create the global router instance\n */\nexport function getRouter(): SPARouter {\n if (typeof window === \"undefined\") {\n // Return a no-op router for SSR\n return new SPARouter();\n }\n\n const installedRouter = (window as any).__FARM_SPA_ROUTER__ as SPARouter | undefined;\n if (installedRouter) {\n routerInstance = installedRouter;\n return installedRouter;\n }\n\n if (!routerInstance) {\n routerInstance = new SPARouter();\n }\n\n return routerInstance;\n}\n\n/**\n * Navigate to a URL using the SPA router\n */\nexport function navigateTo(href: string, options?: FarmNavigateOptions): Promise<void> {\n return getRouter().navigate(href, options);\n}\n\n/**\n * Prefetch a URL\n */\nexport function prefetch(href: string): Promise<void> {\n return getRouter().prefetch(href);\n}\n\nexport function pushState(state: unknown, href?: string): void {\n getRouter().pushState(state, href);\n}\n\nexport function replaceState(state: unknown, href?: string): void {\n getRouter().replaceState(state, href);\n}\n\nexport function readPageState<TState = unknown>(): TState | null {\n if (typeof window === \"undefined\") return null;\n const state = window.history.state;\n if (!state || typeof state !== \"object\") return null;\n return ((state as Record<string, unknown>)[FARM_PAGE_STATE_KEY] as TState | undefined) ?? null;\n}\n\nfunction createHistoryState(\n path: string,\n pageState: unknown,\n currentState?: unknown,\n interceptFrom?: string | null,\n) {\n const base =\n currentState && typeof currentState === \"object\" ? { ...(currentState as object) } : {};\n const nextState: Record<string, unknown> = {\n ...base,\n path,\n [FARM_PAGE_STATE_KEY]: pageState,\n };\n if (interceptFrom === null) {\n delete nextState[FARM_INTERCEPT_FROM_KEY];\n } else if (interceptFrom) {\n nextState[FARM_INTERCEPT_FROM_KEY] = interceptFrom;\n }\n return nextState;\n}\n\nfunction getPageDataCacheKey(path: string, interceptFrom?: string): string {\n return interceptFrom ? `${path}\\nintercept:${interceptFrom}` : path;\n}\n\nfunction createNavigationLocation(url: URL): FarmNavigationLocation {\n return {\n href: url.href,\n pathname: url.pathname,\n search: url.search,\n hash: url.hash,\n };\n}\n\nfunction getScrollElementStorageKey(path: string, key: string): string {\n return `farm-scroll-${path}:${key}`;\n}\n","import { useEffect, useMemo, useRef, useState, type RefObject } from \"react\";\nimport { createFarmRouter, type FarmRouter, type FarmRouterRouteInput } from \"../router\";\nimport {\n getRouter as getSPARouter,\n readPageState,\n type FarmNavigationBlockerContext,\n type FarmNavigationState,\n} from \"./spa-router\";\nimport { getFarmI18nClientState } from \"../i18n/client-runtime\";\nimport { stripFarmLocaleFromPathname } from \"../i18n/routing\";\n\ninterface RouterState {\n pathname: string;\n searchParams: URLSearchParams;\n params: Record<string, string>;\n pageState: unknown;\n}\n\nexport interface UseRouterOptions {\n basePath?: string;\n routes?: FarmRouterRouteInput[];\n}\n\nexport interface UseBlockerOptions {\n when: boolean | ((context: FarmNavigationBlockerContext) => boolean);\n message?: string;\n shouldBlock?: (context: FarmNavigationBlockerContext) => boolean | Promise<boolean>;\n}\n\nexport interface UseBlockerReturn {\n active: boolean;\n}\n\n/**\n * Hook for accessing router state and navigation\n */\nexport function useRouter(options: UseRouterOptions = {}) {\n const basePath = options.basePath || \"\";\n const routes = options.routes;\n const routeKey =\n routes?.map((route) => (typeof route === \"string\" ? route : route.path)).join(\"\\n\") || \"\";\n const routeMatcher = useMemo(\n () => (routeKey ? createFarmRouter(routeKey.split(\"\\n\")) : null),\n [routeKey],\n );\n const [state, setState] = useState<RouterState>(() => {\n return readRouterState(basePath, routeMatcher);\n });\n\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n\n const handlePopState = () => {\n setState(readRouterState(basePath, routeMatcher));\n };\n\n handlePopState();\n window.addEventListener(\"popstate\", handlePopState);\n return () => window.removeEventListener(\"popstate\", handlePopState);\n }, [basePath, routeMatcher]);\n\n const push = (href: string) => {\n if (typeof window === \"undefined\") return;\n\n const url = href.startsWith(\"/\") ? basePath + href : href;\n window.history.pushState(null, \"\", url);\n window.dispatchEvent(new PopStateEvent(\"popstate\"));\n };\n\n const replace = (href: string) => {\n if (typeof window === \"undefined\") return;\n\n const url = href.startsWith(\"/\") ? basePath + href : href;\n window.history.replaceState(null, \"\", url);\n window.dispatchEvent(new PopStateEvent(\"popstate\"));\n };\n\n const pushState = <TState>(pageState: TState, href?: string) => {\n if (typeof window === \"undefined\") return;\n getSPARouter().pushState(pageState, resolveClientHref(href, basePath));\n };\n\n const replaceState = <TState>(pageState: TState, href?: string) => {\n if (typeof window === \"undefined\") return;\n getSPARouter().replaceState(pageState, resolveClientHref(href, basePath));\n };\n\n const back = () => {\n if (typeof window !== \"undefined\") {\n window.history.back();\n }\n };\n\n const forward = () => {\n if (typeof window !== \"undefined\") {\n window.history.forward();\n }\n };\n\n return {\n ...state,\n push,\n replace,\n pushState,\n replaceState,\n back,\n forward,\n };\n}\n\nexport function usePageState<TState = unknown>(): TState | null {\n const [state, setState] = useState<TState | null>(() => readPageState<TState>());\n\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n\n const handlePopState = () => {\n setState(readPageState<TState>());\n };\n\n handlePopState();\n window.addEventListener(\"popstate\", handlePopState);\n return () => window.removeEventListener(\"popstate\", handlePopState);\n }, []);\n\n return state;\n}\n\nexport function useNavigation(): FarmNavigationState {\n const [state, setState] = useState<FarmNavigationState>(() =>\n getSPARouter().getNavigationState(),\n );\n\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n return getSPARouter().subscribeNavigation(setState);\n }, []);\n\n return state;\n}\n\nexport function useBlocker(options: UseBlockerOptions): UseBlockerReturn {\n const optionsRef = useRef(options);\n optionsRef.current = options;\n const active = Boolean(options.when);\n\n useEffect(() => {\n if (typeof window === \"undefined\" || !active) {\n return;\n }\n\n return getSPARouter().addBlocker(async (context) => {\n const current = optionsRef.current;\n const when = typeof current.when === \"function\" ? current.when(context) : current.when;\n\n if (!when) return false;\n\n if (current.shouldBlock && !(await current.shouldBlock(context))) {\n return false;\n }\n\n if (current.message && typeof window.confirm === \"function\") {\n return !window.confirm(current.message);\n }\n\n return true;\n });\n }, [active]);\n\n return { active };\n}\n\nexport function useScrollRestoration<TElement extends HTMLElement = HTMLElement>(\n key: string,\n): RefObject<TElement> {\n const ref = useRef<TElement>(null);\n\n useEffect(() => {\n const element = ref.current;\n if (!element) return;\n return getSPARouter().registerScrollElement(key, element);\n }, [key]);\n\n return ref;\n}\n\nfunction readRouterState(basePath: string, routeMatcher: FarmRouter | null): RouterState {\n if (typeof window === \"undefined\") {\n return {\n pathname: \"/\",\n searchParams: new URLSearchParams(),\n params: {},\n pageState: null,\n };\n }\n\n const url = new URL(window.location.href);\n const pathname = normalizeClientPathname(url.pathname, basePath);\n const i18n = getFarmI18nClientState();\n const routePathname = i18n ? stripFarmLocaleFromPathname(pathname, i18n) : pathname;\n return {\n pathname,\n searchParams: url.searchParams,\n params: routeMatcher?.match(routePathname)?.params || {},\n pageState: readPageState(),\n };\n}\n\nfunction normalizeClientPathname(pathname: string, basePath: string) {\n const normalizedBase = basePath.replace(/\\/+$/, \"\");\n const isUnderBase =\n normalizedBase && (pathname === normalizedBase || pathname.startsWith(`${normalizedBase}/`));\n const withoutBase = isUnderBase ? pathname.slice(normalizedBase.length) || \"/\" : pathname;\n return withoutBase || \"/\";\n}\n\nfunction resolveClientHref(href: string | undefined, basePath: string): string | undefined {\n if (!href) return undefined;\n return href.startsWith(\"/\") ? basePath + href : href;\n}\n"],"mappings":"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","names":["pushState","replaceState"]}
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getServerActionExecutionContext,
|
|
3
3
|
getServerActionSignal
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-UB5UOSHB.mjs";
|
|
5
5
|
import {
|
|
6
6
|
_resolveCurrentRequest
|
|
7
7
|
} from "./chunk-LM2YNO4U.mjs";
|
|
8
|
+
import {
|
|
9
|
+
applyFarmCacheInvalidationTargets
|
|
10
|
+
} from "./chunk-V3XURYJO.mjs";
|
|
8
11
|
import {
|
|
9
12
|
__name
|
|
10
13
|
} from "./chunk-CGILA3WO.mjs";
|
|
@@ -46,8 +49,21 @@ function createServerFn(options) {
|
|
|
46
49
|
request,
|
|
47
50
|
signal
|
|
48
51
|
};
|
|
49
|
-
|
|
50
|
-
|
|
52
|
+
let resolvedContext = Object.freeze(/* @__PURE__ */ Object.create(null));
|
|
53
|
+
const result = await runServerFnMiddleware(middleware, handlerContext, async (context) => {
|
|
54
|
+
resolvedContext = context.context;
|
|
55
|
+
return options.handler(context);
|
|
56
|
+
});
|
|
57
|
+
const parsedResult = await _parseServerFnSchema(options.output, result, "output");
|
|
58
|
+
if (options.invalidates) {
|
|
59
|
+
const declaration = typeof options.invalidates === "function" ? await options.invalidates({
|
|
60
|
+
...handlerContext,
|
|
61
|
+
context: resolvedContext,
|
|
62
|
+
result: parsedResult
|
|
63
|
+
}) : options.invalidates;
|
|
64
|
+
await applyFarmCacheInvalidationTargets(declaration);
|
|
65
|
+
}
|
|
66
|
+
return parsedResult;
|
|
51
67
|
}, "serverFn");
|
|
52
68
|
Object.defineProperties(serverFn, {
|
|
53
69
|
[FARM_SERVER_FN_SYMBOL]: {
|
|
@@ -69,6 +85,10 @@ function createServerFn(options) {
|
|
|
69
85
|
__farmServerFnMiddleware: {
|
|
70
86
|
value: middleware,
|
|
71
87
|
enumerable: false
|
|
88
|
+
},
|
|
89
|
+
__farmServerFnInvalidates: {
|
|
90
|
+
value: options.invalidates,
|
|
91
|
+
enumerable: false
|
|
72
92
|
}
|
|
73
93
|
});
|
|
74
94
|
return serverFn;
|
|
@@ -201,4 +221,4 @@ export {
|
|
|
201
221
|
createServerFn,
|
|
202
222
|
_parseServerFnSchema
|
|
203
223
|
};
|
|
204
|
-
//# sourceMappingURL=chunk-
|
|
224
|
+
//# sourceMappingURL=chunk-VY2UYN5R.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/server-fn.ts"],"sourcesContent":["import { getServerActionExecutionContext, getServerActionSignal } from \"./server-action-security\";\nimport { _resolveCurrentRequest } from \"./server/request-bridge\";\nimport { applyFarmCacheInvalidationTargets, type FarmCacheInvalidationTarget } from \"./cache\";\n\ntype MaybePromise<T> = T | Promise<T>;\n\n// Generic schema type that works with Zod v3/v4 and similar validator APIs.\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type ServerFnSchema = {\n _input?: any;\n _output?: any;\n parse?: (data: unknown) => any;\n parseAsync?: (data: unknown) => Promise<any>;\n safeParse?: (data: unknown) => any;\n safeParseAsync?: (data: unknown) => Promise<any>;\n};\n\nexport type InferServerFnSchemaInput<T> = T extends { _input: infer I } ? I : unknown;\nexport type InferServerFnSchemaOutput<T> = T extends { _output: infer O }\n ? O\n : T extends { parse: (data: unknown) => infer R }\n ? R\n : unknown;\n\nexport type ServerFnFormInput = FormData;\n\ntype Simplify<T> = { [TKey in keyof T]: T[TKey] } & {};\ntype AssignContext<TCurrent extends object, TNext extends object> = Simplify<\n Omit<TCurrent, keyof TNext> & TNext\n>;\ntype MiddlewareContext<TMiddleware> =\n TMiddleware extends ServerFnMiddleware<infer TContext> ? TContext : {};\n\nexport type ServerFnMiddlewareContext<\n TMiddlewares extends readonly AnyServerFnMiddleware[],\n TContext extends object = {},\n> = TMiddlewares extends readonly [infer TMiddleware, ...infer TRest]\n ? TMiddleware extends AnyServerFnMiddleware\n ? TRest extends readonly AnyServerFnMiddleware[]\n ? ServerFnMiddlewareContext<TRest, AssignContext<TContext, MiddlewareContext<TMiddleware>>>\n : TContext\n : TContext\n : number extends TMiddlewares[\"length\"]\n ? Simplify<TContext & MiddlewareContext<TMiddlewares[number]>>\n : Simplify<TContext>;\n\ndeclare const SERVER_FN_MIDDLEWARE_CONTEXT: unique symbol;\n\nexport type ServerFnMiddlewareContinuation<TContext extends object = {}> = {\n readonly [SERVER_FN_MIDDLEWARE_CONTEXT]: TContext;\n};\n\nexport type ServerFnMiddlewareNext = <TContext extends object = {}>(options?: {\n context?: TContext;\n}) => Promise<ServerFnMiddlewareContinuation<TContext>>;\n\nexport type ServerFnContext<TInput, TContext extends object = {}> = {\n input: TInput;\n rawInput: unknown;\n formData?: FormData;\n /** The action request when invoked across the network. Undefined for direct server calls. */\n request?: Request;\n /** Aborts when the underlying action request is cancelled. */\n signal: AbortSignal;\n /** Context produced by this server function's middleware chain. */\n context: Readonly<TContext>;\n};\n\nexport type ServerFnHandler<TInput, TResult, TContext extends object = {}> = (\n ctx: ServerFnContext<TInput, TContext>,\n) => MaybePromise<TResult>;\n\nexport type ServerFnInvalidationContext<\n TInput,\n TResult,\n TContext extends object = {},\n> = ServerFnContext<TInput, TContext> & {\n /** Parsed value returned by the successful server function. */\n result: TResult;\n};\n\nexport type ServerFnInvalidations<TInput, TResult, TContext extends object = {}> =\n | readonly FarmCacheInvalidationTarget[]\n | ((\n context: ServerFnInvalidationContext<TInput, TResult, TContext>,\n ) => readonly FarmCacheInvalidationTarget[] | Promise<readonly FarmCacheInvalidationTarget[]>);\n\nexport type ServerFnMiddlewareHandlerContext<TContext extends object = {}> = ServerFnContext<\n unknown,\n TContext\n> & {\n next: ServerFnMiddlewareNext;\n};\n\nexport type ServerFnMiddlewareHandler<\n TContext extends object = {},\n TProvidedContext extends object = {},\n> = (\n ctx: ServerFnMiddlewareHandlerContext<TContext>,\n) => MaybePromise<ServerFnMiddlewareContinuation<TProvidedContext>>;\n\nexport type ServerFnMiddleware<TContext extends object = {}> = {\n readonly __farmServerFnMiddleware: true;\n readonly __farmServerFnMiddlewareContext?: TContext;\n readonly middleware: readonly AnyServerFnMiddleware[];\n readonly handler: ServerFnMiddlewareHandler<any, any>;\n};\n\nexport type AnyServerFnMiddleware = ServerFnMiddleware<any>;\n\nexport type ServerFnMiddlewareOptions<\n TMiddlewares extends readonly AnyServerFnMiddleware[],\n TProvidedContext extends object,\n> = {\n middleware?: TMiddlewares;\n handler: ServerFnMiddlewareHandler<ServerFnMiddlewareContext<TMiddlewares>, TProvidedContext>;\n};\n\nexport type ServerFnOptions<\n TSchema extends ServerFnSchema | undefined,\n TResult,\n TMiddlewares extends readonly AnyServerFnMiddleware[] = readonly [],\n> = {\n input?: TSchema;\n output?: undefined;\n middleware?: TMiddlewares;\n invalidates?: ServerFnInvalidations<\n TSchema extends ServerFnSchema ? InferServerFnSchemaOutput<TSchema> : unknown,\n Awaited<TResult>,\n ServerFnMiddlewareContext<TMiddlewares>\n >;\n handler: ServerFnHandler<\n TSchema extends ServerFnSchema ? InferServerFnSchemaOutput<TSchema> : unknown,\n TResult,\n ServerFnMiddlewareContext<TMiddlewares>\n >;\n};\n\nexport type ServerFnOutputOptions<\n TInputSchema extends ServerFnSchema | undefined,\n TOutputSchema extends ServerFnSchema,\n TMiddlewares extends readonly AnyServerFnMiddleware[] = readonly [],\n> = {\n input?: TInputSchema;\n output: TOutputSchema;\n middleware?: TMiddlewares;\n invalidates?: ServerFnInvalidations<\n TInputSchema extends ServerFnSchema ? InferServerFnSchemaOutput<TInputSchema> : unknown,\n Awaited<InferServerFnSchemaOutput<TOutputSchema>>,\n ServerFnMiddlewareContext<TMiddlewares>\n >;\n handler: ServerFnHandler<\n TInputSchema extends ServerFnSchema ? InferServerFnSchemaOutput<TInputSchema> : unknown,\n unknown,\n ServerFnMiddlewareContext<TMiddlewares>\n >;\n};\n\nexport type ServerFn<TInput, TResult> = ([unknown] extends [TInput]\n ? (input?: TInput | FormData) => Promise<TResult>\n : (input: TInput | FormData) => Promise<TResult>) & {\n readonly __farmServerFn: true;\n readonly __farmServerFnInput?: unknown;\n readonly __farmServerFnOutput?: unknown;\n};\n\nexport const FARM_SERVER_FN_SYMBOL = Symbol.for(\"farm.server-fn\");\n\nconst UNSAFE_FORM_KEYS = new Set([\"__proto__\", \"constructor\", \"prototype\"]);\n\nexport function createServerMiddleware<\n const TMiddlewares extends readonly AnyServerFnMiddleware[] = readonly [],\n TProvidedContext extends object = {},\n>(\n options: ServerFnMiddlewareOptions<TMiddlewares, TProvidedContext>,\n): ServerFnMiddleware<AssignContext<ServerFnMiddlewareContext<TMiddlewares>, TProvidedContext>>;\nexport function createServerMiddleware(options: {\n middleware?: readonly AnyServerFnMiddleware[];\n handler: ServerFnMiddlewareHandler<any, any>;\n}): ServerFnMiddleware<any> {\n if (!options || typeof options.handler !== \"function\") {\n throw new TypeError(\"createServerMiddleware requires a handler function\");\n }\n\n const middleware = Object.freeze([...(options.middleware ?? [])]);\n for (const entry of middleware) {\n assertServerFnMiddleware(entry);\n }\n\n return Object.freeze({\n __farmServerFnMiddleware: true as const,\n middleware,\n handler: options.handler,\n });\n}\n\nexport function createServerFn<\n TInputSchema extends ServerFnSchema,\n TOutputSchema extends ServerFnSchema,\n const TMiddlewares extends readonly AnyServerFnMiddleware[] = readonly [],\n>(\n options: ServerFnOutputOptions<TInputSchema, TOutputSchema, TMiddlewares>,\n): ServerFn<\n InferServerFnSchemaInput<TInputSchema>,\n Awaited<InferServerFnSchemaOutput<TOutputSchema>>\n>;\nexport function createServerFn<\n TOutputSchema extends ServerFnSchema,\n const TMiddlewares extends readonly AnyServerFnMiddleware[] = readonly [],\n>(\n options: ServerFnOutputOptions<undefined, TOutputSchema, TMiddlewares>,\n): ServerFn<unknown, Awaited<InferServerFnSchemaOutput<TOutputSchema>>>;\nexport function createServerFn<\n TSchema extends ServerFnSchema,\n TResult,\n const TMiddlewares extends readonly AnyServerFnMiddleware[] = readonly [],\n>(\n options: ServerFnOptions<TSchema, TResult, TMiddlewares>,\n): ServerFn<InferServerFnSchemaInput<TSchema>, Awaited<TResult>>;\nexport function createServerFn<\n TResult,\n const TMiddlewares extends readonly AnyServerFnMiddleware[] = readonly [],\n>(options: ServerFnOptions<undefined, TResult, TMiddlewares>): ServerFn<unknown, Awaited<TResult>>;\nexport function createServerFn(options: {\n input?: ServerFnSchema;\n output?: ServerFnSchema;\n middleware?: readonly AnyServerFnMiddleware[];\n invalidates?: ServerFnInvalidations<any, any, any>;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n handler: ServerFnHandler<any, any, any>;\n}) {\n if (!options || typeof options.handler !== \"function\") {\n throw new TypeError(\"createServerFn requires a handler function\");\n }\n\n const middleware = resolveServerFnMiddleware(options.middleware);\n const serverFn = async (value: unknown) => {\n const formData = isFormData(value) ? value : undefined;\n const rawInput = formData ? formDataToObject(formData) : value;\n const input = await _parseServerFnSchema(options.input, rawInput, \"input\");\n const executionContext = getServerActionExecutionContext();\n const request = executionContext?.request ?? _resolveCurrentRequest();\n const signal = executionContext?.signal ?? request?.signal ?? getServerActionSignal();\n const handlerContext = {\n input,\n rawInput,\n formData,\n request,\n signal,\n };\n let resolvedContext: Readonly<object> = Object.freeze(Object.create(null));\n const result = await runServerFnMiddleware(middleware, handlerContext, async (context) => {\n resolvedContext = context.context;\n return options.handler(context);\n });\n const parsedResult = await _parseServerFnSchema(options.output, result, \"output\");\n\n if (options.invalidates) {\n const declaration =\n typeof options.invalidates === \"function\"\n ? await options.invalidates({\n ...handlerContext,\n context: resolvedContext,\n result: parsedResult,\n })\n : options.invalidates;\n await applyFarmCacheInvalidationTargets(declaration);\n }\n\n return parsedResult;\n };\n\n Object.defineProperties(serverFn, {\n [FARM_SERVER_FN_SYMBOL]: {\n value: true,\n enumerable: false,\n },\n __farmServerFn: {\n value: true,\n enumerable: false,\n },\n __farmServerFnInput: {\n value: options.input,\n enumerable: false,\n },\n __farmServerFnOutput: {\n value: options.output,\n enumerable: false,\n },\n __farmServerFnMiddleware: {\n value: middleware,\n enumerable: false,\n },\n __farmServerFnInvalidates: {\n value: options.invalidates,\n enumerable: false,\n },\n });\n\n return serverFn as ServerFn<unknown, unknown>;\n}\n\ntype ServerFnBaseContext = Omit<ServerFnContext<unknown, {}>, \"context\">;\n\nasync function runServerFnMiddleware(\n middleware: readonly AnyServerFnMiddleware[],\n handlerContext: ServerFnBaseContext,\n handler: ServerFnHandler<any, any, any>,\n) {\n const dispatch = async (index: number, context: Readonly<object>): Promise<unknown> => {\n const current = middleware[index];\n if (!current) {\n return handler({ ...handlerContext, context });\n }\n\n let nextCalled = false;\n const result = await current.handler({\n ...handlerContext,\n context,\n next: async (nextOptions) => {\n if (nextCalled) {\n throw new Error(\"Server function middleware next() can only be called once\");\n }\n nextCalled = true;\n\n return dispatch(index + 1, mergeServerFnContext(context, nextOptions?.context)) as Promise<\n ServerFnMiddlewareContinuation<any>\n >;\n },\n });\n\n if (!nextCalled) {\n throw new Error(\"Server function middleware must call next()\");\n }\n\n return result;\n };\n\n return dispatch(0, Object.freeze(Object.create(null)));\n}\n\nfunction resolveServerFnMiddleware(\n middleware: readonly AnyServerFnMiddleware[] | undefined,\n): readonly AnyServerFnMiddleware[] {\n const resolved: AnyServerFnMiddleware[] = [];\n const seen = new Set<AnyServerFnMiddleware>();\n const visiting = new Set<AnyServerFnMiddleware>();\n\n const visit = (entry: AnyServerFnMiddleware) => {\n assertServerFnMiddleware(entry);\n if (seen.has(entry)) return;\n if (visiting.has(entry)) {\n throw new Error(\"Server function middleware dependencies cannot contain a cycle\");\n }\n\n visiting.add(entry);\n for (const dependency of entry.middleware) {\n visit(dependency);\n }\n visiting.delete(entry);\n seen.add(entry);\n resolved.push(entry);\n };\n\n for (const entry of middleware ?? []) {\n visit(entry);\n }\n\n return Object.freeze(resolved);\n}\n\nfunction assertServerFnMiddleware(value: unknown): asserts value is AnyServerFnMiddleware {\n if (\n !value ||\n typeof value !== \"object\" ||\n (value as { __farmServerFnMiddleware?: unknown }).__farmServerFnMiddleware !== true ||\n typeof (value as { handler?: unknown }).handler !== \"function\" ||\n !Array.isArray((value as { middleware?: unknown }).middleware)\n ) {\n throw new TypeError(\"createServerFn middleware must be created with createServerMiddleware\");\n }\n}\n\nfunction mergeServerFnContext(current: Readonly<object>, added: object | undefined) {\n if (\n added !== undefined &&\n (added === null || typeof added !== \"object\" || Array.isArray(added))\n ) {\n throw new TypeError(\"Server function middleware context must be an object\");\n }\n\n return Object.freeze(Object.assign(Object.create(null), current, added));\n}\n\nexport async function _parseServerFnSchema(\n schema: ServerFnSchema | undefined,\n value: unknown,\n contract: \"input\" | \"output\",\n owner = \"createServerFn\",\n) {\n if (!schema) return value;\n\n if (typeof schema.safeParseAsync === \"function\") {\n const result = await schema.safeParseAsync(value);\n return unwrapSafeParseResult(result);\n }\n\n if (typeof schema.safeParse === \"function\") {\n const result = schema.safeParse(value);\n return unwrapSafeParseResult(await result);\n }\n\n if (typeof schema.parseAsync === \"function\") {\n return schema.parseAsync(value);\n }\n\n if (typeof schema.parse === \"function\") {\n return schema.parse(value);\n }\n\n throw new TypeError(`${owner} ${contract} must provide parse, parseAsync, or safeParse`);\n}\n\nfunction unwrapSafeParseResult(result: unknown) {\n if (\n result &&\n typeof result === \"object\" &&\n \"success\" in result &&\n (result as { success: boolean }).success === false\n ) {\n throw (result as { error?: unknown }).error;\n }\n\n if (\n result &&\n typeof result === \"object\" &&\n \"success\" in result &&\n (result as { success: boolean }).success === true\n ) {\n return (result as unknown as { data: unknown }).data;\n }\n\n return result;\n}\n\nfunction formDataToObject(formData: FormData) {\n const output: Record<string, FormDataEntryValue | FormDataEntryValue[]> = Object.create(null);\n\n for (const [key, value] of formData.entries()) {\n if (!isSafeFormKey(key)) continue;\n\n const existing = output[key];\n if (existing === undefined) {\n output[key] = value;\n } else if (Array.isArray(existing)) {\n existing.push(value);\n } else {\n output[key] = [existing, value];\n }\n }\n\n return output;\n}\n\nfunction isSafeFormKey(key: string) {\n return !key.startsWith(\"$ACTION_\") && !UNSAFE_FORM_KEYS.has(key);\n}\n\nfunction isFormData(value: unknown): value is FormData {\n if (!value || typeof value !== \"object\") return false;\n\n if (typeof FormData !== \"undefined\" && value instanceof FormData) {\n return true;\n }\n\n return (\n Object.prototype.toString.call(value) === \"[object FormData]\" &&\n typeof (value as { entries?: unknown }).entries === \"function\"\n );\n}\n"],"mappings":"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","names":[]}
|