@farm.js/core 0.1.0-beta.3 → 0.1.0-beta.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent-runtime.d.mts +2 -1
- package/dist/agent-runtime.d.ts +2 -1
- package/dist/api/route-manager.cjs +313 -10
- package/dist/api/route-manager.cjs.map +1 -1
- package/dist/api/route-manager.d.mts +3 -2
- package/dist/api/route-manager.d.ts +3 -2
- package/dist/api/route-manager.mjs +6 -5
- package/dist/api/runtime.cjs +313 -10
- package/dist/api/runtime.cjs.map +1 -1
- package/dist/api/runtime.d.mts +2 -1
- package/dist/api/runtime.d.ts +2 -1
- package/dist/api/runtime.mjs +4 -3
- package/dist/api.cjs +642 -57
- package/dist/api.cjs.map +1 -1
- package/dist/api.d.mts +3 -2
- package/dist/api.d.ts +3 -2
- package/dist/api.mjs +29 -9
- package/dist/{app-DOKxo-LH.d.ts → app-BjN-da13.d.ts} +38 -3
- package/dist/{app-BB3Iu3xh.d.mts → app-CakAr8Be.d.mts} +38 -3
- package/dist/app-markdown.d.mts +2 -1
- package/dist/app-markdown.d.ts +2 -1
- package/dist/cache.cjs +395 -12
- package/dist/cache.cjs.map +1 -1
- package/dist/cache.d.mts +100 -6
- package/dist/cache.d.ts +100 -6
- package/dist/cache.mjs +8 -2
- package/dist/{chunk-XUBZ7JI4.mjs → chunk-2CUKEMVR.mjs} +187 -16
- package/dist/chunk-2CUKEMVR.mjs.map +1 -0
- package/dist/{chunk-OHC6VCDI.mjs → chunk-2NHCNRF6.mjs} +521 -42
- package/dist/chunk-2NHCNRF6.mjs.map +1 -0
- package/dist/{chunk-6WXJ54TC.mjs → chunk-65A7QIKI.mjs} +5 -5
- package/dist/{chunk-6WXJ54TC.mjs.map → chunk-65A7QIKI.mjs.map} +1 -1
- package/dist/{chunk-5QH4IKY3.mjs → chunk-7N62DNSO.mjs} +2 -2
- package/dist/{chunk-XJSHJN4M.mjs → chunk-A2LUXHD2.mjs} +593 -49
- package/dist/chunk-A2LUXHD2.mjs.map +1 -0
- package/dist/chunk-ALCLXXTY.mjs +187 -0
- package/dist/chunk-ALCLXXTY.mjs.map +1 -0
- package/dist/{chunk-CSU4KJJF.mjs → chunk-C2ROET2V.mjs} +2 -2
- package/dist/{chunk-JNYVN7YP.mjs → chunk-EEABSBKK.mjs} +2 -2
- package/dist/{chunk-JNYVN7YP.mjs.map → chunk-EEABSBKK.mjs.map} +1 -1
- package/dist/{chunk-BIOIOWXZ.mjs → chunk-HNIQFZKB.mjs} +2 -2
- package/dist/{chunk-MH6FKW2I.mjs → chunk-J5YWQVI5.mjs} +4 -4
- package/dist/chunk-J5YWQVI5.mjs.map +1 -0
- package/dist/{chunk-G5I34UA6.mjs → chunk-JDEOUK5V.mjs} +4 -4
- package/dist/{chunk-T543TMFY.mjs → chunk-NM3CRAAL.mjs} +3 -2
- package/dist/chunk-NM3CRAAL.mjs.map +1 -0
- package/dist/{chunk-LWMGIEJA.mjs → chunk-PFE6GMNE.mjs} +47 -37
- package/dist/chunk-PFE6GMNE.mjs.map +1 -0
- package/dist/{chunk-6VS6CKAV.mjs → chunk-QM746KUO.mjs} +8 -1
- package/dist/chunk-QM746KUO.mjs.map +1 -0
- package/dist/{chunk-5FW6PQ3J.mjs → chunk-QTZZ2ISQ.mjs} +41 -16
- package/dist/chunk-QTZZ2ISQ.mjs.map +1 -0
- package/dist/{chunk-SHRJG6OG.mjs → chunk-RBRLLZL5.mjs} +18 -3
- package/dist/chunk-RBRLLZL5.mjs.map +1 -0
- package/dist/{chunk-NRRFGX45.mjs → chunk-TQAEEJB4.mjs} +3 -3
- package/dist/{chunk-45LKHSHJ.mjs → chunk-UB5UOSHB.mjs} +24 -12
- package/dist/chunk-UB5UOSHB.mjs.map +1 -0
- package/dist/chunk-V3XURYJO.mjs +756 -0
- package/dist/chunk-V3XURYJO.mjs.map +1 -0
- package/dist/{chunk-HZYXGV4K.mjs → chunk-VY2UYN5R.mjs} +24 -4
- package/dist/chunk-VY2UYN5R.mjs.map +1 -0
- package/dist/{chunk-C33RALN7.mjs → chunk-W2CRQFF6.mjs} +79 -15
- package/dist/chunk-W2CRQFF6.mjs.map +1 -0
- package/dist/{chunk-LG3YINQN.mjs → chunk-Z5CQMP54.mjs} +3 -3
- package/dist/{client-DiViK9yK.d.mts → client-BT1mFQas.d.mts} +23 -4
- package/dist/{client-DpEBJbts.d.ts → client-Nn0q4eO4.d.ts} +23 -4
- package/dist/{client-plugins-CTnsZz_A.d.ts → client-plugins-Cw4qUGsw.d.ts} +6 -0
- package/dist/{client-plugins-Cnr0D3kk.d.mts → client-plugins-DQQ1adXM.d.mts} +6 -0
- package/dist/client-plugins.d.mts +2 -1
- package/dist/client-plugins.d.ts +2 -1
- package/dist/client.cjs +665 -82
- package/dist/client.cjs.map +1 -1
- package/dist/client.d.mts +71 -5
- package/dist/client.d.ts +71 -5
- package/dist/client.mjs +10 -7
- package/dist/config.d.mts +2 -1
- package/dist/config.d.ts +2 -1
- package/dist/{devtools-HE4FTUDN.mjs → devtools-LVC3VB5P.mjs} +4 -4
- package/dist/docs.cjs +11 -1
- package/dist/docs.cjs.map +1 -1
- package/dist/docs.mjs +4 -4
- package/dist/index.cjs +2113 -198
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +16 -16
- package/dist/index.d.ts +16 -16
- package/dist/index.mjs +49 -21
- package/dist/index.mjs.map +1 -1
- package/dist/integrations.d.mts +2 -1
- package/dist/integrations.d.ts +2 -1
- package/dist/internal/build-runtime.cjs +1455 -90
- package/dist/internal/build-runtime.cjs.map +1 -1
- package/dist/internal/build-runtime.d.mts +4 -3
- package/dist/internal/build-runtime.d.ts +4 -3
- package/dist/internal/build-runtime.mjs +15 -14
- package/dist/internal/config-runtime.cjs +12 -1
- package/dist/internal/config-runtime.cjs.map +1 -1
- package/dist/internal/config-runtime.d.mts +3 -2
- package/dist/internal/config-runtime.d.ts +3 -2
- package/dist/internal/config-runtime.mjs +3 -3
- package/dist/internal/production-runtime.cjs +282 -6
- package/dist/internal/production-runtime.cjs.map +1 -1
- package/dist/internal/production-runtime.d.mts +4 -4
- package/dist/internal/production-runtime.d.ts +4 -4
- package/dist/internal/production-runtime.mjs +4 -2
- package/dist/{metadata-eoVmHoyv.d.ts → metadata-BAPg_Nmo.d.ts} +1 -1
- package/dist/{metadata-Dp8AdvsB.d.mts → metadata-_6i9oFG3.d.mts} +1 -1
- package/dist/middleware.d.mts +4 -3
- package/dist/middleware.d.ts +4 -3
- package/dist/navigation.cjs +40 -15
- package/dist/navigation.cjs.map +1 -1
- package/dist/navigation.mjs +2 -2
- package/dist/plugin.cjs +913 -53
- package/dist/plugin.cjs.map +1 -1
- package/dist/plugin.d.mts +2 -1
- package/dist/plugin.d.ts +2 -1
- package/dist/plugin.mjs +11 -10
- package/dist/{production-runtime-BqTnUTai.d.ts → production-runtime-BoJDc5mc.d.ts} +1 -1
- package/dist/{production-runtime-DtDdG9fc.d.mts → production-runtime-DPfgMV9Y.d.mts} +1 -1
- package/dist/routes.cjs +276 -6
- package/dist/routes.cjs.map +1 -1
- package/dist/routes.d.mts +1 -1
- package/dist/routes.d.ts +1 -1
- package/dist/routes.mjs +3 -3
- package/dist/{runtime-C1B7pSGT.d.mts → runtime-9nQjVM7X.d.mts} +8 -9
- package/dist/{runtime-CdPHt0bv.d.ts → runtime-DgeS2skB.d.ts} +8 -9
- package/dist/server-action-security.cjs +28 -10
- package/dist/server-action-security.cjs.map +1 -1
- package/dist/server-action-security.d.mts +2 -1
- package/dist/server-action-security.d.ts +2 -1
- package/dist/server-action-security.mjs +2 -2
- package/dist/server-fn-client.d.mts +1 -0
- package/dist/server-fn-client.d.ts +1 -0
- package/dist/server-fn.cjs +785 -3
- package/dist/server-fn.cjs.map +1 -1
- package/dist/server-fn.d.mts +10 -1
- package/dist/server-fn.d.ts +10 -1
- package/dist/server-fn.mjs +6 -3
- package/dist/server-plugins.d.mts +3 -2
- package/dist/server-plugins.d.ts +3 -2
- package/dist/server-query-client.cjs +279 -8
- package/dist/server-query-client.cjs.map +1 -1
- package/dist/server-query-client.mjs +4 -4
- package/dist/server-query.cjs +381 -10
- package/dist/server-query.cjs.map +1 -1
- package/dist/server-query.mjs +5 -5
- package/dist/server.cjs +1086 -76
- package/dist/server.cjs.map +1 -1
- package/dist/server.d.mts +8 -7
- package/dist/server.d.ts +8 -7
- package/dist/server.mjs +31 -16
- package/dist/server.mjs.map +1 -1
- package/dist/testing.cjs +341 -20
- package/dist/testing.cjs.map +1 -1
- package/dist/testing.d.mts +3 -2
- package/dist/testing.d.ts +3 -2
- package/dist/testing.mjs +7 -6
- package/dist/testing.mjs.map +1 -1
- package/dist/transport-BmbGTXA5.d.mts +49 -0
- package/dist/transport-BmbGTXA5.d.ts +49 -0
- package/dist/{utils-8USa5BiY.d.mts → utils-CHXlMDkg.d.mts} +1 -1
- package/dist/{utils-DKJb6K6G.d.ts → utils-Drsyz1Vj.d.ts} +1 -1
- package/dist/version.cjs +1 -1
- package/dist/version.cjs.map +1 -1
- package/dist/version.mjs +1 -1
- package/dist/vite.cjs +914 -54
- package/dist/vite.cjs.map +1 -1
- package/dist/vite.d.mts +2 -1
- package/dist/vite.d.ts +2 -1
- package/dist/vite.mjs +11 -10
- package/package.json +1 -1
- package/types/api.d.ts +44 -0
- package/types/client.d.ts +85 -4
- package/dist/chunk-45LKHSHJ.mjs.map +0 -1
- package/dist/chunk-5FW6PQ3J.mjs.map +0 -1
- package/dist/chunk-6VS6CKAV.mjs.map +0 -1
- package/dist/chunk-C33RALN7.mjs.map +0 -1
- package/dist/chunk-GZWT6VI5.mjs +0 -382
- package/dist/chunk-GZWT6VI5.mjs.map +0 -1
- package/dist/chunk-HZYXGV4K.mjs.map +0 -1
- package/dist/chunk-LWMGIEJA.mjs.map +0 -1
- package/dist/chunk-MH6FKW2I.mjs.map +0 -1
- package/dist/chunk-OHC6VCDI.mjs.map +0 -1
- package/dist/chunk-SHRJG6OG.mjs.map +0 -1
- package/dist/chunk-T543TMFY.mjs.map +0 -1
- package/dist/chunk-XJSHJN4M.mjs.map +0 -1
- package/dist/chunk-XUBZ7JI4.mjs.map +0 -1
- /package/dist/{chunk-5QH4IKY3.mjs.map → chunk-7N62DNSO.mjs.map} +0 -0
- /package/dist/{chunk-CSU4KJJF.mjs.map → chunk-C2ROET2V.mjs.map} +0 -0
- /package/dist/{chunk-BIOIOWXZ.mjs.map → chunk-HNIQFZKB.mjs.map} +0 -0
- /package/dist/{chunk-G5I34UA6.mjs.map → chunk-JDEOUK5V.mjs.map} +0 -0
- /package/dist/{chunk-NRRFGX45.mjs.map → chunk-TQAEEJB4.mjs.map} +0 -0
- /package/dist/{chunk-LG3YINQN.mjs.map → chunk-Z5CQMP54.mjs.map} +0 -0
- /package/dist/{devtools-HE4FTUDN.mjs.map → devtools-LVC3VB5P.mjs.map} +0 -0
package/dist/api.cjs
CHANGED
|
@@ -36,6 +36,7 @@ __export(api_exports, {
|
|
|
36
36
|
API_ROUTE_METHODS: () => API_ROUTE_METHODS,
|
|
37
37
|
DELETE: () => DELETE,
|
|
38
38
|
EndpointFailure: () => EndpointFailure,
|
|
39
|
+
FARM_API_ROUTE_META_SYMBOL: () => FARM_API_ROUTE_META_SYMBOL,
|
|
39
40
|
FARM_API_ROUTE_REF_SYMBOL: () => FARM_API_ROUTE_REF_SYMBOL,
|
|
40
41
|
GET: () => GET,
|
|
41
42
|
HEAD: () => HEAD,
|
|
@@ -47,12 +48,20 @@ __export(api_exports, {
|
|
|
47
48
|
createEndpoint: () => createEndpoint,
|
|
48
49
|
createServerAPIClient: () => createServerAPIClient,
|
|
49
50
|
farmApiPlugin: () => farmApiPlugin,
|
|
51
|
+
getAPIRouteRefMetadata: () => getAPIRouteRefMetadata,
|
|
50
52
|
invokeAPIRouteEndpoint: () => invokeAPIRouteEndpoint,
|
|
51
53
|
isAPIRouteRef: () => isAPIRouteRef,
|
|
52
54
|
isEndpointFailure: () => isEndpointFailure,
|
|
55
|
+
isFarmAPIStream: () => isFarmAPIStream,
|
|
56
|
+
isJSONStreamResponse: () => isJSONStreamResponse,
|
|
57
|
+
isMultipartSchema: () => isMultipartSchema,
|
|
53
58
|
isWebResponse: () => isWebResponse,
|
|
59
|
+
jsonStream: () => jsonStream,
|
|
54
60
|
matchAPIRoute: () => matchAPIRoute,
|
|
55
|
-
|
|
61
|
+
multipart: () => multipart,
|
|
62
|
+
normalizeRouteResponse: () => normalizeRouteResponse,
|
|
63
|
+
readJSONStream: () => readJSONStream,
|
|
64
|
+
toFormData: () => toFormData
|
|
56
65
|
});
|
|
57
66
|
module.exports = __toCommonJS(api_exports);
|
|
58
67
|
|
|
@@ -180,7 +189,8 @@ var FARM_CACHE_INVALIDATION_STATE = /* @__PURE__ */ Symbol.for("farm.cacheInvali
|
|
|
180
189
|
var globalState = globalThis;
|
|
181
190
|
function getFarmCacheInvalidationState() {
|
|
182
191
|
return globalState[FARM_CACHE_INVALIDATION_STATE] ?? (globalState[FARM_CACHE_INVALIDATION_STATE] = {
|
|
183
|
-
listeners: /* @__PURE__ */ new Set()
|
|
192
|
+
listeners: /* @__PURE__ */ new Set(),
|
|
193
|
+
taskListeners: /* @__PURE__ */ new Set()
|
|
184
194
|
});
|
|
185
195
|
}
|
|
186
196
|
__name(getFarmCacheInvalidationState, "getFarmCacheInvalidationState");
|
|
@@ -191,6 +201,12 @@ function notifyFarmCacheInvalidation(key) {
|
|
|
191
201
|
}
|
|
192
202
|
}
|
|
193
203
|
__name(notifyFarmCacheInvalidation, "notifyFarmCacheInvalidation");
|
|
204
|
+
function notifyFarmCacheTask(task) {
|
|
205
|
+
for (const listener of getFarmCacheInvalidationState().taskListeners) {
|
|
206
|
+
listener(task);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
__name(notifyFarmCacheTask, "notifyFarmCacheTask");
|
|
194
210
|
function applyFarmCacheInvalidations(keys) {
|
|
195
211
|
if (!Array.isArray(keys)) return;
|
|
196
212
|
for (const key of keys) {
|
|
@@ -236,11 +252,51 @@ __name(_setFarmI18nSnapshotResolver, "_setFarmI18nSnapshotResolver");
|
|
|
236
252
|
|
|
237
253
|
// src/cache.ts
|
|
238
254
|
var _FarmDataCache = class _FarmDataCache {
|
|
239
|
-
constructor() {
|
|
255
|
+
constructor(config = {}) {
|
|
240
256
|
this.entries = /* @__PURE__ */ new Map();
|
|
241
257
|
this.inflight = /* @__PURE__ */ new Map();
|
|
242
258
|
this.invalidatedTagVersions = /* @__PURE__ */ new Map();
|
|
243
259
|
this.version = 0;
|
|
260
|
+
this.namespace = "farm";
|
|
261
|
+
this.local = true;
|
|
262
|
+
this.lease = {
|
|
263
|
+
enabled: true,
|
|
264
|
+
ttlMs: 1e4,
|
|
265
|
+
waitTimeoutMs: 1e4,
|
|
266
|
+
pollIntervalMs: 25
|
|
267
|
+
};
|
|
268
|
+
this.configure(config);
|
|
269
|
+
}
|
|
270
|
+
configure(config = {}) {
|
|
271
|
+
this.adapter = config.adapter;
|
|
272
|
+
this.namespace = normalizeCacheNamespace(config.namespace || "farm");
|
|
273
|
+
this.local = !config.adapter;
|
|
274
|
+
this.lease = config.lease === false ? { ...this.lease, enabled: false } : {
|
|
275
|
+
enabled: true,
|
|
276
|
+
ttlMs: normalizePositiveDuration(config.lease?.ttlMs, 1e4, "cache.lease.ttlMs"),
|
|
277
|
+
waitTimeoutMs: normalizePositiveDuration(
|
|
278
|
+
config.lease?.waitTimeoutMs,
|
|
279
|
+
1e4,
|
|
280
|
+
"cache.lease.waitTimeoutMs"
|
|
281
|
+
),
|
|
282
|
+
pollIntervalMs: normalizePositiveDuration(
|
|
283
|
+
config.lease?.pollIntervalMs,
|
|
284
|
+
25,
|
|
285
|
+
"cache.lease.pollIntervalMs"
|
|
286
|
+
)
|
|
287
|
+
};
|
|
288
|
+
if (!this.local) {
|
|
289
|
+
this.entries.clear();
|
|
290
|
+
this.inflight.clear();
|
|
291
|
+
this.invalidatedTagVersions.clear();
|
|
292
|
+
this.version = 0;
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
get adapterName() {
|
|
296
|
+
return this.adapter?.name || (this.adapter ? "custom" : "memory");
|
|
297
|
+
}
|
|
298
|
+
get hasAdapter() {
|
|
299
|
+
return this.adapter !== void 0;
|
|
244
300
|
}
|
|
245
301
|
get size() {
|
|
246
302
|
return this.entries.size;
|
|
@@ -276,6 +332,45 @@ var _FarmDataCache = class _FarmDataCache {
|
|
|
276
332
|
});
|
|
277
333
|
return this.toPublicEntry(entry);
|
|
278
334
|
}
|
|
335
|
+
async getEntryAsync(key, options = {}) {
|
|
336
|
+
if (this.local) {
|
|
337
|
+
const localEntry = this.getEntry(key, options);
|
|
338
|
+
if (localEntry) return localEntry;
|
|
339
|
+
}
|
|
340
|
+
if (!this.adapter) {
|
|
341
|
+
return this.local ? void 0 : this.getEntry(key, options);
|
|
342
|
+
}
|
|
343
|
+
const entry = await this.adapter.get(this.createAdapterKey(key));
|
|
344
|
+
if (!entry) {
|
|
345
|
+
emitFarmEvent({ type: "cache.miss", key });
|
|
346
|
+
return void 0;
|
|
347
|
+
}
|
|
348
|
+
assertFarmCacheEntry(entry, key);
|
|
349
|
+
const stale = await this.isAdapterEntryStale(entry, options.now);
|
|
350
|
+
if (stale) {
|
|
351
|
+
emitFarmEvent({
|
|
352
|
+
type: "cache.stale",
|
|
353
|
+
key,
|
|
354
|
+
tags: [...entry.tags],
|
|
355
|
+
revalidate: entry.revalidate
|
|
356
|
+
});
|
|
357
|
+
if (!options.allowStale) {
|
|
358
|
+
emitFarmEvent({ type: "cache.miss", key, reason: "stale" });
|
|
359
|
+
return void 0;
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
emitFarmEvent({
|
|
363
|
+
type: "cache.hit",
|
|
364
|
+
key,
|
|
365
|
+
tags: [...entry.tags],
|
|
366
|
+
revalidate: entry.revalidate,
|
|
367
|
+
stale
|
|
368
|
+
});
|
|
369
|
+
if (this.local && !stale) {
|
|
370
|
+
this.hydrateLocalEntry(entry);
|
|
371
|
+
}
|
|
372
|
+
return { ...entry, key };
|
|
373
|
+
}
|
|
279
374
|
set(key, value, options = {}) {
|
|
280
375
|
const tags = /* @__PURE__ */ new Set();
|
|
281
376
|
for (const tag of options.tags ?? []) {
|
|
@@ -288,6 +383,7 @@ var _FarmDataCache = class _FarmDataCache {
|
|
|
288
383
|
key,
|
|
289
384
|
value,
|
|
290
385
|
tags,
|
|
386
|
+
tagVersions: void 0,
|
|
291
387
|
createdAt: options.createdAt ?? Date.now(),
|
|
292
388
|
createdVersion: ++this.version,
|
|
293
389
|
revalidate: normalizeRevalidate(options.revalidate)
|
|
@@ -301,11 +397,45 @@ var _FarmDataCache = class _FarmDataCache {
|
|
|
301
397
|
});
|
|
302
398
|
return this.toPublicEntry(entry);
|
|
303
399
|
}
|
|
400
|
+
async setAsync(key, value, options = {}, tagVersions) {
|
|
401
|
+
const tags = normalizeCacheOptionsTags(options);
|
|
402
|
+
const capturedVersions = tagVersions ?? await this.getAdapterTagVersions(Array.from(tags.values()));
|
|
403
|
+
const entry = {
|
|
404
|
+
key,
|
|
405
|
+
value,
|
|
406
|
+
tags: Array.from(tags),
|
|
407
|
+
tagVersions: capturedVersions,
|
|
408
|
+
createdAt: options.createdAt ?? Date.now(),
|
|
409
|
+
createdVersion: ++this.version,
|
|
410
|
+
revalidate: normalizeRevalidate(options.revalidate)
|
|
411
|
+
};
|
|
412
|
+
if (this.local) {
|
|
413
|
+
this.hydrateLocalEntry(entry);
|
|
414
|
+
}
|
|
415
|
+
if (this.adapter) {
|
|
416
|
+
await this.adapter.set(this.createAdapterKey(key), entry);
|
|
417
|
+
}
|
|
418
|
+
emitFarmEvent({
|
|
419
|
+
type: "cache.set",
|
|
420
|
+
key,
|
|
421
|
+
tags: [...entry.tags],
|
|
422
|
+
revalidate: entry.revalidate
|
|
423
|
+
});
|
|
424
|
+
return entry;
|
|
425
|
+
}
|
|
304
426
|
delete(key) {
|
|
305
427
|
const deleted = this.entries.delete(key);
|
|
306
428
|
emitFarmEvent({ type: "cache.delete", key, deleted });
|
|
307
429
|
return deleted;
|
|
308
430
|
}
|
|
431
|
+
async deleteAsync(key) {
|
|
432
|
+
const deleted = this.entries.delete(key);
|
|
433
|
+
if (this.adapter) {
|
|
434
|
+
await this.adapter.delete(this.createAdapterKey(key));
|
|
435
|
+
}
|
|
436
|
+
emitFarmEvent({ type: "cache.delete", key, deleted: this.adapter ? true : deleted });
|
|
437
|
+
return this.adapter ? true : deleted;
|
|
438
|
+
}
|
|
309
439
|
clear() {
|
|
310
440
|
const count = this.entries.size;
|
|
311
441
|
this.entries.clear();
|
|
@@ -314,6 +444,10 @@ var _FarmDataCache = class _FarmDataCache {
|
|
|
314
444
|
this.version = 0;
|
|
315
445
|
emitFarmEvent({ type: "cache.clear", count });
|
|
316
446
|
}
|
|
447
|
+
async clearAsync() {
|
|
448
|
+
this.clear();
|
|
449
|
+
await this.adapter?.clear?.();
|
|
450
|
+
}
|
|
317
451
|
isStale(entry, now = Date.now()) {
|
|
318
452
|
if (typeof entry.revalidate === "number" && entry.revalidate > 0 && now - entry.createdAt >= entry.revalidate * 1e3) {
|
|
319
453
|
return true;
|
|
@@ -326,6 +460,12 @@ var _FarmDataCache = class _FarmDataCache {
|
|
|
326
460
|
}
|
|
327
461
|
return false;
|
|
328
462
|
}
|
|
463
|
+
async isStaleAsync(entry, now = Date.now()) {
|
|
464
|
+
if (this.adapter) {
|
|
465
|
+
return this.isAdapterEntryStale(entry, now);
|
|
466
|
+
}
|
|
467
|
+
return this.isStale(entry, now);
|
|
468
|
+
}
|
|
329
469
|
revalidateTag(tag, options = {}) {
|
|
330
470
|
const normalized = normalizeCacheTag(tag);
|
|
331
471
|
const count = this.invalidateTag(normalized);
|
|
@@ -334,6 +474,15 @@ var _FarmDataCache = class _FarmDataCache {
|
|
|
334
474
|
);
|
|
335
475
|
return count;
|
|
336
476
|
}
|
|
477
|
+
async revalidateTagAsync(tag, options = {}) {
|
|
478
|
+
const normalized = normalizeCacheTag(tag);
|
|
479
|
+
const count = this.invalidateTag(normalized);
|
|
480
|
+
await this.adapter?.invalidateTags?.([this.createAdapterTag(normalized)]);
|
|
481
|
+
emitFarmEvent(
|
|
482
|
+
options.source === "updateTag" ? { type: "cache.updateTag", tag: normalized, count } : { type: "cache.revalidateTag", tag: normalized, profile: options.profile, count }
|
|
483
|
+
);
|
|
484
|
+
return count;
|
|
485
|
+
}
|
|
337
486
|
revalidatePath(routePath) {
|
|
338
487
|
const normalizedPath = normalizeRevalidatePath(routePath);
|
|
339
488
|
const pathTag = createPathCacheTag(normalizedPath);
|
|
@@ -350,8 +499,25 @@ var _FarmDataCache = class _FarmDataCache {
|
|
|
350
499
|
}
|
|
351
500
|
return count;
|
|
352
501
|
}
|
|
502
|
+
async revalidatePathAsync(routePath) {
|
|
503
|
+
const normalizedPath = normalizeRevalidatePath(routePath);
|
|
504
|
+
const pathTag = createPathCacheTag(normalizedPath);
|
|
505
|
+
const pprCount = this.countEntriesForTags([pathTag, "ppr"]);
|
|
506
|
+
const count = this.invalidateTag(pathTag);
|
|
507
|
+
await this.adapter?.invalidateTags?.([this.createAdapterTag(pathTag)]);
|
|
508
|
+
emitFarmEvent({ type: "cache.revalidatePath", path: normalizedPath, count });
|
|
509
|
+
if (pprCount > 0) {
|
|
510
|
+
emitFarmEvent({
|
|
511
|
+
type: "ppr.shell.invalidated",
|
|
512
|
+
route: normalizedPath,
|
|
513
|
+
reason: "revalidatePath",
|
|
514
|
+
count: pprCount
|
|
515
|
+
});
|
|
516
|
+
}
|
|
517
|
+
return count;
|
|
518
|
+
}
|
|
353
519
|
async getOrSet(key, producer, options = {}) {
|
|
354
|
-
const cached = this.
|
|
520
|
+
const cached = await this.getEntryAsync(key);
|
|
355
521
|
if (cached) {
|
|
356
522
|
return cached.value;
|
|
357
523
|
}
|
|
@@ -360,10 +526,8 @@ var _FarmDataCache = class _FarmDataCache {
|
|
|
360
526
|
emitFarmEvent({ type: "cache.dedupe", key });
|
|
361
527
|
return inflight;
|
|
362
528
|
}
|
|
363
|
-
const
|
|
364
|
-
|
|
365
|
-
return value;
|
|
366
|
-
}).catch((error) => {
|
|
529
|
+
const tags = Array.from(normalizeCacheOptionsTags(options));
|
|
530
|
+
const promise = this.fillCacheEntry(key, producer, options, tags).catch((error) => {
|
|
367
531
|
emitFarmEvent({ type: "cache.error", key, operation: "set", error });
|
|
368
532
|
throw error;
|
|
369
533
|
}).finally(() => {
|
|
@@ -372,6 +536,40 @@ var _FarmDataCache = class _FarmDataCache {
|
|
|
372
536
|
this.inflight.set(key, promise);
|
|
373
537
|
return promise;
|
|
374
538
|
}
|
|
539
|
+
async fillCacheEntry(key, producer, options, tags) {
|
|
540
|
+
const leaseKey = `${this.namespace}:lease:${key}`;
|
|
541
|
+
let leaseToken;
|
|
542
|
+
if (this.adapter?.acquireLease && this.adapter.releaseLease && this.lease.enabled) {
|
|
543
|
+
leaseToken = await this.adapter.acquireLease(leaseKey, this.lease.ttlMs);
|
|
544
|
+
if (!leaseToken) {
|
|
545
|
+
const shared = await this.waitForAdapterEntry(key);
|
|
546
|
+
if (shared) {
|
|
547
|
+
emitFarmEvent({ type: "cache.dedupe", key });
|
|
548
|
+
return shared.value;
|
|
549
|
+
}
|
|
550
|
+
leaseToken = await this.adapter.acquireLease(leaseKey, this.lease.ttlMs);
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
try {
|
|
554
|
+
const initialTagVersions = await this.getAdapterTagVersions(tags);
|
|
555
|
+
const value = await producer();
|
|
556
|
+
await this.setAsync(key, value, options, initialTagVersions);
|
|
557
|
+
return value;
|
|
558
|
+
} finally {
|
|
559
|
+
if (leaseToken && this.adapter?.releaseLease) {
|
|
560
|
+
await this.adapter.releaseLease(leaseKey, leaseToken);
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
async waitForAdapterEntry(key) {
|
|
565
|
+
const deadline = Date.now() + this.lease.waitTimeoutMs;
|
|
566
|
+
while (Date.now() < deadline) {
|
|
567
|
+
await delay(this.lease.pollIntervalMs);
|
|
568
|
+
const entry = await this.getEntryAsync(key);
|
|
569
|
+
if (entry) return entry;
|
|
570
|
+
}
|
|
571
|
+
return void 0;
|
|
572
|
+
}
|
|
375
573
|
countEntriesForTag(tag) {
|
|
376
574
|
let count = 0;
|
|
377
575
|
for (const entry of this.entries.values()) {
|
|
@@ -399,11 +597,53 @@ var _FarmDataCache = class _FarmDataCache {
|
|
|
399
597
|
key: entry.key,
|
|
400
598
|
value: entry.value,
|
|
401
599
|
tags: Array.from(entry.tags),
|
|
600
|
+
tagVersions: entry.tagVersions,
|
|
402
601
|
createdAt: entry.createdAt,
|
|
403
602
|
createdVersion: entry.createdVersion,
|
|
404
603
|
revalidate: entry.revalidate
|
|
405
604
|
};
|
|
406
605
|
}
|
|
606
|
+
hydrateLocalEntry(entry) {
|
|
607
|
+
this.entries.set(entry.key, {
|
|
608
|
+
key: entry.key,
|
|
609
|
+
value: entry.value,
|
|
610
|
+
tags: new Set(entry.tags.map(normalizeCacheTag)),
|
|
611
|
+
tagVersions: entry.tagVersions,
|
|
612
|
+
createdAt: entry.createdAt,
|
|
613
|
+
createdVersion: entry.createdVersion ?? ++this.version,
|
|
614
|
+
revalidate: normalizeRevalidate(entry.revalidate)
|
|
615
|
+
});
|
|
616
|
+
}
|
|
617
|
+
createAdapterKey(key) {
|
|
618
|
+
return `${this.namespace}:entry:${key}`;
|
|
619
|
+
}
|
|
620
|
+
createAdapterTag(tag) {
|
|
621
|
+
return `${this.namespace}:tag:${tag}`;
|
|
622
|
+
}
|
|
623
|
+
async getAdapterTagVersions(tags) {
|
|
624
|
+
if (!this.adapter?.getTagVersions || tags.length === 0) return {};
|
|
625
|
+
const normalized = tags.map(normalizeCacheTag);
|
|
626
|
+
const physicalTags = normalized.map((tag) => this.createAdapterTag(tag));
|
|
627
|
+
const versions = await this.adapter.getTagVersions(physicalTags);
|
|
628
|
+
return Object.fromEntries(
|
|
629
|
+
normalized.map((tag, index) => [
|
|
630
|
+
tag,
|
|
631
|
+
normalizeAdapterVersion(versions[physicalTags[index]])
|
|
632
|
+
])
|
|
633
|
+
);
|
|
634
|
+
}
|
|
635
|
+
async isAdapterEntryStale(entry, now = Date.now()) {
|
|
636
|
+
if (typeof entry.revalidate === "number" && entry.revalidate > 0 && now - entry.createdAt >= entry.revalidate * 1e3) {
|
|
637
|
+
return true;
|
|
638
|
+
}
|
|
639
|
+
const currentVersions = await this.getAdapterTagVersions(entry.tags);
|
|
640
|
+
for (const tag of entry.tags) {
|
|
641
|
+
if (normalizeAdapterVersion(currentVersions[tag]) > normalizeAdapterVersion(entry.tagVersions?.[tag])) {
|
|
642
|
+
return true;
|
|
643
|
+
}
|
|
644
|
+
}
|
|
645
|
+
return false;
|
|
646
|
+
}
|
|
407
647
|
};
|
|
408
648
|
__name(_FarmDataCache, "FarmDataCache");
|
|
409
649
|
var FarmDataCache = _FarmDataCache;
|
|
@@ -416,16 +656,52 @@ function getFarmDataCache() {
|
|
|
416
656
|
return sharedFarmDataCache;
|
|
417
657
|
}
|
|
418
658
|
__name(getFarmDataCache, "getFarmDataCache");
|
|
659
|
+
function updateTag(tag) {
|
|
660
|
+
const cache = getFarmDataCache();
|
|
661
|
+
if (cache.hasAdapter) {
|
|
662
|
+
const task = cache.revalidateTagAsync(tag, { source: "updateTag" }).then(() => void 0);
|
|
663
|
+
notifyFarmCacheTask(task);
|
|
664
|
+
return task;
|
|
665
|
+
}
|
|
666
|
+
cache.revalidateTag(tag, { source: "updateTag" });
|
|
667
|
+
}
|
|
668
|
+
__name(updateTag, "updateTag");
|
|
419
669
|
function revalidatePath(routePath) {
|
|
420
|
-
getFarmDataCache()
|
|
670
|
+
const cache = getFarmDataCache();
|
|
671
|
+
if (cache.hasAdapter) {
|
|
672
|
+
const task = cache.revalidatePathAsync(routePath).then(() => void 0);
|
|
673
|
+
notifyFarmCacheTask(task);
|
|
674
|
+
return task;
|
|
675
|
+
}
|
|
676
|
+
cache.revalidatePath(routePath);
|
|
421
677
|
}
|
|
422
678
|
__name(revalidatePath, "revalidatePath");
|
|
423
679
|
function invalidate(key) {
|
|
424
680
|
const clientKey = createRouteDataCacheKey(key);
|
|
425
|
-
|
|
681
|
+
const task = updateTag(createRouteDataCacheTag(key));
|
|
426
682
|
notifyFarmCacheInvalidation(clientKey);
|
|
683
|
+
return task;
|
|
427
684
|
}
|
|
428
685
|
__name(invalidate, "invalidate");
|
|
686
|
+
async function applyFarmCacheInvalidationTargets(targets) {
|
|
687
|
+
if (!Array.isArray(targets)) {
|
|
688
|
+
throw new TypeError("Cache invalidations must resolve to an array of targets.");
|
|
689
|
+
}
|
|
690
|
+
const clientKeys = [];
|
|
691
|
+
for (const target of targets) {
|
|
692
|
+
assertFarmCacheInvalidationTarget(target);
|
|
693
|
+
if ("key" in target) {
|
|
694
|
+
await invalidate(target.key);
|
|
695
|
+
clientKeys.push(createRouteDataCacheKey(target.key));
|
|
696
|
+
} else if ("path" in target) {
|
|
697
|
+
await revalidatePath(target.path);
|
|
698
|
+
} else {
|
|
699
|
+
await updateTag(target.tag);
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
return Array.from(new Set(clientKeys));
|
|
703
|
+
}
|
|
704
|
+
__name(applyFarmCacheInvalidationTargets, "applyFarmCacheInvalidationTargets");
|
|
429
705
|
function createPathCacheTag(routePath) {
|
|
430
706
|
return `path:${normalizeRevalidatePath(routePath)}`;
|
|
431
707
|
}
|
|
@@ -486,6 +762,67 @@ function normalizeCacheTag(tag) {
|
|
|
486
762
|
return normalized;
|
|
487
763
|
}
|
|
488
764
|
__name(normalizeCacheTag, "normalizeCacheTag");
|
|
765
|
+
function normalizeCacheNamespace(namespace) {
|
|
766
|
+
if (typeof namespace !== "string") {
|
|
767
|
+
throw new TypeError("Cache namespace must be a string.");
|
|
768
|
+
}
|
|
769
|
+
const normalized = namespace.trim().replace(/:+$/g, "");
|
|
770
|
+
if (!normalized) {
|
|
771
|
+
throw new Error("Cache namespace cannot be empty.");
|
|
772
|
+
}
|
|
773
|
+
return normalized;
|
|
774
|
+
}
|
|
775
|
+
__name(normalizeCacheNamespace, "normalizeCacheNamespace");
|
|
776
|
+
function normalizeAdapterVersion(value) {
|
|
777
|
+
return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : 0;
|
|
778
|
+
}
|
|
779
|
+
__name(normalizeAdapterVersion, "normalizeAdapterVersion");
|
|
780
|
+
function normalizePositiveDuration(value, fallback, name) {
|
|
781
|
+
if (value === void 0) return fallback;
|
|
782
|
+
if (!Number.isFinite(value) || value <= 0) {
|
|
783
|
+
throw new TypeError(`${name} must be a positive number of milliseconds.`);
|
|
784
|
+
}
|
|
785
|
+
return Math.floor(value);
|
|
786
|
+
}
|
|
787
|
+
__name(normalizePositiveDuration, "normalizePositiveDuration");
|
|
788
|
+
function delay(ms) {
|
|
789
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
790
|
+
}
|
|
791
|
+
__name(delay, "delay");
|
|
792
|
+
function normalizeCacheOptionsTags(options) {
|
|
793
|
+
const tags = /* @__PURE__ */ new Set();
|
|
794
|
+
for (const tag of options.tags ?? []) {
|
|
795
|
+
tags.add(normalizeCacheTag(tag));
|
|
796
|
+
}
|
|
797
|
+
for (const routePath of options.paths ?? []) {
|
|
798
|
+
tags.add(createPathCacheTag(routePath));
|
|
799
|
+
}
|
|
800
|
+
return tags;
|
|
801
|
+
}
|
|
802
|
+
__name(normalizeCacheOptionsTags, "normalizeCacheOptionsTags");
|
|
803
|
+
function assertFarmCacheEntry(entry, expectedKey) {
|
|
804
|
+
if (!entry || typeof entry !== "object" || entry.key !== expectedKey || !Array.isArray(entry.tags) || typeof entry.createdAt !== "number") {
|
|
805
|
+
throw new TypeError(
|
|
806
|
+
`Cache adapter returned an invalid entry for ${JSON.stringify(expectedKey)}.`
|
|
807
|
+
);
|
|
808
|
+
}
|
|
809
|
+
}
|
|
810
|
+
__name(assertFarmCacheEntry, "assertFarmCacheEntry");
|
|
811
|
+
function assertFarmCacheInvalidationTarget(target) {
|
|
812
|
+
if (!target || typeof target !== "object") {
|
|
813
|
+
throw new TypeError("Cache invalidation targets must be { key }, { path }, or { tag }.");
|
|
814
|
+
}
|
|
815
|
+
if ("key" in target) {
|
|
816
|
+
const key = target.key;
|
|
817
|
+
if (typeof key === "string" || Array.isArray(key)) return;
|
|
818
|
+
} else if ("path" in target && typeof target.path === "string") {
|
|
819
|
+
return;
|
|
820
|
+
} else if ("tag" in target && typeof target.tag === "string") {
|
|
821
|
+
return;
|
|
822
|
+
}
|
|
823
|
+
throw new TypeError("Cache invalidation targets must contain a string/array key, path, or tag.");
|
|
824
|
+
}
|
|
825
|
+
__name(assertFarmCacheInvalidationTarget, "assertFarmCacheInvalidationTarget");
|
|
489
826
|
function getFunctionCacheIdentity(fn) {
|
|
490
827
|
if (fn.name) {
|
|
491
828
|
return `name:${fn.name}`;
|
|
@@ -540,6 +877,179 @@ function stableSerialize(value, seen = /* @__PURE__ */ new WeakSet()) {
|
|
|
540
877
|
}
|
|
541
878
|
__name(stableSerialize, "stableSerialize");
|
|
542
879
|
|
|
880
|
+
// src/api/transport.ts
|
|
881
|
+
function multipart(schema) {
|
|
882
|
+
if (!Object.isExtensible(schema) && !isMultipartSchema(schema)) {
|
|
883
|
+
throw new TypeError("multipart() requires an extensible schema object");
|
|
884
|
+
}
|
|
885
|
+
if (!isMultipartSchema(schema)) {
|
|
886
|
+
Object.defineProperty(schema, "__farmMultipartSchema", {
|
|
887
|
+
value: true,
|
|
888
|
+
configurable: false,
|
|
889
|
+
enumerable: false,
|
|
890
|
+
writable: false
|
|
891
|
+
});
|
|
892
|
+
}
|
|
893
|
+
return schema;
|
|
894
|
+
}
|
|
895
|
+
__name(multipart, "multipart");
|
|
896
|
+
function isMultipartSchema(value) {
|
|
897
|
+
return typeof value === "object" && value !== null && value.__farmMultipartSchema === true && typeof value.parse === "function";
|
|
898
|
+
}
|
|
899
|
+
__name(isMultipartSchema, "isMultipartSchema");
|
|
900
|
+
function toFormData(values) {
|
|
901
|
+
const formData = new FormData();
|
|
902
|
+
for (const [key, value] of Object.entries(values)) {
|
|
903
|
+
if (isUnsafeFormKey(key)) continue;
|
|
904
|
+
if (Array.isArray(value)) {
|
|
905
|
+
for (const entry of value) appendFormValue(formData, key, entry);
|
|
906
|
+
continue;
|
|
907
|
+
}
|
|
908
|
+
appendFormValue(formData, key, value);
|
|
909
|
+
}
|
|
910
|
+
return formData;
|
|
911
|
+
}
|
|
912
|
+
__name(toFormData, "toFormData");
|
|
913
|
+
function jsonStream(source, init = {}) {
|
|
914
|
+
const iterator = toAsyncIterator(source);
|
|
915
|
+
const encoder = new TextEncoder();
|
|
916
|
+
let finished = false;
|
|
917
|
+
const body = new ReadableStream(
|
|
918
|
+
{
|
|
919
|
+
async pull(controller) {
|
|
920
|
+
if (finished) return;
|
|
921
|
+
try {
|
|
922
|
+
const next = await iterator.next();
|
|
923
|
+
if (next.done) {
|
|
924
|
+
finished = true;
|
|
925
|
+
controller.close();
|
|
926
|
+
return;
|
|
927
|
+
}
|
|
928
|
+
controller.enqueue(encoder.encode(`${JSON.stringify(next.value)}
|
|
929
|
+
`));
|
|
930
|
+
} catch (error) {
|
|
931
|
+
finished = true;
|
|
932
|
+
controller.error(error);
|
|
933
|
+
}
|
|
934
|
+
},
|
|
935
|
+
async cancel(reason) {
|
|
936
|
+
finished = true;
|
|
937
|
+
await iterator.return?.(reason);
|
|
938
|
+
}
|
|
939
|
+
},
|
|
940
|
+
{
|
|
941
|
+
// Do not read the next application event until the response consumer
|
|
942
|
+
// requests another chunk.
|
|
943
|
+
highWaterMark: 0
|
|
944
|
+
}
|
|
945
|
+
);
|
|
946
|
+
const headers = new Headers(init.headers);
|
|
947
|
+
if (!headers.has("content-type")) {
|
|
948
|
+
headers.set("content-type", "application/x-ndjson; charset=utf-8");
|
|
949
|
+
}
|
|
950
|
+
headers.set("cache-control", headers.get("cache-control") ?? "no-store");
|
|
951
|
+
return new Response(body, {
|
|
952
|
+
...init,
|
|
953
|
+
headers
|
|
954
|
+
});
|
|
955
|
+
}
|
|
956
|
+
__name(jsonStream, "jsonStream");
|
|
957
|
+
function isJSONStreamResponse(response) {
|
|
958
|
+
const contentType = response.headers?.get?.("content-type")?.toLowerCase() ?? "";
|
|
959
|
+
return contentType.includes("application/x-ndjson") || contentType.includes("application/ndjson");
|
|
960
|
+
}
|
|
961
|
+
__name(isJSONStreamResponse, "isJSONStreamResponse");
|
|
962
|
+
function readJSONStream(response) {
|
|
963
|
+
if (!response.body) {
|
|
964
|
+
throw new TypeError("Cannot read a JSON stream response without a body");
|
|
965
|
+
}
|
|
966
|
+
const reader = response.body.getReader();
|
|
967
|
+
const decoder = new TextDecoder();
|
|
968
|
+
let buffer = "";
|
|
969
|
+
let completed = false;
|
|
970
|
+
let claimed = false;
|
|
971
|
+
const iterator = {
|
|
972
|
+
async next() {
|
|
973
|
+
while (true) {
|
|
974
|
+
const lineEnd = buffer.indexOf("\n");
|
|
975
|
+
if (lineEnd >= 0) {
|
|
976
|
+
const line = buffer.slice(0, lineEnd).trim();
|
|
977
|
+
buffer = buffer.slice(lineEnd + 1);
|
|
978
|
+
if (!line) continue;
|
|
979
|
+
return { done: false, value: JSON.parse(line) };
|
|
980
|
+
}
|
|
981
|
+
if (completed) {
|
|
982
|
+
const line = buffer.trim();
|
|
983
|
+
buffer = "";
|
|
984
|
+
if (!line) return { done: true, value: void 0 };
|
|
985
|
+
return { done: false, value: JSON.parse(line) };
|
|
986
|
+
}
|
|
987
|
+
const chunk = await reader.read();
|
|
988
|
+
completed = chunk.done;
|
|
989
|
+
buffer += decoder.decode(chunk.value, { stream: !chunk.done });
|
|
990
|
+
}
|
|
991
|
+
},
|
|
992
|
+
async return() {
|
|
993
|
+
completed = true;
|
|
994
|
+
buffer = "";
|
|
995
|
+
await reader.cancel();
|
|
996
|
+
return { done: true, value: void 0 };
|
|
997
|
+
}
|
|
998
|
+
};
|
|
999
|
+
return {
|
|
1000
|
+
response,
|
|
1001
|
+
async cancel(reason) {
|
|
1002
|
+
completed = true;
|
|
1003
|
+
buffer = "";
|
|
1004
|
+
await reader.cancel(reason);
|
|
1005
|
+
},
|
|
1006
|
+
[Symbol.asyncIterator]() {
|
|
1007
|
+
if (claimed) {
|
|
1008
|
+
throw new TypeError("Farm API streams can only be consumed once");
|
|
1009
|
+
}
|
|
1010
|
+
claimed = true;
|
|
1011
|
+
return iterator;
|
|
1012
|
+
}
|
|
1013
|
+
};
|
|
1014
|
+
}
|
|
1015
|
+
__name(readJSONStream, "readJSONStream");
|
|
1016
|
+
function isFarmAPIStream(value) {
|
|
1017
|
+
return typeof value === "object" && value !== null && "response" in value && typeof value.cancel === "function" && typeof value[Symbol.asyncIterator] === "function";
|
|
1018
|
+
}
|
|
1019
|
+
__name(isFarmAPIStream, "isFarmAPIStream");
|
|
1020
|
+
function appendFormValue(formData, key, value) {
|
|
1021
|
+
if (value === void 0) return;
|
|
1022
|
+
if (value === null) {
|
|
1023
|
+
formData.append(key, "");
|
|
1024
|
+
return;
|
|
1025
|
+
}
|
|
1026
|
+
if (value instanceof Blob) {
|
|
1027
|
+
formData.append(key, value);
|
|
1028
|
+
return;
|
|
1029
|
+
}
|
|
1030
|
+
if (value instanceof Date) {
|
|
1031
|
+
formData.append(key, value.toISOString());
|
|
1032
|
+
return;
|
|
1033
|
+
}
|
|
1034
|
+
formData.append(key, String(value));
|
|
1035
|
+
}
|
|
1036
|
+
__name(appendFormValue, "appendFormValue");
|
|
1037
|
+
function isUnsafeFormKey(key) {
|
|
1038
|
+
return key === "__proto__" || key === "constructor" || key === "prototype";
|
|
1039
|
+
}
|
|
1040
|
+
__name(isUnsafeFormKey, "isUnsafeFormKey");
|
|
1041
|
+
function toAsyncIterator(source) {
|
|
1042
|
+
if (Symbol.asyncIterator in Object(source)) {
|
|
1043
|
+
return source[Symbol.asyncIterator]();
|
|
1044
|
+
}
|
|
1045
|
+
const iterator = source[Symbol.iterator]();
|
|
1046
|
+
return {
|
|
1047
|
+
next: /* @__PURE__ */ __name(async () => iterator.next(), "next"),
|
|
1048
|
+
return: iterator.return ? async (value) => iterator.return(value) : void 0
|
|
1049
|
+
};
|
|
1050
|
+
}
|
|
1051
|
+
__name(toAsyncIterator, "toAsyncIterator");
|
|
1052
|
+
|
|
543
1053
|
// src/api/endpoint.ts
|
|
544
1054
|
var _EndpointFailure = class _EndpointFailure extends Error {
|
|
545
1055
|
constructor(code, data, options) {
|
|
@@ -607,6 +1117,7 @@ function createEndpoint(pathOrOptions, optionsOrHandler, maybeHandler) {
|
|
|
607
1117
|
endpoint.__errors = errors;
|
|
608
1118
|
endpoint.__types = {
|
|
609
1119
|
body: options.body,
|
|
1120
|
+
inputBody: isMultipartSchema(options.body) ? "form-data" : options.body,
|
|
610
1121
|
query: options.query,
|
|
611
1122
|
headers: options.headers,
|
|
612
1123
|
response: null,
|
|
@@ -725,37 +1236,12 @@ async function applyEndpointInvalidations(declaration, context, result) {
|
|
|
725
1236
|
const targets = typeof declaration === "function" ? await declaration(context) : declaration;
|
|
726
1237
|
if (!Array.isArray(targets)) {
|
|
727
1238
|
throw new TypeError(
|
|
728
|
-
"Endpoint invalidates must resolve to an array of { key } or {
|
|
1239
|
+
"Endpoint invalidates must resolve to an array of { key }, { path }, or { tag } targets"
|
|
729
1240
|
);
|
|
730
1241
|
}
|
|
731
|
-
|
|
732
|
-
for (const target of targets) {
|
|
733
|
-
assertEndpointInvalidationTarget(target);
|
|
734
|
-
if ("key" in target) {
|
|
735
|
-
invalidate(target.key);
|
|
736
|
-
clientKeys.push(createRouteDataCacheKey(target.key));
|
|
737
|
-
} else {
|
|
738
|
-
revalidatePath(target.path);
|
|
739
|
-
}
|
|
740
|
-
}
|
|
741
|
-
return Array.from(new Set(clientKeys));
|
|
1242
|
+
return applyFarmCacheInvalidationTargets(targets);
|
|
742
1243
|
}
|
|
743
1244
|
__name(applyEndpointInvalidations, "applyEndpointInvalidations");
|
|
744
|
-
function assertEndpointInvalidationTarget(target) {
|
|
745
|
-
if (!target || typeof target !== "object") {
|
|
746
|
-
throw new TypeError("Endpoint invalidation targets must be { key } or { path } objects");
|
|
747
|
-
}
|
|
748
|
-
if ("key" in target) {
|
|
749
|
-
const key = target.key;
|
|
750
|
-
if (typeof key === "string" || Array.isArray(key)) return;
|
|
751
|
-
} else if ("path" in target && typeof target.path === "string") {
|
|
752
|
-
return;
|
|
753
|
-
}
|
|
754
|
-
throw new TypeError(
|
|
755
|
-
"Endpoint invalidation targets must contain a string/array key or a path string"
|
|
756
|
-
);
|
|
757
|
-
}
|
|
758
|
-
__name(assertEndpointInvalidationTarget, "assertEndpointInvalidationTarget");
|
|
759
1245
|
function createInitialEndpointContext(value) {
|
|
760
1246
|
if (value === void 0 || value === null) return EMPTY_ENDPOINT_CONTEXT;
|
|
761
1247
|
if (!isPlainEndpointContext(value)) {
|
|
@@ -1248,7 +1734,7 @@ async function invokeAPIRouteEndpointInContext(endpoint, request, params) {
|
|
|
1248
1734
|
});
|
|
1249
1735
|
let body = void 0;
|
|
1250
1736
|
if (request.method.toUpperCase() !== "GET" && request.method.toUpperCase() !== "HEAD") {
|
|
1251
|
-
body = await
|
|
1737
|
+
body = await readRequestBody(request);
|
|
1252
1738
|
}
|
|
1253
1739
|
const headers = Object.fromEntries(request.headers.entries());
|
|
1254
1740
|
const types = endpoint.__types || {};
|
|
@@ -1352,17 +1838,50 @@ function isFarmContextHandler(endpoint) {
|
|
|
1352
1838
|
return firstParameter === "ctx" || firstParameter === "context" || firstParameter.startsWith("{");
|
|
1353
1839
|
}
|
|
1354
1840
|
__name(isFarmContextHandler, "isFarmContextHandler");
|
|
1355
|
-
async function
|
|
1841
|
+
async function readRequestBody(request) {
|
|
1842
|
+
const contentType = request.headers.get("content-type")?.split(";", 1)[0]?.trim().toLowerCase();
|
|
1356
1843
|
try {
|
|
1844
|
+
if (contentType === "multipart/form-data") {
|
|
1845
|
+
return formDataToObject(await request.clone().formData());
|
|
1846
|
+
}
|
|
1357
1847
|
const text = await request.clone().text();
|
|
1358
|
-
if (text)
|
|
1848
|
+
if (!text) return void 0;
|
|
1849
|
+
if (contentType === "application/x-www-form-urlencoded") {
|
|
1850
|
+
return searchParamsToObject(new URLSearchParams(text));
|
|
1851
|
+
}
|
|
1852
|
+
if (contentType === "application/json" || contentType?.endsWith("+json")) {
|
|
1359
1853
|
return JSON.parse(text);
|
|
1360
1854
|
}
|
|
1855
|
+
return JSON.parse(text);
|
|
1361
1856
|
} catch {
|
|
1362
1857
|
}
|
|
1363
1858
|
return void 0;
|
|
1364
1859
|
}
|
|
1365
|
-
__name(
|
|
1860
|
+
__name(readRequestBody, "readRequestBody");
|
|
1861
|
+
function formDataToObject(formData) {
|
|
1862
|
+
return entriesToObject(formData.entries());
|
|
1863
|
+
}
|
|
1864
|
+
__name(formDataToObject, "formDataToObject");
|
|
1865
|
+
function searchParamsToObject(searchParams) {
|
|
1866
|
+
return entriesToObject(searchParams.entries());
|
|
1867
|
+
}
|
|
1868
|
+
__name(searchParamsToObject, "searchParamsToObject");
|
|
1869
|
+
function entriesToObject(entries) {
|
|
1870
|
+
const output = /* @__PURE__ */ Object.create(null);
|
|
1871
|
+
for (const [key, value] of entries) {
|
|
1872
|
+
if (key === "__proto__" || key === "constructor" || key === "prototype") continue;
|
|
1873
|
+
const current = output[key];
|
|
1874
|
+
if (current === void 0) {
|
|
1875
|
+
output[key] = value;
|
|
1876
|
+
} else if (Array.isArray(current)) {
|
|
1877
|
+
current.push(value);
|
|
1878
|
+
} else {
|
|
1879
|
+
output[key] = [current, value];
|
|
1880
|
+
}
|
|
1881
|
+
}
|
|
1882
|
+
return output;
|
|
1883
|
+
}
|
|
1884
|
+
__name(entriesToObject, "entriesToObject");
|
|
1366
1885
|
function validateInput(schema, value, error) {
|
|
1367
1886
|
if (!schema || typeof schema.parse !== "function") {
|
|
1368
1887
|
return value;
|
|
@@ -2474,6 +2993,7 @@ __name(normalizeFarmClientCacheKey, "normalizeFarmClientCacheKey");
|
|
|
2474
2993
|
|
|
2475
2994
|
// src/api/client.ts
|
|
2476
2995
|
var FARM_API_ROUTE_REF_SYMBOL = /* @__PURE__ */ Symbol.for("farm.api.route-ref");
|
|
2996
|
+
var FARM_API_ROUTE_META_SYMBOL = /* @__PURE__ */ Symbol.for("farm.api.route-meta");
|
|
2477
2997
|
var _APIClientError = class _APIClientError extends Error {
|
|
2478
2998
|
constructor(code, data, options) {
|
|
2479
2999
|
super(options.message);
|
|
@@ -2511,16 +3031,22 @@ function createAPIClient(options = {}) {
|
|
|
2511
3031
|
}
|
|
2512
3032
|
});
|
|
2513
3033
|
}
|
|
3034
|
+
const headers = {
|
|
3035
|
+
"Content-Type": "application/json",
|
|
3036
|
+
...options.headers,
|
|
3037
|
+
...requestOptions.headers
|
|
3038
|
+
};
|
|
2514
3039
|
const fetchOptions = {
|
|
2515
3040
|
method: requestOptions.method || "GET",
|
|
2516
|
-
headers
|
|
2517
|
-
"Content-Type": "application/json",
|
|
2518
|
-
...options.headers,
|
|
2519
|
-
...requestOptions.headers
|
|
2520
|
-
}
|
|
3041
|
+
headers
|
|
2521
3042
|
};
|
|
2522
|
-
if (requestOptions.body) {
|
|
2523
|
-
|
|
3043
|
+
if (requestOptions.body !== void 0) {
|
|
3044
|
+
if (isFormData(requestOptions.body)) {
|
|
3045
|
+
deleteHeader(headers, "content-type");
|
|
3046
|
+
fetchOptions.body = requestOptions.body;
|
|
3047
|
+
} else {
|
|
3048
|
+
fetchOptions.body = JSON.stringify(requestOptions.body);
|
|
3049
|
+
}
|
|
2524
3050
|
}
|
|
2525
3051
|
const response = await fetch(url.toString(), fetchOptions);
|
|
2526
3052
|
applyFarmCacheInvalidations(
|
|
@@ -2528,7 +3054,7 @@ function createAPIClient(options = {}) {
|
|
|
2528
3054
|
);
|
|
2529
3055
|
let data = void 0;
|
|
2530
3056
|
if (response.status !== 204 && response.status !== 205) {
|
|
2531
|
-
data = await response.json();
|
|
3057
|
+
data = isJSONStreamResponse(response) ? readJSONStream(response) : await response.json();
|
|
2532
3058
|
}
|
|
2533
3059
|
return { response, data };
|
|
2534
3060
|
}, "fetchClient");
|
|
@@ -2674,16 +3200,16 @@ function createAPIClient(options = {}) {
|
|
|
2674
3200
|
}
|
|
2675
3201
|
}
|
|
2676
3202
|
attempt += 1;
|
|
2677
|
-
const
|
|
2678
|
-
if (
|
|
2679
|
-
await new Promise((resolve) => setTimeout(resolve,
|
|
3203
|
+
const delay2 = typeof clientOptions?.retry?.delay === "function" ? clientOptions.retry.delay(attempt) : clientOptions?.retry?.delay ?? 0;
|
|
3204
|
+
if (delay2 > 0) {
|
|
3205
|
+
await new Promise((resolve) => setTimeout(resolve, delay2));
|
|
2680
3206
|
}
|
|
2681
3207
|
}
|
|
2682
3208
|
})();
|
|
2683
3209
|
inflightState.set(cacheKey, { promise, startedAt: now });
|
|
2684
3210
|
try {
|
|
2685
3211
|
const result2 = await promise;
|
|
2686
|
-
if (!result2.error && isCacheEnabled) {
|
|
3212
|
+
if (!result2.error && isCacheEnabled && !isFarmAPIStream(result2.data)) {
|
|
2687
3213
|
const updatedAt = Date.now();
|
|
2688
3214
|
cacheState.set(cacheKey, {
|
|
2689
3215
|
data: result2.data,
|
|
@@ -2756,10 +3282,17 @@ function createAPIClient(options = {}) {
|
|
|
2756
3282
|
clientOptions?.onSettled?.(result.data, result.error);
|
|
2757
3283
|
return result;
|
|
2758
3284
|
}, "request");
|
|
2759
|
-
return createNestedProxy(
|
|
3285
|
+
return createNestedProxy(
|
|
3286
|
+
[],
|
|
3287
|
+
request,
|
|
3288
|
+
routeMeta,
|
|
3289
|
+
baseURL,
|
|
3290
|
+
options.baseURL === void 0,
|
|
3291
|
+
rootAliases
|
|
3292
|
+
);
|
|
2760
3293
|
}
|
|
2761
3294
|
__name(createAPIClient, "createAPIClient");
|
|
2762
|
-
function createNestedProxy(path4, client, routeMeta, baseURL, rootAliases) {
|
|
3295
|
+
function createNestedProxy(path4, client, routeMeta, baseURL, sameOrigin, rootAliases) {
|
|
2763
3296
|
const target = /* @__PURE__ */ __name(() => {
|
|
2764
3297
|
}, "target");
|
|
2765
3298
|
const proxy = new Proxy(target, {
|
|
@@ -2768,13 +3301,29 @@ function createNestedProxy(path4, client, routeMeta, baseURL, rootAliases) {
|
|
|
2768
3301
|
if (prop === FARM_API_ROUTE_REF_SYMBOL) {
|
|
2769
3302
|
return path4.length > 0;
|
|
2770
3303
|
}
|
|
3304
|
+
if (prop === FARM_API_ROUTE_META_SYMBOL) {
|
|
3305
|
+
const metadata = resolveRouteMeta({ path: path4, baseURL });
|
|
3306
|
+
return Object.freeze({
|
|
3307
|
+
path: metadata.routePath,
|
|
3308
|
+
method: metadata.method,
|
|
3309
|
+
baseURL,
|
|
3310
|
+
sameOrigin
|
|
3311
|
+
});
|
|
3312
|
+
}
|
|
2771
3313
|
if (path4.length === 0 && typeof prop === "string" && rootAliases && prop in rootAliases) {
|
|
2772
3314
|
return rootAliases[prop];
|
|
2773
3315
|
}
|
|
2774
3316
|
if (typeof prop !== "string") {
|
|
2775
3317
|
return Reflect.get(_target, prop);
|
|
2776
3318
|
}
|
|
2777
|
-
return createNestedProxy(
|
|
3319
|
+
return createNestedProxy(
|
|
3320
|
+
[...path4, prop],
|
|
3321
|
+
client,
|
|
3322
|
+
routeMeta,
|
|
3323
|
+
baseURL,
|
|
3324
|
+
sameOrigin,
|
|
3325
|
+
rootAliases
|
|
3326
|
+
);
|
|
2778
3327
|
},
|
|
2779
3328
|
// When calling as a function
|
|
2780
3329
|
apply(_target, _thisArg, args) {
|
|
@@ -2800,6 +3349,22 @@ function isAPIRouteRef(value) {
|
|
|
2800
3349
|
return typeof value === "function" && value[FARM_API_ROUTE_REF_SYMBOL] === true;
|
|
2801
3350
|
}
|
|
2802
3351
|
__name(isAPIRouteRef, "isAPIRouteRef");
|
|
3352
|
+
function getAPIRouteRefMetadata(value) {
|
|
3353
|
+
if (!isAPIRouteRef(value)) return null;
|
|
3354
|
+
const metadata = value[FARM_API_ROUTE_META_SYMBOL];
|
|
3355
|
+
if (!metadata || typeof metadata !== "object") return null;
|
|
3356
|
+
const candidate = metadata;
|
|
3357
|
+
if (typeof candidate.path !== "string" || typeof candidate.method !== "string" || typeof candidate.baseURL !== "string" || typeof candidate.sameOrigin !== "boolean") {
|
|
3358
|
+
return null;
|
|
3359
|
+
}
|
|
3360
|
+
return {
|
|
3361
|
+
path: candidate.path,
|
|
3362
|
+
method: candidate.method,
|
|
3363
|
+
baseURL: candidate.baseURL,
|
|
3364
|
+
sameOrigin: candidate.sameOrigin
|
|
3365
|
+
};
|
|
3366
|
+
}
|
|
3367
|
+
__name(getAPIRouteRefMetadata, "getAPIRouteRefMetadata");
|
|
2803
3368
|
function createServerAPIClient(endpoints, options = {}) {
|
|
2804
3369
|
if (options.integrations === false || Object.prototype.hasOwnProperty.call(endpoints, "integrations")) {
|
|
2805
3370
|
return endpoints;
|
|
@@ -2904,6 +3469,17 @@ function normalizeError(error) {
|
|
|
2904
3469
|
return normalized;
|
|
2905
3470
|
}
|
|
2906
3471
|
__name(normalizeError, "normalizeError");
|
|
3472
|
+
function isFormData(value) {
|
|
3473
|
+
return typeof value === "object" && value !== null && (typeof FormData !== "undefined" && value instanceof FormData || Object.prototype.toString.call(value) === "[object FormData]" && typeof value.entries === "function");
|
|
3474
|
+
}
|
|
3475
|
+
__name(isFormData, "isFormData");
|
|
3476
|
+
function deleteHeader(headers, name) {
|
|
3477
|
+
const normalized = name.toLowerCase();
|
|
3478
|
+
for (const key of Object.keys(headers)) {
|
|
3479
|
+
if (key.toLowerCase() === normalized) delete headers[key];
|
|
3480
|
+
}
|
|
3481
|
+
}
|
|
3482
|
+
__name(deleteHeader, "deleteHeader");
|
|
2907
3483
|
function createResponseError2(response, data) {
|
|
2908
3484
|
const expected = readEndpointErrorEnvelope(data);
|
|
2909
3485
|
if (expected) {
|
|
@@ -3494,6 +4070,7 @@ __name(farmApiPlugin, "farmApiPlugin");
|
|
|
3494
4070
|
API_ROUTE_METHODS,
|
|
3495
4071
|
DELETE,
|
|
3496
4072
|
EndpointFailure,
|
|
4073
|
+
FARM_API_ROUTE_META_SYMBOL,
|
|
3497
4074
|
FARM_API_ROUTE_REF_SYMBOL,
|
|
3498
4075
|
GET,
|
|
3499
4076
|
HEAD,
|
|
@@ -3505,11 +4082,19 @@ __name(farmApiPlugin, "farmApiPlugin");
|
|
|
3505
4082
|
createEndpoint,
|
|
3506
4083
|
createServerAPIClient,
|
|
3507
4084
|
farmApiPlugin,
|
|
4085
|
+
getAPIRouteRefMetadata,
|
|
3508
4086
|
invokeAPIRouteEndpoint,
|
|
3509
4087
|
isAPIRouteRef,
|
|
3510
4088
|
isEndpointFailure,
|
|
4089
|
+
isFarmAPIStream,
|
|
4090
|
+
isJSONStreamResponse,
|
|
4091
|
+
isMultipartSchema,
|
|
3511
4092
|
isWebResponse,
|
|
4093
|
+
jsonStream,
|
|
3512
4094
|
matchAPIRoute,
|
|
3513
|
-
|
|
4095
|
+
multipart,
|
|
4096
|
+
normalizeRouteResponse,
|
|
4097
|
+
readJSONStream,
|
|
4098
|
+
toFormData
|
|
3514
4099
|
});
|
|
3515
4100
|
//# sourceMappingURL=api.cjs.map
|