@farm.js/core 0.1.0-beta.80 → 0.1.0-beta.81

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.
Files changed (113) hide show
  1. package/dist/agent-runtime.d.mts +1 -1
  2. package/dist/agent-runtime.d.ts +1 -1
  3. package/dist/{app-D1fYgNSZ.d.mts → app-B9tbSdKW.d.mts} +3 -3
  4. package/dist/{app-DKW_R78N.d.ts → app-C7twWiJY.d.ts} +3 -3
  5. package/dist/app-markdown.d.mts +2 -2
  6. package/dist/app-markdown.d.ts +2 -2
  7. package/dist/{chunk-OEI62POE.mjs → chunk-6NV2RJSZ.mjs} +2 -2
  8. package/dist/{chunk-OEI62POE.mjs.map → chunk-6NV2RJSZ.mjs.map} +1 -1
  9. package/dist/{chunk-DNPQOJQW.mjs → chunk-CRK3RQ7C.mjs} +3 -3
  10. package/dist/{chunk-DBG42367.mjs → chunk-CVCIL6KH.mjs} +37 -14
  11. package/dist/chunk-CVCIL6KH.mjs.map +1 -0
  12. package/dist/{chunk-3UGGCJT5.mjs → chunk-HSCQGINR.mjs} +2 -2
  13. package/dist/{chunk-YSX4KDLV.mjs → chunk-VPEC2CWG.mjs} +42 -8
  14. package/dist/chunk-VPEC2CWG.mjs.map +1 -0
  15. package/dist/{chunk-3HIATXA4.mjs → chunk-XSUYR4Q3.mjs} +67 -25
  16. package/dist/chunk-XSUYR4Q3.mjs.map +1 -0
  17. package/dist/{chunk-3S7V7QHJ.mjs → chunk-Z73XASLT.mjs} +46 -19
  18. package/dist/chunk-Z73XASLT.mjs.map +1 -0
  19. package/dist/client/lifecycle.mjs +2 -2
  20. package/dist/{client-plugins-BtfLE4dW.d.mts → client-plugins-HizW0gLc.d.mts} +13 -1
  21. package/dist/{client-plugins-C4me5UPd.d.ts → client-plugins-w_b1wA8e.d.ts} +13 -1
  22. package/dist/client-plugins.cjs +1 -1
  23. package/dist/client-plugins.cjs.map +1 -1
  24. package/dist/client-plugins.d.mts +1 -1
  25. package/dist/client-plugins.d.ts +1 -1
  26. package/dist/client-plugins.mjs +2 -2
  27. package/dist/client.cjs +102 -37
  28. package/dist/client.cjs.map +1 -1
  29. package/dist/client.d.mts +4 -4
  30. package/dist/client.d.ts +4 -4
  31. package/dist/client.mjs +4 -4
  32. package/dist/config.d.mts +1 -1
  33. package/dist/config.d.ts +1 -1
  34. package/dist/index.cjs +186 -60
  35. package/dist/index.cjs.map +1 -1
  36. package/dist/index.d.mts +9 -9
  37. package/dist/index.d.ts +9 -9
  38. package/dist/index.mjs +7 -7
  39. package/dist/integrations.d.mts +1 -1
  40. package/dist/integrations.d.ts +1 -1
  41. package/dist/internal/build-runtime.cjs +85 -24
  42. package/dist/internal/build-runtime.cjs.map +1 -1
  43. package/dist/internal/build-runtime.d.mts +3 -3
  44. package/dist/internal/build-runtime.d.ts +3 -3
  45. package/dist/internal/build-runtime.mjs +3 -3
  46. package/dist/internal/client-runtime.cjs +1 -1
  47. package/dist/internal/client-runtime.cjs.map +1 -1
  48. package/dist/internal/client-runtime.mjs +2 -2
  49. package/dist/internal/config-runtime.d.mts +2 -2
  50. package/dist/internal/config-runtime.d.ts +2 -2
  51. package/dist/internal/product-telemetry-runtime.cjs +1 -1
  52. package/dist/internal/product-telemetry-runtime.cjs.map +1 -1
  53. package/dist/internal/product-telemetry-runtime.mjs +1 -1
  54. package/dist/internal/production-runtime.d.mts +5 -5
  55. package/dist/internal/production-runtime.d.ts +5 -5
  56. package/dist/{metadata-route-Bf4aVrYO.d.mts → metadata-route-CjF_sf9F.d.mts} +1 -1
  57. package/dist/{metadata-route-CUPYRgfT.d.ts → metadata-route-DkyJlQFD.d.ts} +1 -1
  58. package/dist/middleware.d.mts +3 -3
  59. package/dist/middleware.d.ts +3 -3
  60. package/dist/navigation.cjs +66 -24
  61. package/dist/navigation.cjs.map +1 -1
  62. package/dist/navigation.mjs +3 -3
  63. package/dist/plugin.cjs +40 -7
  64. package/dist/plugin.cjs.map +1 -1
  65. package/dist/plugin.d.mts +1 -1
  66. package/dist/plugin.d.ts +1 -1
  67. package/dist/plugin.mjs +2 -2
  68. package/dist/{production-runtime-D5ECiSmc.d.mts → production-runtime-CDSs0Rwo.d.mts} +1 -1
  69. package/dist/{production-runtime-Cb29k5Oi.d.ts → production-runtime-CSPVu_3h.d.ts} +1 -1
  70. package/dist/query/client.cjs +9 -5
  71. package/dist/query/client.cjs.map +1 -1
  72. package/dist/query/client.mjs +1 -1
  73. package/dist/{render-plan-DZ0LA8wX.d.ts → render-plan-C62oFdVD.d.ts} +1 -1
  74. package/dist/{render-plan-HL0ChBbH.d.mts → render-plan-D3TuPEmY.d.mts} +1 -1
  75. package/dist/renderer-client.cjs +66 -24
  76. package/dist/renderer-client.cjs.map +1 -1
  77. package/dist/renderer-client.d.mts +3 -3
  78. package/dist/renderer-client.d.ts +3 -3
  79. package/dist/renderer-client.mjs +1 -1
  80. package/dist/{request-8__ppqcz.d.ts → request-C-ZYE89s.d.ts} +1 -1
  81. package/dist/{request-DAZMscB9.d.mts → request-DPMdCOtv.d.mts} +1 -1
  82. package/dist/request.d.mts +2 -2
  83. package/dist/request.d.ts +2 -2
  84. package/dist/routes.d.mts +1 -1
  85. package/dist/routes.d.ts +1 -1
  86. package/dist/server-plugins.d.mts +2 -2
  87. package/dist/server-plugins.d.ts +2 -2
  88. package/dist/server.cjs +40 -7
  89. package/dist/server.cjs.map +1 -1
  90. package/dist/server.d.mts +7 -7
  91. package/dist/server.d.ts +7 -7
  92. package/dist/server.mjs +2 -2
  93. package/dist/{spa-router-DMKCWHT5.d.ts → spa-router-C7RwU8o-.d.ts} +6 -2
  94. package/dist/{spa-router-BM-OHflh.d.mts → spa-router-Cr39oWnX.d.mts} +6 -2
  95. package/dist/testing.d.mts +1 -1
  96. package/dist/testing.d.ts +1 -1
  97. package/dist/{utils-B8t0bZ5X.d.ts → utils-B6Jk-ITz.d.ts} +1 -1
  98. package/dist/{utils-B7dij0CU.d.mts → utils-U4zuTiDB.d.mts} +1 -1
  99. package/dist/version.cjs +1 -1
  100. package/dist/version.cjs.map +1 -1
  101. package/dist/version.mjs +1 -1
  102. package/dist/vite.cjs +42 -7
  103. package/dist/vite.cjs.map +1 -1
  104. package/dist/vite.d.mts +1 -1
  105. package/dist/vite.d.ts +1 -1
  106. package/dist/vite.mjs +4 -2
  107. package/package.json +1 -1
  108. package/dist/chunk-3HIATXA4.mjs.map +0 -1
  109. package/dist/chunk-3S7V7QHJ.mjs.map +0 -1
  110. package/dist/chunk-DBG42367.mjs.map +0 -1
  111. package/dist/chunk-YSX4KDLV.mjs.map +0 -1
  112. /package/dist/{chunk-DNPQOJQW.mjs.map → chunk-CRK3RQ7C.mjs.map} +0 -0
  113. /package/dist/{chunk-3UGGCJT5.mjs.map → chunk-HSCQGINR.mjs.map} +0 -0
package/dist/client.d.mts CHANGED
@@ -7,8 +7,8 @@ export { UseServerQueryOptions, UseServerQueryResult, useServerQuery } from './s
7
7
  export { F as FarmIntegrationAPI, e as FarmIntegrationAPIBodyFormat, f as FarmIntegrationAPIMethod, a as FarmIntegrationAPIOperation, g as FarmIntegrationAPIResponseFormat, b as api, d as defineIntegrationAPI, c as defineIntegrationAPIOperation, i as endpoint } from './config-C0N_7HJ6.mjs';
8
8
  export { UseThemeResult, useTheme } from './theme/client.mjs';
9
9
  import { FarmRouterPathParams, FarmRouterPathParam, FarmRouterBuildOptions, FarmRouterRouteInput } from './router.mjs';
10
- import { i as FarmViewTransitionMode, e as FarmNavigationBlockerContext, F as FarmNavigationState } from './spa-router-BM-OHflh.mjs';
11
- export { a as FarmNavigateOptions, d as FarmNavigationBlocker, f as FarmNavigationListener, h as FarmNavigationLocation, S as SPARouter, g as getRouter, n as navigateTo, p as prefetch, b as pushState, r as readPageState, c as replaceState } from './spa-router-BM-OHflh.mjs';
10
+ import { i as FarmViewTransitionMode, e as FarmNavigationBlockerContext, F as FarmNavigationState } from './spa-router-Cr39oWnX.mjs';
11
+ export { a as FarmNavigateOptions, d as FarmNavigationBlocker, f as FarmNavigationListener, h as FarmNavigationLocation, S as SPARouter, g as getRouter, n as navigateTo, p as prefetch, b as pushState, r as readPageState, c as replaceState } from './spa-router-Cr39oWnX.mjs';
12
12
  import { b as FarmI18nLocale } from './types-mP6R6CzS.mjs';
13
13
  export { F as FarmChunkRecoveryOptions, i as installChunkErrorRecovery, a as isChunkLoadError } from './chunk-recovery-lnQFzcQP.mjs';
14
14
  export { a as FarmClientHydrationCompleteEvent, b as FarmClientHydrationEvent, d as FarmClientHydrationMode, e as FarmClientHydrationSession, f as FarmClientLocation, g as FarmClientNavigationAction, h as FarmClientNavigationErrorEvent, i as FarmClientNavigationEvent, j as FarmClientNavigationLoadedEvent, k as FarmClientNavigationResolvedEvent, l as FarmClientNavigationSession, m as FarmClientPerformanceEvent, n as FarmClientPlugin, o as FarmClientPluginCloseEvent, p as FarmClientPluginEnforce, q as FarmClientPluginErrorEvent, r as FarmClientPluginErrorPhase, F as FarmClientPluginManager, s as FarmClientPluginManagerOptions, t as FarmClientPluginMetadata, u as FarmClientPluginRegistration, v as FarmClientPluginRouter, w as FarmClientPluginSetupEvent, x as FarmClientPluginStateEvent, c as createClientPluginManager } from './lifecycle-De0vQG45.mjs';
@@ -22,8 +22,8 @@ import './server-query.mjs';
22
22
  import './env.mjs';
23
23
  import './types-DQnyD3VD.mjs';
24
24
  import './island-CfGru1MO.mjs';
25
- import './render-plan-HL0ChBbH.mjs';
26
- import './client-plugins-BtfLE4dW.mjs';
25
+ import './render-plan-D3TuPEmY.mjs';
26
+ import './client-plugins-HizW0gLc.mjs';
27
27
  import './renderer.mjs';
28
28
  import 'http';
29
29
  import './types-D1A6-XvH.mjs';
package/dist/client.d.ts CHANGED
@@ -7,8 +7,8 @@ export { UseServerQueryOptions, UseServerQueryResult, useServerQuery } from './s
7
7
  export { F as FarmIntegrationAPI, e as FarmIntegrationAPIBodyFormat, f as FarmIntegrationAPIMethod, a as FarmIntegrationAPIOperation, g as FarmIntegrationAPIResponseFormat, b as api, d as defineIntegrationAPI, c as defineIntegrationAPIOperation, i as endpoint } from './config-B6GcJfNA.js';
8
8
  export { UseThemeResult, useTheme } from './theme/client.js';
9
9
  import { FarmRouterPathParams, FarmRouterPathParam, FarmRouterBuildOptions, FarmRouterRouteInput } from './router.js';
10
- import { i as FarmViewTransitionMode, e as FarmNavigationBlockerContext, F as FarmNavigationState } from './spa-router-DMKCWHT5.js';
11
- export { a as FarmNavigateOptions, d as FarmNavigationBlocker, f as FarmNavigationListener, h as FarmNavigationLocation, S as SPARouter, g as getRouter, n as navigateTo, p as prefetch, b as pushState, r as readPageState, c as replaceState } from './spa-router-DMKCWHT5.js';
10
+ import { i as FarmViewTransitionMode, e as FarmNavigationBlockerContext, F as FarmNavigationState } from './spa-router-C7RwU8o-.js';
11
+ export { a as FarmNavigateOptions, d as FarmNavigationBlocker, f as FarmNavigationListener, h as FarmNavigationLocation, S as SPARouter, g as getRouter, n as navigateTo, p as prefetch, b as pushState, r as readPageState, c as replaceState } from './spa-router-C7RwU8o-.js';
12
12
  import { b as FarmI18nLocale } from './types-mP6R6CzS.js';
13
13
  export { F as FarmChunkRecoveryOptions, i as installChunkErrorRecovery, a as isChunkLoadError } from './chunk-recovery-lnQFzcQP.js';
14
14
  export { a as FarmClientHydrationCompleteEvent, b as FarmClientHydrationEvent, d as FarmClientHydrationMode, e as FarmClientHydrationSession, f as FarmClientLocation, g as FarmClientNavigationAction, h as FarmClientNavigationErrorEvent, i as FarmClientNavigationEvent, j as FarmClientNavigationLoadedEvent, k as FarmClientNavigationResolvedEvent, l as FarmClientNavigationSession, m as FarmClientPerformanceEvent, n as FarmClientPlugin, o as FarmClientPluginCloseEvent, p as FarmClientPluginEnforce, q as FarmClientPluginErrorEvent, r as FarmClientPluginErrorPhase, F as FarmClientPluginManager, s as FarmClientPluginManagerOptions, t as FarmClientPluginMetadata, u as FarmClientPluginRegistration, v as FarmClientPluginRouter, w as FarmClientPluginSetupEvent, x as FarmClientPluginStateEvent, c as createClientPluginManager } from './lifecycle-De0vQG45.js';
@@ -22,8 +22,8 @@ import './server-query.js';
22
22
  import './env.js';
23
23
  import './types-DQnyD3VD.js';
24
24
  import './island-CfGru1MO.js';
25
- import './render-plan-DZ0LA8wX.js';
26
- import './client-plugins-C4me5UPd.js';
25
+ import './render-plan-C62oFdVD.js';
26
+ import './client-plugins-w_b1wA8e.js';
27
27
  import './renderer.js';
28
28
  import 'http';
29
29
  import './types-D1A6-XvH.js';
package/dist/client.mjs CHANGED
@@ -16,7 +16,7 @@ import {
16
16
  usePageState,
17
17
  useRouter,
18
18
  useScrollRestoration
19
- } from "./chunk-DBG42367.mjs";
19
+ } from "./chunk-CVCIL6KH.mjs";
20
20
  import {
21
21
  useTheme
22
22
  } from "./chunk-CHITERV2.mjs";
@@ -53,7 +53,7 @@ import {
53
53
  pushState,
54
54
  readPageState,
55
55
  replaceState
56
- } from "./chunk-3HIATXA4.mjs";
56
+ } from "./chunk-XSUYR4Q3.mjs";
57
57
  import "./chunk-EUUCXDW6.mjs";
58
58
  import "./chunk-JIT7GXDP.mjs";
59
59
  import "./chunk-6Q7GEEA7.mjs";
@@ -63,7 +63,7 @@ import {
63
63
  createClientPluginManager,
64
64
  installChunkErrorRecovery,
65
65
  isChunkLoadError
66
- } from "./chunk-3UGGCJT5.mjs";
66
+ } from "./chunk-HSCQGINR.mjs";
67
67
  import "./chunk-RCNUKRBF.mjs";
68
68
  import "./chunk-GQVQESLY.mjs";
69
69
  import {
@@ -84,7 +84,7 @@ import "./chunk-RBRLLZL5.mjs";
84
84
  import "./chunk-WZ5QFROO.mjs";
85
85
  import "./chunk-ZRBCBOEX.mjs";
86
86
  import "./chunk-FXG2PS27.mjs";
87
- import "./chunk-OEI62POE.mjs";
87
+ import "./chunk-6NV2RJSZ.mjs";
88
88
  import "./chunk-44ZCFSKE.mjs";
89
89
  import "./chunk-CGILA3WO.mjs";
90
90
  export {
package/dist/config.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { a5 as FarmUserConfig } from './client-plugins-BtfLE4dW.mjs';
1
+ import { a5 as FarmUserConfig } from './client-plugins-HizW0gLc.mjs';
2
2
  import './lifecycle-De0vQG45.mjs';
3
3
  import './renderer.mjs';
4
4
  import 'http';
package/dist/config.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { a5 as FarmUserConfig } from './client-plugins-C4me5UPd.js';
1
+ import { a5 as FarmUserConfig } from './client-plugins-w_b1wA8e.js';
2
2
  import './lifecycle-De0vQG45.js';
3
3
  import './renderer.js';
4
4
  import 'http';
package/dist/index.cjs CHANGED
@@ -15912,7 +15912,7 @@ var init_server3 = __esm({
15912
15912
  var version;
15913
15913
  var init_package = __esm({
15914
15914
  "package.json"() {
15915
- version = "0.1.0-beta.80";
15915
+ version = "0.1.0-beta.81";
15916
15916
  }
15917
15917
  });
15918
15918
 
@@ -30114,6 +30114,7 @@ var init_image_sharp = __esm({
30114
30114
  // src/vite.ts
30115
30115
  var vite_exports = {};
30116
30116
  __export(vite_exports, {
30117
+ createFarmNodeRequestAbortSignal: () => createFarmNodeRequestAbortSignal,
30117
30118
  defineConfig: () => defineConfig2,
30118
30119
  farmI18nClientBridgePlugin: () => farmI18nClientBridgePlugin,
30119
30120
  farmPlugin: () => farmPlugin,
@@ -30187,7 +30188,7 @@ function getPublicEnvDefine(config) {
30187
30188
  }
30188
30189
  return publicEnv2;
30189
30190
  }
30190
- function createRequestFromNodeRequest(req, url) {
30191
+ function createRequestFromNodeRequest(req, url, signal) {
30191
30192
  const headers2 = new Headers();
30192
30193
  for (const [key, value] of Object.entries(req.headers)) {
30193
30194
  if (Array.isArray(value)) {
@@ -30198,9 +30199,36 @@ function createRequestFromNodeRequest(req, url) {
30198
30199
  }
30199
30200
  return new Request(url.toString(), {
30200
30201
  method: req.method || "GET",
30201
- headers: headers2
30202
+ headers: headers2,
30203
+ signal
30202
30204
  });
30203
30205
  }
30206
+ function createFarmNodeRequestAbortSignal(req, res) {
30207
+ const controller = new AbortController();
30208
+ let disposed = false;
30209
+ const dispose = /* @__PURE__ */ __name(() => {
30210
+ if (disposed) return;
30211
+ disposed = true;
30212
+ req.off("aborted", abort);
30213
+ res.off("close", abortOnEarlyClose);
30214
+ res.off("finish", dispose);
30215
+ controller.signal.removeEventListener("abort", dispose);
30216
+ }, "dispose");
30217
+ const abort = /* @__PURE__ */ __name(() => controller.abort(), "abort");
30218
+ const abortOnEarlyClose = /* @__PURE__ */ __name(() => {
30219
+ if (!res.writableEnded) abort();
30220
+ dispose();
30221
+ }, "abortOnEarlyClose");
30222
+ if (req.aborted) {
30223
+ controller.abort();
30224
+ return controller.signal;
30225
+ }
30226
+ req.once("aborted", abort);
30227
+ res.once("close", abortOnEarlyClose);
30228
+ res.once("finish", dispose);
30229
+ controller.signal.addEventListener("abort", dispose, { once: true });
30230
+ return controller.signal;
30231
+ }
30204
30232
  function withFarmRequestTracing(handler) {
30205
30233
  const middleware2 = _withAfterNodeMiddleware(handler);
30206
30234
  return (req, res, next) => {
@@ -31468,7 +31496,11 @@ window.__FARM_MANIFEST__ = ${inlineValue({
31468
31496
  const urlObj = new URL(req.url, `http://${req.headers.host || "localhost:3000"}`);
31469
31497
  const targetPath = urlObj.searchParams.get("path") || "/";
31470
31498
  try {
31471
- const request = createRequestFromNodeRequest(req, urlObj);
31499
+ const request = createRequestFromNodeRequest(
31500
+ req,
31501
+ urlObj,
31502
+ createFarmNodeRequestAbortSignal(req, res)
31503
+ );
31472
31504
  const deploymentMismatch = getFarmDeploymentMismatch(
31473
31505
  request,
31474
31506
  farmConfig.deploymentId
@@ -31483,7 +31515,8 @@ window.__FARM_MANIFEST__ = ${inlineValue({
31483
31515
  const targetRequestUrl = new URL(targetPath, request.url);
31484
31516
  const targetRequest = new Request(targetRequestUrl, {
31485
31517
  method: "GET",
31486
- headers: request.headers
31518
+ headers: request.headers,
31519
+ signal: request.signal
31487
31520
  });
31488
31521
  await farmApp.getServerRenderer().runWithRequestContext(targetRequest, async () => {
31489
31522
  const routeManager3 = farmApp.getRouteManager();
@@ -31562,7 +31595,7 @@ window.__FARM_MANIFEST__ = ${inlineValue({
31562
31595
  const targetUrl = new URL(targetPath, "http://localhost");
31563
31596
  const searchParams = searchParamsToObject(targetUrl.searchParams);
31564
31597
  const routeContext = await resolveFarmRouteContext(farmApp.getConfig(), {
31565
- request,
31598
+ request: targetRequest,
31566
31599
  params,
31567
31600
  search: searchParams,
31568
31601
  path: targetUrl.pathname
@@ -31586,7 +31619,7 @@ window.__FARM_MANIFEST__ = ${inlineValue({
31586
31619
  (entry) => entry.name === slot.name && entry.ownerPattern === slot.ownerPattern && entry.pattern === slot.route.pattern
31587
31620
  ) ?? getClientModuleMetadata(slot.route.modulePath, server.config.root);
31588
31621
  const slotContext = await resolveFarmRouteContext(farmApp.getConfig(), {
31589
- request,
31622
+ request: targetRequest,
31590
31623
  params: slot.params,
31591
31624
  search: searchParams,
31592
31625
  path: targetUrl.pathname
@@ -34527,6 +34560,7 @@ async function mountFarmDocsSearch() {
34527
34560
  __name(renderFarmI18nStaticHead, "renderFarmI18nStaticHead");
34528
34561
  __name(getPublicEnvDefine, "getPublicEnvDefine");
34529
34562
  __name(createRequestFromNodeRequest, "createRequestFromNodeRequest");
34563
+ __name(createFarmNodeRequestAbortSignal, "createFarmNodeRequestAbortSignal");
34530
34564
  __name(withFarmRequestTracing, "withFarmRequestTracing");
34531
34565
  __name(toRequestBody, "toRequestBody");
34532
34566
  __name(applyWebRequestToNodeRequest, "applyWebRequestToNodeRequest");
@@ -43442,6 +43476,7 @@ __name(generateRuntimePathMatcherSource, "generateRuntimePathMatcherSource");
43442
43476
  function generateUniversalRouterStateProperties() {
43443
43477
  return `
43444
43478
  blockers: new Set(),
43479
+ unloadBlockers: new Map(),
43445
43480
  navigationListeners: new Set(),
43446
43481
  navigationState: IDLE_NAVIGATION_STATE,
43447
43482
  navigationSequence: 0,
@@ -43485,9 +43520,20 @@ function generateUniversalRouterStateProperties() {
43485
43520
  return () => this.navigationListeners.delete(listener);
43486
43521
  },
43487
43522
 
43488
- addBlocker: function(blocker) {
43523
+ addBlocker: function(blocker, shouldBlockUnload) {
43489
43524
  this.blockers.add(blocker);
43490
- return () => this.blockers.delete(blocker);
43525
+ this.unloadBlockers.set(blocker, shouldBlockUnload || (() => {
43526
+ const result = blocker({ from: this.currentPath, to: this.currentPath, action: "replace" });
43527
+ if (result && typeof result.then === "function") {
43528
+ result.catch(() => undefined);
43529
+ return true;
43530
+ }
43531
+ return result === true;
43532
+ }));
43533
+ return () => {
43534
+ this.blockers.delete(blocker);
43535
+ this.unloadBlockers.delete(blocker);
43536
+ };
43491
43537
  },
43492
43538
 
43493
43539
  shouldBlockNavigation: async function(context) {
@@ -43497,6 +43543,17 @@ function generateUniversalRouterStateProperties() {
43497
43543
  return false;
43498
43544
  },
43499
43545
 
43546
+ shouldBlockUnload: function() {
43547
+ for (const blocker of this.blockers) {
43548
+ try {
43549
+ if (this.unloadBlockers.get(blocker)?.()) return true;
43550
+ } catch {
43551
+ return true;
43552
+ }
43553
+ }
43554
+ return false;
43555
+ },
43556
+
43500
43557
  handlePopState: function(event) {
43501
43558
  if (document.documentElement.dataset.farmDocsRuntime === "true") return;
43502
43559
  return this.navigate(window.location.href, {
@@ -43587,17 +43644,10 @@ function generateUniversalRouterStateProperties() {
43587
43644
 
43588
43645
  writePageState: function(action, state, href) {
43589
43646
  const url = new URL(href || window.location.href, window.location.origin);
43590
- this.writeHistoryEntry(action, url.pathname + url.search, state, url);
43591
- // Announce on the dedicated history channel; a synthetic popstate would
43592
- // be treated as back/forward by the popstate listener below and trigger
43593
- // a full navigation for a shallow page-state write. The bundled client
43594
- // hooks subscribe to this event via subscribeHistoryChange.
43595
- window.dispatchEvent(
43596
- new CustomEvent("farm:historychange", { detail: { kind: "page-state" } }),
43597
- );
43647
+ this.writeHistoryEntry(action, url.pathname + url.search, state, url, "page-state");
43598
43648
  },
43599
43649
 
43600
- writeHistoryEntry: function(action, path, pageState, url) {
43650
+ writeHistoryEntry: function(action, path, pageState, url, changeKind = "url-search") {
43601
43651
  if (action === "pop") return;
43602
43652
  const nextState = createHistoryState(path, pageState, window.history.state);
43603
43653
  const nextIndex = this.currentHistoryIndex == null
@@ -43610,6 +43660,11 @@ function generateUniversalRouterStateProperties() {
43610
43660
  else window.history.pushState(nextState, "", url);
43611
43661
  this.currentHistoryIndex = nextIndex;
43612
43662
  this.currentHistoryState = nextState;
43663
+ // Announce programmatic history writes without synthesizing popstate,
43664
+ // which the router reserves for real back/forward navigation.
43665
+ window.dispatchEvent(
43666
+ new CustomEvent("farm:historychange", { detail: { kind: changeKind } }),
43667
+ );
43613
43668
  },
43614
43669
 
43615
43670
  registerScrollElement: function(key, element) {
@@ -43808,12 +43863,14 @@ ${generateUniversalRouterStateProperties()}
43808
43863
  const url = new URL(href, window.location.origin);
43809
43864
  if (isFarmExternalNavigationURL(url, window.location.origin)) {
43810
43865
  this.cancelActiveNavigation();
43811
- window.location.href = href;
43866
+ if (options.replace || options.action === "replace") window.location.replace(href);
43867
+ else window.location.href = href;
43812
43868
  return;
43813
43869
  }
43814
43870
  if (isFarmDocsPath(url.pathname)) {
43815
43871
  this.cancelActiveNavigation();
43816
- window.location.href = href;
43872
+ if (options.replace || options.action === "replace") window.location.replace(href);
43873
+ else window.location.href = href;
43817
43874
  return;
43818
43875
  }
43819
43876
 
@@ -43975,6 +44032,7 @@ ${generateUniversalRouterStateProperties()}
43975
44032
  prefetch: function(href) {
43976
44033
  const url = new URL(href, window.location.origin);
43977
44034
  if (isFarmExternalNavigationURL(url, window.location.origin)) return;
44035
+ if (isFarmDocsPath(url.pathname)) return;
43978
44036
 
43979
44037
  const pathname = url.pathname + url.search;
43980
44038
  if (this.prefetchCache.has(pathname)) return;
@@ -44038,7 +44096,7 @@ window.__FARM_SPA_ROUTER__ = spaRouter;
44038
44096
  void hydrateFarmDocsAdapterRuntime();
44039
44097
 
44040
44098
  window.addEventListener("beforeunload", function(event) {
44041
- if (spaRouter.blockers.size > 0) {
44099
+ if (spaRouter.shouldBlockUnload()) {
44042
44100
  event.preventDefault();
44043
44101
  event.returnValue = "";
44044
44102
  }
@@ -44661,12 +44719,14 @@ ${generateUniversalRouterStateProperties()}
44661
44719
  const url = new URL(href, window.location.origin);
44662
44720
  if (isFarmExternalNavigationURL(url, window.location.origin)) {
44663
44721
  this.cancelActiveNavigation();
44664
- window.location.href = href;
44722
+ if (options.replace || options.action === "replace") window.location.replace(href);
44723
+ else window.location.href = href;
44665
44724
  return;
44666
44725
  }
44667
44726
  if (isFarmDocsPath(url.pathname)) {
44668
44727
  this.cancelActiveNavigation();
44669
- window.location.href = href;
44728
+ if (options.replace || options.action === "replace") window.location.replace(href);
44729
+ else window.location.href = href;
44670
44730
  return;
44671
44731
  }
44672
44732
 
@@ -45003,6 +45063,7 @@ ${generateUniversalRouterStateProperties()}
45003
45063
  prefetch: function(href) {
45004
45064
  const url = new URL(href, window.location.origin);
45005
45065
  if (isFarmExternalNavigationURL(url, window.location.origin)) return;
45066
+ if (isFarmDocsPath(url.pathname)) return;
45006
45067
 
45007
45068
  const pathname = url.pathname + url.search;
45008
45069
  const interceptFrom = this.currentPath;
@@ -45062,7 +45123,7 @@ spaRouter.initializeHistory();
45062
45123
  window.__FARM_SPA_ROUTER__ = spaRouter;
45063
45124
 
45064
45125
  window.addEventListener("beforeunload", function(event) {
45065
- if (spaRouter.blockers.size > 0) {
45126
+ if (spaRouter.shouldBlockUnload()) {
45066
45127
  event.preventDefault();
45067
45128
  event.returnValue = "";
45068
45129
  }
@@ -50921,6 +50982,14 @@ init_deferred();
50921
50982
 
50922
50983
  // src/client/history-sync.ts
50923
50984
  var FARM_HISTORY_CHANGE_EVENT = "farm:historychange";
50985
+ function dispatchHistoryChange(kind) {
50986
+ window.dispatchEvent(
50987
+ new CustomEvent(FARM_HISTORY_CHANGE_EVENT, {
50988
+ detail: { kind }
50989
+ })
50990
+ );
50991
+ }
50992
+ __name(dispatchHistoryChange, "dispatchHistoryChange");
50924
50993
  function notifyHistoryChange(kind) {
50925
50994
  if (typeof window === "undefined") return;
50926
50995
  setTimeout(() => {
@@ -50928,14 +50997,15 @@ function notifyHistoryChange(kind) {
50928
50997
  window.dispatchEvent(new PopStateEvent("popstate"));
50929
50998
  return;
50930
50999
  }
50931
- window.dispatchEvent(
50932
- new CustomEvent(FARM_HISTORY_CHANGE_EVENT, {
50933
- detail: { kind }
50934
- })
50935
- );
51000
+ dispatchHistoryChange(kind);
50936
51001
  }, 0);
50937
51002
  }
50938
51003
  __name(notifyHistoryChange, "notifyHistoryChange");
51004
+ function notifyRouterHistoryChange() {
51005
+ if (typeof window === "undefined") return;
51006
+ setTimeout(() => dispatchHistoryChange("url-search"), 0);
51007
+ }
51008
+ __name(notifyRouterHistoryChange, "notifyRouterHistoryChange");
50939
51009
  function subscribeHistoryChange(listener) {
50940
51010
  if (typeof window === "undefined") return () => {
50941
51011
  };
@@ -51003,6 +51073,7 @@ var _SPARouter = class _SPARouter {
51003
51073
  this.prefetchingUrls = /* @__PURE__ */ new Set();
51004
51074
  this.observers = /* @__PURE__ */ new Map();
51005
51075
  this.blockers = /* @__PURE__ */ new Set();
51076
+ this.unloadBlockers = /* @__PURE__ */ new Map();
51006
51077
  this.navigationListeners = /* @__PURE__ */ new Set();
51007
51078
  this.navigationState = IDLE_NAVIGATION_STATE;
51008
51079
  this.currentHistoryPath = null;
@@ -51014,7 +51085,7 @@ var _SPARouter = class _SPARouter {
51014
51085
  void this.handlePopState(event);
51015
51086
  }, "onPopState");
51016
51087
  this.onBeforeUnload = /* @__PURE__ */ __name((event) => {
51017
- if (this.blockers.size > 0) {
51088
+ if (this.shouldBlockUnload()) {
51018
51089
  event.preventDefault();
51019
51090
  event.returnValue = "";
51020
51091
  }
@@ -51192,6 +51263,7 @@ var _SPARouter = class _SPARouter {
51192
51263
  if (isFarmLocaleChangeHref(href)) return;
51193
51264
  const url = new URL(href, window.location.origin);
51194
51265
  if (isFarmExternalNavigationURL(url, window.location.origin)) return;
51266
+ if (this.options.shouldUseDocumentNavigation(url.pathname)) return;
51195
51267
  const fullPath = url.pathname + url.search;
51196
51268
  const interceptFrom = window.location.pathname + window.location.search;
51197
51269
  if (this.prefetchingUrls.has(fullPath)) return;
@@ -51240,10 +51312,15 @@ var _SPARouter = class _SPARouter {
51240
51312
  this.observers.delete(element);
51241
51313
  }
51242
51314
  }
51243
- addBlocker(blocker) {
51315
+ addBlocker(blocker, shouldBlockUnload2) {
51244
51316
  this.blockers.add(blocker);
51317
+ this.unloadBlockers.set(
51318
+ blocker,
51319
+ shouldBlockUnload2 ?? (() => this.evaluateBlockerForUnload(blocker))
51320
+ );
51245
51321
  return () => {
51246
51322
  this.blockers.delete(blocker);
51323
+ this.unloadBlockers.delete(blocker);
51247
51324
  };
51248
51325
  }
51249
51326
  getNavigationState() {
@@ -51272,11 +51349,16 @@ var _SPARouter = class _SPARouter {
51272
51349
  this.writePageState("replace", state, href);
51273
51350
  }
51274
51351
  async commitNavigation(options) {
51275
- const historyPath = options.pageData.canonicalPath || options.fullPath;
51352
+ const historyUrl = new URL(
51353
+ options.pageData.canonicalPath || options.fullPath,
51354
+ window.location.origin
51355
+ );
51356
+ historyUrl.hash = options.url.hash;
51357
+ const historyPath = historyUrl.pathname + historyUrl.search + historyUrl.hash;
51276
51358
  const historyState = createHistoryState(
51277
51359
  historyPath,
51278
51360
  options.state,
51279
- void 0,
51361
+ options.replace ? window.history.state : void 0,
51280
51362
  options.pageData.interception?.from ?? null
51281
51363
  );
51282
51364
  const nextHistoryIndex = this.currentHistoryIndex == null ? null : options.replace ? this.currentHistoryIndex : this.currentHistoryIndex + 1;
@@ -51290,18 +51372,8 @@ var _SPARouter = class _SPARouter {
51290
51372
  }
51291
51373
  this.currentHistoryIndex = nextHistoryIndex;
51292
51374
  this.currentHistoryPath = new URL(historyPath, window.location.origin).pathname + new URL(historyPath, window.location.origin).search;
51293
- if (options.pageData.metadata?.title) {
51294
- document.title = options.pageData.metadata.title;
51295
- }
51296
- if (options.pageData.metadata?.description) {
51297
- let metaDesc = document.querySelector('meta[name="description"]');
51298
- if (!metaDesc) {
51299
- metaDesc = document.createElement("meta");
51300
- metaDesc.setAttribute("name", "description");
51301
- document.head.appendChild(metaDesc);
51302
- }
51303
- metaDesc.setAttribute("content", options.pageData.metadata.description);
51304
- }
51375
+ notifyRouterHistoryChange();
51376
+ this.updateDocumentMetadata(options.pageData.metadata);
51305
51377
  _hydrateFarmI18n(options.pageData.i18n);
51306
51378
  if (this.onNavigate) {
51307
51379
  await this.onNavigate(options.pageData);
@@ -51451,9 +51523,7 @@ var _SPARouter = class _SPARouter {
51451
51523
  await this.clientPlugins?.markNavigationLoaded(clientNavigation, pageData);
51452
51524
  }
51453
51525
  if (!this.isCurrentNavigation(navigation, clientNavigation)) return;
51454
- if (pageData.metadata?.title) {
51455
- document.title = pageData.metadata.title;
51456
- }
51526
+ this.updateDocumentMetadata(pageData.metadata);
51457
51527
  _hydrateFarmI18n(pageData.i18n);
51458
51528
  if (this.onNavigate) {
51459
51529
  await this.onNavigate(pageData);
@@ -51497,6 +51567,39 @@ var _SPARouter = class _SPARouter {
51497
51567
  }
51498
51568
  return false;
51499
51569
  }
51570
+ evaluateBlockerForUnload(blocker) {
51571
+ const path41 = window.location.pathname + window.location.search;
51572
+ const result = blocker({ from: path41, to: path41, action: "replace" });
51573
+ if (result && typeof result !== "boolean") {
51574
+ void result.catch(() => void 0);
51575
+ return true;
51576
+ }
51577
+ return result === true;
51578
+ }
51579
+ shouldBlockUnload() {
51580
+ for (const blocker of this.blockers) {
51581
+ try {
51582
+ if (this.unloadBlockers.get(blocker)?.()) return true;
51583
+ } catch {
51584
+ return true;
51585
+ }
51586
+ }
51587
+ return false;
51588
+ }
51589
+ updateDocumentMetadata(metadata) {
51590
+ document.title = metadata?.title || "Farm.js App";
51591
+ let description = document.querySelector('meta[name="description"]');
51592
+ if (!metadata?.description) {
51593
+ description?.remove();
51594
+ return;
51595
+ }
51596
+ if (!description) {
51597
+ description = document.createElement("meta");
51598
+ description.setAttribute("name", "description");
51599
+ document.head.appendChild(description);
51600
+ }
51601
+ description.setAttribute("content", metadata.description);
51602
+ }
51500
51603
  startNavigation(options) {
51501
51604
  this.activeNavigation?.controller.abort("superseded");
51502
51605
  const navigation = {
@@ -51699,6 +51802,26 @@ __name(getScrollElementStorageKey, "getScrollElementStorageKey");
51699
51802
  init_request_bridge();
51700
51803
  init_routing();
51701
51804
  init_base_path();
51805
+ function shouldBlockUnload(options) {
51806
+ const path41 = window.location.pathname + window.location.search;
51807
+ const context2 = {
51808
+ from: path41,
51809
+ to: path41,
51810
+ action: "replace"
51811
+ };
51812
+ const when = typeof options.when === "function" ? options.when(context2) : options.when;
51813
+ if (!when) return false;
51814
+ if (!options.shouldBlock) return true;
51815
+ try {
51816
+ const result = options.shouldBlock(context2);
51817
+ if (typeof result === "boolean") return result;
51818
+ void result.catch(() => void 0);
51819
+ return true;
51820
+ } catch {
51821
+ return true;
51822
+ }
51823
+ }
51824
+ __name(shouldBlockUnload, "shouldBlockUnload");
51702
51825
  function navigateViaRouter(href, basePath, replace) {
51703
51826
  if (typeof window === "undefined") return;
51704
51827
  const url = applyFarmBasePath(href, basePath);
@@ -51802,18 +51925,21 @@ function useBlocker(options) {
51802
51925
  if (typeof window === "undefined" || !active) {
51803
51926
  return;
51804
51927
  }
51805
- return getRouter2().addBlocker(async (context2) => {
51806
- const current = optionsRef.current;
51807
- const when = typeof current.when === "function" ? current.when(context2) : current.when;
51808
- if (!when) return false;
51809
- if (current.shouldBlock && !await current.shouldBlock(context2)) {
51810
- return false;
51811
- }
51812
- if (current.message && typeof window.confirm === "function") {
51813
- return !window.confirm(current.message);
51814
- }
51815
- return true;
51816
- });
51928
+ return getRouter2().addBlocker(
51929
+ async (context2) => {
51930
+ const current = optionsRef.current;
51931
+ const when = typeof current.when === "function" ? current.when(context2) : current.when;
51932
+ if (!when) return false;
51933
+ if (current.shouldBlock && !await current.shouldBlock(context2)) {
51934
+ return false;
51935
+ }
51936
+ if (current.message && typeof window.confirm === "function") {
51937
+ return !window.confirm(current.message);
51938
+ }
51939
+ return true;
51940
+ },
51941
+ () => shouldBlockUnload(optionsRef.current)
51942
+ );
51817
51943
  }, [active]);
51818
51944
  return { active };
51819
51945
  }