@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/testing.cjs
CHANGED
|
@@ -161,7 +161,8 @@ var FARM_CACHE_INVALIDATION_STATE = /* @__PURE__ */ Symbol.for("farm.cacheInvali
|
|
|
161
161
|
var globalState = globalThis;
|
|
162
162
|
function getFarmCacheInvalidationState() {
|
|
163
163
|
return globalState[FARM_CACHE_INVALIDATION_STATE] ?? (globalState[FARM_CACHE_INVALIDATION_STATE] = {
|
|
164
|
-
listeners: /* @__PURE__ */ new Set()
|
|
164
|
+
listeners: /* @__PURE__ */ new Set(),
|
|
165
|
+
taskListeners: /* @__PURE__ */ new Set()
|
|
165
166
|
});
|
|
166
167
|
}
|
|
167
168
|
__name(getFarmCacheInvalidationState, "getFarmCacheInvalidationState");
|
|
@@ -191,6 +192,12 @@ function subscribeFarmCacheInvalidation(listener) {
|
|
|
191
192
|
return () => state.listeners.delete(listener);
|
|
192
193
|
}
|
|
193
194
|
__name(subscribeFarmCacheInvalidation, "subscribeFarmCacheInvalidation");
|
|
195
|
+
function subscribeFarmCacheTask(listener) {
|
|
196
|
+
const state = getFarmCacheInvalidationState();
|
|
197
|
+
state.taskListeners.add(listener);
|
|
198
|
+
return () => state.taskListeners.delete(listener);
|
|
199
|
+
}
|
|
200
|
+
__name(subscribeFarmCacheTask, "subscribeFarmCacheTask");
|
|
194
201
|
|
|
195
202
|
// src/i18n/bridge.ts
|
|
196
203
|
var FARM_I18N_SNAPSHOT_RESOLVER = /* @__PURE__ */ Symbol.for("farm.i18n.snapshotResolver");
|
|
@@ -201,11 +208,51 @@ __name(_setFarmI18nSnapshotResolver, "_setFarmI18nSnapshotResolver");
|
|
|
201
208
|
|
|
202
209
|
// src/cache.ts
|
|
203
210
|
var _FarmDataCache = class _FarmDataCache {
|
|
204
|
-
constructor() {
|
|
211
|
+
constructor(config = {}) {
|
|
205
212
|
this.entries = /* @__PURE__ */ new Map();
|
|
206
213
|
this.inflight = /* @__PURE__ */ new Map();
|
|
207
214
|
this.invalidatedTagVersions = /* @__PURE__ */ new Map();
|
|
208
215
|
this.version = 0;
|
|
216
|
+
this.namespace = "farm";
|
|
217
|
+
this.local = true;
|
|
218
|
+
this.lease = {
|
|
219
|
+
enabled: true,
|
|
220
|
+
ttlMs: 1e4,
|
|
221
|
+
waitTimeoutMs: 1e4,
|
|
222
|
+
pollIntervalMs: 25
|
|
223
|
+
};
|
|
224
|
+
this.configure(config);
|
|
225
|
+
}
|
|
226
|
+
configure(config = {}) {
|
|
227
|
+
this.adapter = config.adapter;
|
|
228
|
+
this.namespace = normalizeCacheNamespace(config.namespace || "farm");
|
|
229
|
+
this.local = !config.adapter;
|
|
230
|
+
this.lease = config.lease === false ? { ...this.lease, enabled: false } : {
|
|
231
|
+
enabled: true,
|
|
232
|
+
ttlMs: normalizePositiveDuration(config.lease?.ttlMs, 1e4, "cache.lease.ttlMs"),
|
|
233
|
+
waitTimeoutMs: normalizePositiveDuration(
|
|
234
|
+
config.lease?.waitTimeoutMs,
|
|
235
|
+
1e4,
|
|
236
|
+
"cache.lease.waitTimeoutMs"
|
|
237
|
+
),
|
|
238
|
+
pollIntervalMs: normalizePositiveDuration(
|
|
239
|
+
config.lease?.pollIntervalMs,
|
|
240
|
+
25,
|
|
241
|
+
"cache.lease.pollIntervalMs"
|
|
242
|
+
)
|
|
243
|
+
};
|
|
244
|
+
if (!this.local) {
|
|
245
|
+
this.entries.clear();
|
|
246
|
+
this.inflight.clear();
|
|
247
|
+
this.invalidatedTagVersions.clear();
|
|
248
|
+
this.version = 0;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
get adapterName() {
|
|
252
|
+
return this.adapter?.name || (this.adapter ? "custom" : "memory");
|
|
253
|
+
}
|
|
254
|
+
get hasAdapter() {
|
|
255
|
+
return this.adapter !== void 0;
|
|
209
256
|
}
|
|
210
257
|
get size() {
|
|
211
258
|
return this.entries.size;
|
|
@@ -241,6 +288,45 @@ var _FarmDataCache = class _FarmDataCache {
|
|
|
241
288
|
});
|
|
242
289
|
return this.toPublicEntry(entry);
|
|
243
290
|
}
|
|
291
|
+
async getEntryAsync(key, options = {}) {
|
|
292
|
+
if (this.local) {
|
|
293
|
+
const localEntry = this.getEntry(key, options);
|
|
294
|
+
if (localEntry) return localEntry;
|
|
295
|
+
}
|
|
296
|
+
if (!this.adapter) {
|
|
297
|
+
return this.local ? void 0 : this.getEntry(key, options);
|
|
298
|
+
}
|
|
299
|
+
const entry = await this.adapter.get(this.createAdapterKey(key));
|
|
300
|
+
if (!entry) {
|
|
301
|
+
emitFarmEvent({ type: "cache.miss", key });
|
|
302
|
+
return void 0;
|
|
303
|
+
}
|
|
304
|
+
assertFarmCacheEntry(entry, key);
|
|
305
|
+
const stale = await this.isAdapterEntryStale(entry, options.now);
|
|
306
|
+
if (stale) {
|
|
307
|
+
emitFarmEvent({
|
|
308
|
+
type: "cache.stale",
|
|
309
|
+
key,
|
|
310
|
+
tags: [...entry.tags],
|
|
311
|
+
revalidate: entry.revalidate
|
|
312
|
+
});
|
|
313
|
+
if (!options.allowStale) {
|
|
314
|
+
emitFarmEvent({ type: "cache.miss", key, reason: "stale" });
|
|
315
|
+
return void 0;
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
emitFarmEvent({
|
|
319
|
+
type: "cache.hit",
|
|
320
|
+
key,
|
|
321
|
+
tags: [...entry.tags],
|
|
322
|
+
revalidate: entry.revalidate,
|
|
323
|
+
stale
|
|
324
|
+
});
|
|
325
|
+
if (this.local && !stale) {
|
|
326
|
+
this.hydrateLocalEntry(entry);
|
|
327
|
+
}
|
|
328
|
+
return { ...entry, key };
|
|
329
|
+
}
|
|
244
330
|
set(key, value, options = {}) {
|
|
245
331
|
const tags = /* @__PURE__ */ new Set();
|
|
246
332
|
for (const tag of options.tags ?? []) {
|
|
@@ -253,6 +339,7 @@ var _FarmDataCache = class _FarmDataCache {
|
|
|
253
339
|
key,
|
|
254
340
|
value,
|
|
255
341
|
tags,
|
|
342
|
+
tagVersions: void 0,
|
|
256
343
|
createdAt: options.createdAt ?? Date.now(),
|
|
257
344
|
createdVersion: ++this.version,
|
|
258
345
|
revalidate: normalizeRevalidate(options.revalidate)
|
|
@@ -266,11 +353,45 @@ var _FarmDataCache = class _FarmDataCache {
|
|
|
266
353
|
});
|
|
267
354
|
return this.toPublicEntry(entry);
|
|
268
355
|
}
|
|
356
|
+
async setAsync(key, value, options = {}, tagVersions) {
|
|
357
|
+
const tags = normalizeCacheOptionsTags(options);
|
|
358
|
+
const capturedVersions = tagVersions ?? await this.getAdapterTagVersions(Array.from(tags.values()));
|
|
359
|
+
const entry = {
|
|
360
|
+
key,
|
|
361
|
+
value,
|
|
362
|
+
tags: Array.from(tags),
|
|
363
|
+
tagVersions: capturedVersions,
|
|
364
|
+
createdAt: options.createdAt ?? Date.now(),
|
|
365
|
+
createdVersion: ++this.version,
|
|
366
|
+
revalidate: normalizeRevalidate(options.revalidate)
|
|
367
|
+
};
|
|
368
|
+
if (this.local) {
|
|
369
|
+
this.hydrateLocalEntry(entry);
|
|
370
|
+
}
|
|
371
|
+
if (this.adapter) {
|
|
372
|
+
await this.adapter.set(this.createAdapterKey(key), entry);
|
|
373
|
+
}
|
|
374
|
+
emitFarmEvent({
|
|
375
|
+
type: "cache.set",
|
|
376
|
+
key,
|
|
377
|
+
tags: [...entry.tags],
|
|
378
|
+
revalidate: entry.revalidate
|
|
379
|
+
});
|
|
380
|
+
return entry;
|
|
381
|
+
}
|
|
269
382
|
delete(key) {
|
|
270
383
|
const deleted = this.entries.delete(key);
|
|
271
384
|
emitFarmEvent({ type: "cache.delete", key, deleted });
|
|
272
385
|
return deleted;
|
|
273
386
|
}
|
|
387
|
+
async deleteAsync(key) {
|
|
388
|
+
const deleted = this.entries.delete(key);
|
|
389
|
+
if (this.adapter) {
|
|
390
|
+
await this.adapter.delete(this.createAdapterKey(key));
|
|
391
|
+
}
|
|
392
|
+
emitFarmEvent({ type: "cache.delete", key, deleted: this.adapter ? true : deleted });
|
|
393
|
+
return this.adapter ? true : deleted;
|
|
394
|
+
}
|
|
274
395
|
clear() {
|
|
275
396
|
const count = this.entries.size;
|
|
276
397
|
this.entries.clear();
|
|
@@ -279,6 +400,10 @@ var _FarmDataCache = class _FarmDataCache {
|
|
|
279
400
|
this.version = 0;
|
|
280
401
|
emitFarmEvent({ type: "cache.clear", count });
|
|
281
402
|
}
|
|
403
|
+
async clearAsync() {
|
|
404
|
+
this.clear();
|
|
405
|
+
await this.adapter?.clear?.();
|
|
406
|
+
}
|
|
282
407
|
isStale(entry, now = Date.now()) {
|
|
283
408
|
if (typeof entry.revalidate === "number" && entry.revalidate > 0 && now - entry.createdAt >= entry.revalidate * 1e3) {
|
|
284
409
|
return true;
|
|
@@ -291,6 +416,12 @@ var _FarmDataCache = class _FarmDataCache {
|
|
|
291
416
|
}
|
|
292
417
|
return false;
|
|
293
418
|
}
|
|
419
|
+
async isStaleAsync(entry, now = Date.now()) {
|
|
420
|
+
if (this.adapter) {
|
|
421
|
+
return this.isAdapterEntryStale(entry, now);
|
|
422
|
+
}
|
|
423
|
+
return this.isStale(entry, now);
|
|
424
|
+
}
|
|
294
425
|
revalidateTag(tag, options = {}) {
|
|
295
426
|
const normalized = normalizeCacheTag(tag);
|
|
296
427
|
const count = this.invalidateTag(normalized);
|
|
@@ -299,6 +430,15 @@ var _FarmDataCache = class _FarmDataCache {
|
|
|
299
430
|
);
|
|
300
431
|
return count;
|
|
301
432
|
}
|
|
433
|
+
async revalidateTagAsync(tag, options = {}) {
|
|
434
|
+
const normalized = normalizeCacheTag(tag);
|
|
435
|
+
const count = this.invalidateTag(normalized);
|
|
436
|
+
await this.adapter?.invalidateTags?.([this.createAdapterTag(normalized)]);
|
|
437
|
+
emitFarmEvent(
|
|
438
|
+
options.source === "updateTag" ? { type: "cache.updateTag", tag: normalized, count } : { type: "cache.revalidateTag", tag: normalized, profile: options.profile, count }
|
|
439
|
+
);
|
|
440
|
+
return count;
|
|
441
|
+
}
|
|
302
442
|
revalidatePath(routePath) {
|
|
303
443
|
const normalizedPath = normalizeRevalidatePath(routePath);
|
|
304
444
|
const pathTag = createPathCacheTag(normalizedPath);
|
|
@@ -315,8 +455,25 @@ var _FarmDataCache = class _FarmDataCache {
|
|
|
315
455
|
}
|
|
316
456
|
return count;
|
|
317
457
|
}
|
|
458
|
+
async revalidatePathAsync(routePath) {
|
|
459
|
+
const normalizedPath = normalizeRevalidatePath(routePath);
|
|
460
|
+
const pathTag = createPathCacheTag(normalizedPath);
|
|
461
|
+
const pprCount = this.countEntriesForTags([pathTag, "ppr"]);
|
|
462
|
+
const count = this.invalidateTag(pathTag);
|
|
463
|
+
await this.adapter?.invalidateTags?.([this.createAdapterTag(pathTag)]);
|
|
464
|
+
emitFarmEvent({ type: "cache.revalidatePath", path: normalizedPath, count });
|
|
465
|
+
if (pprCount > 0) {
|
|
466
|
+
emitFarmEvent({
|
|
467
|
+
type: "ppr.shell.invalidated",
|
|
468
|
+
route: normalizedPath,
|
|
469
|
+
reason: "revalidatePath",
|
|
470
|
+
count: pprCount
|
|
471
|
+
});
|
|
472
|
+
}
|
|
473
|
+
return count;
|
|
474
|
+
}
|
|
318
475
|
async getOrSet(key, producer, options = {}) {
|
|
319
|
-
const cached = this.
|
|
476
|
+
const cached = await this.getEntryAsync(key);
|
|
320
477
|
if (cached) {
|
|
321
478
|
return cached.value;
|
|
322
479
|
}
|
|
@@ -325,10 +482,8 @@ var _FarmDataCache = class _FarmDataCache {
|
|
|
325
482
|
emitFarmEvent({ type: "cache.dedupe", key });
|
|
326
483
|
return inflight;
|
|
327
484
|
}
|
|
328
|
-
const
|
|
329
|
-
|
|
330
|
-
return value;
|
|
331
|
-
}).catch((error) => {
|
|
485
|
+
const tags = Array.from(normalizeCacheOptionsTags(options));
|
|
486
|
+
const promise = this.fillCacheEntry(key, producer, options, tags).catch((error) => {
|
|
332
487
|
emitFarmEvent({ type: "cache.error", key, operation: "set", error });
|
|
333
488
|
throw error;
|
|
334
489
|
}).finally(() => {
|
|
@@ -337,6 +492,40 @@ var _FarmDataCache = class _FarmDataCache {
|
|
|
337
492
|
this.inflight.set(key, promise);
|
|
338
493
|
return promise;
|
|
339
494
|
}
|
|
495
|
+
async fillCacheEntry(key, producer, options, tags) {
|
|
496
|
+
const leaseKey = `${this.namespace}:lease:${key}`;
|
|
497
|
+
let leaseToken;
|
|
498
|
+
if (this.adapter?.acquireLease && this.adapter.releaseLease && this.lease.enabled) {
|
|
499
|
+
leaseToken = await this.adapter.acquireLease(leaseKey, this.lease.ttlMs);
|
|
500
|
+
if (!leaseToken) {
|
|
501
|
+
const shared = await this.waitForAdapterEntry(key);
|
|
502
|
+
if (shared) {
|
|
503
|
+
emitFarmEvent({ type: "cache.dedupe", key });
|
|
504
|
+
return shared.value;
|
|
505
|
+
}
|
|
506
|
+
leaseToken = await this.adapter.acquireLease(leaseKey, this.lease.ttlMs);
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
try {
|
|
510
|
+
const initialTagVersions = await this.getAdapterTagVersions(tags);
|
|
511
|
+
const value = await producer();
|
|
512
|
+
await this.setAsync(key, value, options, initialTagVersions);
|
|
513
|
+
return value;
|
|
514
|
+
} finally {
|
|
515
|
+
if (leaseToken && this.adapter?.releaseLease) {
|
|
516
|
+
await this.adapter.releaseLease(leaseKey, leaseToken);
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
async waitForAdapterEntry(key) {
|
|
521
|
+
const deadline = Date.now() + this.lease.waitTimeoutMs;
|
|
522
|
+
while (Date.now() < deadline) {
|
|
523
|
+
await delay(this.lease.pollIntervalMs);
|
|
524
|
+
const entry = await this.getEntryAsync(key);
|
|
525
|
+
if (entry) return entry;
|
|
526
|
+
}
|
|
527
|
+
return void 0;
|
|
528
|
+
}
|
|
340
529
|
countEntriesForTag(tag) {
|
|
341
530
|
let count = 0;
|
|
342
531
|
for (const entry of this.entries.values()) {
|
|
@@ -364,11 +553,53 @@ var _FarmDataCache = class _FarmDataCache {
|
|
|
364
553
|
key: entry.key,
|
|
365
554
|
value: entry.value,
|
|
366
555
|
tags: Array.from(entry.tags),
|
|
556
|
+
tagVersions: entry.tagVersions,
|
|
367
557
|
createdAt: entry.createdAt,
|
|
368
558
|
createdVersion: entry.createdVersion,
|
|
369
559
|
revalidate: entry.revalidate
|
|
370
560
|
};
|
|
371
561
|
}
|
|
562
|
+
hydrateLocalEntry(entry) {
|
|
563
|
+
this.entries.set(entry.key, {
|
|
564
|
+
key: entry.key,
|
|
565
|
+
value: entry.value,
|
|
566
|
+
tags: new Set(entry.tags.map(normalizeCacheTag)),
|
|
567
|
+
tagVersions: entry.tagVersions,
|
|
568
|
+
createdAt: entry.createdAt,
|
|
569
|
+
createdVersion: entry.createdVersion ?? ++this.version,
|
|
570
|
+
revalidate: normalizeRevalidate(entry.revalidate)
|
|
571
|
+
});
|
|
572
|
+
}
|
|
573
|
+
createAdapterKey(key) {
|
|
574
|
+
return `${this.namespace}:entry:${key}`;
|
|
575
|
+
}
|
|
576
|
+
createAdapterTag(tag) {
|
|
577
|
+
return `${this.namespace}:tag:${tag}`;
|
|
578
|
+
}
|
|
579
|
+
async getAdapterTagVersions(tags) {
|
|
580
|
+
if (!this.adapter?.getTagVersions || tags.length === 0) return {};
|
|
581
|
+
const normalized = tags.map(normalizeCacheTag);
|
|
582
|
+
const physicalTags = normalized.map((tag) => this.createAdapterTag(tag));
|
|
583
|
+
const versions = await this.adapter.getTagVersions(physicalTags);
|
|
584
|
+
return Object.fromEntries(
|
|
585
|
+
normalized.map((tag, index) => [
|
|
586
|
+
tag,
|
|
587
|
+
normalizeAdapterVersion(versions[physicalTags[index]])
|
|
588
|
+
])
|
|
589
|
+
);
|
|
590
|
+
}
|
|
591
|
+
async isAdapterEntryStale(entry, now = Date.now()) {
|
|
592
|
+
if (typeof entry.revalidate === "number" && entry.revalidate > 0 && now - entry.createdAt >= entry.revalidate * 1e3) {
|
|
593
|
+
return true;
|
|
594
|
+
}
|
|
595
|
+
const currentVersions = await this.getAdapterTagVersions(entry.tags);
|
|
596
|
+
for (const tag of entry.tags) {
|
|
597
|
+
if (normalizeAdapterVersion(currentVersions[tag]) > normalizeAdapterVersion(entry.tagVersions?.[tag])) {
|
|
598
|
+
return true;
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
return false;
|
|
602
|
+
}
|
|
372
603
|
};
|
|
373
604
|
__name(_FarmDataCache, "FarmDataCache");
|
|
374
605
|
var FarmDataCache = _FarmDataCache;
|
|
@@ -441,6 +672,52 @@ function normalizeCacheTag(tag) {
|
|
|
441
672
|
return normalized;
|
|
442
673
|
}
|
|
443
674
|
__name(normalizeCacheTag, "normalizeCacheTag");
|
|
675
|
+
function normalizeCacheNamespace(namespace) {
|
|
676
|
+
if (typeof namespace !== "string") {
|
|
677
|
+
throw new TypeError("Cache namespace must be a string.");
|
|
678
|
+
}
|
|
679
|
+
const normalized = namespace.trim().replace(/:+$/g, "");
|
|
680
|
+
if (!normalized) {
|
|
681
|
+
throw new Error("Cache namespace cannot be empty.");
|
|
682
|
+
}
|
|
683
|
+
return normalized;
|
|
684
|
+
}
|
|
685
|
+
__name(normalizeCacheNamespace, "normalizeCacheNamespace");
|
|
686
|
+
function normalizeAdapterVersion(value) {
|
|
687
|
+
return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : 0;
|
|
688
|
+
}
|
|
689
|
+
__name(normalizeAdapterVersion, "normalizeAdapterVersion");
|
|
690
|
+
function normalizePositiveDuration(value, fallback, name) {
|
|
691
|
+
if (value === void 0) return fallback;
|
|
692
|
+
if (!Number.isFinite(value) || value <= 0) {
|
|
693
|
+
throw new TypeError(`${name} must be a positive number of milliseconds.`);
|
|
694
|
+
}
|
|
695
|
+
return Math.floor(value);
|
|
696
|
+
}
|
|
697
|
+
__name(normalizePositiveDuration, "normalizePositiveDuration");
|
|
698
|
+
function delay(ms) {
|
|
699
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
700
|
+
}
|
|
701
|
+
__name(delay, "delay");
|
|
702
|
+
function normalizeCacheOptionsTags(options) {
|
|
703
|
+
const tags = /* @__PURE__ */ new Set();
|
|
704
|
+
for (const tag of options.tags ?? []) {
|
|
705
|
+
tags.add(normalizeCacheTag(tag));
|
|
706
|
+
}
|
|
707
|
+
for (const routePath of options.paths ?? []) {
|
|
708
|
+
tags.add(createPathCacheTag(routePath));
|
|
709
|
+
}
|
|
710
|
+
return tags;
|
|
711
|
+
}
|
|
712
|
+
__name(normalizeCacheOptionsTags, "normalizeCacheOptionsTags");
|
|
713
|
+
function assertFarmCacheEntry(entry, expectedKey) {
|
|
714
|
+
if (!entry || typeof entry !== "object" || entry.key !== expectedKey || !Array.isArray(entry.tags) || typeof entry.createdAt !== "number") {
|
|
715
|
+
throw new TypeError(
|
|
716
|
+
`Cache adapter returned an invalid entry for ${JSON.stringify(expectedKey)}.`
|
|
717
|
+
);
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
__name(assertFarmCacheEntry, "assertFarmCacheEntry");
|
|
444
721
|
function getFunctionCacheIdentity(fn) {
|
|
445
722
|
if (fn.name) {
|
|
446
723
|
return `name:${fn.name}`;
|
|
@@ -1281,7 +1558,7 @@ async function invokeAPIRouteEndpointInContext(endpoint, request, params) {
|
|
|
1281
1558
|
});
|
|
1282
1559
|
let body = void 0;
|
|
1283
1560
|
if (request.method.toUpperCase() !== "GET" && request.method.toUpperCase() !== "HEAD") {
|
|
1284
|
-
body = await
|
|
1561
|
+
body = await readRequestBody(request);
|
|
1285
1562
|
}
|
|
1286
1563
|
const headers = Object.fromEntries(request.headers.entries());
|
|
1287
1564
|
const types = endpoint.__types || {};
|
|
@@ -1385,17 +1662,50 @@ function isFarmContextHandler(endpoint) {
|
|
|
1385
1662
|
return firstParameter === "ctx" || firstParameter === "context" || firstParameter.startsWith("{");
|
|
1386
1663
|
}
|
|
1387
1664
|
__name(isFarmContextHandler, "isFarmContextHandler");
|
|
1388
|
-
async function
|
|
1665
|
+
async function readRequestBody(request) {
|
|
1666
|
+
const contentType = request.headers.get("content-type")?.split(";", 1)[0]?.trim().toLowerCase();
|
|
1389
1667
|
try {
|
|
1668
|
+
if (contentType === "multipart/form-data") {
|
|
1669
|
+
return formDataToObject(await request.clone().formData());
|
|
1670
|
+
}
|
|
1390
1671
|
const text = await request.clone().text();
|
|
1391
|
-
if (text)
|
|
1672
|
+
if (!text) return void 0;
|
|
1673
|
+
if (contentType === "application/x-www-form-urlencoded") {
|
|
1674
|
+
return searchParamsToObject(new URLSearchParams(text));
|
|
1675
|
+
}
|
|
1676
|
+
if (contentType === "application/json" || contentType?.endsWith("+json")) {
|
|
1392
1677
|
return JSON.parse(text);
|
|
1393
1678
|
}
|
|
1679
|
+
return JSON.parse(text);
|
|
1394
1680
|
} catch {
|
|
1395
1681
|
}
|
|
1396
1682
|
return void 0;
|
|
1397
1683
|
}
|
|
1398
|
-
__name(
|
|
1684
|
+
__name(readRequestBody, "readRequestBody");
|
|
1685
|
+
function formDataToObject(formData) {
|
|
1686
|
+
return entriesToObject(formData.entries());
|
|
1687
|
+
}
|
|
1688
|
+
__name(formDataToObject, "formDataToObject");
|
|
1689
|
+
function searchParamsToObject(searchParams) {
|
|
1690
|
+
return entriesToObject(searchParams.entries());
|
|
1691
|
+
}
|
|
1692
|
+
__name(searchParamsToObject, "searchParamsToObject");
|
|
1693
|
+
function entriesToObject(entries) {
|
|
1694
|
+
const output = /* @__PURE__ */ Object.create(null);
|
|
1695
|
+
for (const [key, value] of entries) {
|
|
1696
|
+
if (key === "__proto__" || key === "constructor" || key === "prototype") continue;
|
|
1697
|
+
const current = output[key];
|
|
1698
|
+
if (current === void 0) {
|
|
1699
|
+
output[key] = value;
|
|
1700
|
+
} else if (Array.isArray(current)) {
|
|
1701
|
+
current.push(value);
|
|
1702
|
+
} else {
|
|
1703
|
+
output[key] = [current, value];
|
|
1704
|
+
}
|
|
1705
|
+
}
|
|
1706
|
+
return output;
|
|
1707
|
+
}
|
|
1708
|
+
__name(entriesToObject, "entriesToObject");
|
|
1399
1709
|
function validateInput(schema, value, error) {
|
|
1400
1710
|
if (!schema || typeof schema.parse !== "function") {
|
|
1401
1711
|
return value;
|
|
@@ -1649,16 +1959,24 @@ __name(createSearchParams2, "createSearchParams");
|
|
|
1649
1959
|
// src/server-action-security.ts
|
|
1650
1960
|
var import_node_async_hooks3 = require("async_hooks");
|
|
1651
1961
|
var SERVER_ACTION_STORAGE_KEY = /* @__PURE__ */ Symbol.for("farm.serverActionStorage");
|
|
1652
|
-
function runWithServerActionRequest(request, callback) {
|
|
1962
|
+
async function runWithServerActionRequest(request, callback) {
|
|
1653
1963
|
throwIfAborted(request.signal);
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1964
|
+
const context = {
|
|
1965
|
+
request,
|
|
1966
|
+
signal: request.signal,
|
|
1967
|
+
invalidations: /* @__PURE__ */ new Set(),
|
|
1968
|
+
cacheTasks: /* @__PURE__ */ new Set()
|
|
1969
|
+
};
|
|
1970
|
+
return getServerActionStorage().run(context, async () => {
|
|
1971
|
+
try {
|
|
1972
|
+
const result = await callback();
|
|
1973
|
+
await Promise.all(context.cacheTasks);
|
|
1974
|
+
return result;
|
|
1975
|
+
} catch (error) {
|
|
1976
|
+
await Promise.allSettled(context.cacheTasks);
|
|
1977
|
+
throw error;
|
|
1978
|
+
}
|
|
1979
|
+
});
|
|
1662
1980
|
}
|
|
1663
1981
|
__name(runWithServerActionRequest, "runWithServerActionRequest");
|
|
1664
1982
|
function getServerActionExecutionContext() {
|
|
@@ -1668,6 +1986,9 @@ __name(getServerActionExecutionContext, "getServerActionExecutionContext");
|
|
|
1668
1986
|
subscribeFarmCacheInvalidation((key) => {
|
|
1669
1987
|
getServerActionExecutionContext()?.invalidations.add(key);
|
|
1670
1988
|
});
|
|
1989
|
+
subscribeFarmCacheTask((task) => {
|
|
1990
|
+
getServerActionExecutionContext()?.cacheTasks.add(task);
|
|
1991
|
+
});
|
|
1671
1992
|
function getServerActionStorage() {
|
|
1672
1993
|
const globalState2 = globalThis;
|
|
1673
1994
|
if (!globalState2[SERVER_ACTION_STORAGE_KEY]) {
|