@farm.js/core 0.1.0-beta.0
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/LICENSE +22 -0
- package/README.md +11 -0
- package/dist/after.cjs +227 -0
- package/dist/after.cjs.map +1 -0
- package/dist/after.d.mts +25 -0
- package/dist/after.d.ts +25 -0
- package/dist/after.mjs +14 -0
- package/dist/after.mjs.map +1 -0
- package/dist/agent-runtime.cjs +2379 -0
- package/dist/agent-runtime.cjs.map +1 -0
- package/dist/agent-runtime.d.mts +93 -0
- package/dist/agent-runtime.d.ts +93 -0
- package/dist/agent-runtime.mjs +479 -0
- package/dist/agent-runtime.mjs.map +1 -0
- package/dist/api/route-manager.cjs +1196 -0
- package/dist/api/route-manager.cjs.map +1 -0
- package/dist/api/route-manager.d.mts +64 -0
- package/dist/api/route-manager.d.ts +64 -0
- package/dist/api/route-manager.mjs +34 -0
- package/dist/api/route-manager.mjs.map +1 -0
- package/dist/api/runtime.cjs +272 -0
- package/dist/api/runtime.cjs.map +1 -0
- package/dist/api/runtime.d.mts +16 -0
- package/dist/api/runtime.d.ts +16 -0
- package/dist/api/runtime.mjs +16 -0
- package/dist/api/runtime.mjs.map +1 -0
- package/dist/api.cjs +3199 -0
- package/dist/api.cjs.map +1 -0
- package/dist/api.d.mts +190 -0
- package/dist/api.d.ts +190 -0
- package/dist/api.mjs +63 -0
- package/dist/api.mjs.map +1 -0
- package/dist/app-BiX4qb-d.d.mts +265 -0
- package/dist/app-CFRNJXP1.d.ts +265 -0
- package/dist/app-markdown.cjs +220 -0
- package/dist/app-markdown.cjs.map +1 -0
- package/dist/app-markdown.d.mts +21 -0
- package/dist/app-markdown.d.ts +21 -0
- package/dist/app-markdown.mjs +26 -0
- package/dist/app-markdown.mjs.map +1 -0
- package/dist/cache.cjs +543 -0
- package/dist/cache.cjs.map +1 -0
- package/dist/cache.d.mts +78 -0
- package/dist/cache.d.ts +78 -0
- package/dist/cache.mjs +38 -0
- package/dist/cache.mjs.map +1 -0
- package/dist/chunk-25D7G34K.mjs +142 -0
- package/dist/chunk-25D7G34K.mjs.map +1 -0
- package/dist/chunk-3QJO55ZF.mjs +3548 -0
- package/dist/chunk-3QJO55ZF.mjs.map +1 -0
- package/dist/chunk-3XNTL3FQ.mjs +452 -0
- package/dist/chunk-3XNTL3FQ.mjs.map +1 -0
- package/dist/chunk-44ZCFSKE.mjs +84 -0
- package/dist/chunk-44ZCFSKE.mjs.map +1 -0
- package/dist/chunk-4PTK6KT4.mjs +364 -0
- package/dist/chunk-4PTK6KT4.mjs.map +1 -0
- package/dist/chunk-4S3ORGFA.mjs +44 -0
- package/dist/chunk-4S3ORGFA.mjs.map +1 -0
- package/dist/chunk-5BY76U2M.mjs +1 -0
- package/dist/chunk-5BY76U2M.mjs.map +1 -0
- package/dist/chunk-5ZGPRGWV.mjs +136 -0
- package/dist/chunk-5ZGPRGWV.mjs.map +1 -0
- package/dist/chunk-6XDUHOEM.mjs +157 -0
- package/dist/chunk-6XDUHOEM.mjs.map +1 -0
- package/dist/chunk-74YTBPTY.mjs +450 -0
- package/dist/chunk-74YTBPTY.mjs.map +1 -0
- package/dist/chunk-7HO6AEOP.mjs +74 -0
- package/dist/chunk-7HO6AEOP.mjs.map +1 -0
- package/dist/chunk-7MABZJIM.mjs +29 -0
- package/dist/chunk-7MABZJIM.mjs.map +1 -0
- package/dist/chunk-7ZY5AIJO.mjs +161 -0
- package/dist/chunk-7ZY5AIJO.mjs.map +1 -0
- package/dist/chunk-AGS7UJ52.mjs +446 -0
- package/dist/chunk-AGS7UJ52.mjs.map +1 -0
- package/dist/chunk-AZ7YUVNR.mjs +65 -0
- package/dist/chunk-AZ7YUVNR.mjs.map +1 -0
- package/dist/chunk-B232I2GP.mjs +163 -0
- package/dist/chunk-B232I2GP.mjs.map +1 -0
- package/dist/chunk-B6N4ZB2H.mjs +718 -0
- package/dist/chunk-B6N4ZB2H.mjs.map +1 -0
- package/dist/chunk-BHG3LVHH.mjs +176 -0
- package/dist/chunk-BHG3LVHH.mjs.map +1 -0
- package/dist/chunk-C3DLZMBU.mjs +597 -0
- package/dist/chunk-C3DLZMBU.mjs.map +1 -0
- package/dist/chunk-CGILA3WO.mjs +14 -0
- package/dist/chunk-CGILA3WO.mjs.map +1 -0
- package/dist/chunk-CHFHNEMO.mjs +7088 -0
- package/dist/chunk-CHFHNEMO.mjs.map +1 -0
- package/dist/chunk-E2MPIBRE.mjs +149 -0
- package/dist/chunk-E2MPIBRE.mjs.map +1 -0
- package/dist/chunk-E6EPN5BT.mjs +203 -0
- package/dist/chunk-E6EPN5BT.mjs.map +1 -0
- package/dist/chunk-EVGBEZDF.mjs +215 -0
- package/dist/chunk-EVGBEZDF.mjs.map +1 -0
- package/dist/chunk-FQYDHKKU.mjs +128 -0
- package/dist/chunk-FQYDHKKU.mjs.map +1 -0
- package/dist/chunk-G3B5BRDY.mjs +5763 -0
- package/dist/chunk-G3B5BRDY.mjs.map +1 -0
- package/dist/chunk-GN72QAIH.mjs +146 -0
- package/dist/chunk-GN72QAIH.mjs.map +1 -0
- package/dist/chunk-GS6K5OCM.mjs +407 -0
- package/dist/chunk-GS6K5OCM.mjs.map +1 -0
- package/dist/chunk-GY2STC2S.mjs +180 -0
- package/dist/chunk-GY2STC2S.mjs.map +1 -0
- package/dist/chunk-GZP5W4K3.mjs +158 -0
- package/dist/chunk-GZP5W4K3.mjs.map +1 -0
- package/dist/chunk-H2FA2SBS.mjs +51 -0
- package/dist/chunk-H2FA2SBS.mjs.map +1 -0
- package/dist/chunk-HXP3ZSPC.mjs +211 -0
- package/dist/chunk-HXP3ZSPC.mjs.map +1 -0
- package/dist/chunk-ITN462YM.mjs +98 -0
- package/dist/chunk-ITN462YM.mjs.map +1 -0
- package/dist/chunk-J23HNLFY.mjs +72 -0
- package/dist/chunk-J23HNLFY.mjs.map +1 -0
- package/dist/chunk-J4FNJ5IU.mjs +179 -0
- package/dist/chunk-J4FNJ5IU.mjs.map +1 -0
- package/dist/chunk-JK25YEN6.mjs +219 -0
- package/dist/chunk-JK25YEN6.mjs.map +1 -0
- package/dist/chunk-JLWMCADZ.mjs +204 -0
- package/dist/chunk-JLWMCADZ.mjs.map +1 -0
- package/dist/chunk-JN3UU635.mjs +622 -0
- package/dist/chunk-JN3UU635.mjs.map +1 -0
- package/dist/chunk-K4667E2Q.mjs +1916 -0
- package/dist/chunk-K4667E2Q.mjs.map +1 -0
- package/dist/chunk-LGHEOHBU.mjs +218 -0
- package/dist/chunk-LGHEOHBU.mjs.map +1 -0
- package/dist/chunk-LLC7BNXW.mjs +275 -0
- package/dist/chunk-LLC7BNXW.mjs.map +1 -0
- package/dist/chunk-LM2YNO4U.mjs +24 -0
- package/dist/chunk-LM2YNO4U.mjs.map +1 -0
- package/dist/chunk-NNLCAVB6.mjs +391 -0
- package/dist/chunk-NNLCAVB6.mjs.map +1 -0
- package/dist/chunk-O3HADRW6.mjs +639 -0
- package/dist/chunk-O3HADRW6.mjs.map +1 -0
- package/dist/chunk-OYXO65LI.mjs +119 -0
- package/dist/chunk-OYXO65LI.mjs.map +1 -0
- package/dist/chunk-P7QDS5AT.mjs +191 -0
- package/dist/chunk-P7QDS5AT.mjs.map +1 -0
- package/dist/chunk-PRNYWD7K.mjs +599 -0
- package/dist/chunk-PRNYWD7K.mjs.map +1 -0
- package/dist/chunk-QF4PHCMA.mjs +422 -0
- package/dist/chunk-QF4PHCMA.mjs.map +1 -0
- package/dist/chunk-QFQRHRZS.mjs +1224 -0
- package/dist/chunk-QFQRHRZS.mjs.map +1 -0
- package/dist/chunk-QGOHVJ6J.mjs +63 -0
- package/dist/chunk-QGOHVJ6J.mjs.map +1 -0
- package/dist/chunk-QKVUNGAH.mjs +39 -0
- package/dist/chunk-QKVUNGAH.mjs.map +1 -0
- package/dist/chunk-QM6VV26B.mjs +149 -0
- package/dist/chunk-QM6VV26B.mjs.map +1 -0
- package/dist/chunk-RHIFZZUI.mjs +69 -0
- package/dist/chunk-RHIFZZUI.mjs.map +1 -0
- package/dist/chunk-RKI6TN3A.mjs +49 -0
- package/dist/chunk-RKI6TN3A.mjs.map +1 -0
- package/dist/chunk-RSKVYESE.mjs +187 -0
- package/dist/chunk-RSKVYESE.mjs.map +1 -0
- package/dist/chunk-S2XHZS7W.mjs +180 -0
- package/dist/chunk-S2XHZS7W.mjs.map +1 -0
- package/dist/chunk-SCFX4UTD.mjs +28 -0
- package/dist/chunk-SCFX4UTD.mjs.map +1 -0
- package/dist/chunk-SL6HTIOK.mjs +66 -0
- package/dist/chunk-SL6HTIOK.mjs.map +1 -0
- package/dist/chunk-SOU3Q3ZA.mjs +173 -0
- package/dist/chunk-SOU3Q3ZA.mjs.map +1 -0
- package/dist/chunk-SPBBQLXI.mjs +207 -0
- package/dist/chunk-SPBBQLXI.mjs.map +1 -0
- package/dist/chunk-SXZTEK3V.mjs +396 -0
- package/dist/chunk-SXZTEK3V.mjs.map +1 -0
- package/dist/chunk-T4QJQK76.mjs +459 -0
- package/dist/chunk-T4QJQK76.mjs.map +1 -0
- package/dist/chunk-TRORP7E4.mjs +41 -0
- package/dist/chunk-TRORP7E4.mjs.map +1 -0
- package/dist/chunk-TU4YJICB.mjs +728 -0
- package/dist/chunk-TU4YJICB.mjs.map +1 -0
- package/dist/chunk-TXCFGOHW.mjs +42 -0
- package/dist/chunk-TXCFGOHW.mjs.map +1 -0
- package/dist/chunk-UHE2TTLK.mjs +466 -0
- package/dist/chunk-UHE2TTLK.mjs.map +1 -0
- package/dist/chunk-UREJA4GZ.mjs +364 -0
- package/dist/chunk-UREJA4GZ.mjs.map +1 -0
- package/dist/chunk-USWZZUEH.mjs +25 -0
- package/dist/chunk-USWZZUEH.mjs.map +1 -0
- package/dist/chunk-UVCIEUJC.mjs +16 -0
- package/dist/chunk-UVCIEUJC.mjs.map +1 -0
- package/dist/chunk-V6WE6JSZ.mjs +352 -0
- package/dist/chunk-V6WE6JSZ.mjs.map +1 -0
- package/dist/chunk-V7RBCSDJ.mjs +170 -0
- package/dist/chunk-V7RBCSDJ.mjs.map +1 -0
- package/dist/chunk-VCANOYFI.mjs +588 -0
- package/dist/chunk-VCANOYFI.mjs.map +1 -0
- package/dist/chunk-WZ5QFROO.mjs +23 -0
- package/dist/chunk-WZ5QFROO.mjs.map +1 -0
- package/dist/chunk-Y2OJJD7R.mjs +543 -0
- package/dist/chunk-Y2OJJD7R.mjs.map +1 -0
- package/dist/chunk-Y7A27276.mjs +538 -0
- package/dist/chunk-Y7A27276.mjs.map +1 -0
- package/dist/chunk-YHU7SS6L.mjs +365 -0
- package/dist/chunk-YHU7SS6L.mjs.map +1 -0
- package/dist/chunk-ZBE6MLHL.mjs +230 -0
- package/dist/chunk-ZBE6MLHL.mjs.map +1 -0
- package/dist/chunk-ZJQNATYV.mjs +299 -0
- package/dist/chunk-ZJQNATYV.mjs.map +1 -0
- package/dist/client-D_yUjVhe.d.mts +402 -0
- package/dist/client-Dkc03WP8.d.ts +402 -0
- package/dist/client-cache-CIlyBlmx.d.ts +6 -0
- package/dist/client-cache-D-EZ7XVW.d.mts +6 -0
- package/dist/client-plugins-BZnpeTGA.d.ts +1848 -0
- package/dist/client-plugins-g4bzuCmo.d.mts +1848 -0
- package/dist/client-plugins.cjs +415 -0
- package/dist/client-plugins.cjs.map +1 -0
- package/dist/client-plugins.d.mts +21 -0
- package/dist/client-plugins.d.ts +21 -0
- package/dist/client-plugins.mjs +10 -0
- package/dist/client-plugins.mjs.map +1 -0
- package/dist/client.cjs +4571 -0
- package/dist/client.cjs.map +1 -0
- package/dist/client.d.mts +329 -0
- package/dist/client.d.ts +329 -0
- package/dist/client.mjs +103 -0
- package/dist/client.mjs.map +1 -0
- package/dist/config.cjs +38 -0
- package/dist/config.cjs.map +1 -0
- package/dist/config.d.mts +28 -0
- package/dist/config.d.ts +28 -0
- package/dist/config.mjs +10 -0
- package/dist/config.mjs.map +1 -0
- package/dist/cron.cjs +406 -0
- package/dist/cron.cjs.map +1 -0
- package/dist/cron.d.mts +78 -0
- package/dist/cron.d.ts +78 -0
- package/dist/cron.mjs +30 -0
- package/dist/cron.mjs.map +1 -0
- package/dist/deferred.cjs +438 -0
- package/dist/deferred.cjs.map +1 -0
- package/dist/deferred.d.mts +42 -0
- package/dist/deferred.d.ts +42 -0
- package/dist/deferred.mjs +28 -0
- package/dist/deferred.mjs.map +1 -0
- package/dist/deployment.cjs +199 -0
- package/dist/deployment.cjs.map +1 -0
- package/dist/deployment.d.mts +34 -0
- package/dist/deployment.d.ts +34 -0
- package/dist/deployment.mjs +38 -0
- package/dist/deployment.mjs.map +1 -0
- package/dist/devtools-AE4RVXCM.mjs +370 -0
- package/dist/devtools-AE4RVXCM.mjs.map +1 -0
- package/dist/devtools-client-6WPY2AQU.mjs +225 -0
- package/dist/devtools-client-6WPY2AQU.mjs.map +1 -0
- package/dist/devtools-ui-NJKFORTG.mjs +1349 -0
- package/dist/devtools-ui-NJKFORTG.mjs.map +1 -0
- package/dist/docs.cjs +5541 -0
- package/dist/docs.cjs.map +1 -0
- package/dist/docs.d.mts +69 -0
- package/dist/docs.d.ts +69 -0
- package/dist/docs.mjs +46 -0
- package/dist/docs.mjs.map +1 -0
- package/dist/env-types.cjs +223 -0
- package/dist/env-types.cjs.map +1 -0
- package/dist/env-types.d.mts +11 -0
- package/dist/env-types.d.ts +11 -0
- package/dist/env-types.mjs +9 -0
- package/dist/env-types.mjs.map +1 -0
- package/dist/env.cjs +215 -0
- package/dist/env.cjs.map +1 -0
- package/dist/env.d.mts +45 -0
- package/dist/env.d.ts +45 -0
- package/dist/env.mjs +22 -0
- package/dist/env.mjs.map +1 -0
- package/dist/environment/vite.cjs +374 -0
- package/dist/environment/vite.cjs.map +1 -0
- package/dist/environment/vite.d.mts +22 -0
- package/dist/environment/vite.d.ts +22 -0
- package/dist/environment/vite.mjs +10 -0
- package/dist/environment/vite.mjs.map +1 -0
- package/dist/environment.cjs +96 -0
- package/dist/environment.cjs.map +1 -0
- package/dist/environment.d.mts +18 -0
- package/dist/environment.d.ts +18 -0
- package/dist/environment.mjs +14 -0
- package/dist/environment.mjs.map +1 -0
- package/dist/headers.cjs +126 -0
- package/dist/headers.cjs.map +1 -0
- package/dist/headers.d.mts +22 -0
- package/dist/headers.d.ts +22 -0
- package/dist/headers.mjs +12 -0
- package/dist/headers.mjs.map +1 -0
- package/dist/i18n/client.cjs +283 -0
- package/dist/i18n/client.cjs.map +1 -0
- package/dist/i18n/client.d.mts +32 -0
- package/dist/i18n/client.d.ts +32 -0
- package/dist/i18n/client.mjs +121 -0
- package/dist/i18n/client.mjs.map +1 -0
- package/dist/i18n/index.cjs +130 -0
- package/dist/i18n/index.cjs.map +1 -0
- package/dist/i18n/index.d.mts +20 -0
- package/dist/i18n/index.d.ts +20 -0
- package/dist/i18n/index.mjs +22 -0
- package/dist/i18n/index.mjs.map +1 -0
- package/dist/i18n/server.cjs +637 -0
- package/dist/i18n/server.cjs.map +1 -0
- package/dist/i18n/server.d.mts +30 -0
- package/dist/i18n/server.d.ts +30 -0
- package/dist/i18n/server.mjs +32 -0
- package/dist/i18n/server.mjs.map +1 -0
- package/dist/image/server.cjs +477 -0
- package/dist/image/server.cjs.map +1 -0
- package/dist/image/server.d.mts +37 -0
- package/dist/image/server.d.ts +37 -0
- package/dist/image/server.mjs +16 -0
- package/dist/image/server.mjs.map +1 -0
- package/dist/image/sharp.cjs +135 -0
- package/dist/image/sharp.cjs.map +1 -0
- package/dist/image/sharp.d.mts +7 -0
- package/dist/image/sharp.d.ts +7 -0
- package/dist/image/sharp.mjs +75 -0
- package/dist/image/sharp.mjs.map +1 -0
- package/dist/image-config-Duob7wER.d.mts +50 -0
- package/dist/image-config-Duob7wER.d.ts +50 -0
- package/dist/image.cjs +209 -0
- package/dist/image.cjs.map +1 -0
- package/dist/image.d.mts +39 -0
- package/dist/image.d.ts +39 -0
- package/dist/image.mjs +165 -0
- package/dist/image.mjs.map +1 -0
- package/dist/index.cjs +39433 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.mts +451 -0
- package/dist/index.d.ts +451 -0
- package/dist/index.mjs +930 -0
- package/dist/index.mjs.map +1 -0
- package/dist/integration-api-CHT2OKAf.d.mts +93 -0
- package/dist/integration-api-CHT2OKAf.d.ts +93 -0
- package/dist/integration-orm-GQLGU66X.mjs +13 -0
- package/dist/integration-orm-GQLGU66X.mjs.map +1 -0
- package/dist/integrations.cjs +2820 -0
- package/dist/integrations.cjs.map +1 -0
- package/dist/integrations.d.mts +21 -0
- package/dist/integrations.d.ts +21 -0
- package/dist/integrations.mjs +51 -0
- package/dist/integrations.mjs.map +1 -0
- package/dist/internal/build-runtime.cjs +31340 -0
- package/dist/internal/build-runtime.cjs.map +1 -0
- package/dist/internal/build-runtime.d.mts +38 -0
- package/dist/internal/build-runtime.d.ts +38 -0
- package/dist/internal/build-runtime.mjs +73 -0
- package/dist/internal/build-runtime.mjs.map +1 -0
- package/dist/internal/client-runtime.cjs +579 -0
- package/dist/internal/client-runtime.cjs.map +1 -0
- package/dist/internal/client-runtime.d.mts +2 -0
- package/dist/internal/client-runtime.d.ts +2 -0
- package/dist/internal/client-runtime.mjs +12 -0
- package/dist/internal/client-runtime.mjs.map +1 -0
- package/dist/internal/config-runtime.cjs +4172 -0
- package/dist/internal/config-runtime.cjs.map +1 -0
- package/dist/internal/config-runtime.d.mts +38 -0
- package/dist/internal/config-runtime.d.ts +38 -0
- package/dist/internal/config-runtime.mjs +38 -0
- package/dist/internal/config-runtime.mjs.map +1 -0
- package/dist/internal/production-node-env.cjs +65 -0
- package/dist/internal/production-node-env.cjs.map +1 -0
- package/dist/internal/production-node-env.d.mts +12 -0
- package/dist/internal/production-node-env.d.ts +12 -0
- package/dist/internal/production-node-env.mjs +8 -0
- package/dist/internal/production-node-env.mjs.map +1 -0
- package/dist/internal/production-runtime.cjs +1896 -0
- package/dist/internal/production-runtime.cjs.map +1 -0
- package/dist/internal/production-runtime.d.mts +39 -0
- package/dist/internal/production-runtime.d.ts +39 -0
- package/dist/internal/production-runtime.mjs +79 -0
- package/dist/internal/production-runtime.mjs.map +1 -0
- package/dist/layers-VWVDTPUZ.mjs +16 -0
- package/dist/layers-VWVDTPUZ.mjs.map +1 -0
- package/dist/manager-THKFTOFE.mjs +10 -0
- package/dist/manager-THKFTOFE.mjs.map +1 -0
- package/dist/markdown.cjs +299 -0
- package/dist/markdown.cjs.map +1 -0
- package/dist/markdown.d.mts +43 -0
- package/dist/markdown.d.ts +43 -0
- package/dist/markdown.mjs +14 -0
- package/dist/markdown.mjs.map +1 -0
- package/dist/metadata-C9NZxMDW.d.mts +22 -0
- package/dist/metadata-DAXRaOHx.d.ts +22 -0
- package/dist/middleware.cjs +2148 -0
- package/dist/middleware.cjs.map +1 -0
- package/dist/middleware.d.mts +163 -0
- package/dist/middleware.d.ts +163 -0
- package/dist/middleware.mjs +49 -0
- package/dist/middleware.mjs.map +1 -0
- package/dist/navigation-errors-Dvwpzaer.d.mts +13 -0
- package/dist/navigation-errors-Dvwpzaer.d.ts +13 -0
- package/dist/navigation.cjs +1304 -0
- package/dist/navigation.cjs.map +1 -0
- package/dist/navigation.d.mts +14 -0
- package/dist/navigation.d.ts +14 -0
- package/dist/navigation.mjs +33 -0
- package/dist/navigation.mjs.map +1 -0
- package/dist/nitro-KME62MWG.mjs +691 -0
- package/dist/nitro-KME62MWG.mjs.map +1 -0
- package/dist/observability.cjs +186 -0
- package/dist/observability.cjs.map +1 -0
- package/dist/observability.d.mts +335 -0
- package/dist/observability.d.ts +335 -0
- package/dist/observability.mjs +16 -0
- package/dist/observability.mjs.map +1 -0
- package/dist/params-BALtrRim.d.ts +15 -0
- package/dist/params-ry-lxqmy.d.mts +15 -0
- package/dist/plugin-BJDf43dc.d.mts +165 -0
- package/dist/plugin-BJDf43dc.d.ts +165 -0
- package/dist/plugin.cjs +22285 -0
- package/dist/plugin.cjs.map +1 -0
- package/dist/plugin.d.mts +21 -0
- package/dist/plugin.d.ts +21 -0
- package/dist/plugin.mjs +60 -0
- package/dist/plugin.mjs.map +1 -0
- package/dist/production-runtime-C_B79w2P.d.mts +28 -0
- package/dist/production-runtime-DDEM1D2q.d.ts +28 -0
- package/dist/production-runtime-DRkCHUvJ.d.ts +79 -0
- package/dist/production-runtime-flrjp_nC.d.mts +79 -0
- package/dist/query/client.cjs +560 -0
- package/dist/query/client.cjs.map +1 -0
- package/dist/query/client.d.mts +61 -0
- package/dist/query/client.d.ts +61 -0
- package/dist/query/client.mjs +364 -0
- package/dist/query/client.mjs.map +1 -0
- package/dist/query/index.cjs +226 -0
- package/dist/query/index.cjs.map +1 -0
- package/dist/query/index.d.mts +90 -0
- package/dist/query/index.d.ts +90 -0
- package/dist/query/index.mjs +31 -0
- package/dist/query/index.mjs.map +1 -0
- package/dist/query/parsers.cjs +178 -0
- package/dist/query/parsers.cjs.map +1 -0
- package/dist/query/parsers.d.mts +25 -0
- package/dist/query/parsers.d.ts +25 -0
- package/dist/query/parsers.mjs +24 -0
- package/dist/query/parsers.mjs.map +1 -0
- package/dist/query/server.cjs +301 -0
- package/dist/query/server.cjs.map +1 -0
- package/dist/query/server.d.mts +55 -0
- package/dist/query/server.d.ts +55 -0
- package/dist/query/server.mjs +105 -0
- package/dist/query/server.mjs.map +1 -0
- package/dist/request-BrFBuc8G.d.mts +6 -0
- package/dist/request-BslSZIRz.d.ts +6 -0
- package/dist/request.cjs +71 -0
- package/dist/request.cjs.map +1 -0
- package/dist/request.d.mts +2 -0
- package/dist/request.d.ts +2 -0
- package/dist/request.mjs +9 -0
- package/dist/request.mjs.map +1 -0
- package/dist/resolver-C6iecsDV.d.ts +14 -0
- package/dist/resolver-DlOPpjkB.d.mts +14 -0
- package/dist/route-runtime-DoOHzCAD.d.mts +38 -0
- package/dist/route-runtime-DoOHzCAD.d.ts +38 -0
- package/dist/router.cjs +254 -0
- package/dist/router.cjs.map +1 -0
- package/dist/router.d.mts +36 -0
- package/dist/router.d.ts +36 -0
- package/dist/router.mjs +14 -0
- package/dist/router.mjs.map +1 -0
- package/dist/routes.cjs +1213 -0
- package/dist/routes.cjs.map +1 -0
- package/dist/routes.d.mts +224 -0
- package/dist/routes.d.ts +224 -0
- package/dist/routes.mjs +52 -0
- package/dist/routes.mjs.map +1 -0
- package/dist/runtime-B6GvwDS1.d.ts +27 -0
- package/dist/runtime-DeAAZ6gO.d.mts +27 -0
- package/dist/search-client-6OXIBNYQ.mjs +14 -0
- package/dist/search-client-6OXIBNYQ.mjs.map +1 -0
- package/dist/server-action-security.cjs +492 -0
- package/dist/server-action-security.cjs.map +1 -0
- package/dist/server-action-security.d.mts +42 -0
- package/dist/server-action-security.d.ts +42 -0
- package/dist/server-action-security.mjs +29 -0
- package/dist/server-action-security.mjs.map +1 -0
- package/dist/server-fn-client.cjs +180 -0
- package/dist/server-fn-client.cjs.map +1 -0
- package/dist/server-fn-client.d.mts +31 -0
- package/dist/server-fn-client.d.ts +31 -0
- package/dist/server-fn-client.mjs +9 -0
- package/dist/server-fn-client.mjs.map +1 -0
- package/dist/server-fn.cjs +284 -0
- package/dist/server-fn.cjs.map +1 -0
- package/dist/server-fn.d.mts +84 -0
- package/dist/server-fn.d.ts +84 -0
- package/dist/server-fn.mjs +17 -0
- package/dist/server-fn.mjs.map +1 -0
- package/dist/server-plugins.cjs +235 -0
- package/dist/server-plugins.cjs.map +1 -0
- package/dist/server-plugins.d.mts +54 -0
- package/dist/server-plugins.d.ts +54 -0
- package/dist/server-plugins.mjs +18 -0
- package/dist/server-plugins.mjs.map +1 -0
- package/dist/server-query-client.cjs +792 -0
- package/dist/server-query-client.cjs.map +1 -0
- package/dist/server-query-client.d.mts +50 -0
- package/dist/server-query-client.d.ts +50 -0
- package/dist/server-query-client.mjs +23 -0
- package/dist/server-query-client.mjs.map +1 -0
- package/dist/server-query.cjs +804 -0
- package/dist/server-query.cjs.map +1 -0
- package/dist/server-query.d.mts +36 -0
- package/dist/server-query.d.ts +36 -0
- package/dist/server-query.mjs +18 -0
- package/dist/server-query.mjs.map +1 -0
- package/dist/server.cjs +25739 -0
- package/dist/server.cjs.map +1 -0
- package/dist/server.d.mts +47 -0
- package/dist/server.d.ts +47 -0
- package/dist/server.mjs +511 -0
- package/dist/server.mjs.map +1 -0
- package/dist/storage.cjs +515 -0
- package/dist/storage.cjs.map +1 -0
- package/dist/storage.d.mts +52 -0
- package/dist/storage.d.ts +52 -0
- package/dist/storage.mjs +58 -0
- package/dist/storage.mjs.map +1 -0
- package/dist/testing.cjs +1882 -0
- package/dist/testing.cjs.map +1 -0
- package/dist/testing.d.mts +100 -0
- package/dist/testing.d.ts +100 -0
- package/dist/testing.mjs +324 -0
- package/dist/testing.mjs.map +1 -0
- package/dist/types-BH1lhg5G.d.mts +81 -0
- package/dist/types-BH1lhg5G.d.ts +81 -0
- package/dist/types-C9N-nk5R.d.mts +53 -0
- package/dist/types-C9N-nk5R.d.ts +53 -0
- package/dist/types-D1A6-XvH.d.mts +73 -0
- package/dist/types-D1A6-XvH.d.ts +73 -0
- package/dist/utils-DA1yo54_.d.ts +23 -0
- package/dist/utils-DOXXivjL.d.mts +23 -0
- package/dist/vite.cjs +22684 -0
- package/dist/vite.cjs.map +1 -0
- package/dist/vite.d.mts +21 -0
- package/dist/vite.d.ts +21 -0
- package/dist/vite.mjs +59 -0
- package/dist/vite.mjs.map +1 -0
- package/dist/workflows.cjs +586 -0
- package/dist/workflows.cjs.map +1 -0
- package/dist/workflows.d.mts +110 -0
- package/dist/workflows.d.ts +110 -0
- package/dist/workflows.mjs +32 -0
- package/dist/workflows.mjs.map +1 -0
- package/package.json +523 -0
- package/types/api.d.ts +88 -0
- package/types/client.d.ts +1171 -0
- package/types/index.d.ts +17 -0
- package/types/middleware.d.ts +266 -0
package/dist/client.cjs
ADDED
|
@@ -0,0 +1,4571 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
9
|
+
var __export = (target, all) => {
|
|
10
|
+
for (var name in all)
|
|
11
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
12
|
+
};
|
|
13
|
+
var __copyProps = (to, from, except, desc) => {
|
|
14
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
15
|
+
for (let key of __getOwnPropNames(from))
|
|
16
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
17
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
18
|
+
}
|
|
19
|
+
return to;
|
|
20
|
+
};
|
|
21
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
22
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
23
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
24
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
25
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
26
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
27
|
+
mod
|
|
28
|
+
));
|
|
29
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
30
|
+
|
|
31
|
+
// src/client.ts
|
|
32
|
+
var client_exports = {};
|
|
33
|
+
__export(client_exports, {
|
|
34
|
+
FarmClientPluginManager: () => FarmClientPluginManager,
|
|
35
|
+
IntegrationClientError: () => IntegrationClientError,
|
|
36
|
+
Link: () => Link,
|
|
37
|
+
SPARouter: () => SPARouter,
|
|
38
|
+
api: () => api,
|
|
39
|
+
createAPIClient: () => createAPIClient,
|
|
40
|
+
createClientPluginManager: () => createClientPluginManager,
|
|
41
|
+
createIntegrationApi: () => createIntegrationApi,
|
|
42
|
+
createIntegrationClient: () => createIntegrationClient,
|
|
43
|
+
createIntegrationClients: () => createIntegrationClients,
|
|
44
|
+
createIntegrationServerClient: () => createIntegrationServerClient,
|
|
45
|
+
createIntegrations: () => createIntegrations,
|
|
46
|
+
createServerAPIClient: () => createServerAPIClient,
|
|
47
|
+
createStore: () => createStore,
|
|
48
|
+
defineIntegrationAPI: () => defineIntegrationAPI,
|
|
49
|
+
defineIntegrationAPIOperation: () => defineIntegrationAPIOperation,
|
|
50
|
+
endpoint: () => endpoint,
|
|
51
|
+
fetchServerQuery: () => fetchServerQuery,
|
|
52
|
+
getIntegrationAPIManifest: () => getIntegrationAPIManifest,
|
|
53
|
+
getRouter: () => getRouter2,
|
|
54
|
+
installChunkErrorRecovery: () => installChunkErrorRecovery,
|
|
55
|
+
integrationClients: () => integrationClients,
|
|
56
|
+
integrationsClient: () => integrationsClient,
|
|
57
|
+
integrationsServer: () => integrationsServer,
|
|
58
|
+
isChunkLoadError: () => isChunkLoadError,
|
|
59
|
+
navigateTo: () => navigateTo,
|
|
60
|
+
prefetch: () => prefetch,
|
|
61
|
+
prefetchServerQuery: () => prefetchServerQuery,
|
|
62
|
+
pushState: () => pushState,
|
|
63
|
+
readPageState: () => readPageState,
|
|
64
|
+
replaceState: () => replaceState,
|
|
65
|
+
useBlocker: () => useBlocker,
|
|
66
|
+
useNavigation: () => useNavigation,
|
|
67
|
+
usePageState: () => usePageState,
|
|
68
|
+
useRouter: () => useRouter,
|
|
69
|
+
useScrollRestoration: () => useScrollRestoration,
|
|
70
|
+
useServerQuery: () => useServerQuery
|
|
71
|
+
});
|
|
72
|
+
module.exports = __toCommonJS(client_exports);
|
|
73
|
+
|
|
74
|
+
// src/integration-client.ts
|
|
75
|
+
var _IntegrationClientError = class _IntegrationClientError extends Error {
|
|
76
|
+
constructor(message, response, data) {
|
|
77
|
+
super(message);
|
|
78
|
+
this.name = "IntegrationClientError";
|
|
79
|
+
this.status = response.status;
|
|
80
|
+
this.response = response;
|
|
81
|
+
this.data = data;
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
__name(_IntegrationClientError, "IntegrationClientError");
|
|
85
|
+
var IntegrationClientError = _IntegrationClientError;
|
|
86
|
+
var INTEGRATION_RUNTIME_REGISTRY_KEY = /* @__PURE__ */ Symbol.for("farm.integrationRuntimeRegistry");
|
|
87
|
+
var CURRENT_REQUEST_RESOLVER_KEY = /* @__PURE__ */ Symbol.for("farm.currentRequestResolver");
|
|
88
|
+
var INTEGRATION_REQUEST_DISPATCHER_KEY = /* @__PURE__ */ Symbol.for("farm.integrationRequestDispatcher");
|
|
89
|
+
function isOperation(value) {
|
|
90
|
+
return !!value && typeof value === "object" && value.kind === "farm-integration-api-operation";
|
|
91
|
+
}
|
|
92
|
+
__name(isOperation, "isOperation");
|
|
93
|
+
function tryResolveSourceAPI(source) {
|
|
94
|
+
if ("kind" in source && source.kind === "farm-integration") {
|
|
95
|
+
if (!source.api) {
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
return source.api;
|
|
99
|
+
}
|
|
100
|
+
return source;
|
|
101
|
+
}
|
|
102
|
+
__name(tryResolveSourceAPI, "tryResolveSourceAPI");
|
|
103
|
+
function getIntegrationRuntimeRegistry() {
|
|
104
|
+
const globalState2 = globalThis;
|
|
105
|
+
return globalState2[INTEGRATION_RUNTIME_REGISTRY_KEY] || /* @__PURE__ */ new Map();
|
|
106
|
+
}
|
|
107
|
+
__name(getIntegrationRuntimeRegistry, "getIntegrationRuntimeRegistry");
|
|
108
|
+
function getRegisteredIntegrationRuntimeLocal(key) {
|
|
109
|
+
return getIntegrationRuntimeRegistry().get(key);
|
|
110
|
+
}
|
|
111
|
+
__name(getRegisteredIntegrationRuntimeLocal, "getRegisteredIntegrationRuntimeLocal");
|
|
112
|
+
function getRegisteredIntegrationsLocal() {
|
|
113
|
+
return Object.fromEntries(
|
|
114
|
+
Array.from(getIntegrationRuntimeRegistry().entries()).map(([key, runtime]) => [
|
|
115
|
+
key,
|
|
116
|
+
runtime.integration
|
|
117
|
+
])
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
__name(getRegisteredIntegrationsLocal, "getRegisteredIntegrationsLocal");
|
|
121
|
+
function resolveCurrentRequestLocal() {
|
|
122
|
+
const globalState2 = globalThis;
|
|
123
|
+
return globalState2[CURRENT_REQUEST_RESOLVER_KEY]?.();
|
|
124
|
+
}
|
|
125
|
+
__name(resolveCurrentRequestLocal, "resolveCurrentRequestLocal");
|
|
126
|
+
function resolveIntegrationRequestDispatcherLocal() {
|
|
127
|
+
const globalState2 = globalThis;
|
|
128
|
+
return globalState2[INTEGRATION_REQUEST_DISPATCHER_KEY];
|
|
129
|
+
}
|
|
130
|
+
__name(resolveIntegrationRequestDispatcherLocal, "resolveIntegrationRequestDispatcherLocal");
|
|
131
|
+
var INTEGRATION_DATA_HEADER = "x-farm-integration-data";
|
|
132
|
+
var INTEGRATION_DATA_HEADER_MAX_LENGTH = 16 * 1024;
|
|
133
|
+
var BLOCKED_INTEGRATION_DATA_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
|
|
134
|
+
function isIntegrationClientData(value) {
|
|
135
|
+
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
136
|
+
}
|
|
137
|
+
__name(isIntegrationClientData, "isIntegrationClientData");
|
|
138
|
+
function isPlainIntegrationDataObject(value) {
|
|
139
|
+
if (!isIntegrationClientData(value)) {
|
|
140
|
+
return false;
|
|
141
|
+
}
|
|
142
|
+
const prototype = Object.getPrototypeOf(value);
|
|
143
|
+
return prototype === Object.prototype || prototype === null;
|
|
144
|
+
}
|
|
145
|
+
__name(isPlainIntegrationDataObject, "isPlainIntegrationDataObject");
|
|
146
|
+
function sanitizeIntegrationClientDataValue(value) {
|
|
147
|
+
if (Array.isArray(value)) {
|
|
148
|
+
return value.map((item) => sanitizeIntegrationClientDataValue(item));
|
|
149
|
+
}
|
|
150
|
+
if (!isPlainIntegrationDataObject(value)) {
|
|
151
|
+
return value;
|
|
152
|
+
}
|
|
153
|
+
const sanitized = {};
|
|
154
|
+
for (const [key, item] of Object.entries(value)) {
|
|
155
|
+
if (BLOCKED_INTEGRATION_DATA_KEYS.has(key)) {
|
|
156
|
+
continue;
|
|
157
|
+
}
|
|
158
|
+
sanitized[key] = sanitizeIntegrationClientDataValue(item);
|
|
159
|
+
}
|
|
160
|
+
return sanitized;
|
|
161
|
+
}
|
|
162
|
+
__name(sanitizeIntegrationClientDataValue, "sanitizeIntegrationClientDataValue");
|
|
163
|
+
function normalizeIntegrationClientData(value) {
|
|
164
|
+
if (!isIntegrationClientData(value)) {
|
|
165
|
+
return void 0;
|
|
166
|
+
}
|
|
167
|
+
const sanitized = sanitizeIntegrationClientDataValue(value);
|
|
168
|
+
return isIntegrationClientData(sanitized) && Object.keys(sanitized).length > 0 ? sanitized : void 0;
|
|
169
|
+
}
|
|
170
|
+
__name(normalizeIntegrationClientData, "normalizeIntegrationClientData");
|
|
171
|
+
function getIntegrationDataHeaderByteLength(value) {
|
|
172
|
+
return new TextEncoder().encode(value).byteLength;
|
|
173
|
+
}
|
|
174
|
+
__name(getIntegrationDataHeaderByteLength, "getIntegrationDataHeaderByteLength");
|
|
175
|
+
function mergeIntegrationClientData(...values) {
|
|
176
|
+
let merged;
|
|
177
|
+
for (const value of values) {
|
|
178
|
+
const data = normalizeIntegrationClientData(value);
|
|
179
|
+
if (!data) {
|
|
180
|
+
continue;
|
|
181
|
+
}
|
|
182
|
+
merged = {
|
|
183
|
+
...merged || {},
|
|
184
|
+
...data
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
return merged && Object.keys(merged).length > 0 ? merged : void 0;
|
|
188
|
+
}
|
|
189
|
+
__name(mergeIntegrationClientData, "mergeIntegrationClientData");
|
|
190
|
+
function serializeIntegrationClientData(data) {
|
|
191
|
+
const serialized = JSON.stringify(data);
|
|
192
|
+
if (getIntegrationDataHeaderByteLength(serialized) > INTEGRATION_DATA_HEADER_MAX_LENGTH) {
|
|
193
|
+
throw new Error(
|
|
194
|
+
`Integration client data must be smaller than ${INTEGRATION_DATA_HEADER_MAX_LENGTH} bytes when sent over HTTP headers.`
|
|
195
|
+
);
|
|
196
|
+
}
|
|
197
|
+
return serialized;
|
|
198
|
+
}
|
|
199
|
+
__name(serializeIntegrationClientData, "serializeIntegrationClientData");
|
|
200
|
+
function appendIntegrationClientDataHeader(headers, data) {
|
|
201
|
+
if (!data) {
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
headers.set(INTEGRATION_DATA_HEADER, serializeIntegrationClientData(data));
|
|
205
|
+
}
|
|
206
|
+
__name(appendIntegrationClientDataHeader, "appendIntegrationClientDataHeader");
|
|
207
|
+
function resolveAutomaticClientNamespaces() {
|
|
208
|
+
const globalState2 = globalThis;
|
|
209
|
+
const manifest = globalState2.window?.__FARM_INTEGRATION_API_MANIFEST__ || globalState2.__FARM_INTEGRATION_API_MANIFEST__ || {};
|
|
210
|
+
return Object.entries(manifest).map(([key, api2]) => [key, api2, api2]);
|
|
211
|
+
}
|
|
212
|
+
__name(resolveAutomaticClientNamespaces, "resolveAutomaticClientNamespaces");
|
|
213
|
+
function resolveAutomaticServerNamespaces() {
|
|
214
|
+
return Object.entries(getRegisteredIntegrationsLocal()).flatMap(([key, source]) => {
|
|
215
|
+
const api2 = tryResolveSourceAPI(source);
|
|
216
|
+
return api2 ? [[key, api2, source]] : [];
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
__name(resolveAutomaticServerNamespaces, "resolveAutomaticServerNamespaces");
|
|
220
|
+
function appendQuery(url, query) {
|
|
221
|
+
if (!query) {
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
for (const [key, value] of Object.entries(query)) {
|
|
225
|
+
if (value == null) {
|
|
226
|
+
continue;
|
|
227
|
+
}
|
|
228
|
+
if (Array.isArray(value)) {
|
|
229
|
+
for (const item of value) {
|
|
230
|
+
if (item != null) {
|
|
231
|
+
url.searchParams.append(key, String(item));
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
continue;
|
|
235
|
+
}
|
|
236
|
+
url.searchParams.set(key, String(value));
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
__name(appendQuery, "appendQuery");
|
|
240
|
+
function appendHeaders(target, source) {
|
|
241
|
+
if (!source) {
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
const headers = new Headers(source);
|
|
245
|
+
headers.forEach((value, key) => {
|
|
246
|
+
target.set(key, value);
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
__name(appendHeaders, "appendHeaders");
|
|
250
|
+
var DEFAULT_FORWARDED_HEADERS = [
|
|
251
|
+
"authorization",
|
|
252
|
+
"cookie",
|
|
253
|
+
"x-client-ip",
|
|
254
|
+
"x-forwarded-for",
|
|
255
|
+
"x-forwarded-host",
|
|
256
|
+
"x-forwarded-proto",
|
|
257
|
+
"x-real-ip"
|
|
258
|
+
];
|
|
259
|
+
function resolveRequestLike(request) {
|
|
260
|
+
if (!request) {
|
|
261
|
+
return void 0;
|
|
262
|
+
}
|
|
263
|
+
if (request instanceof Request) {
|
|
264
|
+
return {
|
|
265
|
+
url: request.url,
|
|
266
|
+
headers: request.headers
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
return {
|
|
270
|
+
url: request.url,
|
|
271
|
+
headers: request.headers ? new Headers(request.headers) : void 0
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
__name(resolveRequestLike, "resolveRequestLike");
|
|
275
|
+
function resolveServerBaseURL(explicitBaseURL, request) {
|
|
276
|
+
if (explicitBaseURL) {
|
|
277
|
+
return explicitBaseURL;
|
|
278
|
+
}
|
|
279
|
+
if (request?.url) {
|
|
280
|
+
try {
|
|
281
|
+
return new URL(request.url).origin;
|
|
282
|
+
} catch {
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
const headers = request?.headers;
|
|
286
|
+
const host = headers?.get("x-forwarded-host") || headers?.get("host");
|
|
287
|
+
if (host) {
|
|
288
|
+
const proto = headers?.get("x-forwarded-proto") || "http";
|
|
289
|
+
return `${proto}://${host}`;
|
|
290
|
+
}
|
|
291
|
+
return "http://localhost:3000";
|
|
292
|
+
}
|
|
293
|
+
__name(resolveServerBaseURL, "resolveServerBaseURL");
|
|
294
|
+
function resolveForwardHeaders(request, forwardHeaders) {
|
|
295
|
+
if (!request?.headers || forwardHeaders === false) {
|
|
296
|
+
return new Headers();
|
|
297
|
+
}
|
|
298
|
+
const allowed = Array.isArray(forwardHeaders) && forwardHeaders.length > 0 ? new Set(forwardHeaders.map((item) => item.toLowerCase())) : new Set(DEFAULT_FORWARDED_HEADERS);
|
|
299
|
+
const headers = new Headers();
|
|
300
|
+
request.headers.forEach((value, key) => {
|
|
301
|
+
if (allowed.has(key.toLowerCase())) {
|
|
302
|
+
headers.set(key, value);
|
|
303
|
+
}
|
|
304
|
+
});
|
|
305
|
+
return headers;
|
|
306
|
+
}
|
|
307
|
+
__name(resolveForwardHeaders, "resolveForwardHeaders");
|
|
308
|
+
function createBody(format, body, headers) {
|
|
309
|
+
if (body == null || format === "none") {
|
|
310
|
+
return void 0;
|
|
311
|
+
}
|
|
312
|
+
if (format === "form") {
|
|
313
|
+
if (body instanceof FormData || body instanceof URLSearchParams) {
|
|
314
|
+
return body;
|
|
315
|
+
}
|
|
316
|
+
const form = new URLSearchParams();
|
|
317
|
+
for (const [key, value] of Object.entries(body)) {
|
|
318
|
+
if (value == null) {
|
|
319
|
+
continue;
|
|
320
|
+
}
|
|
321
|
+
if (Array.isArray(value)) {
|
|
322
|
+
for (const item of value) {
|
|
323
|
+
if (item != null) {
|
|
324
|
+
form.append(key, String(item));
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
continue;
|
|
328
|
+
}
|
|
329
|
+
form.set(key, String(value));
|
|
330
|
+
}
|
|
331
|
+
headers.set("content-type", "application/x-www-form-urlencoded;charset=UTF-8");
|
|
332
|
+
return form;
|
|
333
|
+
}
|
|
334
|
+
headers.set("content-type", "application/json");
|
|
335
|
+
return JSON.stringify(body);
|
|
336
|
+
}
|
|
337
|
+
__name(createBody, "createBody");
|
|
338
|
+
async function parseResponseData(response) {
|
|
339
|
+
if (response.status === 204 || response.status === 205) {
|
|
340
|
+
return void 0;
|
|
341
|
+
}
|
|
342
|
+
const contentType = response.headers.get("content-type") || "";
|
|
343
|
+
if (contentType.includes("application/json")) {
|
|
344
|
+
return await response.json();
|
|
345
|
+
}
|
|
346
|
+
return await response.text();
|
|
347
|
+
}
|
|
348
|
+
__name(parseResponseData, "parseResponseData");
|
|
349
|
+
async function safeParseResponseData(response) {
|
|
350
|
+
try {
|
|
351
|
+
return await parseResponseData(response);
|
|
352
|
+
} catch {
|
|
353
|
+
return void 0;
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
__name(safeParseResponseData, "safeParseResponseData");
|
|
357
|
+
function createResponseError(response, errorData) {
|
|
358
|
+
const message = typeof errorData === "string" ? errorData : typeof errorData === "object" && errorData ? String(
|
|
359
|
+
errorData.error || errorData.message || response.statusText
|
|
360
|
+
) : response.statusText || "Integration request failed.";
|
|
361
|
+
return new IntegrationClientError(message, response, errorData);
|
|
362
|
+
}
|
|
363
|
+
__name(createResponseError, "createResponseError");
|
|
364
|
+
function normalizeExecutionError(error) {
|
|
365
|
+
if (error instanceof Error) {
|
|
366
|
+
return error;
|
|
367
|
+
}
|
|
368
|
+
if (typeof error === "string" && error.length > 0) {
|
|
369
|
+
return new Error(error);
|
|
370
|
+
}
|
|
371
|
+
return new Error("Integration request failed.");
|
|
372
|
+
}
|
|
373
|
+
__name(normalizeExecutionError, "normalizeExecutionError");
|
|
374
|
+
async function finalizeOperationResponse(operation2, response) {
|
|
375
|
+
if (!response.ok) {
|
|
376
|
+
const errorData = await safeParseResponseData(response);
|
|
377
|
+
return {
|
|
378
|
+
data: null,
|
|
379
|
+
error: createResponseError(response, errorData)
|
|
380
|
+
};
|
|
381
|
+
}
|
|
382
|
+
if (operation2.responseFormat === "response") {
|
|
383
|
+
return {
|
|
384
|
+
data: response,
|
|
385
|
+
error: null
|
|
386
|
+
};
|
|
387
|
+
}
|
|
388
|
+
return {
|
|
389
|
+
data: await parseResponseData(response),
|
|
390
|
+
error: null
|
|
391
|
+
};
|
|
392
|
+
}
|
|
393
|
+
__name(finalizeOperationResponse, "finalizeOperationResponse");
|
|
394
|
+
async function executeClientOperation(operation2, input, options, requestOptions) {
|
|
395
|
+
try {
|
|
396
|
+
if (!operation2.path) {
|
|
397
|
+
return {
|
|
398
|
+
data: null,
|
|
399
|
+
error: new Error(
|
|
400
|
+
"Integration API operation path is missing. Pass a path to api.get/post/... or wrap pathless methods with api.route(path, { ... })."
|
|
401
|
+
)
|
|
402
|
+
};
|
|
403
|
+
}
|
|
404
|
+
const baseURL = options.baseURL || (typeof window !== "undefined" ? window.location.origin : "http://localhost:3000");
|
|
405
|
+
const url = new URL(operation2.path, baseURL);
|
|
406
|
+
appendQuery(url, input.query);
|
|
407
|
+
const headers = new Headers({
|
|
408
|
+
"x-farm-integration-client": "1",
|
|
409
|
+
...options.headers,
|
|
410
|
+
...operation2.headers,
|
|
411
|
+
...requestOptions?.headers
|
|
412
|
+
});
|
|
413
|
+
if (operation2.responseFormat !== "response") {
|
|
414
|
+
headers.set("accept", "application/json");
|
|
415
|
+
}
|
|
416
|
+
appendIntegrationClientDataHeader(
|
|
417
|
+
headers,
|
|
418
|
+
mergeIntegrationClientData(options.data, requestOptions?.data)
|
|
419
|
+
);
|
|
420
|
+
const response = await fetch(url.toString(), {
|
|
421
|
+
method: operation2.method,
|
|
422
|
+
headers,
|
|
423
|
+
body: createBody(operation2.bodyFormat, input.body, headers),
|
|
424
|
+
credentials: requestOptions?.credentials ?? operation2.credentials ?? options.credentials ?? "include",
|
|
425
|
+
signal: requestOptions?.signal
|
|
426
|
+
});
|
|
427
|
+
if (!response.ok) {
|
|
428
|
+
const errorData = await safeParseResponseData(response);
|
|
429
|
+
return {
|
|
430
|
+
data: null,
|
|
431
|
+
error: createResponseError(response, errorData)
|
|
432
|
+
};
|
|
433
|
+
}
|
|
434
|
+
if (operation2.responseFormat === "response") {
|
|
435
|
+
return {
|
|
436
|
+
data: response,
|
|
437
|
+
error: null
|
|
438
|
+
};
|
|
439
|
+
}
|
|
440
|
+
return {
|
|
441
|
+
data: await parseResponseData(response),
|
|
442
|
+
error: null
|
|
443
|
+
};
|
|
444
|
+
} catch (error) {
|
|
445
|
+
return {
|
|
446
|
+
data: null,
|
|
447
|
+
error: normalizeExecutionError(error)
|
|
448
|
+
};
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
__name(executeClientOperation, "executeClientOperation");
|
|
452
|
+
async function executeServerOperation(operation2, input, options, requestOptions, integrationKey, source) {
|
|
453
|
+
try {
|
|
454
|
+
if (!operation2.path) {
|
|
455
|
+
return {
|
|
456
|
+
data: null,
|
|
457
|
+
error: new Error(
|
|
458
|
+
"Integration API operation path is missing. Pass a path to api.get/post/... or wrap pathless methods with api.route(path, { ... })."
|
|
459
|
+
)
|
|
460
|
+
};
|
|
461
|
+
}
|
|
462
|
+
const serverRequestOptions = requestOptions && ("request" in requestOptions || "baseURL" in requestOptions || "forwardHeaders" in requestOptions) ? requestOptions : void 0;
|
|
463
|
+
const currentRequest = serverRequestOptions?.request instanceof Request ? serverRequestOptions.request : options.request instanceof Request ? options.request : resolveCurrentRequestLocal();
|
|
464
|
+
const request = resolveRequestLike(
|
|
465
|
+
serverRequestOptions?.request ?? options.request ?? currentRequest
|
|
466
|
+
);
|
|
467
|
+
const baseURL = resolveServerBaseURL(serverRequestOptions?.baseURL ?? options.baseURL, request);
|
|
468
|
+
const url = new URL(operation2.path, baseURL);
|
|
469
|
+
appendQuery(url, input.query);
|
|
470
|
+
const headers = new Headers();
|
|
471
|
+
appendHeaders(
|
|
472
|
+
headers,
|
|
473
|
+
resolveForwardHeaders(
|
|
474
|
+
request,
|
|
475
|
+
serverRequestOptions?.forwardHeaders ?? options.forwardHeaders
|
|
476
|
+
)
|
|
477
|
+
);
|
|
478
|
+
appendHeaders(headers, options.headers);
|
|
479
|
+
appendHeaders(headers, operation2.headers);
|
|
480
|
+
appendHeaders(headers, requestOptions?.headers);
|
|
481
|
+
headers.set("x-farm-integration-client", "1");
|
|
482
|
+
if (operation2.responseFormat !== "response") {
|
|
483
|
+
headers.set("accept", "application/json");
|
|
484
|
+
}
|
|
485
|
+
const data = mergeIntegrationClientData(options.data, requestOptions?.data);
|
|
486
|
+
if (integrationKey) {
|
|
487
|
+
const runtime = "kind" in (source || {}) && source.kind === "farm-integration" ? getRegisteredIntegrationRuntimeLocal(integrationKey) || {
|
|
488
|
+
integration: source,
|
|
489
|
+
config: {},
|
|
490
|
+
isDev: process.env.NODE_ENV !== "production",
|
|
491
|
+
isProd: process.env.NODE_ENV === "production"
|
|
492
|
+
} : getRegisteredIntegrationRuntimeLocal(integrationKey);
|
|
493
|
+
if (runtime) {
|
|
494
|
+
const dispatchIntegrationRequest = resolveIntegrationRequestDispatcherLocal();
|
|
495
|
+
const directResponse = dispatchIntegrationRequest ? await dispatchIntegrationRequest(
|
|
496
|
+
runtime,
|
|
497
|
+
new Request(url.toString(), {
|
|
498
|
+
method: operation2.method,
|
|
499
|
+
headers,
|
|
500
|
+
body: createBody(operation2.bodyFormat, input.body, headers)
|
|
501
|
+
}),
|
|
502
|
+
{
|
|
503
|
+
currentRequest,
|
|
504
|
+
data,
|
|
505
|
+
internal: true
|
|
506
|
+
}
|
|
507
|
+
) : null;
|
|
508
|
+
if (directResponse) {
|
|
509
|
+
return await finalizeOperationResponse(operation2, directResponse);
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
appendIntegrationClientDataHeader(headers, data);
|
|
514
|
+
const response = await fetch(url.toString(), {
|
|
515
|
+
method: operation2.method,
|
|
516
|
+
headers,
|
|
517
|
+
body: createBody(operation2.bodyFormat, input.body, headers),
|
|
518
|
+
credentials: requestOptions?.credentials ?? operation2.credentials ?? options.credentials ?? "include",
|
|
519
|
+
signal: requestOptions?.signal
|
|
520
|
+
});
|
|
521
|
+
return await finalizeOperationResponse(operation2, response);
|
|
522
|
+
} catch (error) {
|
|
523
|
+
return {
|
|
524
|
+
data: null,
|
|
525
|
+
error: normalizeExecutionError(error)
|
|
526
|
+
};
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
__name(executeServerOperation, "executeServerOperation");
|
|
530
|
+
function createIntegrationClient(sources, options = {}) {
|
|
531
|
+
const rawSources = "integrations" in sources ? sources.integrations : sources;
|
|
532
|
+
const isServer = options.isServer === true;
|
|
533
|
+
const namespaces = Object.entries(rawSources).map(([key, source]) => {
|
|
534
|
+
const api2 = tryResolveSourceAPI(source);
|
|
535
|
+
if (!api2) {
|
|
536
|
+
return null;
|
|
537
|
+
}
|
|
538
|
+
return [key, api2, source];
|
|
539
|
+
}).filter(
|
|
540
|
+
(value) => value !== null
|
|
541
|
+
);
|
|
542
|
+
const cache = /* @__PURE__ */ new Map();
|
|
543
|
+
const integrationNamespaces = new Proxy(
|
|
544
|
+
{},
|
|
545
|
+
{
|
|
546
|
+
get(target, property) {
|
|
547
|
+
if (typeof property !== "string") {
|
|
548
|
+
return void 0;
|
|
549
|
+
}
|
|
550
|
+
if (Reflect.has(target, property)) {
|
|
551
|
+
return Reflect.get(target, property);
|
|
552
|
+
}
|
|
553
|
+
if (cache.has(property)) {
|
|
554
|
+
return cache.get(property);
|
|
555
|
+
}
|
|
556
|
+
const match = namespaces.find(([key]) => key === property);
|
|
557
|
+
if (!match) {
|
|
558
|
+
return void 0;
|
|
559
|
+
}
|
|
560
|
+
const namespace = isServer ? createServerNamespaceProxy(
|
|
561
|
+
match[0],
|
|
562
|
+
match[2],
|
|
563
|
+
match[1],
|
|
564
|
+
options
|
|
565
|
+
) : createNamespaceProxy(match[1], options);
|
|
566
|
+
cache.set(property, namespace);
|
|
567
|
+
return namespace;
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
);
|
|
571
|
+
if ("integrations" in sources) {
|
|
572
|
+
Object.defineProperty(integrationNamespaces, "integrations", {
|
|
573
|
+
value: integrationNamespaces,
|
|
574
|
+
enumerable: false,
|
|
575
|
+
configurable: false,
|
|
576
|
+
writable: false
|
|
577
|
+
});
|
|
578
|
+
return integrationNamespaces;
|
|
579
|
+
}
|
|
580
|
+
return integrationNamespaces;
|
|
581
|
+
}
|
|
582
|
+
__name(createIntegrationClient, "createIntegrationClient");
|
|
583
|
+
function createAutomaticIntegrationAliases(isServer, options = {}) {
|
|
584
|
+
const cache = isServer ? /* @__PURE__ */ new Map() : null;
|
|
585
|
+
const integrationNamespaces = new Proxy(
|
|
586
|
+
{},
|
|
587
|
+
{
|
|
588
|
+
get(_target, property) {
|
|
589
|
+
if (typeof property !== "string") {
|
|
590
|
+
return void 0;
|
|
591
|
+
}
|
|
592
|
+
if (property === "integrations") {
|
|
593
|
+
return integrationNamespaces;
|
|
594
|
+
}
|
|
595
|
+
if (cache?.has(property)) {
|
|
596
|
+
return cache.get(property);
|
|
597
|
+
}
|
|
598
|
+
const namespaces = isServer ? resolveAutomaticServerNamespaces() : resolveAutomaticClientNamespaces();
|
|
599
|
+
const match = namespaces.find(([key]) => key === property);
|
|
600
|
+
if (!match) {
|
|
601
|
+
return void 0;
|
|
602
|
+
}
|
|
603
|
+
const namespace = isServer ? createServerNamespaceProxy(
|
|
604
|
+
match[0],
|
|
605
|
+
match[2],
|
|
606
|
+
match[1],
|
|
607
|
+
options
|
|
608
|
+
) : createNamespaceProxy(match[1], options);
|
|
609
|
+
cache?.set(property, namespace);
|
|
610
|
+
return namespace;
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
);
|
|
614
|
+
Object.defineProperty(integrationNamespaces, "integrations", {
|
|
615
|
+
value: integrationNamespaces,
|
|
616
|
+
enumerable: false,
|
|
617
|
+
configurable: false,
|
|
618
|
+
writable: false
|
|
619
|
+
});
|
|
620
|
+
return integrationNamespaces;
|
|
621
|
+
}
|
|
622
|
+
__name(createAutomaticIntegrationAliases, "createAutomaticIntegrationAliases");
|
|
623
|
+
function integrationsClient(options = {}) {
|
|
624
|
+
return createAutomaticIntegrationAliases(
|
|
625
|
+
false,
|
|
626
|
+
options
|
|
627
|
+
);
|
|
628
|
+
}
|
|
629
|
+
__name(integrationsClient, "integrationsClient");
|
|
630
|
+
function integrationsServer(options = {}) {
|
|
631
|
+
return createAutomaticIntegrationAliases(true, {
|
|
632
|
+
...options,
|
|
633
|
+
isServer: true
|
|
634
|
+
});
|
|
635
|
+
}
|
|
636
|
+
__name(integrationsServer, "integrationsServer");
|
|
637
|
+
function createIntegrationServerClient(sources, options = {}) {
|
|
638
|
+
return createIntegrationClient(sources, {
|
|
639
|
+
...options,
|
|
640
|
+
isServer: true
|
|
641
|
+
});
|
|
642
|
+
}
|
|
643
|
+
__name(createIntegrationServerClient, "createIntegrationServerClient");
|
|
644
|
+
function createIntegrationApi(sources, options = {}) {
|
|
645
|
+
const client = createIntegrationClient(sources, options);
|
|
646
|
+
return {
|
|
647
|
+
...client,
|
|
648
|
+
server(serverOptions = {}) {
|
|
649
|
+
return createIntegrationServerClient(sources, {
|
|
650
|
+
...options,
|
|
651
|
+
...serverOptions
|
|
652
|
+
});
|
|
653
|
+
}
|
|
654
|
+
};
|
|
655
|
+
}
|
|
656
|
+
__name(createIntegrationApi, "createIntegrationApi");
|
|
657
|
+
function isIntegrationClientOptionsInput(value) {
|
|
658
|
+
return !!value && typeof value === "object" && !Array.isArray(value) && ("baseURL" in value || "headers" in value || "credentials" in value || "data" in value || "isServer" in value);
|
|
659
|
+
}
|
|
660
|
+
__name(isIntegrationClientOptionsInput, "isIntegrationClientOptionsInput");
|
|
661
|
+
function resolveIntegrationServerOptions(clientOptions = {}, serverOptions = {}) {
|
|
662
|
+
const data = mergeIntegrationClientData(clientOptions.data, serverOptions.data);
|
|
663
|
+
return {
|
|
664
|
+
baseURL: clientOptions.baseURL,
|
|
665
|
+
headers: clientOptions.headers,
|
|
666
|
+
credentials: clientOptions.credentials,
|
|
667
|
+
...serverOptions,
|
|
668
|
+
...data ? { data } : {}
|
|
669
|
+
};
|
|
670
|
+
}
|
|
671
|
+
__name(resolveIntegrationServerOptions, "resolveIntegrationServerOptions");
|
|
672
|
+
function createIntegrationClients(sources, clientOptions, serverOptions) {
|
|
673
|
+
if (arguments.length === 0 || isIntegrationClientOptionsInput(sources)) {
|
|
674
|
+
const automaticClientOptions = isIntegrationClientOptionsInput(sources) ? sources : {};
|
|
675
|
+
const automaticServerOptions = arguments.length > 1 ? clientOptions : void 0;
|
|
676
|
+
return {
|
|
677
|
+
api: integrationsServer(
|
|
678
|
+
resolveIntegrationServerOptions(
|
|
679
|
+
automaticClientOptions,
|
|
680
|
+
automaticServerOptions
|
|
681
|
+
)
|
|
682
|
+
),
|
|
683
|
+
apiClient: integrationsClient(automaticClientOptions)
|
|
684
|
+
};
|
|
685
|
+
}
|
|
686
|
+
const explicitSources = sources && "integrations" in sources ? sources.integrations : sources;
|
|
687
|
+
return {
|
|
688
|
+
api: createIntegrationServerClient(
|
|
689
|
+
{
|
|
690
|
+
integrations: explicitSources
|
|
691
|
+
},
|
|
692
|
+
resolveIntegrationServerOptions(clientOptions, serverOptions)
|
|
693
|
+
),
|
|
694
|
+
apiClient: createIntegrationClient(
|
|
695
|
+
{
|
|
696
|
+
integrations: explicitSources
|
|
697
|
+
},
|
|
698
|
+
clientOptions
|
|
699
|
+
)
|
|
700
|
+
};
|
|
701
|
+
}
|
|
702
|
+
__name(createIntegrationClients, "createIntegrationClients");
|
|
703
|
+
function createIntegrations(sources, clientOptions, serverOptions) {
|
|
704
|
+
if (arguments.length === 0) {
|
|
705
|
+
return createIntegrationClients();
|
|
706
|
+
}
|
|
707
|
+
return createIntegrationClients(
|
|
708
|
+
sources,
|
|
709
|
+
clientOptions,
|
|
710
|
+
serverOptions
|
|
711
|
+
);
|
|
712
|
+
}
|
|
713
|
+
__name(createIntegrations, "createIntegrations");
|
|
714
|
+
function createClientSafeIntegrationAPI(api2) {
|
|
715
|
+
if (!api2) {
|
|
716
|
+
return void 0;
|
|
717
|
+
}
|
|
718
|
+
const entries = Object.entries(api2).map(([key, value]) => {
|
|
719
|
+
if (isOperation(value)) {
|
|
720
|
+
return [
|
|
721
|
+
key,
|
|
722
|
+
{
|
|
723
|
+
kind: value.kind,
|
|
724
|
+
path: value.path,
|
|
725
|
+
method: value.method,
|
|
726
|
+
bodyFormat: value.bodyFormat,
|
|
727
|
+
responseFormat: value.responseFormat,
|
|
728
|
+
credentials: value.credentials,
|
|
729
|
+
isServer: value.isServer,
|
|
730
|
+
__pathless: value.__pathless
|
|
731
|
+
}
|
|
732
|
+
];
|
|
733
|
+
}
|
|
734
|
+
if (value && typeof value === "object") {
|
|
735
|
+
return [key, createClientSafeIntegrationAPI(value)];
|
|
736
|
+
}
|
|
737
|
+
return [key, value];
|
|
738
|
+
});
|
|
739
|
+
return Object.fromEntries(entries);
|
|
740
|
+
}
|
|
741
|
+
__name(createClientSafeIntegrationAPI, "createClientSafeIntegrationAPI");
|
|
742
|
+
function getIntegrationAPIManifest() {
|
|
743
|
+
const manifestEntries = Object.entries(getRegisteredIntegrationsLocal()).map(([key, integration]) => {
|
|
744
|
+
const api2 = createClientSafeIntegrationAPI(integration.api);
|
|
745
|
+
return api2 ? [key, api2] : null;
|
|
746
|
+
}).filter((value) => value !== null);
|
|
747
|
+
return Object.fromEntries(manifestEntries);
|
|
748
|
+
}
|
|
749
|
+
__name(getIntegrationAPIManifest, "getIntegrationAPIManifest");
|
|
750
|
+
function integrationClients(sources, clientOptions, serverOptions) {
|
|
751
|
+
if (arguments.length === 0) {
|
|
752
|
+
return createIntegrationClients();
|
|
753
|
+
}
|
|
754
|
+
return createIntegrationClients(
|
|
755
|
+
sources,
|
|
756
|
+
clientOptions,
|
|
757
|
+
serverOptions
|
|
758
|
+
);
|
|
759
|
+
}
|
|
760
|
+
__name(integrationClients, "integrationClients");
|
|
761
|
+
function resolveSingleNamespaceOperation(api2) {
|
|
762
|
+
const entries = Object.entries(api2);
|
|
763
|
+
if (entries.length !== 1) {
|
|
764
|
+
return null;
|
|
765
|
+
}
|
|
766
|
+
const [, value] = entries[0];
|
|
767
|
+
return isOperation(value) ? value : null;
|
|
768
|
+
}
|
|
769
|
+
__name(resolveSingleNamespaceOperation, "resolveSingleNamespaceOperation");
|
|
770
|
+
function createClientOperationCaller(operation2, property, options) {
|
|
771
|
+
if (operation2.isServer === true) {
|
|
772
|
+
return async () => {
|
|
773
|
+
throw new Error(
|
|
774
|
+
`Integration method "${property}" is registered with isServer: true and is only available from a server integration client.`
|
|
775
|
+
);
|
|
776
|
+
};
|
|
777
|
+
}
|
|
778
|
+
return async (input = {}, requestOptions) => {
|
|
779
|
+
if (typeof window === "undefined") {
|
|
780
|
+
throw new Error(
|
|
781
|
+
"Client integration API cannot be called on the server. Pass { isServer: true } to createIntegrationClient(...) during server rendering, or provide { isServer: true, request } outside it."
|
|
782
|
+
);
|
|
783
|
+
}
|
|
784
|
+
return executeClientOperation(operation2, input, options, requestOptions);
|
|
785
|
+
};
|
|
786
|
+
}
|
|
787
|
+
__name(createClientOperationCaller, "createClientOperationCaller");
|
|
788
|
+
function createServerOperationCaller(operation2, options, integrationKey, source) {
|
|
789
|
+
return async (input = {}, requestOptions) => {
|
|
790
|
+
if (typeof window !== "undefined") {
|
|
791
|
+
throw new Error(
|
|
792
|
+
"Server integration API cannot be called in the browser. Remove { isServer: true } and create a client integration API instead."
|
|
793
|
+
);
|
|
794
|
+
}
|
|
795
|
+
return executeServerOperation(
|
|
796
|
+
operation2,
|
|
797
|
+
input,
|
|
798
|
+
options,
|
|
799
|
+
requestOptions,
|
|
800
|
+
integrationKey,
|
|
801
|
+
source
|
|
802
|
+
);
|
|
803
|
+
};
|
|
804
|
+
}
|
|
805
|
+
__name(createServerOperationCaller, "createServerOperationCaller");
|
|
806
|
+
function createNamespaceProxy(api2, options) {
|
|
807
|
+
const cache = /* @__PURE__ */ new Map();
|
|
808
|
+
const directOperation = resolveSingleNamespaceOperation(api2);
|
|
809
|
+
const target = directOperation ? createClientOperationCaller(directOperation, directOperation.method.toLowerCase(), options) : {};
|
|
810
|
+
return new Proxy(target, {
|
|
811
|
+
get(targetObject, property, receiver) {
|
|
812
|
+
if (typeof property !== "string") {
|
|
813
|
+
return Reflect.get(targetObject, property, receiver);
|
|
814
|
+
}
|
|
815
|
+
if (cache.has(property)) {
|
|
816
|
+
return cache.get(property);
|
|
817
|
+
}
|
|
818
|
+
const value = api2[property];
|
|
819
|
+
if (!value) {
|
|
820
|
+
return Reflect.get(targetObject, property, receiver);
|
|
821
|
+
}
|
|
822
|
+
if (isOperation(value)) {
|
|
823
|
+
const caller = createClientOperationCaller(value, property, options);
|
|
824
|
+
cache.set(property, caller);
|
|
825
|
+
return caller;
|
|
826
|
+
}
|
|
827
|
+
const namespace = createNamespaceProxy(value, options);
|
|
828
|
+
cache.set(property, namespace);
|
|
829
|
+
return namespace;
|
|
830
|
+
}
|
|
831
|
+
});
|
|
832
|
+
}
|
|
833
|
+
__name(createNamespaceProxy, "createNamespaceProxy");
|
|
834
|
+
function createServerNamespaceProxy(integrationKey, source, api2, options) {
|
|
835
|
+
const cache = /* @__PURE__ */ new Map();
|
|
836
|
+
const directOperation = resolveSingleNamespaceOperation(api2);
|
|
837
|
+
const target = directOperation ? createServerOperationCaller(directOperation, options, integrationKey, source) : {};
|
|
838
|
+
return new Proxy(target, {
|
|
839
|
+
get(targetObject, property, receiver) {
|
|
840
|
+
if (typeof property !== "string") {
|
|
841
|
+
return Reflect.get(targetObject, property, receiver);
|
|
842
|
+
}
|
|
843
|
+
if (cache.has(property)) {
|
|
844
|
+
return cache.get(property);
|
|
845
|
+
}
|
|
846
|
+
const value = api2[property];
|
|
847
|
+
if (!value) {
|
|
848
|
+
return Reflect.get(targetObject, property, receiver);
|
|
849
|
+
}
|
|
850
|
+
if (isOperation(value)) {
|
|
851
|
+
const caller = createServerOperationCaller(value, options, integrationKey, source);
|
|
852
|
+
cache.set(property, caller);
|
|
853
|
+
return caller;
|
|
854
|
+
}
|
|
855
|
+
const namespace = createServerNamespaceProxy(
|
|
856
|
+
integrationKey,
|
|
857
|
+
source,
|
|
858
|
+
value,
|
|
859
|
+
options
|
|
860
|
+
);
|
|
861
|
+
cache.set(property, namespace);
|
|
862
|
+
return namespace;
|
|
863
|
+
}
|
|
864
|
+
});
|
|
865
|
+
}
|
|
866
|
+
__name(createServerNamespaceProxy, "createServerNamespaceProxy");
|
|
867
|
+
|
|
868
|
+
// src/observability.ts
|
|
869
|
+
var runtimeHandlers = /* @__PURE__ */ new Set();
|
|
870
|
+
var observabilityState = {
|
|
871
|
+
logs: false,
|
|
872
|
+
handlers: []
|
|
873
|
+
};
|
|
874
|
+
function emitFarmEvent(input) {
|
|
875
|
+
const event = {
|
|
876
|
+
timestamp: Date.now(),
|
|
877
|
+
level: inferFarmEventLevel(input.type),
|
|
878
|
+
...input
|
|
879
|
+
};
|
|
880
|
+
if (!shouldEmitFarmEvent(event)) {
|
|
881
|
+
return event;
|
|
882
|
+
}
|
|
883
|
+
if (observabilityState.logs) {
|
|
884
|
+
logFarmEvent(event);
|
|
885
|
+
}
|
|
886
|
+
for (const handler of [...observabilityState.handlers, ...runtimeHandlers]) {
|
|
887
|
+
try {
|
|
888
|
+
Promise.resolve(handler(event)).catch((error) => {
|
|
889
|
+
console.warn(`[farm:observability] event handler failed: ${formatError(error)}`);
|
|
890
|
+
});
|
|
891
|
+
} catch (error) {
|
|
892
|
+
console.warn(`[farm:observability] event handler failed: ${formatError(error)}`);
|
|
893
|
+
}
|
|
894
|
+
}
|
|
895
|
+
return event;
|
|
896
|
+
}
|
|
897
|
+
__name(emitFarmEvent, "emitFarmEvent");
|
|
898
|
+
function shouldEmitFarmEvent(event) {
|
|
899
|
+
if (!observabilityState.logs && observabilityState.handlers.length === 0 && runtimeHandlers.size === 0) {
|
|
900
|
+
return false;
|
|
901
|
+
}
|
|
902
|
+
if (observabilityState.events && !observabilityState.events.has(event.type)) {
|
|
903
|
+
return false;
|
|
904
|
+
}
|
|
905
|
+
return true;
|
|
906
|
+
}
|
|
907
|
+
__name(shouldEmitFarmEvent, "shouldEmitFarmEvent");
|
|
908
|
+
function inferFarmEventLevel(type) {
|
|
909
|
+
if (type === "error" || type.endsWith(".error") || type.endsWith(".failed")) {
|
|
910
|
+
return "error";
|
|
911
|
+
}
|
|
912
|
+
if (type.endsWith(".bypass") || type.endsWith(".invalidated") || type.endsWith(".stale") || type.endsWith(".notFound")) {
|
|
913
|
+
return "warn";
|
|
914
|
+
}
|
|
915
|
+
if (type.endsWith(".hit") || type.endsWith(".miss") || type.endsWith(".start") || type.endsWith(".shellReady")) {
|
|
916
|
+
return "debug";
|
|
917
|
+
}
|
|
918
|
+
return "info";
|
|
919
|
+
}
|
|
920
|
+
__name(inferFarmEventLevel, "inferFarmEventLevel");
|
|
921
|
+
function logFarmEvent(event) {
|
|
922
|
+
const message = `[farm:${event.level}] ${event.type}${formatFarmEventDetails(event)}`;
|
|
923
|
+
switch (event.level) {
|
|
924
|
+
case "error":
|
|
925
|
+
console.error(message);
|
|
926
|
+
break;
|
|
927
|
+
case "warn":
|
|
928
|
+
console.warn(message);
|
|
929
|
+
break;
|
|
930
|
+
default:
|
|
931
|
+
console.log(message);
|
|
932
|
+
break;
|
|
933
|
+
}
|
|
934
|
+
}
|
|
935
|
+
__name(logFarmEvent, "logFarmEvent");
|
|
936
|
+
function formatFarmEventDetails(event) {
|
|
937
|
+
const details = [];
|
|
938
|
+
const record = event;
|
|
939
|
+
for (const key of [
|
|
940
|
+
"route",
|
|
941
|
+
"pathname",
|
|
942
|
+
"method",
|
|
943
|
+
"status",
|
|
944
|
+
"key",
|
|
945
|
+
"tag",
|
|
946
|
+
"path",
|
|
947
|
+
"reason",
|
|
948
|
+
"durationMs",
|
|
949
|
+
"integration",
|
|
950
|
+
"operation",
|
|
951
|
+
"plugin",
|
|
952
|
+
"hook",
|
|
953
|
+
"target",
|
|
954
|
+
"count"
|
|
955
|
+
]) {
|
|
956
|
+
const value = record[key];
|
|
957
|
+
if (value !== void 0) {
|
|
958
|
+
details.push(`${key}=${formatDetailValue(value)}`);
|
|
959
|
+
}
|
|
960
|
+
}
|
|
961
|
+
return details.length > 0 ? ` ${details.join(" ")}` : "";
|
|
962
|
+
}
|
|
963
|
+
__name(formatFarmEventDetails, "formatFarmEventDetails");
|
|
964
|
+
function formatDetailValue(value) {
|
|
965
|
+
if (typeof value === "string") {
|
|
966
|
+
return value;
|
|
967
|
+
}
|
|
968
|
+
if (typeof value === "number" || typeof value === "boolean") {
|
|
969
|
+
return String(value);
|
|
970
|
+
}
|
|
971
|
+
try {
|
|
972
|
+
return JSON.stringify(value);
|
|
973
|
+
} catch {
|
|
974
|
+
return String(value);
|
|
975
|
+
}
|
|
976
|
+
}
|
|
977
|
+
__name(formatDetailValue, "formatDetailValue");
|
|
978
|
+
function formatError(error) {
|
|
979
|
+
return error instanceof Error ? error.message : String(error);
|
|
980
|
+
}
|
|
981
|
+
__name(formatError, "formatError");
|
|
982
|
+
|
|
983
|
+
// src/cache-invalidation.ts
|
|
984
|
+
var FARM_CACHE_INVALIDATION_STATE = /* @__PURE__ */ Symbol.for("farm.cacheInvalidationState");
|
|
985
|
+
var globalState = globalThis;
|
|
986
|
+
function getFarmCacheInvalidationState() {
|
|
987
|
+
return globalState[FARM_CACHE_INVALIDATION_STATE] ?? (globalState[FARM_CACHE_INVALIDATION_STATE] = {
|
|
988
|
+
listeners: /* @__PURE__ */ new Set()
|
|
989
|
+
});
|
|
990
|
+
}
|
|
991
|
+
__name(getFarmCacheInvalidationState, "getFarmCacheInvalidationState");
|
|
992
|
+
function subscribeFarmCacheInvalidation(listener) {
|
|
993
|
+
const state = getFarmCacheInvalidationState();
|
|
994
|
+
state.listeners.add(listener);
|
|
995
|
+
return () => state.listeners.delete(listener);
|
|
996
|
+
}
|
|
997
|
+
__name(subscribeFarmCacheInvalidation, "subscribeFarmCacheInvalidation");
|
|
998
|
+
|
|
999
|
+
// src/i18n/bridge.ts
|
|
1000
|
+
var FARM_I18N_SNAPSHOT_RESOLVER = /* @__PURE__ */ Symbol.for("farm.i18n.snapshotResolver");
|
|
1001
|
+
function getActiveFarmI18nSnapshot() {
|
|
1002
|
+
if (typeof window !== "undefined" && window.__FARM_I18N__) {
|
|
1003
|
+
return window.__FARM_I18N__;
|
|
1004
|
+
}
|
|
1005
|
+
return globalThis[FARM_I18N_SNAPSHOT_RESOLVER]?.();
|
|
1006
|
+
}
|
|
1007
|
+
__name(getActiveFarmI18nSnapshot, "getActiveFarmI18nSnapshot");
|
|
1008
|
+
|
|
1009
|
+
// src/cache.ts
|
|
1010
|
+
var _FarmDataCache = class _FarmDataCache {
|
|
1011
|
+
constructor() {
|
|
1012
|
+
this.entries = /* @__PURE__ */ new Map();
|
|
1013
|
+
this.inflight = /* @__PURE__ */ new Map();
|
|
1014
|
+
this.invalidatedTagVersions = /* @__PURE__ */ new Map();
|
|
1015
|
+
this.version = 0;
|
|
1016
|
+
}
|
|
1017
|
+
get size() {
|
|
1018
|
+
return this.entries.size;
|
|
1019
|
+
}
|
|
1020
|
+
get(key, options = {}) {
|
|
1021
|
+
return this.getEntry(key, options)?.value;
|
|
1022
|
+
}
|
|
1023
|
+
getEntry(key, options = {}) {
|
|
1024
|
+
const entry = this.entries.get(key);
|
|
1025
|
+
if (!entry) {
|
|
1026
|
+
emitFarmEvent({ type: "cache.miss", key });
|
|
1027
|
+
return void 0;
|
|
1028
|
+
}
|
|
1029
|
+
const stale = this.isStale(entry, options.now);
|
|
1030
|
+
if (stale) {
|
|
1031
|
+
emitFarmEvent({
|
|
1032
|
+
type: "cache.stale",
|
|
1033
|
+
key,
|
|
1034
|
+
tags: Array.from(entry.tags),
|
|
1035
|
+
revalidate: entry.revalidate
|
|
1036
|
+
});
|
|
1037
|
+
}
|
|
1038
|
+
if (!options.allowStale && stale) {
|
|
1039
|
+
emitFarmEvent({ type: "cache.miss", key, reason: "stale" });
|
|
1040
|
+
return void 0;
|
|
1041
|
+
}
|
|
1042
|
+
emitFarmEvent({
|
|
1043
|
+
type: "cache.hit",
|
|
1044
|
+
key,
|
|
1045
|
+
tags: Array.from(entry.tags),
|
|
1046
|
+
revalidate: entry.revalidate,
|
|
1047
|
+
stale
|
|
1048
|
+
});
|
|
1049
|
+
return this.toPublicEntry(entry);
|
|
1050
|
+
}
|
|
1051
|
+
set(key, value, options = {}) {
|
|
1052
|
+
const tags = /* @__PURE__ */ new Set();
|
|
1053
|
+
for (const tag of options.tags ?? []) {
|
|
1054
|
+
tags.add(normalizeCacheTag(tag));
|
|
1055
|
+
}
|
|
1056
|
+
for (const routePath of options.paths ?? []) {
|
|
1057
|
+
tags.add(createPathCacheTag(routePath));
|
|
1058
|
+
}
|
|
1059
|
+
const entry = {
|
|
1060
|
+
key,
|
|
1061
|
+
value,
|
|
1062
|
+
tags,
|
|
1063
|
+
createdAt: options.createdAt ?? Date.now(),
|
|
1064
|
+
createdVersion: ++this.version,
|
|
1065
|
+
revalidate: normalizeRevalidate(options.revalidate)
|
|
1066
|
+
};
|
|
1067
|
+
this.entries.set(key, entry);
|
|
1068
|
+
emitFarmEvent({
|
|
1069
|
+
type: "cache.set",
|
|
1070
|
+
key,
|
|
1071
|
+
tags: Array.from(tags),
|
|
1072
|
+
revalidate: entry.revalidate
|
|
1073
|
+
});
|
|
1074
|
+
return this.toPublicEntry(entry);
|
|
1075
|
+
}
|
|
1076
|
+
delete(key) {
|
|
1077
|
+
const deleted = this.entries.delete(key);
|
|
1078
|
+
emitFarmEvent({ type: "cache.delete", key, deleted });
|
|
1079
|
+
return deleted;
|
|
1080
|
+
}
|
|
1081
|
+
clear() {
|
|
1082
|
+
const count = this.entries.size;
|
|
1083
|
+
this.entries.clear();
|
|
1084
|
+
this.inflight.clear();
|
|
1085
|
+
this.invalidatedTagVersions.clear();
|
|
1086
|
+
this.version = 0;
|
|
1087
|
+
emitFarmEvent({ type: "cache.clear", count });
|
|
1088
|
+
}
|
|
1089
|
+
isStale(entry, now2 = Date.now()) {
|
|
1090
|
+
if (typeof entry.revalidate === "number" && entry.revalidate > 0 && now2 - entry.createdAt >= entry.revalidate * 1e3) {
|
|
1091
|
+
return true;
|
|
1092
|
+
}
|
|
1093
|
+
for (const tag of entry.tags) {
|
|
1094
|
+
const invalidatedVersion = this.invalidatedTagVersions.get(normalizeCacheTag(tag));
|
|
1095
|
+
if (typeof invalidatedVersion === "number" && typeof entry.createdVersion === "number" && invalidatedVersion > entry.createdVersion) {
|
|
1096
|
+
return true;
|
|
1097
|
+
}
|
|
1098
|
+
}
|
|
1099
|
+
return false;
|
|
1100
|
+
}
|
|
1101
|
+
revalidateTag(tag, options = {}) {
|
|
1102
|
+
const normalized = normalizeCacheTag(tag);
|
|
1103
|
+
const count = this.invalidateTag(normalized);
|
|
1104
|
+
emitFarmEvent(
|
|
1105
|
+
options.source === "updateTag" ? { type: "cache.updateTag", tag: normalized, count } : { type: "cache.revalidateTag", tag: normalized, profile: options.profile, count }
|
|
1106
|
+
);
|
|
1107
|
+
return count;
|
|
1108
|
+
}
|
|
1109
|
+
revalidatePath(routePath) {
|
|
1110
|
+
const normalizedPath = normalizeRevalidatePath(routePath);
|
|
1111
|
+
const pathTag = createPathCacheTag(normalizedPath);
|
|
1112
|
+
const pprCount = this.countEntriesForTags([pathTag, "ppr"]);
|
|
1113
|
+
const count = this.invalidateTag(pathTag);
|
|
1114
|
+
emitFarmEvent({ type: "cache.revalidatePath", path: normalizedPath, count });
|
|
1115
|
+
if (pprCount > 0) {
|
|
1116
|
+
emitFarmEvent({
|
|
1117
|
+
type: "ppr.shell.invalidated",
|
|
1118
|
+
route: normalizedPath,
|
|
1119
|
+
reason: "revalidatePath",
|
|
1120
|
+
count: pprCount
|
|
1121
|
+
});
|
|
1122
|
+
}
|
|
1123
|
+
return count;
|
|
1124
|
+
}
|
|
1125
|
+
async getOrSet(key, producer, options = {}) {
|
|
1126
|
+
const cached = this.getEntry(key);
|
|
1127
|
+
if (cached) {
|
|
1128
|
+
return cached.value;
|
|
1129
|
+
}
|
|
1130
|
+
const inflight = this.inflight.get(key);
|
|
1131
|
+
if (inflight) {
|
|
1132
|
+
emitFarmEvent({ type: "cache.dedupe", key });
|
|
1133
|
+
return inflight;
|
|
1134
|
+
}
|
|
1135
|
+
const promise = Promise.resolve().then(producer).then((value) => {
|
|
1136
|
+
this.set(key, value, options);
|
|
1137
|
+
return value;
|
|
1138
|
+
}).catch((error) => {
|
|
1139
|
+
emitFarmEvent({ type: "cache.error", key, operation: "set", error });
|
|
1140
|
+
throw error;
|
|
1141
|
+
}).finally(() => {
|
|
1142
|
+
this.inflight.delete(key);
|
|
1143
|
+
});
|
|
1144
|
+
this.inflight.set(key, promise);
|
|
1145
|
+
return promise;
|
|
1146
|
+
}
|
|
1147
|
+
countEntriesForTag(tag) {
|
|
1148
|
+
let count = 0;
|
|
1149
|
+
for (const entry of this.entries.values()) {
|
|
1150
|
+
if (entry.tags.has(tag)) {
|
|
1151
|
+
count++;
|
|
1152
|
+
}
|
|
1153
|
+
}
|
|
1154
|
+
return count;
|
|
1155
|
+
}
|
|
1156
|
+
countEntriesForTags(tags) {
|
|
1157
|
+
let count = 0;
|
|
1158
|
+
for (const entry of this.entries.values()) {
|
|
1159
|
+
if (tags.every((tag) => entry.tags.has(tag))) {
|
|
1160
|
+
count++;
|
|
1161
|
+
}
|
|
1162
|
+
}
|
|
1163
|
+
return count;
|
|
1164
|
+
}
|
|
1165
|
+
invalidateTag(normalizedTag) {
|
|
1166
|
+
this.invalidatedTagVersions.set(normalizedTag, ++this.version);
|
|
1167
|
+
return this.countEntriesForTag(normalizedTag);
|
|
1168
|
+
}
|
|
1169
|
+
toPublicEntry(entry) {
|
|
1170
|
+
return {
|
|
1171
|
+
key: entry.key,
|
|
1172
|
+
value: entry.value,
|
|
1173
|
+
tags: Array.from(entry.tags),
|
|
1174
|
+
createdAt: entry.createdAt,
|
|
1175
|
+
createdVersion: entry.createdVersion,
|
|
1176
|
+
revalidate: entry.revalidate
|
|
1177
|
+
};
|
|
1178
|
+
}
|
|
1179
|
+
};
|
|
1180
|
+
__name(_FarmDataCache, "FarmDataCache");
|
|
1181
|
+
var FarmDataCache = _FarmDataCache;
|
|
1182
|
+
var FARM_DATA_CACHE_SYMBOL = /* @__PURE__ */ Symbol.for("farm.dataCache");
|
|
1183
|
+
var farmDataCacheGlobal = globalThis;
|
|
1184
|
+
var sharedFarmDataCache = farmDataCacheGlobal[FARM_DATA_CACHE_SYMBOL] ?? (farmDataCacheGlobal[FARM_DATA_CACHE_SYMBOL] = new FarmDataCache());
|
|
1185
|
+
var functionIds = /* @__PURE__ */ new WeakMap();
|
|
1186
|
+
var nextFunctionId = 0;
|
|
1187
|
+
function createPathCacheTag(routePath) {
|
|
1188
|
+
return `path:${normalizeRevalidatePath(routePath)}`;
|
|
1189
|
+
}
|
|
1190
|
+
__name(createPathCacheTag, "createPathCacheTag");
|
|
1191
|
+
function createRouteDataCacheKey(key) {
|
|
1192
|
+
return createFarmCacheKey(Array.isArray(key) ? key : [key]);
|
|
1193
|
+
}
|
|
1194
|
+
__name(createRouteDataCacheKey, "createRouteDataCacheKey");
|
|
1195
|
+
function normalizeRevalidatePath(routePath) {
|
|
1196
|
+
if (typeof routePath !== "string") {
|
|
1197
|
+
throw new TypeError("revalidatePath expects a path string.");
|
|
1198
|
+
}
|
|
1199
|
+
let normalized = routePath.trim();
|
|
1200
|
+
if (!normalized) {
|
|
1201
|
+
throw new Error("revalidatePath expects a non-empty path.");
|
|
1202
|
+
}
|
|
1203
|
+
try {
|
|
1204
|
+
if (/^https?:\/\//.test(normalized)) {
|
|
1205
|
+
normalized = new URL(normalized).pathname;
|
|
1206
|
+
}
|
|
1207
|
+
} catch {
|
|
1208
|
+
}
|
|
1209
|
+
normalized = normalized.split("?")[0] ?? normalized;
|
|
1210
|
+
normalized = normalized.startsWith("/") ? normalized : `/${normalized}`;
|
|
1211
|
+
normalized = normalized.replace(/\/{2,}/g, "/");
|
|
1212
|
+
if (normalized.length > 1) {
|
|
1213
|
+
normalized = normalized.replace(/\/+$/, "");
|
|
1214
|
+
}
|
|
1215
|
+
return normalized || "/";
|
|
1216
|
+
}
|
|
1217
|
+
__name(normalizeRevalidatePath, "normalizeRevalidatePath");
|
|
1218
|
+
function createFarmCacheKey(parts) {
|
|
1219
|
+
return stableSerialize(parts);
|
|
1220
|
+
}
|
|
1221
|
+
__name(createFarmCacheKey, "createFarmCacheKey");
|
|
1222
|
+
function normalizeRevalidate(revalidate) {
|
|
1223
|
+
if (revalidate === false || revalidate === void 0) {
|
|
1224
|
+
return revalidate;
|
|
1225
|
+
}
|
|
1226
|
+
if (!Number.isFinite(revalidate) || revalidate <= 0) {
|
|
1227
|
+
return void 0;
|
|
1228
|
+
}
|
|
1229
|
+
return revalidate;
|
|
1230
|
+
}
|
|
1231
|
+
__name(normalizeRevalidate, "normalizeRevalidate");
|
|
1232
|
+
function normalizeCacheTag(tag) {
|
|
1233
|
+
if (typeof tag !== "string") {
|
|
1234
|
+
throw new TypeError("Cache tags must be strings.");
|
|
1235
|
+
}
|
|
1236
|
+
const normalized = tag.trim();
|
|
1237
|
+
if (!normalized) {
|
|
1238
|
+
throw new Error("Cache tags cannot be empty.");
|
|
1239
|
+
}
|
|
1240
|
+
return normalized;
|
|
1241
|
+
}
|
|
1242
|
+
__name(normalizeCacheTag, "normalizeCacheTag");
|
|
1243
|
+
function getFunctionCacheIdentity(fn) {
|
|
1244
|
+
if (fn.name) {
|
|
1245
|
+
return `name:${fn.name}`;
|
|
1246
|
+
}
|
|
1247
|
+
let id = functionIds.get(fn);
|
|
1248
|
+
if (!id) {
|
|
1249
|
+
id = ++nextFunctionId;
|
|
1250
|
+
functionIds.set(fn, id);
|
|
1251
|
+
}
|
|
1252
|
+
return `anonymous:${id}`;
|
|
1253
|
+
}
|
|
1254
|
+
__name(getFunctionCacheIdentity, "getFunctionCacheIdentity");
|
|
1255
|
+
function stableSerialize(value, seen = /* @__PURE__ */ new WeakSet()) {
|
|
1256
|
+
if (value === null) return "null";
|
|
1257
|
+
if (value === void 0) return "undefined";
|
|
1258
|
+
const valueType = typeof value;
|
|
1259
|
+
if (valueType === "string") return JSON.stringify(value);
|
|
1260
|
+
if (valueType === "number" || valueType === "boolean" || valueType === "bigint") {
|
|
1261
|
+
return `${valueType}:${String(value)}`;
|
|
1262
|
+
}
|
|
1263
|
+
if (valueType === "symbol") {
|
|
1264
|
+
return `symbol:${String(value)}`;
|
|
1265
|
+
}
|
|
1266
|
+
if (valueType === "function") {
|
|
1267
|
+
return `function:${getFunctionCacheIdentity(value)}`;
|
|
1268
|
+
}
|
|
1269
|
+
if (value instanceof Date) {
|
|
1270
|
+
return `date:${value.toISOString()}`;
|
|
1271
|
+
}
|
|
1272
|
+
if (value instanceof URL) {
|
|
1273
|
+
return `url:${value.toString()}`;
|
|
1274
|
+
}
|
|
1275
|
+
if (value instanceof RegExp) {
|
|
1276
|
+
return `regexp:${value.toString()}`;
|
|
1277
|
+
}
|
|
1278
|
+
if (Array.isArray(value)) {
|
|
1279
|
+
return `[${value.map((item) => stableSerialize(item, seen)).join(",")}]`;
|
|
1280
|
+
}
|
|
1281
|
+
if (value && typeof value === "object") {
|
|
1282
|
+
if (seen.has(value)) {
|
|
1283
|
+
return "[Circular]";
|
|
1284
|
+
}
|
|
1285
|
+
seen.add(value);
|
|
1286
|
+
const entries = Object.entries(value).sort(
|
|
1287
|
+
([a], [b]) => a.localeCompare(b)
|
|
1288
|
+
);
|
|
1289
|
+
const serialized = entries.map(([key, item]) => `${JSON.stringify(key)}:${stableSerialize(item, seen)}`).join(",");
|
|
1290
|
+
seen.delete(value);
|
|
1291
|
+
return `{${serialized}}`;
|
|
1292
|
+
}
|
|
1293
|
+
return String(value);
|
|
1294
|
+
}
|
|
1295
|
+
__name(stableSerialize, "stableSerialize");
|
|
1296
|
+
|
|
1297
|
+
// src/client-cache.ts
|
|
1298
|
+
var _FarmClientDataCache = class _FarmClientDataCache {
|
|
1299
|
+
constructor() {
|
|
1300
|
+
this.entries = /* @__PURE__ */ new Map();
|
|
1301
|
+
this.aliases = /* @__PURE__ */ new Map();
|
|
1302
|
+
this.invalidatedAt = /* @__PURE__ */ new Map();
|
|
1303
|
+
this.listeners = /* @__PURE__ */ new Map();
|
|
1304
|
+
this.inflight = /* @__PURE__ */ new Map();
|
|
1305
|
+
subscribeFarmCacheInvalidation((key) => this.invalidate(key));
|
|
1306
|
+
}
|
|
1307
|
+
get size() {
|
|
1308
|
+
return this.entries.size;
|
|
1309
|
+
}
|
|
1310
|
+
resolveKey(key) {
|
|
1311
|
+
let resolved = key;
|
|
1312
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1313
|
+
while (this.aliases.has(resolved) && !seen.has(resolved)) {
|
|
1314
|
+
seen.add(resolved);
|
|
1315
|
+
resolved = this.aliases.get(resolved);
|
|
1316
|
+
}
|
|
1317
|
+
return resolved;
|
|
1318
|
+
}
|
|
1319
|
+
get(key, now2 = Date.now()) {
|
|
1320
|
+
const resolved = this.resolveKey(key);
|
|
1321
|
+
const entry = this.entries.get(resolved);
|
|
1322
|
+
if (!entry) return void 0;
|
|
1323
|
+
if (entry.gcAt !== void 0 && now2 >= entry.gcAt) {
|
|
1324
|
+
this.entries.delete(resolved);
|
|
1325
|
+
this.emit(resolved);
|
|
1326
|
+
return void 0;
|
|
1327
|
+
}
|
|
1328
|
+
return entry;
|
|
1329
|
+
}
|
|
1330
|
+
set(key, entry) {
|
|
1331
|
+
const resolved = this.resolveKey(key);
|
|
1332
|
+
const invalidatedAt = this.invalidatedAt.get(resolved);
|
|
1333
|
+
const nextEntry = invalidatedAt !== void 0 && invalidatedAt > entry.updatedAt ? { ...entry, staleAt: 0, invalidatedAt } : { ...entry, invalidatedAt: void 0 };
|
|
1334
|
+
if (invalidatedAt === void 0 || entry.updatedAt >= invalidatedAt) {
|
|
1335
|
+
this.invalidatedAt.delete(resolved);
|
|
1336
|
+
}
|
|
1337
|
+
this.entries.set(resolved, nextEntry);
|
|
1338
|
+
this.emit(resolved);
|
|
1339
|
+
return this;
|
|
1340
|
+
}
|
|
1341
|
+
delete(key) {
|
|
1342
|
+
const resolved = this.resolveKey(key);
|
|
1343
|
+
const deleted = this.entries.delete(resolved);
|
|
1344
|
+
this.inflight.delete(resolved);
|
|
1345
|
+
this.emit(resolved);
|
|
1346
|
+
return deleted;
|
|
1347
|
+
}
|
|
1348
|
+
clear() {
|
|
1349
|
+
const keys = /* @__PURE__ */ new Set([...this.entries.keys(), ...this.listeners.keys()]);
|
|
1350
|
+
this.entries.clear();
|
|
1351
|
+
this.aliases.clear();
|
|
1352
|
+
this.invalidatedAt.clear();
|
|
1353
|
+
this.inflight.clear();
|
|
1354
|
+
for (const key of keys) this.emit(key);
|
|
1355
|
+
}
|
|
1356
|
+
isStale(key, now2 = Date.now()) {
|
|
1357
|
+
const entry = this.get(key, now2);
|
|
1358
|
+
return !entry || entry.invalidatedAt !== void 0 || now2 >= entry.staleAt;
|
|
1359
|
+
}
|
|
1360
|
+
invalidate(key, now2 = Date.now()) {
|
|
1361
|
+
const resolved = this.resolveKey(key);
|
|
1362
|
+
this.invalidatedAt.set(resolved, now2);
|
|
1363
|
+
const entry = this.entries.get(resolved);
|
|
1364
|
+
if (entry) {
|
|
1365
|
+
this.entries.set(resolved, {
|
|
1366
|
+
...entry,
|
|
1367
|
+
staleAt: 0,
|
|
1368
|
+
invalidatedAt: now2
|
|
1369
|
+
});
|
|
1370
|
+
}
|
|
1371
|
+
this.emit(resolved);
|
|
1372
|
+
}
|
|
1373
|
+
alias(alias, key) {
|
|
1374
|
+
const resolved = this.resolveKey(key);
|
|
1375
|
+
if (alias === resolved) return;
|
|
1376
|
+
const aliasEntry = this.entries.get(alias);
|
|
1377
|
+
if (aliasEntry && !this.entries.has(resolved)) {
|
|
1378
|
+
this.entries.set(resolved, aliasEntry);
|
|
1379
|
+
}
|
|
1380
|
+
this.entries.delete(alias);
|
|
1381
|
+
const aliasInflight = this.inflight.get(alias);
|
|
1382
|
+
if (aliasInflight && !this.inflight.has(resolved)) {
|
|
1383
|
+
this.inflight.set(resolved, aliasInflight);
|
|
1384
|
+
}
|
|
1385
|
+
this.inflight.delete(alias);
|
|
1386
|
+
this.aliases.set(alias, resolved);
|
|
1387
|
+
this.emit(alias);
|
|
1388
|
+
this.emit(resolved);
|
|
1389
|
+
}
|
|
1390
|
+
subscribe(key, listener) {
|
|
1391
|
+
let listeners2 = this.listeners.get(key);
|
|
1392
|
+
if (!listeners2) {
|
|
1393
|
+
listeners2 = /* @__PURE__ */ new Set();
|
|
1394
|
+
this.listeners.set(key, listeners2);
|
|
1395
|
+
}
|
|
1396
|
+
listeners2.add(listener);
|
|
1397
|
+
return () => {
|
|
1398
|
+
listeners2.delete(listener);
|
|
1399
|
+
if (listeners2.size === 0) this.listeners.delete(key);
|
|
1400
|
+
};
|
|
1401
|
+
}
|
|
1402
|
+
getInflight(key) {
|
|
1403
|
+
return this.inflight.get(this.resolveKey(key));
|
|
1404
|
+
}
|
|
1405
|
+
setInflight(key, promise) {
|
|
1406
|
+
this.inflight.set(this.resolveKey(key), promise);
|
|
1407
|
+
}
|
|
1408
|
+
deleteInflight(key) {
|
|
1409
|
+
this.inflight.delete(this.resolveKey(key));
|
|
1410
|
+
}
|
|
1411
|
+
emit(key) {
|
|
1412
|
+
this.notifyListeners(key);
|
|
1413
|
+
for (const [alias, target] of this.aliases) {
|
|
1414
|
+
if (this.resolveKey(target) === key) {
|
|
1415
|
+
this.notifyListeners(alias);
|
|
1416
|
+
}
|
|
1417
|
+
}
|
|
1418
|
+
}
|
|
1419
|
+
notifyListeners(key) {
|
|
1420
|
+
for (const listener of this.listeners.get(key) ?? []) {
|
|
1421
|
+
listener();
|
|
1422
|
+
}
|
|
1423
|
+
}
|
|
1424
|
+
};
|
|
1425
|
+
__name(_FarmClientDataCache, "FarmClientDataCache");
|
|
1426
|
+
var FarmClientDataCache = _FarmClientDataCache;
|
|
1427
|
+
var FARM_CLIENT_DATA_CACHE = /* @__PURE__ */ Symbol.for("farm.clientDataCache");
|
|
1428
|
+
var clientCacheGlobal = globalThis;
|
|
1429
|
+
var sharedFarmClientDataCache = clientCacheGlobal[FARM_CLIENT_DATA_CACHE] ?? (clientCacheGlobal[FARM_CLIENT_DATA_CACHE] = new FarmClientDataCache());
|
|
1430
|
+
function getFarmClientDataCache() {
|
|
1431
|
+
return sharedFarmClientDataCache;
|
|
1432
|
+
}
|
|
1433
|
+
__name(getFarmClientDataCache, "getFarmClientDataCache");
|
|
1434
|
+
function normalizeFarmClientCacheKey(key) {
|
|
1435
|
+
return typeof key === "string" ? key : createRouteDataCacheKey(key);
|
|
1436
|
+
}
|
|
1437
|
+
__name(normalizeFarmClientCacheKey, "normalizeFarmClientCacheKey");
|
|
1438
|
+
|
|
1439
|
+
// src/api/client.ts
|
|
1440
|
+
function createAPIClient(options = {}) {
|
|
1441
|
+
options ?? (options = {});
|
|
1442
|
+
const baseURL = options.baseURL || (typeof window !== "undefined" ? window.location.origin : "http://localhost:3000");
|
|
1443
|
+
const integrationOptions = options.integrations === false ? false : {
|
|
1444
|
+
baseURL: options.baseURL,
|
|
1445
|
+
headers: options.headers,
|
|
1446
|
+
credentials: options.credentials,
|
|
1447
|
+
...typeof options.integrations === "object" ? options.integrations : {}
|
|
1448
|
+
};
|
|
1449
|
+
const rootAliases = integrationOptions === false ? void 0 : {
|
|
1450
|
+
integrations: integrationsClient(integrationOptions)
|
|
1451
|
+
};
|
|
1452
|
+
const cacheState = getFarmClientDataCache();
|
|
1453
|
+
const inflightState = /* @__PURE__ */ new Map();
|
|
1454
|
+
const routeMeta = /* @__PURE__ */ new WeakMap();
|
|
1455
|
+
let requestCounter = 0;
|
|
1456
|
+
const fetchClient = /* @__PURE__ */ __name(async (path, requestOptions = {}) => {
|
|
1457
|
+
const url = new URL(path, baseURL);
|
|
1458
|
+
if (requestOptions.query) {
|
|
1459
|
+
Object.entries(requestOptions.query).forEach(([key, value]) => {
|
|
1460
|
+
if (value !== void 0 && value !== null) {
|
|
1461
|
+
url.searchParams.set(key, String(value));
|
|
1462
|
+
}
|
|
1463
|
+
});
|
|
1464
|
+
}
|
|
1465
|
+
const fetchOptions = {
|
|
1466
|
+
method: requestOptions.method || "GET",
|
|
1467
|
+
headers: {
|
|
1468
|
+
"Content-Type": "application/json",
|
|
1469
|
+
...options.headers,
|
|
1470
|
+
...requestOptions.headers
|
|
1471
|
+
}
|
|
1472
|
+
};
|
|
1473
|
+
if (requestOptions.body) {
|
|
1474
|
+
fetchOptions.body = JSON.stringify(requestOptions.body);
|
|
1475
|
+
}
|
|
1476
|
+
const response = await fetch(url.toString(), fetchOptions);
|
|
1477
|
+
let data = void 0;
|
|
1478
|
+
if (response.status !== 204 && response.status !== 205) {
|
|
1479
|
+
data = await response.json();
|
|
1480
|
+
}
|
|
1481
|
+
return { response, data };
|
|
1482
|
+
}, "fetchClient");
|
|
1483
|
+
const request = /* @__PURE__ */ __name(async (path, method, input = {}, clientOptions) => {
|
|
1484
|
+
const methodUpper = method.toUpperCase();
|
|
1485
|
+
const requestId = `${Date.now()}-${++requestCounter}`;
|
|
1486
|
+
const cacheOptions = clientOptions?.cache ? {
|
|
1487
|
+
...options.cacheDefaults,
|
|
1488
|
+
...clientOptions.cache
|
|
1489
|
+
} : void 0;
|
|
1490
|
+
const configuredCacheKey = clientOptions?.key ?? cacheOptions?.key;
|
|
1491
|
+
const cacheKey = normalizeFarmClientCacheKey(
|
|
1492
|
+
configuredCacheKey ?? buildCacheKey(methodUpper, path, input, baseURL)
|
|
1493
|
+
);
|
|
1494
|
+
const now2 = Date.now();
|
|
1495
|
+
const emitStatus = /* @__PURE__ */ __name((phase, payload) => {
|
|
1496
|
+
clientOptions?.onStatus?.({
|
|
1497
|
+
phase,
|
|
1498
|
+
requestId,
|
|
1499
|
+
method: methodUpper,
|
|
1500
|
+
key: cacheKey,
|
|
1501
|
+
input,
|
|
1502
|
+
timestamp: Date.now(),
|
|
1503
|
+
...payload
|
|
1504
|
+
});
|
|
1505
|
+
}, "emitStatus");
|
|
1506
|
+
const entry = getValidCacheEntry(cacheState, cacheKey, now2);
|
|
1507
|
+
const policy = cacheOptions?.policy ?? (cacheOptions ? "cache-first" : "network-only");
|
|
1508
|
+
const staleTime = cacheOptions?.staleTime ?? 0;
|
|
1509
|
+
const isCacheEnabled = Boolean(cacheOptions) && methodUpper === "GET";
|
|
1510
|
+
const isStale = entry ? isEntryStale(entry, now2) : true;
|
|
1511
|
+
const applyOptimisticUpdates = /* @__PURE__ */ __name(() => {
|
|
1512
|
+
if (!clientOptions?.optimistic?.update?.length) return [];
|
|
1513
|
+
const snapshots = [];
|
|
1514
|
+
for (const update of clientOptions.optimistic.update) {
|
|
1515
|
+
const [target, targetInput, updater] = update.length === 2 ? [update[0], void 0, update[1]] : [update[0], update[1], update[2]];
|
|
1516
|
+
const targetKey = resolveTargetKey(routeMeta, target, targetInput, baseURL);
|
|
1517
|
+
if (!targetKey) continue;
|
|
1518
|
+
const targetEntry = getValidCacheEntry(cacheState, targetKey, now2);
|
|
1519
|
+
const previousEntry = targetEntry ? { ...targetEntry } : void 0;
|
|
1520
|
+
const previousData = targetEntry?.data;
|
|
1521
|
+
const nextData = updater(previousData);
|
|
1522
|
+
cacheState.set(targetKey, {
|
|
1523
|
+
data: nextData,
|
|
1524
|
+
updatedAt: now2,
|
|
1525
|
+
staleAt: targetEntry?.staleAt ?? now2 + (cacheOptions?.staleTime ?? options.cacheDefaults?.staleTime ?? 0),
|
|
1526
|
+
gcAt: targetEntry?.gcAt ?? getGcAt(now2, cacheOptions?.gcTime ?? options.cacheDefaults?.gcTime),
|
|
1527
|
+
invalidatedAt: targetEntry?.invalidatedAt
|
|
1528
|
+
});
|
|
1529
|
+
snapshots.push({ key: targetKey, entry: previousEntry });
|
|
1530
|
+
}
|
|
1531
|
+
return snapshots;
|
|
1532
|
+
}, "applyOptimisticUpdates");
|
|
1533
|
+
const rollbackOptimisticUpdates = /* @__PURE__ */ __name((snapshots) => {
|
|
1534
|
+
if (!clientOptions?.optimistic?.rollbackOnError) return;
|
|
1535
|
+
for (const snapshot of snapshots) {
|
|
1536
|
+
if (!snapshot.entry) {
|
|
1537
|
+
cacheState.delete(snapshot.key);
|
|
1538
|
+
continue;
|
|
1539
|
+
}
|
|
1540
|
+
cacheState.set(snapshot.key, { ...snapshot.entry });
|
|
1541
|
+
}
|
|
1542
|
+
}, "rollbackOptimisticUpdates");
|
|
1543
|
+
const executeNetwork = /* @__PURE__ */ __name(async (opts) => {
|
|
1544
|
+
const dedupeMs = cacheOptions?.dedupeMs ?? 0;
|
|
1545
|
+
const inflight = inflightState.get(cacheKey);
|
|
1546
|
+
const allowDedupe = isCacheEnabled && dedupeMs > 0;
|
|
1547
|
+
if (allowDedupe && inflight && now2 - inflight.startedAt < dedupeMs) {
|
|
1548
|
+
emitStatus("pending", { isBackground: opts?.isBackground, data: entry?.data });
|
|
1549
|
+
const result2 = await inflight.promise;
|
|
1550
|
+
if (result2.error) {
|
|
1551
|
+
emitStatus("error", { error: result2.error, isBackground: opts?.isBackground });
|
|
1552
|
+
if (opts?.callCallbacks !== false) {
|
|
1553
|
+
clientOptions?.onError?.(result2.error);
|
|
1554
|
+
}
|
|
1555
|
+
} else {
|
|
1556
|
+
emitStatus("success", { data: result2.data, isBackground: opts?.isBackground });
|
|
1557
|
+
if (opts?.callCallbacks !== false) {
|
|
1558
|
+
clientOptions?.onSuccess?.(result2.data);
|
|
1559
|
+
}
|
|
1560
|
+
}
|
|
1561
|
+
return result2;
|
|
1562
|
+
}
|
|
1563
|
+
emitStatus(opts?.isBackground ? "revalidating" : "pending", {
|
|
1564
|
+
isBackground: opts?.isBackground
|
|
1565
|
+
});
|
|
1566
|
+
const promise = (async () => {
|
|
1567
|
+
const maxRetries = Math.max(0, clientOptions?.retry?.count ?? 0);
|
|
1568
|
+
let attempt = 0;
|
|
1569
|
+
while (true) {
|
|
1570
|
+
clientOptions?.onRequest?.({
|
|
1571
|
+
requestId,
|
|
1572
|
+
method: methodUpper,
|
|
1573
|
+
key: cacheKey,
|
|
1574
|
+
path,
|
|
1575
|
+
input,
|
|
1576
|
+
attempt,
|
|
1577
|
+
timestamp: Date.now()
|
|
1578
|
+
});
|
|
1579
|
+
try {
|
|
1580
|
+
const { response, data } = await fetchClient(path, {
|
|
1581
|
+
...input,
|
|
1582
|
+
method: methodUpper
|
|
1583
|
+
});
|
|
1584
|
+
const error = response.ok ? null : createResponseError2(response, data);
|
|
1585
|
+
const responseEvent = {
|
|
1586
|
+
requestId,
|
|
1587
|
+
method: methodUpper,
|
|
1588
|
+
key: cacheKey,
|
|
1589
|
+
path,
|
|
1590
|
+
input,
|
|
1591
|
+
attempt,
|
|
1592
|
+
timestamp: Date.now(),
|
|
1593
|
+
response,
|
|
1594
|
+
data: response.ok ? data : void 0,
|
|
1595
|
+
error: error ?? void 0,
|
|
1596
|
+
ok: response.ok,
|
|
1597
|
+
status: response.status
|
|
1598
|
+
};
|
|
1599
|
+
clientOptions?.onResponse?.(response.ok ? data : void 0, error, responseEvent);
|
|
1600
|
+
if (!error) {
|
|
1601
|
+
return { data, error: null, key: cacheKey };
|
|
1602
|
+
}
|
|
1603
|
+
if (attempt >= maxRetries) {
|
|
1604
|
+
return { data: void 0, error, key: cacheKey };
|
|
1605
|
+
}
|
|
1606
|
+
} catch (err) {
|
|
1607
|
+
const error = normalizeError(err);
|
|
1608
|
+
const responseEvent = {
|
|
1609
|
+
requestId,
|
|
1610
|
+
method: methodUpper,
|
|
1611
|
+
key: cacheKey,
|
|
1612
|
+
path,
|
|
1613
|
+
input,
|
|
1614
|
+
attempt,
|
|
1615
|
+
timestamp: Date.now(),
|
|
1616
|
+
error,
|
|
1617
|
+
ok: false
|
|
1618
|
+
};
|
|
1619
|
+
clientOptions?.onResponse?.(void 0, error, responseEvent);
|
|
1620
|
+
if (attempt >= maxRetries) {
|
|
1621
|
+
return { data: void 0, error, key: cacheKey };
|
|
1622
|
+
}
|
|
1623
|
+
}
|
|
1624
|
+
attempt += 1;
|
|
1625
|
+
const delay = typeof clientOptions?.retry?.delay === "function" ? clientOptions.retry.delay(attempt) : clientOptions?.retry?.delay ?? 0;
|
|
1626
|
+
if (delay > 0) {
|
|
1627
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
1628
|
+
}
|
|
1629
|
+
}
|
|
1630
|
+
})();
|
|
1631
|
+
inflightState.set(cacheKey, { promise, startedAt: now2 });
|
|
1632
|
+
try {
|
|
1633
|
+
const result2 = await promise;
|
|
1634
|
+
if (!result2.error && isCacheEnabled) {
|
|
1635
|
+
const updatedAt = Date.now();
|
|
1636
|
+
cacheState.set(cacheKey, {
|
|
1637
|
+
data: result2.data,
|
|
1638
|
+
updatedAt,
|
|
1639
|
+
staleAt: updatedAt + staleTime,
|
|
1640
|
+
gcAt: getGcAt(updatedAt, cacheOptions?.gcTime),
|
|
1641
|
+
invalidatedAt: void 0
|
|
1642
|
+
});
|
|
1643
|
+
}
|
|
1644
|
+
if (result2.error) {
|
|
1645
|
+
emitStatus("error", { error: result2.error, isBackground: opts?.isBackground });
|
|
1646
|
+
if (opts?.callCallbacks !== false) {
|
|
1647
|
+
clientOptions?.onError?.(result2.error);
|
|
1648
|
+
}
|
|
1649
|
+
} else {
|
|
1650
|
+
emitStatus("success", { data: result2.data, isBackground: opts?.isBackground });
|
|
1651
|
+
if (opts?.callCallbacks !== false) {
|
|
1652
|
+
clientOptions?.onSuccess?.(result2.data);
|
|
1653
|
+
}
|
|
1654
|
+
}
|
|
1655
|
+
return result2;
|
|
1656
|
+
} finally {
|
|
1657
|
+
inflightState.delete(cacheKey);
|
|
1658
|
+
}
|
|
1659
|
+
}, "executeNetwork");
|
|
1660
|
+
const invalidateTargets = /* @__PURE__ */ __name(async () => {
|
|
1661
|
+
if (!clientOptions?.invalidate) return;
|
|
1662
|
+
const invalidateOptions = Array.isArray(clientOptions.invalidate) ? { targets: clientOptions.invalidate, refetch: false } : {
|
|
1663
|
+
targets: clientOptions.invalidate.targets,
|
|
1664
|
+
refetch: clientOptions.invalidate.refetch ?? false
|
|
1665
|
+
};
|
|
1666
|
+
for (const target of invalidateOptions.targets) {
|
|
1667
|
+
const targetKey = resolveTargetKey(routeMeta, target, void 0, baseURL);
|
|
1668
|
+
if (!targetKey) continue;
|
|
1669
|
+
const existing = cacheState.get(targetKey);
|
|
1670
|
+
if (existing) {
|
|
1671
|
+
cacheState.set(targetKey, {
|
|
1672
|
+
...existing,
|
|
1673
|
+
staleAt: 0,
|
|
1674
|
+
invalidatedAt: Date.now()
|
|
1675
|
+
});
|
|
1676
|
+
}
|
|
1677
|
+
emitStatus("invalidated", { key: targetKey });
|
|
1678
|
+
if (invalidateOptions.refetch && existing && targetKey === cacheKey) {
|
|
1679
|
+
void executeNetwork({ isBackground: true, callCallbacks: false });
|
|
1680
|
+
}
|
|
1681
|
+
}
|
|
1682
|
+
}, "invalidateTargets");
|
|
1683
|
+
const optimisticSnapshots = applyOptimisticUpdates();
|
|
1684
|
+
if (isCacheEnabled) {
|
|
1685
|
+
if (entry && !isStale && policy !== "network-only") {
|
|
1686
|
+
emitStatus("success", { data: entry.data });
|
|
1687
|
+
clientOptions?.onSuccess?.(entry.data);
|
|
1688
|
+
clientOptions?.onSettled?.(entry.data, null);
|
|
1689
|
+
return { data: entry.data, error: null, key: cacheKey };
|
|
1690
|
+
}
|
|
1691
|
+
if (entry && isStale && policy === "stale-while-revalidate") {
|
|
1692
|
+
emitStatus("success", { data: entry.data });
|
|
1693
|
+
clientOptions?.onSuccess?.(entry.data);
|
|
1694
|
+
clientOptions?.onSettled?.(entry.data, null);
|
|
1695
|
+
void executeNetwork({ isBackground: true, callCallbacks: false });
|
|
1696
|
+
return { data: entry.data, error: null, key: cacheKey };
|
|
1697
|
+
}
|
|
1698
|
+
}
|
|
1699
|
+
const result = await executeNetwork();
|
|
1700
|
+
if (result.error) {
|
|
1701
|
+
rollbackOptimisticUpdates(optimisticSnapshots);
|
|
1702
|
+
}
|
|
1703
|
+
await invalidateTargets();
|
|
1704
|
+
clientOptions?.onSettled?.(result.data, result.error);
|
|
1705
|
+
return result;
|
|
1706
|
+
}, "request");
|
|
1707
|
+
return createNestedProxy([], request, routeMeta, baseURL, rootAliases);
|
|
1708
|
+
}
|
|
1709
|
+
__name(createAPIClient, "createAPIClient");
|
|
1710
|
+
function createNestedProxy(path, client, routeMeta, baseURL, rootAliases) {
|
|
1711
|
+
const target = /* @__PURE__ */ __name(() => {
|
|
1712
|
+
}, "target");
|
|
1713
|
+
const proxy = new Proxy(target, {
|
|
1714
|
+
// When accessing a property (api.hello)
|
|
1715
|
+
get(_target, prop) {
|
|
1716
|
+
if (path.length === 0 && typeof prop === "string" && rootAliases && prop in rootAliases) {
|
|
1717
|
+
return rootAliases[prop];
|
|
1718
|
+
}
|
|
1719
|
+
return createNestedProxy([...path, prop], client, routeMeta, baseURL, rootAliases);
|
|
1720
|
+
},
|
|
1721
|
+
// When calling as a function
|
|
1722
|
+
apply(_target, _thisArg, args) {
|
|
1723
|
+
const lastPart = path[path.length - 1];
|
|
1724
|
+
const httpMethods = ["get", "post", "put", "delete", "patch", "options", "head"];
|
|
1725
|
+
if (httpMethods.includes(lastPart)) {
|
|
1726
|
+
const routePath = "/api/" + path.slice(0, -1).join("/");
|
|
1727
|
+
const method = lastPart.toUpperCase();
|
|
1728
|
+
const [options, clientOptions] = args;
|
|
1729
|
+
return client(routePath, method, options, clientOptions);
|
|
1730
|
+
} else {
|
|
1731
|
+
const routePath = "/api/" + path.join("/");
|
|
1732
|
+
const [options, clientOptions] = args;
|
|
1733
|
+
return client(routePath, options?.method || "GET", options, clientOptions);
|
|
1734
|
+
}
|
|
1735
|
+
}
|
|
1736
|
+
});
|
|
1737
|
+
routeMeta.set(proxy, { path: [...path], baseURL });
|
|
1738
|
+
return proxy;
|
|
1739
|
+
}
|
|
1740
|
+
__name(createNestedProxy, "createNestedProxy");
|
|
1741
|
+
function createServerAPIClient(endpoints, options = {}) {
|
|
1742
|
+
if (options.integrations === false || Object.prototype.hasOwnProperty.call(endpoints, "integrations")) {
|
|
1743
|
+
return endpoints;
|
|
1744
|
+
}
|
|
1745
|
+
Object.defineProperty(endpoints, "integrations", {
|
|
1746
|
+
get() {
|
|
1747
|
+
return integrationsServer(
|
|
1748
|
+
typeof options.integrations === "object" ? options.integrations : {}
|
|
1749
|
+
);
|
|
1750
|
+
},
|
|
1751
|
+
enumerable: false,
|
|
1752
|
+
configurable: true
|
|
1753
|
+
});
|
|
1754
|
+
return endpoints;
|
|
1755
|
+
}
|
|
1756
|
+
__name(createServerAPIClient, "createServerAPIClient");
|
|
1757
|
+
function buildCacheKey(method, path, input, baseURL) {
|
|
1758
|
+
const keyInput = input && typeof input === "object" ? { query: input.query, body: input.body } : input;
|
|
1759
|
+
const url = new URL(path, baseURL);
|
|
1760
|
+
return `${method}:${url.origin}${url.pathname}:${stableStringify(keyInput ?? {})}`;
|
|
1761
|
+
}
|
|
1762
|
+
__name(buildCacheKey, "buildCacheKey");
|
|
1763
|
+
function stableStringify(value) {
|
|
1764
|
+
if (value === null || value === void 0) return String(value);
|
|
1765
|
+
if (value instanceof Date) return value.toISOString();
|
|
1766
|
+
if (typeof value !== "object") return JSON.stringify(value);
|
|
1767
|
+
if (Array.isArray(value)) {
|
|
1768
|
+
return `[${value.map((item) => stableStringify(item)).join(",")}]`;
|
|
1769
|
+
}
|
|
1770
|
+
const keys = Object.keys(value).sort();
|
|
1771
|
+
const entries = keys.map((key) => `${JSON.stringify(key)}:${stableStringify(value[key])}`);
|
|
1772
|
+
return `{${entries.join(",")}}`;
|
|
1773
|
+
}
|
|
1774
|
+
__name(stableStringify, "stableStringify");
|
|
1775
|
+
function getGcAt(now2, gcTime) {
|
|
1776
|
+
if (gcTime === void 0) return void 0;
|
|
1777
|
+
if (!Number.isFinite(gcTime) || gcTime <= 0) return now2;
|
|
1778
|
+
return now2 + gcTime;
|
|
1779
|
+
}
|
|
1780
|
+
__name(getGcAt, "getGcAt");
|
|
1781
|
+
function getValidCacheEntry(cacheState, key, now2) {
|
|
1782
|
+
const entry = cacheState.get(key);
|
|
1783
|
+
if (!entry) return void 0;
|
|
1784
|
+
if (entry.gcAt !== void 0 && now2 >= entry.gcAt) {
|
|
1785
|
+
cacheState.delete(key);
|
|
1786
|
+
return void 0;
|
|
1787
|
+
}
|
|
1788
|
+
return entry;
|
|
1789
|
+
}
|
|
1790
|
+
__name(getValidCacheEntry, "getValidCacheEntry");
|
|
1791
|
+
function isEntryStale(entry, now2) {
|
|
1792
|
+
if (entry.invalidatedAt !== void 0) return true;
|
|
1793
|
+
return now2 >= entry.staleAt;
|
|
1794
|
+
}
|
|
1795
|
+
__name(isEntryStale, "isEntryStale");
|
|
1796
|
+
function resolveTargetKey(routeMeta, target, input, baseURL = "http://localhost:3000") {
|
|
1797
|
+
if (!target) return null;
|
|
1798
|
+
if (typeof target === "string") return target;
|
|
1799
|
+
if (typeof target === "function") {
|
|
1800
|
+
const meta = routeMeta.get(target);
|
|
1801
|
+
if (!meta) return null;
|
|
1802
|
+
const { method, routePath } = resolveRouteMeta(meta);
|
|
1803
|
+
return buildCacheKey(method, routePath, input ?? {}, meta.baseURL);
|
|
1804
|
+
}
|
|
1805
|
+
if (Array.isArray(target)) {
|
|
1806
|
+
const [route2, routeInput] = target;
|
|
1807
|
+
return resolveTargetKey(routeMeta, route2, routeInput, baseURL);
|
|
1808
|
+
}
|
|
1809
|
+
if ("key" in target) return normalizeFarmClientCacheKey(target.key);
|
|
1810
|
+
if ("path" in target) {
|
|
1811
|
+
const method = target.method ?? "GET";
|
|
1812
|
+
return buildCacheKey(method, target.path, target.input ?? {}, baseURL);
|
|
1813
|
+
}
|
|
1814
|
+
return null;
|
|
1815
|
+
}
|
|
1816
|
+
__name(resolveTargetKey, "resolveTargetKey");
|
|
1817
|
+
function resolveRouteMeta(meta) {
|
|
1818
|
+
const httpMethods = ["get", "post", "put", "delete", "patch", "options", "head"];
|
|
1819
|
+
const lastPart = meta.path[meta.path.length - 1];
|
|
1820
|
+
if (lastPart && httpMethods.includes(lastPart)) {
|
|
1821
|
+
return {
|
|
1822
|
+
routePath: "/api/" + meta.path.slice(0, -1).join("/"),
|
|
1823
|
+
method: lastPart.toUpperCase()
|
|
1824
|
+
};
|
|
1825
|
+
}
|
|
1826
|
+
return {
|
|
1827
|
+
routePath: "/api/" + meta.path.join("/"),
|
|
1828
|
+
method: "GET"
|
|
1829
|
+
};
|
|
1830
|
+
}
|
|
1831
|
+
__name(resolveRouteMeta, "resolveRouteMeta");
|
|
1832
|
+
function normalizeError(error) {
|
|
1833
|
+
if (error instanceof Error) return error;
|
|
1834
|
+
return new Error(typeof error === "string" ? error : "Unknown error");
|
|
1835
|
+
}
|
|
1836
|
+
__name(normalizeError, "normalizeError");
|
|
1837
|
+
function createResponseError2(response, data) {
|
|
1838
|
+
const error = new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
1839
|
+
error.status = response.status;
|
|
1840
|
+
error.response = response;
|
|
1841
|
+
error.data = data;
|
|
1842
|
+
return error;
|
|
1843
|
+
}
|
|
1844
|
+
__name(createResponseError2, "createResponseError");
|
|
1845
|
+
|
|
1846
|
+
// src/server-query-client.ts
|
|
1847
|
+
var import_react = require("react");
|
|
1848
|
+
var FARM_SERVER_QUERY_CLIENT_STATE = /* @__PURE__ */ Symbol.for("farm.serverQueryClientState");
|
|
1849
|
+
var serverQueryClientGlobal = globalThis;
|
|
1850
|
+
var serverQueryClientState = serverQueryClientGlobal[FARM_SERVER_QUERY_CLIENT_STATE] ?? (serverQueryClientGlobal[FARM_SERVER_QUERY_CLIENT_STATE] = {
|
|
1851
|
+
functionIds: /* @__PURE__ */ new WeakMap(),
|
|
1852
|
+
nextFunctionId: 0,
|
|
1853
|
+
active: []
|
|
1854
|
+
});
|
|
1855
|
+
async function fetchServerQuery(query, input, options = {}) {
|
|
1856
|
+
const cache = getFarmClientDataCache();
|
|
1857
|
+
const provisionalKey = createServerQueryCallKey(query, input);
|
|
1858
|
+
const entry = cache.get(provisionalKey);
|
|
1859
|
+
const stale = cache.isStale(provisionalKey);
|
|
1860
|
+
const inflight = cache.getInflight(provisionalKey);
|
|
1861
|
+
if (inflight) return inflight;
|
|
1862
|
+
if (!options.force && entry && !stale && entry.status !== "error") {
|
|
1863
|
+
return entry.data;
|
|
1864
|
+
}
|
|
1865
|
+
if (!options.force && entry && stale && entry.status !== "pending" && entry.status !== "error" && (options.swr ?? true)) {
|
|
1866
|
+
void executeServerQuery(query, input, provisionalKey, options).catch(() => void 0);
|
|
1867
|
+
return entry.data;
|
|
1868
|
+
}
|
|
1869
|
+
return executeServerQuery(query, input, provisionalKey, options);
|
|
1870
|
+
}
|
|
1871
|
+
__name(fetchServerQuery, "fetchServerQuery");
|
|
1872
|
+
function prefetchServerQuery(query, input, options = {}) {
|
|
1873
|
+
return fetchServerQuery(query, input, options);
|
|
1874
|
+
}
|
|
1875
|
+
__name(prefetchServerQuery, "prefetchServerQuery");
|
|
1876
|
+
function useServerQuery(query, input, options = {}) {
|
|
1877
|
+
const cache = getFarmClientDataCache();
|
|
1878
|
+
const key = createServerQueryCallKey(query, input);
|
|
1879
|
+
const inputRef = (0, import_react.useRef)(input);
|
|
1880
|
+
const optionsRef = (0, import_react.useRef)(options);
|
|
1881
|
+
const mountedKeyRef = (0, import_react.useRef)();
|
|
1882
|
+
inputRef.current = input;
|
|
1883
|
+
optionsRef.current = options;
|
|
1884
|
+
const subscribe = (0, import_react.useCallback)(
|
|
1885
|
+
(listener) => cache.subscribe(key, listener),
|
|
1886
|
+
[cache, key]
|
|
1887
|
+
);
|
|
1888
|
+
const getSnapshot = (0, import_react.useCallback)(() => cache.get(key), [cache, key]);
|
|
1889
|
+
const entry = (0, import_react.useSyncExternalStore)(subscribe, getSnapshot, () => void 0);
|
|
1890
|
+
const run = (0, import_react.useCallback)(
|
|
1891
|
+
(force = false) => fetchServerQuery(query, inputRef.current, {
|
|
1892
|
+
...optionsRef.current,
|
|
1893
|
+
force
|
|
1894
|
+
}),
|
|
1895
|
+
[query]
|
|
1896
|
+
);
|
|
1897
|
+
(0, import_react.useEffect)(() => {
|
|
1898
|
+
if (options.enabled === false) return;
|
|
1899
|
+
const firstReadForKey = mountedKeyRef.current !== key;
|
|
1900
|
+
if (firstReadForKey) mountedKeyRef.current = key;
|
|
1901
|
+
if (firstReadForKey && (!entry || cache.isStale(key)) || entry?.invalidatedAt !== void 0 && !entry.fetching) {
|
|
1902
|
+
void run().catch(() => void 0);
|
|
1903
|
+
}
|
|
1904
|
+
}, [cache, entry, key, options.enabled, run]);
|
|
1905
|
+
(0, import_react.useEffect)(() => {
|
|
1906
|
+
if (options.enabled === false || typeof window === "undefined") return;
|
|
1907
|
+
const refreshIfStale = /* @__PURE__ */ __name(() => {
|
|
1908
|
+
if (cache.isStale(key)) void run().catch(() => void 0);
|
|
1909
|
+
}, "refreshIfStale");
|
|
1910
|
+
const onFocus = options.refetchOnWindowFocus === false ? void 0 : refreshIfStale;
|
|
1911
|
+
const onOnline = options.refetchOnReconnect === false ? void 0 : refreshIfStale;
|
|
1912
|
+
if (onFocus) window.addEventListener("focus", onFocus);
|
|
1913
|
+
if (onOnline) window.addEventListener("online", onOnline);
|
|
1914
|
+
return () => {
|
|
1915
|
+
if (onFocus) window.removeEventListener("focus", onFocus);
|
|
1916
|
+
if (onOnline) window.removeEventListener("online", onOnline);
|
|
1917
|
+
};
|
|
1918
|
+
}, [cache, key, options.enabled, options.refetchOnReconnect, options.refetchOnWindowFocus, run]);
|
|
1919
|
+
const status = entry?.status ?? (entry ? "success" : "idle");
|
|
1920
|
+
const fetching = entry?.fetching ?? false;
|
|
1921
|
+
return {
|
|
1922
|
+
data: entry?.data,
|
|
1923
|
+
error: entry?.error ?? null,
|
|
1924
|
+
status,
|
|
1925
|
+
pending: status === "pending" && (entry?.updatedAt ?? 0) === 0,
|
|
1926
|
+
fetching,
|
|
1927
|
+
stale: cache.isStale(key),
|
|
1928
|
+
refetch: /* @__PURE__ */ __name(() => run(true), "refetch")
|
|
1929
|
+
};
|
|
1930
|
+
}
|
|
1931
|
+
__name(useServerQuery, "useServerQuery");
|
|
1932
|
+
function createServerQueryCallKey(query, input) {
|
|
1933
|
+
let id = serverQueryClientState.functionIds.get(query);
|
|
1934
|
+
if (!id) {
|
|
1935
|
+
id = ++serverQueryClientState.nextFunctionId;
|
|
1936
|
+
serverQueryClientState.functionIds.set(query, id);
|
|
1937
|
+
}
|
|
1938
|
+
return createFarmCacheKey(["server-query-call", id, input]);
|
|
1939
|
+
}
|
|
1940
|
+
__name(createServerQueryCallKey, "createServerQueryCallKey");
|
|
1941
|
+
async function executeServerQuery(query, input, provisionalKey, options) {
|
|
1942
|
+
const cache = getFarmClientDataCache();
|
|
1943
|
+
const inflight = cache.getInflight(provisionalKey);
|
|
1944
|
+
if (inflight) return inflight;
|
|
1945
|
+
const previous = cache.get(provisionalKey);
|
|
1946
|
+
cache.set(provisionalKey, {
|
|
1947
|
+
data: previous?.data,
|
|
1948
|
+
updatedAt: previous?.updatedAt ?? 0,
|
|
1949
|
+
staleAt: previous?.staleAt ?? 0,
|
|
1950
|
+
gcAt: previous?.gcAt,
|
|
1951
|
+
invalidatedAt: previous?.invalidatedAt,
|
|
1952
|
+
status: "pending",
|
|
1953
|
+
error: null,
|
|
1954
|
+
fetching: true
|
|
1955
|
+
});
|
|
1956
|
+
const promise = (async () => {
|
|
1957
|
+
try {
|
|
1958
|
+
serverQueryClientState.active.push({ provisionalKey });
|
|
1959
|
+
let pending;
|
|
1960
|
+
try {
|
|
1961
|
+
pending = query(input);
|
|
1962
|
+
} finally {
|
|
1963
|
+
serverQueryClientState.active.pop();
|
|
1964
|
+
}
|
|
1965
|
+
const data = await pending;
|
|
1966
|
+
const transported = cache.get(provisionalKey);
|
|
1967
|
+
if (!transported || transported.fetching) {
|
|
1968
|
+
const updatedAt = Date.now();
|
|
1969
|
+
cache.set(provisionalKey, {
|
|
1970
|
+
data,
|
|
1971
|
+
updatedAt,
|
|
1972
|
+
staleAt: options.staleTime === false ? Number.POSITIVE_INFINITY : updatedAt + (options.staleTime ?? 0),
|
|
1973
|
+
status: "success",
|
|
1974
|
+
error: null,
|
|
1975
|
+
fetching: false
|
|
1976
|
+
});
|
|
1977
|
+
}
|
|
1978
|
+
return data;
|
|
1979
|
+
} catch (cause) {
|
|
1980
|
+
const error = normalizeServerQueryError(cause);
|
|
1981
|
+
const current = cache.get(provisionalKey);
|
|
1982
|
+
cache.set(provisionalKey, {
|
|
1983
|
+
data: current?.data,
|
|
1984
|
+
updatedAt: current?.updatedAt ?? 0,
|
|
1985
|
+
staleAt: current?.staleAt ?? 0,
|
|
1986
|
+
gcAt: current?.gcAt,
|
|
1987
|
+
invalidatedAt: current?.invalidatedAt,
|
|
1988
|
+
status: "error",
|
|
1989
|
+
error,
|
|
1990
|
+
fetching: false
|
|
1991
|
+
});
|
|
1992
|
+
throw error;
|
|
1993
|
+
} finally {
|
|
1994
|
+
cache.deleteInflight(provisionalKey);
|
|
1995
|
+
}
|
|
1996
|
+
})();
|
|
1997
|
+
cache.setInflight(provisionalKey, promise);
|
|
1998
|
+
return promise;
|
|
1999
|
+
}
|
|
2000
|
+
__name(executeServerQuery, "executeServerQuery");
|
|
2001
|
+
function normalizeServerQueryError(cause) {
|
|
2002
|
+
if (cause instanceof Error) return cause;
|
|
2003
|
+
const error = new Error(typeof cause === "string" ? cause : "Server query failed");
|
|
2004
|
+
error.cause = cause;
|
|
2005
|
+
return error;
|
|
2006
|
+
}
|
|
2007
|
+
__name(normalizeServerQueryError, "normalizeServerQueryError");
|
|
2008
|
+
|
|
2009
|
+
// src/integration-api.ts
|
|
2010
|
+
function defineIntegrationAPIOperation(operation2) {
|
|
2011
|
+
return {
|
|
2012
|
+
kind: "farm-integration-api-operation",
|
|
2013
|
+
...operation2
|
|
2014
|
+
};
|
|
2015
|
+
}
|
|
2016
|
+
__name(defineIntegrationAPIOperation, "defineIntegrationAPIOperation");
|
|
2017
|
+
function defineIntegrationAPI(api2) {
|
|
2018
|
+
return api2;
|
|
2019
|
+
}
|
|
2020
|
+
__name(defineIntegrationAPI, "defineIntegrationAPI");
|
|
2021
|
+
function operation(method, pathOrOptions, maybeOptions = {}) {
|
|
2022
|
+
const hasExplicitPath = typeof pathOrOptions === "string";
|
|
2023
|
+
const path = hasExplicitPath ? pathOrOptions : "";
|
|
2024
|
+
const options = hasExplicitPath ? maybeOptions : {
|
|
2025
|
+
...maybeOptions,
|
|
2026
|
+
...pathOrOptions
|
|
2027
|
+
};
|
|
2028
|
+
return defineIntegrationAPIOperation({
|
|
2029
|
+
path,
|
|
2030
|
+
method,
|
|
2031
|
+
__pathless: !hasExplicitPath,
|
|
2032
|
+
...options
|
|
2033
|
+
});
|
|
2034
|
+
}
|
|
2035
|
+
__name(operation, "operation");
|
|
2036
|
+
function get(pathOrOptions, maybeOptions = {}) {
|
|
2037
|
+
return operation("GET", pathOrOptions, maybeOptions);
|
|
2038
|
+
}
|
|
2039
|
+
__name(get, "get");
|
|
2040
|
+
function isOperation2(value) {
|
|
2041
|
+
return !!value && typeof value === "object" && value.kind === "farm-integration-api-operation";
|
|
2042
|
+
}
|
|
2043
|
+
__name(isOperation2, "isOperation");
|
|
2044
|
+
function bindRoutePath(path, api2) {
|
|
2045
|
+
const entries = Object.entries(api2).map(([key, value]) => {
|
|
2046
|
+
if (isOperation2(value)) {
|
|
2047
|
+
return [
|
|
2048
|
+
key,
|
|
2049
|
+
{
|
|
2050
|
+
...value,
|
|
2051
|
+
path,
|
|
2052
|
+
__pathless: false
|
|
2053
|
+
}
|
|
2054
|
+
];
|
|
2055
|
+
}
|
|
2056
|
+
if (value && typeof value === "object") {
|
|
2057
|
+
return [key, bindRoutePath(path, value)];
|
|
2058
|
+
}
|
|
2059
|
+
return [key, value];
|
|
2060
|
+
});
|
|
2061
|
+
return Object.fromEntries(entries);
|
|
2062
|
+
}
|
|
2063
|
+
__name(bindRoutePath, "bindRoutePath");
|
|
2064
|
+
function route(path, definitionOrOperation, ...operations) {
|
|
2065
|
+
if (isOperation2(definitionOrOperation)) {
|
|
2066
|
+
const allOperations = [definitionOrOperation, ...operations];
|
|
2067
|
+
return Object.fromEntries(
|
|
2068
|
+
allOperations.map((operation2) => [
|
|
2069
|
+
operation2.method.toLowerCase(),
|
|
2070
|
+
{
|
|
2071
|
+
...operation2,
|
|
2072
|
+
path,
|
|
2073
|
+
__pathless: false
|
|
2074
|
+
}
|
|
2075
|
+
])
|
|
2076
|
+
);
|
|
2077
|
+
}
|
|
2078
|
+
return bindRoutePath(path, definitionOrOperation);
|
|
2079
|
+
}
|
|
2080
|
+
__name(route, "route");
|
|
2081
|
+
function normalizeRouteSegment(segment) {
|
|
2082
|
+
if (!segment) {
|
|
2083
|
+
return "index";
|
|
2084
|
+
}
|
|
2085
|
+
if (segment.startsWith("[...") && segment.endsWith("]")) {
|
|
2086
|
+
return segment.slice(4, -1) || "index";
|
|
2087
|
+
}
|
|
2088
|
+
if (segment.startsWith("[") && segment.endsWith("]")) {
|
|
2089
|
+
return segment.slice(1, -1) || "index";
|
|
2090
|
+
}
|
|
2091
|
+
const matcherIndex = segment.indexOf("(");
|
|
2092
|
+
if (matcherIndex > 0) {
|
|
2093
|
+
return segment.slice(0, matcherIndex);
|
|
2094
|
+
}
|
|
2095
|
+
return camelCaseRouteSegment(segment);
|
|
2096
|
+
}
|
|
2097
|
+
__name(normalizeRouteSegment, "normalizeRouteSegment");
|
|
2098
|
+
function camelCaseRouteSegment(segment) {
|
|
2099
|
+
return segment.replace(/-([a-zA-Z0-9])/g, (_match, value) => value.toUpperCase());
|
|
2100
|
+
}
|
|
2101
|
+
__name(camelCaseRouteSegment, "camelCaseRouteSegment");
|
|
2102
|
+
function getRouteClientSegments(path) {
|
|
2103
|
+
const segments = path.split("/").filter(Boolean);
|
|
2104
|
+
if (segments.length === 0) {
|
|
2105
|
+
return ["index"];
|
|
2106
|
+
}
|
|
2107
|
+
const stripped = segments[0] === "api" && segments.length > 2 ? segments.slice(2) : segments.length > 1 ? segments.slice(1) : [segments[segments.length - 1]];
|
|
2108
|
+
return stripped.map(normalizeRouteSegment).filter(Boolean);
|
|
2109
|
+
}
|
|
2110
|
+
__name(getRouteClientSegments, "getRouteClientSegments");
|
|
2111
|
+
function setRouteOperation(target, pathSegments, operation2) {
|
|
2112
|
+
const [head, ...tail] = pathSegments;
|
|
2113
|
+
if (!head) {
|
|
2114
|
+
return;
|
|
2115
|
+
}
|
|
2116
|
+
if (tail.length === 0) {
|
|
2117
|
+
const leaf = target[head] || {};
|
|
2118
|
+
leaf[operation2.method.toLowerCase()] = {
|
|
2119
|
+
...operation2,
|
|
2120
|
+
path: operation2.path,
|
|
2121
|
+
__pathless: false
|
|
2122
|
+
};
|
|
2123
|
+
target[head] = leaf;
|
|
2124
|
+
return;
|
|
2125
|
+
}
|
|
2126
|
+
const branch = target[head] || {};
|
|
2127
|
+
target[head] = branch;
|
|
2128
|
+
setRouteOperation(branch, tail, operation2);
|
|
2129
|
+
}
|
|
2130
|
+
__name(setRouteOperation, "setRouteOperation");
|
|
2131
|
+
function fromRoutes(routes) {
|
|
2132
|
+
const definition = {};
|
|
2133
|
+
for (const route2 of routes) {
|
|
2134
|
+
if (!isOperation2(route2.__operation)) {
|
|
2135
|
+
continue;
|
|
2136
|
+
}
|
|
2137
|
+
setRouteOperation(definition, getRouteClientSegments(route2.path), {
|
|
2138
|
+
...route2.__operation,
|
|
2139
|
+
path: route2.path,
|
|
2140
|
+
__pathless: false
|
|
2141
|
+
});
|
|
2142
|
+
}
|
|
2143
|
+
return definition;
|
|
2144
|
+
}
|
|
2145
|
+
__name(fromRoutes, "fromRoutes");
|
|
2146
|
+
var api = {
|
|
2147
|
+
get,
|
|
2148
|
+
route,
|
|
2149
|
+
fromRoutes,
|
|
2150
|
+
post(pathOrOptions, maybeOptions = {}) {
|
|
2151
|
+
return operation("POST", pathOrOptions, {
|
|
2152
|
+
bodyFormat: "json",
|
|
2153
|
+
...typeof pathOrOptions === "string" ? maybeOptions : pathOrOptions
|
|
2154
|
+
});
|
|
2155
|
+
},
|
|
2156
|
+
put(pathOrOptions, maybeOptions = {}) {
|
|
2157
|
+
return operation("PUT", pathOrOptions, {
|
|
2158
|
+
bodyFormat: "json",
|
|
2159
|
+
...typeof pathOrOptions === "string" ? maybeOptions : pathOrOptions
|
|
2160
|
+
});
|
|
2161
|
+
},
|
|
2162
|
+
patch(pathOrOptions, maybeOptions = {}) {
|
|
2163
|
+
return operation("PATCH", pathOrOptions, {
|
|
2164
|
+
bodyFormat: "json",
|
|
2165
|
+
...typeof pathOrOptions === "string" ? maybeOptions : pathOrOptions
|
|
2166
|
+
});
|
|
2167
|
+
},
|
|
2168
|
+
delete(pathOrOptions, maybeOptions = {}) {
|
|
2169
|
+
return operation("DELETE", pathOrOptions, {
|
|
2170
|
+
bodyFormat: "json",
|
|
2171
|
+
...typeof pathOrOptions === "string" ? maybeOptions : pathOrOptions
|
|
2172
|
+
});
|
|
2173
|
+
},
|
|
2174
|
+
options(pathOrOptions, maybeOptions = {}) {
|
|
2175
|
+
return operation(
|
|
2176
|
+
"OPTIONS",
|
|
2177
|
+
pathOrOptions,
|
|
2178
|
+
maybeOptions
|
|
2179
|
+
);
|
|
2180
|
+
},
|
|
2181
|
+
head(pathOrOptions, maybeOptions = {}) {
|
|
2182
|
+
return operation(
|
|
2183
|
+
"HEAD",
|
|
2184
|
+
pathOrOptions,
|
|
2185
|
+
maybeOptions
|
|
2186
|
+
);
|
|
2187
|
+
},
|
|
2188
|
+
form: {
|
|
2189
|
+
post(pathOrOptions, maybeOptions = {}) {
|
|
2190
|
+
return operation("POST", pathOrOptions, {
|
|
2191
|
+
bodyFormat: "form",
|
|
2192
|
+
...typeof pathOrOptions === "string" ? maybeOptions : pathOrOptions
|
|
2193
|
+
});
|
|
2194
|
+
},
|
|
2195
|
+
put(pathOrOptions, maybeOptions = {}) {
|
|
2196
|
+
return operation("PUT", pathOrOptions, {
|
|
2197
|
+
bodyFormat: "form",
|
|
2198
|
+
...typeof pathOrOptions === "string" ? maybeOptions : pathOrOptions
|
|
2199
|
+
});
|
|
2200
|
+
},
|
|
2201
|
+
patch(pathOrOptions, maybeOptions = {}) {
|
|
2202
|
+
return operation("PATCH", pathOrOptions, {
|
|
2203
|
+
bodyFormat: "form",
|
|
2204
|
+
...typeof pathOrOptions === "string" ? maybeOptions : pathOrOptions
|
|
2205
|
+
});
|
|
2206
|
+
},
|
|
2207
|
+
delete(pathOrOptions, maybeOptions = {}) {
|
|
2208
|
+
return operation("DELETE", pathOrOptions, {
|
|
2209
|
+
bodyFormat: "form",
|
|
2210
|
+
...typeof pathOrOptions === "string" ? maybeOptions : pathOrOptions
|
|
2211
|
+
});
|
|
2212
|
+
}
|
|
2213
|
+
}
|
|
2214
|
+
};
|
|
2215
|
+
var endpoint = api;
|
|
2216
|
+
|
|
2217
|
+
// src/store.ts
|
|
2218
|
+
var import_react2 = require("react");
|
|
2219
|
+
var RESERVED_STORE_KEYS = /* @__PURE__ */ new Set([
|
|
2220
|
+
"use",
|
|
2221
|
+
"get",
|
|
2222
|
+
"set",
|
|
2223
|
+
"replace",
|
|
2224
|
+
"reset",
|
|
2225
|
+
"subscribe"
|
|
2226
|
+
]);
|
|
2227
|
+
function cloneState(state) {
|
|
2228
|
+
return { ...state };
|
|
2229
|
+
}
|
|
2230
|
+
__name(cloneState, "cloneState");
|
|
2231
|
+
function pickState(state, keys) {
|
|
2232
|
+
const slice = {};
|
|
2233
|
+
for (const key of keys) {
|
|
2234
|
+
slice[key] = state[key];
|
|
2235
|
+
}
|
|
2236
|
+
return slice;
|
|
2237
|
+
}
|
|
2238
|
+
__name(pickState, "pickState");
|
|
2239
|
+
function getChangedKeys(state, previousState) {
|
|
2240
|
+
const keys = /* @__PURE__ */ new Set([
|
|
2241
|
+
...Object.keys(state),
|
|
2242
|
+
...Object.keys(previousState)
|
|
2243
|
+
]);
|
|
2244
|
+
return [...keys].filter((key) => !Object.is(state[key], previousState[key]));
|
|
2245
|
+
}
|
|
2246
|
+
__name(getChangedKeys, "getChangedKeys");
|
|
2247
|
+
function normalizeKeys(keys) {
|
|
2248
|
+
return Array.from(new Set(keys));
|
|
2249
|
+
}
|
|
2250
|
+
__name(normalizeKeys, "normalizeKeys");
|
|
2251
|
+
function resolveValue(value, previousValue) {
|
|
2252
|
+
return typeof value === "function" ? value(previousValue) : value;
|
|
2253
|
+
}
|
|
2254
|
+
__name(resolveValue, "resolveValue");
|
|
2255
|
+
function isStoreKey(value) {
|
|
2256
|
+
return typeof value === "string" || typeof value === "number" || typeof value === "symbol";
|
|
2257
|
+
}
|
|
2258
|
+
__name(isStoreKey, "isStoreKey");
|
|
2259
|
+
function createStore(initialState, extend) {
|
|
2260
|
+
const initialSnapshot = cloneState(initialState);
|
|
2261
|
+
let state = cloneState(initialState);
|
|
2262
|
+
const subscriptions = /* @__PURE__ */ new Set();
|
|
2263
|
+
const addSubscription = /* @__PURE__ */ __name((keys, notify) => {
|
|
2264
|
+
const subscription = { keys, notify };
|
|
2265
|
+
subscriptions.add(subscription);
|
|
2266
|
+
return () => {
|
|
2267
|
+
subscriptions.delete(subscription);
|
|
2268
|
+
};
|
|
2269
|
+
}, "addSubscription");
|
|
2270
|
+
const emit = /* @__PURE__ */ __name((nextState, previousState) => {
|
|
2271
|
+
const changedKeys = getChangedKeys(nextState, previousState);
|
|
2272
|
+
if (changedKeys.length === 0) {
|
|
2273
|
+
return;
|
|
2274
|
+
}
|
|
2275
|
+
const changedKeySet = new Set(changedKeys);
|
|
2276
|
+
for (const subscription of subscriptions) {
|
|
2277
|
+
if (subscription.keys === null || subscription.keys.some((key) => changedKeySet.has(key))) {
|
|
2278
|
+
subscription.notify(nextState, previousState);
|
|
2279
|
+
}
|
|
2280
|
+
}
|
|
2281
|
+
}, "emit");
|
|
2282
|
+
const getState = /* @__PURE__ */ __name((key) => {
|
|
2283
|
+
return key === void 0 ? state : state[key];
|
|
2284
|
+
}, "getState");
|
|
2285
|
+
const replaceState2 = /* @__PURE__ */ __name((nextState) => {
|
|
2286
|
+
const previousState = state;
|
|
2287
|
+
const resolvedState = typeof nextState === "function" ? nextState(previousState) : nextState;
|
|
2288
|
+
state = resolvedState;
|
|
2289
|
+
emit(state, previousState);
|
|
2290
|
+
return state;
|
|
2291
|
+
}, "replaceState");
|
|
2292
|
+
const setState = /* @__PURE__ */ __name((keyOrPatch, value) => {
|
|
2293
|
+
const previousState = state;
|
|
2294
|
+
let nextState;
|
|
2295
|
+
if (isStoreKey(keyOrPatch)) {
|
|
2296
|
+
const key = keyOrPatch;
|
|
2297
|
+
const nextValue = resolveValue(value, previousState[key]);
|
|
2298
|
+
if (Object.is(previousState[key], nextValue)) {
|
|
2299
|
+
return nextValue;
|
|
2300
|
+
}
|
|
2301
|
+
nextState = {
|
|
2302
|
+
...previousState,
|
|
2303
|
+
[key]: nextValue
|
|
2304
|
+
};
|
|
2305
|
+
state = nextState;
|
|
2306
|
+
emit(nextState, previousState);
|
|
2307
|
+
return nextValue;
|
|
2308
|
+
}
|
|
2309
|
+
const patch = typeof keyOrPatch === "function" ? keyOrPatch(previousState) : keyOrPatch;
|
|
2310
|
+
nextState = {
|
|
2311
|
+
...previousState,
|
|
2312
|
+
...patch
|
|
2313
|
+
};
|
|
2314
|
+
state = nextState;
|
|
2315
|
+
emit(nextState, previousState);
|
|
2316
|
+
return nextState;
|
|
2317
|
+
}, "setState");
|
|
2318
|
+
const subscribeState = /* @__PURE__ */ __name((keyOrListener, listener) => {
|
|
2319
|
+
if (typeof keyOrListener === "function") {
|
|
2320
|
+
return addSubscription(null, (nextState, previousState) => {
|
|
2321
|
+
keyOrListener(nextState, previousState);
|
|
2322
|
+
});
|
|
2323
|
+
}
|
|
2324
|
+
if (Array.isArray(keyOrListener)) {
|
|
2325
|
+
const keys = normalizeKeys(keyOrListener);
|
|
2326
|
+
return addSubscription(keys, (nextState, previousState) => {
|
|
2327
|
+
listener(
|
|
2328
|
+
pickState(nextState, keys),
|
|
2329
|
+
pickState(previousState, keys)
|
|
2330
|
+
);
|
|
2331
|
+
});
|
|
2332
|
+
}
|
|
2333
|
+
const key = keyOrListener;
|
|
2334
|
+
return addSubscription([key], (nextState, previousState) => {
|
|
2335
|
+
listener(nextState[key], previousState[key]);
|
|
2336
|
+
});
|
|
2337
|
+
}, "subscribeState");
|
|
2338
|
+
const useStateValue = /* @__PURE__ */ __name((keyOrKeys) => {
|
|
2339
|
+
if (Array.isArray(keyOrKeys)) {
|
|
2340
|
+
const keys = normalizeKeys(keyOrKeys);
|
|
2341
|
+
let lastState = state;
|
|
2342
|
+
let lastSlice = pickState(state, keys);
|
|
2343
|
+
const getSnapshot = /* @__PURE__ */ __name(() => {
|
|
2344
|
+
if (lastState !== state) {
|
|
2345
|
+
lastState = state;
|
|
2346
|
+
lastSlice = pickState(state, keys);
|
|
2347
|
+
}
|
|
2348
|
+
return lastSlice;
|
|
2349
|
+
}, "getSnapshot");
|
|
2350
|
+
return (0, import_react2.useSyncExternalStore)(
|
|
2351
|
+
(notify) => addSubscription(keys, () => notify()),
|
|
2352
|
+
getSnapshot,
|
|
2353
|
+
getSnapshot
|
|
2354
|
+
);
|
|
2355
|
+
}
|
|
2356
|
+
if (typeof keyOrKeys === "string") {
|
|
2357
|
+
return (0, import_react2.useSyncExternalStore)(
|
|
2358
|
+
(notify) => addSubscription([keyOrKeys], () => notify()),
|
|
2359
|
+
() => state[keyOrKeys],
|
|
2360
|
+
() => state[keyOrKeys]
|
|
2361
|
+
);
|
|
2362
|
+
}
|
|
2363
|
+
return (0, import_react2.useSyncExternalStore)(
|
|
2364
|
+
(notify) => addSubscription(null, () => notify()),
|
|
2365
|
+
() => state,
|
|
2366
|
+
() => state
|
|
2367
|
+
);
|
|
2368
|
+
}, "useStateValue");
|
|
2369
|
+
const store = {
|
|
2370
|
+
use: useStateValue,
|
|
2371
|
+
get: getState,
|
|
2372
|
+
set: setState,
|
|
2373
|
+
replace: replaceState2,
|
|
2374
|
+
reset: /* @__PURE__ */ __name(() => replaceState2(cloneState(initialSnapshot)), "reset"),
|
|
2375
|
+
subscribe: subscribeState
|
|
2376
|
+
};
|
|
2377
|
+
for (const key of Object.keys(initialSnapshot)) {
|
|
2378
|
+
if (RESERVED_STORE_KEYS.has(key)) {
|
|
2379
|
+
throw new Error(
|
|
2380
|
+
`createStore does not allow the reserved key "${String(key)}" in the initial state.`
|
|
2381
|
+
);
|
|
2382
|
+
}
|
|
2383
|
+
const field = /* @__PURE__ */ __name((() => useStateValue(key)), "field");
|
|
2384
|
+
field.get = () => state[key];
|
|
2385
|
+
field.set = (value) => setState(key, value);
|
|
2386
|
+
field.subscribe = (listener) => subscribeState(key, listener);
|
|
2387
|
+
Object.defineProperty(store, key, {
|
|
2388
|
+
configurable: false,
|
|
2389
|
+
enumerable: true,
|
|
2390
|
+
value: field,
|
|
2391
|
+
writable: false
|
|
2392
|
+
});
|
|
2393
|
+
}
|
|
2394
|
+
if (extend) {
|
|
2395
|
+
const methods = extend(store);
|
|
2396
|
+
for (const [name, method] of Object.entries(methods)) {
|
|
2397
|
+
if (name in store) {
|
|
2398
|
+
throw new Error(
|
|
2399
|
+
`createStore cannot attach the method "${name}" because it already exists.`
|
|
2400
|
+
);
|
|
2401
|
+
}
|
|
2402
|
+
Object.defineProperty(store, name, {
|
|
2403
|
+
configurable: false,
|
|
2404
|
+
enumerable: true,
|
|
2405
|
+
value: method,
|
|
2406
|
+
writable: false
|
|
2407
|
+
});
|
|
2408
|
+
}
|
|
2409
|
+
}
|
|
2410
|
+
return store;
|
|
2411
|
+
}
|
|
2412
|
+
__name(createStore, "createStore");
|
|
2413
|
+
|
|
2414
|
+
// src/client/link.tsx
|
|
2415
|
+
var import_react3 = require("react");
|
|
2416
|
+
|
|
2417
|
+
// src/router.ts
|
|
2418
|
+
function createFarmRouter(routes) {
|
|
2419
|
+
const normalizedRoutes = routes.map(normalizeRouteInput).sort(compareRoutes);
|
|
2420
|
+
return {
|
|
2421
|
+
routes: normalizedRoutes.map((entry) => entry.route),
|
|
2422
|
+
match(pathname) {
|
|
2423
|
+
const normalizedPathname = normalizePathname(pathname);
|
|
2424
|
+
for (const entry of normalizedRoutes) {
|
|
2425
|
+
const params = matchSegments(entry.segments, normalizedPathname);
|
|
2426
|
+
if (params) {
|
|
2427
|
+
return {
|
|
2428
|
+
route: entry.route,
|
|
2429
|
+
pathname: normalizedPathname,
|
|
2430
|
+
params
|
|
2431
|
+
};
|
|
2432
|
+
}
|
|
2433
|
+
}
|
|
2434
|
+
return null;
|
|
2435
|
+
},
|
|
2436
|
+
build: buildFarmRoutePath,
|
|
2437
|
+
isActive: isFarmRouteActive
|
|
2438
|
+
};
|
|
2439
|
+
}
|
|
2440
|
+
__name(createFarmRouter, "createFarmRouter");
|
|
2441
|
+
function matchFarmRoute(pattern, pathname) {
|
|
2442
|
+
return matchSegments(parseRoutePattern(pattern), normalizePathname(pathname));
|
|
2443
|
+
}
|
|
2444
|
+
__name(matchFarmRoute, "matchFarmRoute");
|
|
2445
|
+
function buildFarmRoutePath(pattern, params = {}, options = {}) {
|
|
2446
|
+
const parts = [];
|
|
2447
|
+
for (const segment of parseRoutePattern(pattern)) {
|
|
2448
|
+
if (segment.type === "static") {
|
|
2449
|
+
parts.push(encodePathSegment(segment.value));
|
|
2450
|
+
continue;
|
|
2451
|
+
}
|
|
2452
|
+
const value = params[segment.name];
|
|
2453
|
+
const values = Array.isArray(value) ? value : value == null ? [] : [value];
|
|
2454
|
+
if (values.length === 0) {
|
|
2455
|
+
if (segment.optional) continue;
|
|
2456
|
+
throw new Error(`Missing route param "${segment.name}" for ${pattern}.`);
|
|
2457
|
+
}
|
|
2458
|
+
if (!segment.catchAll && values.length > 1) {
|
|
2459
|
+
throw new Error(`Route param "${segment.name}" for ${pattern} expects a single value.`);
|
|
2460
|
+
}
|
|
2461
|
+
parts.push(...values.map((item) => encodePathSegment(String(item))));
|
|
2462
|
+
}
|
|
2463
|
+
let pathname = parts.length ? `/${parts.join("/")}` : "/";
|
|
2464
|
+
if (options.trailingSlash && pathname !== "/") {
|
|
2465
|
+
pathname = `${pathname}/`;
|
|
2466
|
+
}
|
|
2467
|
+
return appendQueryAndHash(pathname, options);
|
|
2468
|
+
}
|
|
2469
|
+
__name(buildFarmRoutePath, "buildFarmRoutePath");
|
|
2470
|
+
function isFarmRouteActive(pattern, pathname, options = {}) {
|
|
2471
|
+
const normalizedPathname = normalizePathname(pathname);
|
|
2472
|
+
if (matchFarmRoute(pattern, normalizedPathname)) return true;
|
|
2473
|
+
if (options.exact !== false) return false;
|
|
2474
|
+
const normalizedPattern = normalizePathname(pattern);
|
|
2475
|
+
if (normalizedPattern === "/") return normalizedPathname === "/";
|
|
2476
|
+
return normalizedPathname.startsWith(`${normalizedPattern}/`);
|
|
2477
|
+
}
|
|
2478
|
+
__name(isFarmRouteActive, "isFarmRouteActive");
|
|
2479
|
+
function normalizeRouteInput(input, index) {
|
|
2480
|
+
const route2 = typeof input === "string" ? { path: input } : input;
|
|
2481
|
+
const path = normalizePathname(route2.path);
|
|
2482
|
+
const segments = parseRoutePattern(path);
|
|
2483
|
+
return {
|
|
2484
|
+
route: {
|
|
2485
|
+
...route2,
|
|
2486
|
+
path
|
|
2487
|
+
},
|
|
2488
|
+
segments,
|
|
2489
|
+
score: scoreSegments(segments),
|
|
2490
|
+
index
|
|
2491
|
+
};
|
|
2492
|
+
}
|
|
2493
|
+
__name(normalizeRouteInput, "normalizeRouteInput");
|
|
2494
|
+
function parseRoutePattern(pattern) {
|
|
2495
|
+
return splitPathname(pattern).filter((part) => !isRouteGroup(part)).map((part) => {
|
|
2496
|
+
const optionalCatchAll = part.match(/^\[\[\.\.\.([A-Za-z0-9_$-]+)\]\]$/);
|
|
2497
|
+
if (optionalCatchAll) {
|
|
2498
|
+
return {
|
|
2499
|
+
type: "dynamic",
|
|
2500
|
+
name: optionalCatchAll[1],
|
|
2501
|
+
catchAll: true,
|
|
2502
|
+
optional: true
|
|
2503
|
+
};
|
|
2504
|
+
}
|
|
2505
|
+
const catchAll = part.match(/^\[\.\.\.([A-Za-z0-9_$-]+)\]$/);
|
|
2506
|
+
if (catchAll) {
|
|
2507
|
+
return {
|
|
2508
|
+
type: "dynamic",
|
|
2509
|
+
name: catchAll[1],
|
|
2510
|
+
catchAll: true,
|
|
2511
|
+
optional: false
|
|
2512
|
+
};
|
|
2513
|
+
}
|
|
2514
|
+
const dynamic = part.match(/^\[([A-Za-z0-9_$-]+)\]$/) || part.match(/^:([A-Za-z0-9_$-]+)$/);
|
|
2515
|
+
if (dynamic) {
|
|
2516
|
+
return {
|
|
2517
|
+
type: "dynamic",
|
|
2518
|
+
name: dynamic[1],
|
|
2519
|
+
catchAll: false,
|
|
2520
|
+
optional: false
|
|
2521
|
+
};
|
|
2522
|
+
}
|
|
2523
|
+
const star = part.match(/^\*([A-Za-z0-9_$-]+)(\?)?$/);
|
|
2524
|
+
if (star) {
|
|
2525
|
+
return {
|
|
2526
|
+
type: "dynamic",
|
|
2527
|
+
name: star[1],
|
|
2528
|
+
catchAll: true,
|
|
2529
|
+
optional: !!star[2]
|
|
2530
|
+
};
|
|
2531
|
+
}
|
|
2532
|
+
return {
|
|
2533
|
+
type: "static",
|
|
2534
|
+
value: decodePathSegment(part)
|
|
2535
|
+
};
|
|
2536
|
+
});
|
|
2537
|
+
}
|
|
2538
|
+
__name(parseRoutePattern, "parseRoutePattern");
|
|
2539
|
+
function matchSegments(segments, pathname) {
|
|
2540
|
+
const parts = splitPathname(pathname);
|
|
2541
|
+
const params = {};
|
|
2542
|
+
if (segments.length === 0) {
|
|
2543
|
+
return parts.length === 0 ? params : null;
|
|
2544
|
+
}
|
|
2545
|
+
let pathIndex = 0;
|
|
2546
|
+
for (const segment of segments) {
|
|
2547
|
+
if (segment.type === "static") {
|
|
2548
|
+
if (decodePathSegment(parts[pathIndex] || "") !== segment.value) return null;
|
|
2549
|
+
pathIndex++;
|
|
2550
|
+
continue;
|
|
2551
|
+
}
|
|
2552
|
+
if (segment.catchAll) {
|
|
2553
|
+
const remaining = parts.slice(pathIndex).map(decodePathSegment);
|
|
2554
|
+
if (remaining.length === 0 && !segment.optional) return null;
|
|
2555
|
+
params[segment.name] = remaining.join("/");
|
|
2556
|
+
pathIndex = parts.length;
|
|
2557
|
+
continue;
|
|
2558
|
+
}
|
|
2559
|
+
const value = parts[pathIndex];
|
|
2560
|
+
if (!value) return null;
|
|
2561
|
+
params[segment.name] = decodePathSegment(value);
|
|
2562
|
+
pathIndex++;
|
|
2563
|
+
}
|
|
2564
|
+
return pathIndex === parts.length ? params : null;
|
|
2565
|
+
}
|
|
2566
|
+
__name(matchSegments, "matchSegments");
|
|
2567
|
+
function compareRoutes(left, right) {
|
|
2568
|
+
if (right.score !== left.score) return right.score - left.score;
|
|
2569
|
+
return left.index - right.index;
|
|
2570
|
+
}
|
|
2571
|
+
__name(compareRoutes, "compareRoutes");
|
|
2572
|
+
function scoreSegments(segments) {
|
|
2573
|
+
return segments.reduce((score, segment) => {
|
|
2574
|
+
if (segment.type === "static") return score + 100;
|
|
2575
|
+
if (!segment.catchAll) return score + 50;
|
|
2576
|
+
return score + (segment.optional ? 5 : 10);
|
|
2577
|
+
}, segments.length);
|
|
2578
|
+
}
|
|
2579
|
+
__name(scoreSegments, "scoreSegments");
|
|
2580
|
+
function normalizePathname(value) {
|
|
2581
|
+
const raw = value || "/";
|
|
2582
|
+
let pathname = raw;
|
|
2583
|
+
try {
|
|
2584
|
+
pathname = new URL(raw, "http://farm.local").pathname;
|
|
2585
|
+
} catch {
|
|
2586
|
+
pathname = raw.split(/[?#]/, 1)[0] || "/";
|
|
2587
|
+
}
|
|
2588
|
+
pathname = pathname.replace(/\\/g, "/").replace(/\/+/g, "/");
|
|
2589
|
+
if (!pathname.startsWith("/")) pathname = `/${pathname}`;
|
|
2590
|
+
if (pathname.length > 1) pathname = pathname.replace(/\/+$/, "");
|
|
2591
|
+
return pathname || "/";
|
|
2592
|
+
}
|
|
2593
|
+
__name(normalizePathname, "normalizePathname");
|
|
2594
|
+
function splitPathname(pathname) {
|
|
2595
|
+
return normalizePathname(pathname).split("/").filter(Boolean);
|
|
2596
|
+
}
|
|
2597
|
+
__name(splitPathname, "splitPathname");
|
|
2598
|
+
function isRouteGroup(part) {
|
|
2599
|
+
return part.startsWith("(") && part.endsWith(")");
|
|
2600
|
+
}
|
|
2601
|
+
__name(isRouteGroup, "isRouteGroup");
|
|
2602
|
+
function decodePathSegment(value) {
|
|
2603
|
+
try {
|
|
2604
|
+
return decodeURIComponent(value);
|
|
2605
|
+
} catch {
|
|
2606
|
+
return value;
|
|
2607
|
+
}
|
|
2608
|
+
}
|
|
2609
|
+
__name(decodePathSegment, "decodePathSegment");
|
|
2610
|
+
function encodePathSegment(value) {
|
|
2611
|
+
return encodeURIComponent(value);
|
|
2612
|
+
}
|
|
2613
|
+
__name(encodePathSegment, "encodePathSegment");
|
|
2614
|
+
function appendQueryAndHash(pathname, options) {
|
|
2615
|
+
const search = createSearchParams(options.query);
|
|
2616
|
+
const hash = options.hash ? `#${options.hash.replace(/^#/, "")}` : "";
|
|
2617
|
+
const query = search.toString();
|
|
2618
|
+
return `${pathname}${query ? `?${query}` : ""}${hash}`;
|
|
2619
|
+
}
|
|
2620
|
+
__name(appendQueryAndHash, "appendQueryAndHash");
|
|
2621
|
+
function createSearchParams(query) {
|
|
2622
|
+
if (query instanceof URLSearchParams) return query;
|
|
2623
|
+
const search = new URLSearchParams();
|
|
2624
|
+
if (!query) return search;
|
|
2625
|
+
for (const [key, value] of Object.entries(query)) {
|
|
2626
|
+
const values = Array.isArray(value) ? value : [value];
|
|
2627
|
+
for (const item of values) {
|
|
2628
|
+
if (item == null) continue;
|
|
2629
|
+
search.append(key, String(item));
|
|
2630
|
+
}
|
|
2631
|
+
}
|
|
2632
|
+
return search;
|
|
2633
|
+
}
|
|
2634
|
+
__name(createSearchParams, "createSearchParams");
|
|
2635
|
+
|
|
2636
|
+
// src/i18n/client-runtime.ts
|
|
2637
|
+
var import_intl_messageformat = __toESM(require("intl-messageformat"));
|
|
2638
|
+
|
|
2639
|
+
// src/i18n/routing.ts
|
|
2640
|
+
function resolveFarmLocalePath(pathname, config) {
|
|
2641
|
+
const normalized = normalizePathname2(pathname);
|
|
2642
|
+
if (config.routing === "none") {
|
|
2643
|
+
return { pathname: normalized, explicit: false };
|
|
2644
|
+
}
|
|
2645
|
+
const segments = normalized.split("/").filter(Boolean);
|
|
2646
|
+
const firstSegment = segments[0];
|
|
2647
|
+
const locale = config.locales.find(
|
|
2648
|
+
(candidate) => candidate.toLowerCase() === firstSegment?.toLowerCase()
|
|
2649
|
+
);
|
|
2650
|
+
if (!locale) {
|
|
2651
|
+
return { pathname: normalized, explicit: false };
|
|
2652
|
+
}
|
|
2653
|
+
const remaining = segments.slice(1);
|
|
2654
|
+
return {
|
|
2655
|
+
locale,
|
|
2656
|
+
pathname: remaining.length > 0 ? `/${remaining.join("/")}` : "/",
|
|
2657
|
+
explicit: true
|
|
2658
|
+
};
|
|
2659
|
+
}
|
|
2660
|
+
__name(resolveFarmLocalePath, "resolveFarmLocalePath");
|
|
2661
|
+
function stripFarmLocaleFromPathname(pathname, config) {
|
|
2662
|
+
return resolveFarmLocalePath(pathname, config).pathname;
|
|
2663
|
+
}
|
|
2664
|
+
__name(stripFarmLocaleFromPathname, "stripFarmLocaleFromPathname");
|
|
2665
|
+
function localizeFarmPathname(pathname, locale, config) {
|
|
2666
|
+
const internalPathname = resolveFarmLocalePath(pathname, config).pathname;
|
|
2667
|
+
if (config.routing === "none") return internalPathname;
|
|
2668
|
+
if (config.routing === "prefix-except-default" && locale === config.defaultLocale) {
|
|
2669
|
+
return internalPathname;
|
|
2670
|
+
}
|
|
2671
|
+
return internalPathname === "/" ? `/${locale}` : `/${locale}${internalPathname}`;
|
|
2672
|
+
}
|
|
2673
|
+
__name(localizeFarmPathname, "localizeFarmPathname");
|
|
2674
|
+
function localizeFarmHref(href, locale, config) {
|
|
2675
|
+
if (!href.startsWith("/") || href.startsWith("//")) return href;
|
|
2676
|
+
const url = new URL(href, "http://farm.local");
|
|
2677
|
+
url.pathname = localizeFarmPathname(url.pathname, locale, config);
|
|
2678
|
+
return `${url.pathname}${url.search}${url.hash}`;
|
|
2679
|
+
}
|
|
2680
|
+
__name(localizeFarmHref, "localizeFarmHref");
|
|
2681
|
+
function normalizePathname2(pathname) {
|
|
2682
|
+
const withLeadingSlash = pathname.startsWith("/") ? pathname : `/${pathname}`;
|
|
2683
|
+
if (withLeadingSlash === "/") return "/";
|
|
2684
|
+
return withLeadingSlash.replace(/\/{2,}/g, "/").replace(/\/$/, "") || "/";
|
|
2685
|
+
}
|
|
2686
|
+
__name(normalizePathname2, "normalizePathname");
|
|
2687
|
+
|
|
2688
|
+
// src/i18n/client-runtime.ts
|
|
2689
|
+
var listeners = /* @__PURE__ */ new Set();
|
|
2690
|
+
var compiled = /* @__PURE__ */ new Map();
|
|
2691
|
+
var currentSnapshot;
|
|
2692
|
+
function getFarmI18nClientState() {
|
|
2693
|
+
return currentSnapshot || getActiveFarmI18nSnapshot();
|
|
2694
|
+
}
|
|
2695
|
+
__name(getFarmI18nClientState, "getFarmI18nClientState");
|
|
2696
|
+
function _hydrateFarmI18n(snapshot) {
|
|
2697
|
+
if (!snapshot) return;
|
|
2698
|
+
const changed = currentSnapshot?.locale !== snapshot.locale;
|
|
2699
|
+
currentSnapshot = snapshot;
|
|
2700
|
+
if (typeof window !== "undefined") window.__FARM_I18N__ = snapshot;
|
|
2701
|
+
if (typeof document !== "undefined") {
|
|
2702
|
+
document.documentElement.lang = snapshot.locale;
|
|
2703
|
+
document.documentElement.dir = snapshot.direction;
|
|
2704
|
+
}
|
|
2705
|
+
if (changed) compiled.clear();
|
|
2706
|
+
for (const listener of listeners) listener();
|
|
2707
|
+
}
|
|
2708
|
+
__name(_hydrateFarmI18n, "_hydrateFarmI18n");
|
|
2709
|
+
var translate = /* @__PURE__ */ __name((key, values, rich = false) => {
|
|
2710
|
+
const snapshot = requireSnapshot();
|
|
2711
|
+
const message = snapshot.messages[key];
|
|
2712
|
+
if (message === void 0) return key;
|
|
2713
|
+
const cacheKey = `${snapshot.locale}\0${key}\0${message}`;
|
|
2714
|
+
let formatter = compiled.get(cacheKey);
|
|
2715
|
+
if (!formatter) {
|
|
2716
|
+
formatter = new import_intl_messageformat.default(message, snapshot.locale);
|
|
2717
|
+
compiled.set(cacheKey, formatter);
|
|
2718
|
+
}
|
|
2719
|
+
const result = formatter.format(values);
|
|
2720
|
+
if (rich) return Array.isArray(result) && result.length === 1 ? result[0] : result;
|
|
2721
|
+
if (Array.isArray(result) && result.some((part) => typeof part !== "string")) {
|
|
2722
|
+
throw new Error(`Farm i18n message "${key}" contains rich content. Render it with t.rich().`);
|
|
2723
|
+
}
|
|
2724
|
+
return Array.isArray(result) ? result.join("") : String(result);
|
|
2725
|
+
}, "translate");
|
|
2726
|
+
var t = /* @__PURE__ */ __name(((key, values) => translate(key, values)), "t");
|
|
2727
|
+
t.rich = (key, values) => translate(key, values, true);
|
|
2728
|
+
t.raw = (key) => requireSnapshot().messages[key] ?? key;
|
|
2729
|
+
t.has = (key) => key in requireSnapshot().messages;
|
|
2730
|
+
function localizeActiveFarmHref(href, locale) {
|
|
2731
|
+
const snapshot = getFarmI18nClientState();
|
|
2732
|
+
if (!snapshot) return href;
|
|
2733
|
+
return localizeFarmHref(href, locale || snapshot.locale, snapshot);
|
|
2734
|
+
}
|
|
2735
|
+
__name(localizeActiveFarmHref, "localizeActiveFarmHref");
|
|
2736
|
+
function isFarmLocaleChangeHref(href) {
|
|
2737
|
+
const snapshot = getFarmI18nClientState();
|
|
2738
|
+
if (!snapshot || typeof window === "undefined") return false;
|
|
2739
|
+
if (snapshot.routing === "none") return false;
|
|
2740
|
+
const target = new URL(href, window.location.origin);
|
|
2741
|
+
const match = resolveFarmLocalePath(target.pathname, snapshot);
|
|
2742
|
+
const targetLocale = match.locale || snapshot.defaultLocale;
|
|
2743
|
+
return targetLocale !== snapshot.locale;
|
|
2744
|
+
}
|
|
2745
|
+
__name(isFarmLocaleChangeHref, "isFarmLocaleChangeHref");
|
|
2746
|
+
function requireSnapshot() {
|
|
2747
|
+
const snapshot = getFarmI18nClientState();
|
|
2748
|
+
if (!snapshot) {
|
|
2749
|
+
throw new Error("Farm i18n is not configured or has not been hydrated.");
|
|
2750
|
+
}
|
|
2751
|
+
return snapshot;
|
|
2752
|
+
}
|
|
2753
|
+
__name(requireSnapshot, "requireSnapshot");
|
|
2754
|
+
|
|
2755
|
+
// src/client/link.tsx
|
|
2756
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
2757
|
+
function isModifierEvent(e) {
|
|
2758
|
+
return !!(e.metaKey || e.altKey || e.ctrlKey || e.shiftKey);
|
|
2759
|
+
}
|
|
2760
|
+
__name(isModifierEvent, "isModifierEvent");
|
|
2761
|
+
function isExternalUrl(href) {
|
|
2762
|
+
return href.startsWith("http://") || href.startsWith("https://") || href.startsWith("//");
|
|
2763
|
+
}
|
|
2764
|
+
__name(isExternalUrl, "isExternalUrl");
|
|
2765
|
+
function getRouter() {
|
|
2766
|
+
if (typeof window !== "undefined" && window.__FARM_SPA_ROUTER__) {
|
|
2767
|
+
return window.__FARM_SPA_ROUTER__;
|
|
2768
|
+
}
|
|
2769
|
+
return null;
|
|
2770
|
+
}
|
|
2771
|
+
__name(getRouter, "getRouter");
|
|
2772
|
+
function normalizePrefetch(prefetch2) {
|
|
2773
|
+
if (prefetch2 === false || prefetch2 === "none") {
|
|
2774
|
+
return { intent: false, viewport: false, render: false };
|
|
2775
|
+
}
|
|
2776
|
+
if (prefetch2 === true) {
|
|
2777
|
+
return { intent: true, viewport: true, render: false };
|
|
2778
|
+
}
|
|
2779
|
+
if (prefetch2 === "hover") {
|
|
2780
|
+
return { intent: true, viewport: false, render: false };
|
|
2781
|
+
}
|
|
2782
|
+
if (prefetch2 === "intent") {
|
|
2783
|
+
return { intent: true, viewport: false, render: false };
|
|
2784
|
+
}
|
|
2785
|
+
if (prefetch2 === "viewport") {
|
|
2786
|
+
return { intent: false, viewport: true, render: false };
|
|
2787
|
+
}
|
|
2788
|
+
if (prefetch2 === "render") {
|
|
2789
|
+
return { intent: false, viewport: false, render: true };
|
|
2790
|
+
}
|
|
2791
|
+
return { intent: false, viewport: false, render: false };
|
|
2792
|
+
}
|
|
2793
|
+
__name(normalizePrefetch, "normalizePrefetch");
|
|
2794
|
+
function LinkInner({
|
|
2795
|
+
href,
|
|
2796
|
+
params,
|
|
2797
|
+
query,
|
|
2798
|
+
hash,
|
|
2799
|
+
trailingSlash,
|
|
2800
|
+
prefetch: prefetch2 = true,
|
|
2801
|
+
prefetchDelay = 50,
|
|
2802
|
+
replace = false,
|
|
2803
|
+
scroll = true,
|
|
2804
|
+
viewTransition = false,
|
|
2805
|
+
locale,
|
|
2806
|
+
onClick,
|
|
2807
|
+
target,
|
|
2808
|
+
onMouseEnter,
|
|
2809
|
+
onMouseLeave,
|
|
2810
|
+
onFocus,
|
|
2811
|
+
onBlur,
|
|
2812
|
+
onTouchStart,
|
|
2813
|
+
...props
|
|
2814
|
+
}, ref) {
|
|
2815
|
+
const elementRef = (0, import_react3.useRef)(null);
|
|
2816
|
+
const intentTimeoutRef = (0, import_react3.useRef)(null);
|
|
2817
|
+
const hasPrefetched = (0, import_react3.useRef)(false);
|
|
2818
|
+
const { intent, viewport, render } = normalizePrefetch(prefetch2);
|
|
2819
|
+
const baseHref = resolveLinkHref(href, params, {
|
|
2820
|
+
query,
|
|
2821
|
+
hash,
|
|
2822
|
+
trailingSlash
|
|
2823
|
+
});
|
|
2824
|
+
const resolvedHref = localizeActiveFarmHref(baseHref, locale);
|
|
2825
|
+
const isExternal = isExternalUrl(resolvedHref);
|
|
2826
|
+
const doPrefetch = (0, import_react3.useCallback)(() => {
|
|
2827
|
+
if (isExternal || hasPrefetched.current) return;
|
|
2828
|
+
const router = getRouter();
|
|
2829
|
+
if (!router) return;
|
|
2830
|
+
hasPrefetched.current = true;
|
|
2831
|
+
router.prefetch(resolvedHref);
|
|
2832
|
+
}, [resolvedHref, isExternal]);
|
|
2833
|
+
(0, import_react3.useEffect)(() => {
|
|
2834
|
+
hasPrefetched.current = false;
|
|
2835
|
+
}, [resolvedHref]);
|
|
2836
|
+
(0, import_react3.useEffect)(() => {
|
|
2837
|
+
const element = elementRef.current;
|
|
2838
|
+
if (!element || isExternal) return;
|
|
2839
|
+
const router = getRouter();
|
|
2840
|
+
if (!router) return;
|
|
2841
|
+
if (viewport) {
|
|
2842
|
+
router.observeForPrefetch(element);
|
|
2843
|
+
return () => router.unobserveForPrefetch(element);
|
|
2844
|
+
}
|
|
2845
|
+
}, [resolvedHref, viewport, isExternal]);
|
|
2846
|
+
(0, import_react3.useEffect)(() => {
|
|
2847
|
+
if (!render || isExternal) return;
|
|
2848
|
+
let cancelled = false;
|
|
2849
|
+
let timeoutId = null;
|
|
2850
|
+
const tryRenderPrefetch = /* @__PURE__ */ __name(() => {
|
|
2851
|
+
if (cancelled || hasPrefetched.current) return;
|
|
2852
|
+
const router = getRouter();
|
|
2853
|
+
if (!router) {
|
|
2854
|
+
timeoutId = setTimeout(tryRenderPrefetch, 30);
|
|
2855
|
+
return;
|
|
2856
|
+
}
|
|
2857
|
+
hasPrefetched.current = true;
|
|
2858
|
+
router.prefetch(resolvedHref);
|
|
2859
|
+
}, "tryRenderPrefetch");
|
|
2860
|
+
tryRenderPrefetch();
|
|
2861
|
+
return () => {
|
|
2862
|
+
cancelled = true;
|
|
2863
|
+
if (timeoutId) {
|
|
2864
|
+
clearTimeout(timeoutId);
|
|
2865
|
+
}
|
|
2866
|
+
};
|
|
2867
|
+
}, [render, isExternal, resolvedHref]);
|
|
2868
|
+
(0, import_react3.useEffect)(() => {
|
|
2869
|
+
return () => {
|
|
2870
|
+
if (intentTimeoutRef.current) {
|
|
2871
|
+
clearTimeout(intentTimeoutRef.current);
|
|
2872
|
+
intentTimeoutRef.current = null;
|
|
2873
|
+
}
|
|
2874
|
+
};
|
|
2875
|
+
}, []);
|
|
2876
|
+
const cancelIntent = (0, import_react3.useCallback)(() => {
|
|
2877
|
+
if (intentTimeoutRef.current) {
|
|
2878
|
+
clearTimeout(intentTimeoutRef.current);
|
|
2879
|
+
intentTimeoutRef.current = null;
|
|
2880
|
+
}
|
|
2881
|
+
}, []);
|
|
2882
|
+
const scheduleIntentPrefetch = (0, import_react3.useCallback)(() => {
|
|
2883
|
+
if (isExternal || !intent || hasPrefetched.current) return;
|
|
2884
|
+
cancelIntent();
|
|
2885
|
+
intentTimeoutRef.current = setTimeout(() => {
|
|
2886
|
+
intentTimeoutRef.current = null;
|
|
2887
|
+
doPrefetch();
|
|
2888
|
+
}, prefetchDelay);
|
|
2889
|
+
}, [intent, isExternal, prefetchDelay, doPrefetch, cancelIntent]);
|
|
2890
|
+
const handleMouseEnter = (0, import_react3.useCallback)(
|
|
2891
|
+
(event) => {
|
|
2892
|
+
onMouseEnter?.(event);
|
|
2893
|
+
scheduleIntentPrefetch();
|
|
2894
|
+
},
|
|
2895
|
+
[onMouseEnter, scheduleIntentPrefetch]
|
|
2896
|
+
);
|
|
2897
|
+
const handleMouseLeave = (0, import_react3.useCallback)(
|
|
2898
|
+
(event) => {
|
|
2899
|
+
onMouseLeave?.(event);
|
|
2900
|
+
cancelIntent();
|
|
2901
|
+
},
|
|
2902
|
+
[onMouseLeave, cancelIntent]
|
|
2903
|
+
);
|
|
2904
|
+
const handleTouchStart = (0, import_react3.useCallback)(
|
|
2905
|
+
(event) => {
|
|
2906
|
+
onTouchStart?.(event);
|
|
2907
|
+
scheduleIntentPrefetch();
|
|
2908
|
+
},
|
|
2909
|
+
[onTouchStart, scheduleIntentPrefetch]
|
|
2910
|
+
);
|
|
2911
|
+
const handleFocus = (0, import_react3.useCallback)(
|
|
2912
|
+
(event) => {
|
|
2913
|
+
onFocus?.(event);
|
|
2914
|
+
scheduleIntentPrefetch();
|
|
2915
|
+
},
|
|
2916
|
+
[onFocus, scheduleIntentPrefetch]
|
|
2917
|
+
);
|
|
2918
|
+
const handleBlur = (0, import_react3.useCallback)(
|
|
2919
|
+
(event) => {
|
|
2920
|
+
onBlur?.(event);
|
|
2921
|
+
cancelIntent();
|
|
2922
|
+
},
|
|
2923
|
+
[onBlur, cancelIntent]
|
|
2924
|
+
);
|
|
2925
|
+
const handleClick = (0, import_react3.useCallback)(
|
|
2926
|
+
(event) => {
|
|
2927
|
+
onClick?.(event);
|
|
2928
|
+
if (event.defaultPrevented) return;
|
|
2929
|
+
if (isExternal) return;
|
|
2930
|
+
if (target && target !== "_self") return;
|
|
2931
|
+
if (isModifierEvent(event)) return;
|
|
2932
|
+
if (event.button !== 0) return;
|
|
2933
|
+
if (typeof window !== "undefined") {
|
|
2934
|
+
event.preventDefault();
|
|
2935
|
+
if (isFarmLocaleChangeHref(resolvedHref)) {
|
|
2936
|
+
window.location.assign(resolvedHref);
|
|
2937
|
+
return;
|
|
2938
|
+
}
|
|
2939
|
+
const router = getRouter();
|
|
2940
|
+
if (router) {
|
|
2941
|
+
router.navigate(resolvedHref, { replace, scroll, viewTransition });
|
|
2942
|
+
} else {
|
|
2943
|
+
if (replace) window.location.replace(resolvedHref);
|
|
2944
|
+
else window.location.href = resolvedHref;
|
|
2945
|
+
}
|
|
2946
|
+
}
|
|
2947
|
+
},
|
|
2948
|
+
[resolvedHref, replace, scroll, viewTransition, target, isExternal, onClick]
|
|
2949
|
+
);
|
|
2950
|
+
const setRefs = (0, import_react3.useCallback)(
|
|
2951
|
+
(node) => {
|
|
2952
|
+
elementRef.current = node;
|
|
2953
|
+
if (typeof ref === "function") ref(node);
|
|
2954
|
+
else if (ref) ref.current = node;
|
|
2955
|
+
},
|
|
2956
|
+
[ref]
|
|
2957
|
+
);
|
|
2958
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
2959
|
+
"a",
|
|
2960
|
+
{
|
|
2961
|
+
ref: setRefs,
|
|
2962
|
+
href: resolvedHref,
|
|
2963
|
+
target,
|
|
2964
|
+
onClick: handleClick,
|
|
2965
|
+
onMouseEnter: handleMouseEnter,
|
|
2966
|
+
onMouseLeave: handleMouseLeave,
|
|
2967
|
+
onFocus: handleFocus,
|
|
2968
|
+
onBlur: handleBlur,
|
|
2969
|
+
onTouchStart: handleTouchStart,
|
|
2970
|
+
...props,
|
|
2971
|
+
"data-farm-link": "",
|
|
2972
|
+
"data-replace": replace ? "" : void 0,
|
|
2973
|
+
"data-no-scroll": !scroll ? "" : void 0,
|
|
2974
|
+
"data-view-transition": viewTransition === "auto" ? "auto" : viewTransition ? "true" : void 0
|
|
2975
|
+
}
|
|
2976
|
+
);
|
|
2977
|
+
}
|
|
2978
|
+
__name(LinkInner, "LinkInner");
|
|
2979
|
+
var LinkWithRef = (0, import_react3.forwardRef)(LinkInner);
|
|
2980
|
+
LinkWithRef.displayName = "Link";
|
|
2981
|
+
var Link = LinkWithRef;
|
|
2982
|
+
function resolveLinkHref(href, params, options) {
|
|
2983
|
+
if (isExternalUrl(href)) return href;
|
|
2984
|
+
const { pathname, query, hash } = splitInternalHref(href);
|
|
2985
|
+
const resolvedHref = buildFarmRoutePath(pathname, params, {
|
|
2986
|
+
query: mergeQueryParams(query, options.query),
|
|
2987
|
+
hash: options.hash ?? hash,
|
|
2988
|
+
trailingSlash: options.trailingSlash
|
|
2989
|
+
});
|
|
2990
|
+
return applyPreservedSearchParams(resolvedHref);
|
|
2991
|
+
}
|
|
2992
|
+
__name(resolveLinkHref, "resolveLinkHref");
|
|
2993
|
+
function splitInternalHref(href) {
|
|
2994
|
+
try {
|
|
2995
|
+
const url = new URL(href, "http://farm.local");
|
|
2996
|
+
return {
|
|
2997
|
+
pathname: url.pathname || "/",
|
|
2998
|
+
query: url.searchParams,
|
|
2999
|
+
hash: url.hash ? url.hash.slice(1) : void 0
|
|
3000
|
+
};
|
|
3001
|
+
} catch {
|
|
3002
|
+
const [withoutHash, rawHash] = href.split("#", 2);
|
|
3003
|
+
const [pathname, rawQuery] = withoutHash.split("?", 2);
|
|
3004
|
+
return {
|
|
3005
|
+
pathname: pathname || "/",
|
|
3006
|
+
query: new URLSearchParams(rawQuery || ""),
|
|
3007
|
+
hash: rawHash
|
|
3008
|
+
};
|
|
3009
|
+
}
|
|
3010
|
+
}
|
|
3011
|
+
__name(splitInternalHref, "splitInternalHref");
|
|
3012
|
+
function mergeQueryParams(current, next) {
|
|
3013
|
+
const merged = new URLSearchParams(current);
|
|
3014
|
+
if (next instanceof URLSearchParams) {
|
|
3015
|
+
for (const [key, value] of next.entries()) {
|
|
3016
|
+
merged.append(key, value);
|
|
3017
|
+
}
|
|
3018
|
+
} else if (next) {
|
|
3019
|
+
for (const [key, value] of Object.entries(next)) {
|
|
3020
|
+
const values = Array.isArray(value) ? value : [value];
|
|
3021
|
+
for (const item of values) {
|
|
3022
|
+
if (item == null) continue;
|
|
3023
|
+
merged.append(key, String(item));
|
|
3024
|
+
}
|
|
3025
|
+
}
|
|
3026
|
+
}
|
|
3027
|
+
return merged.toString() ? merged : void 0;
|
|
3028
|
+
}
|
|
3029
|
+
__name(mergeQueryParams, "mergeQueryParams");
|
|
3030
|
+
function applyPreservedSearchParams(href) {
|
|
3031
|
+
if (typeof window === "undefined") return href;
|
|
3032
|
+
const manifest = window.__FARM_MANIFEST__;
|
|
3033
|
+
const routes = manifest?.routes && typeof manifest.routes === "object" ? Object.values(manifest.routes) : [];
|
|
3034
|
+
if (routes.length === 0) return href;
|
|
3035
|
+
const url = new URL(href, window.location.origin);
|
|
3036
|
+
const route2 = routes.find((candidate) => matchManifestRoute(url.pathname, candidate));
|
|
3037
|
+
const preserve = Array.isArray(route2?.search?.preserve) ? route2.search.preserve : [];
|
|
3038
|
+
if (preserve.length === 0) return href;
|
|
3039
|
+
const current = new URLSearchParams(window.location.search);
|
|
3040
|
+
let changed = false;
|
|
3041
|
+
for (const key of preserve) {
|
|
3042
|
+
if (url.searchParams.has(key) || !current.has(key)) continue;
|
|
3043
|
+
for (const value of current.getAll(key)) {
|
|
3044
|
+
url.searchParams.append(key, value);
|
|
3045
|
+
changed = true;
|
|
3046
|
+
}
|
|
3047
|
+
}
|
|
3048
|
+
if (!changed) return href;
|
|
3049
|
+
return `${url.pathname}${url.search}${url.hash}`;
|
|
3050
|
+
}
|
|
3051
|
+
__name(applyPreservedSearchParams, "applyPreservedSearchParams");
|
|
3052
|
+
function matchManifestRoute(pathname, route2) {
|
|
3053
|
+
if (!route2 || !Array.isArray(route2.segments)) return false;
|
|
3054
|
+
const routeSegments = route2.segments;
|
|
3055
|
+
const normalized = pathname === "/" ? "" : pathname.replace(/^\/+/, "").replace(/\/+$/, "");
|
|
3056
|
+
const pathSegments = normalized ? normalized.split("/") : [];
|
|
3057
|
+
const hasCatchAll = routeSegments.some((segment) => segment.isCatchAll);
|
|
3058
|
+
if (!hasCatchAll && pathSegments.length !== routeSegments.length) {
|
|
3059
|
+
return false;
|
|
3060
|
+
}
|
|
3061
|
+
for (let index = 0; index < routeSegments.length; index++) {
|
|
3062
|
+
const routeSegment = routeSegments[index];
|
|
3063
|
+
const pathSegment = pathSegments[index];
|
|
3064
|
+
if (routeSegment.isCatchAll) {
|
|
3065
|
+
return true;
|
|
3066
|
+
}
|
|
3067
|
+
if (pathSegment === void 0) {
|
|
3068
|
+
if (routeSegment.isOptional) continue;
|
|
3069
|
+
return false;
|
|
3070
|
+
}
|
|
3071
|
+
if (!routeSegment.isDynamic && routeSegment.segment !== pathSegment) {
|
|
3072
|
+
return false;
|
|
3073
|
+
}
|
|
3074
|
+
}
|
|
3075
|
+
return pathSegments.length === routeSegments.length || hasCatchAll;
|
|
3076
|
+
}
|
|
3077
|
+
__name(matchManifestRoute, "matchManifestRoute");
|
|
3078
|
+
|
|
3079
|
+
// src/client/router.ts
|
|
3080
|
+
var import_react4 = require("react");
|
|
3081
|
+
|
|
3082
|
+
// src/deferred.ts
|
|
3083
|
+
var FARM_DEFERRED_CONTENT_TYPE = "application/x-farm-deferred+json";
|
|
3084
|
+
var FARM_DEFERRED_ERROR_CODE = "FARM_DEFERRED_DATA_ERROR";
|
|
3085
|
+
var FARM_DEFERRED_MARKER = "$farmDeferred";
|
|
3086
|
+
var _DeferredDataError = class _DeferredDataError extends Error {
|
|
3087
|
+
constructor(message = "Deferred route data failed to load") {
|
|
3088
|
+
super(message);
|
|
3089
|
+
this.name = "DeferredDataError";
|
|
3090
|
+
this.code = FARM_DEFERRED_ERROR_CODE;
|
|
3091
|
+
}
|
|
3092
|
+
};
|
|
3093
|
+
__name(_DeferredDataError, "DeferredDataError");
|
|
3094
|
+
var DeferredDataError = _DeferredDataError;
|
|
3095
|
+
async function readDeferredDataResponse(response) {
|
|
3096
|
+
const contentType = response.headers.get("Content-Type") || "";
|
|
3097
|
+
if (!contentType.toLowerCase().startsWith(FARM_DEFERRED_CONTENT_TYPE)) {
|
|
3098
|
+
return await response.json();
|
|
3099
|
+
}
|
|
3100
|
+
if (!response.body) {
|
|
3101
|
+
throw new DeferredDataError("Deferred route data response has no body");
|
|
3102
|
+
}
|
|
3103
|
+
const reader = response.body.getReader();
|
|
3104
|
+
const decoder = new TextDecoder();
|
|
3105
|
+
const controllers = /* @__PURE__ */ new Map();
|
|
3106
|
+
let buffer = "";
|
|
3107
|
+
let complete = false;
|
|
3108
|
+
const readLine = /* @__PURE__ */ __name(async () => {
|
|
3109
|
+
while (true) {
|
|
3110
|
+
const newline = buffer.indexOf("\n");
|
|
3111
|
+
if (newline >= 0) {
|
|
3112
|
+
const line = buffer.slice(0, newline);
|
|
3113
|
+
buffer = buffer.slice(newline + 1);
|
|
3114
|
+
return line;
|
|
3115
|
+
}
|
|
3116
|
+
if (complete) {
|
|
3117
|
+
if (!buffer) return void 0;
|
|
3118
|
+
const line = buffer;
|
|
3119
|
+
buffer = "";
|
|
3120
|
+
return line;
|
|
3121
|
+
}
|
|
3122
|
+
const chunk = await reader.read();
|
|
3123
|
+
complete = chunk.done;
|
|
3124
|
+
if (chunk.value) buffer += decoder.decode(chunk.value, { stream: !chunk.done });
|
|
3125
|
+
if (chunk.done) buffer += decoder.decode();
|
|
3126
|
+
}
|
|
3127
|
+
}, "readLine");
|
|
3128
|
+
const firstLine = await readLine();
|
|
3129
|
+
if (!firstLine) {
|
|
3130
|
+
reader.releaseLock();
|
|
3131
|
+
throw new DeferredDataError("Deferred route data response is empty");
|
|
3132
|
+
}
|
|
3133
|
+
const initial = parseDeferredMessage(firstLine);
|
|
3134
|
+
if (initial.type !== "data") {
|
|
3135
|
+
reader.releaseLock();
|
|
3136
|
+
throw new DeferredDataError("Deferred route data response is invalid");
|
|
3137
|
+
}
|
|
3138
|
+
const data = reviveDeferredValue(initial.data, controllers);
|
|
3139
|
+
void (async () => {
|
|
3140
|
+
try {
|
|
3141
|
+
for (let line = await readLine(); line !== void 0; line = await readLine()) {
|
|
3142
|
+
if (!line) continue;
|
|
3143
|
+
const message = parseDeferredMessage(line);
|
|
3144
|
+
if (message.type === "resolve") {
|
|
3145
|
+
const controller = getControlledDeferred(message.id, controllers);
|
|
3146
|
+
controller.resolve(reviveDeferredValue(message.data, controllers));
|
|
3147
|
+
} else if (message.type === "reject") {
|
|
3148
|
+
getControlledDeferred(message.id, controllers).reject(
|
|
3149
|
+
new DeferredDataError(message.error?.message)
|
|
3150
|
+
);
|
|
3151
|
+
}
|
|
3152
|
+
}
|
|
3153
|
+
rejectPendingDeferred(controllers, "Deferred route data stream ended before completion");
|
|
3154
|
+
} catch {
|
|
3155
|
+
rejectPendingDeferred(controllers, "Deferred route data stream could not be read");
|
|
3156
|
+
} finally {
|
|
3157
|
+
reader.releaseLock();
|
|
3158
|
+
}
|
|
3159
|
+
})();
|
|
3160
|
+
return data;
|
|
3161
|
+
}
|
|
3162
|
+
__name(readDeferredDataResponse, "readDeferredDataResponse");
|
|
3163
|
+
function reviveDeferredValue(value, controllers, settlements, applyingSettlements = /* @__PURE__ */ new Set()) {
|
|
3164
|
+
if (isDeferredMarker(value)) {
|
|
3165
|
+
const id = value[FARM_DEFERRED_MARKER];
|
|
3166
|
+
const controller = getControlledDeferred(id, controllers);
|
|
3167
|
+
const settlement = settlements?.[id];
|
|
3168
|
+
if (settlement && controller.promise.status === "pending") {
|
|
3169
|
+
if (applyingSettlements.has(id)) return controller.promise;
|
|
3170
|
+
applyingSettlements.add(id);
|
|
3171
|
+
if (settlement.status === "fulfilled") {
|
|
3172
|
+
controller.resolve(
|
|
3173
|
+
reviveDeferredValue(settlement.value, controllers, settlements, applyingSettlements)
|
|
3174
|
+
);
|
|
3175
|
+
} else {
|
|
3176
|
+
controller.reject(new DeferredDataError(settlement.error.message));
|
|
3177
|
+
}
|
|
3178
|
+
applyingSettlements.delete(id);
|
|
3179
|
+
} else if (settlements && controller.promise.status === "pending") {
|
|
3180
|
+
controller.reject(new DeferredDataError("Deferred route data was not resolved"));
|
|
3181
|
+
}
|
|
3182
|
+
return controller.promise;
|
|
3183
|
+
}
|
|
3184
|
+
if (Array.isArray(value)) {
|
|
3185
|
+
return value.map(
|
|
3186
|
+
(item) => reviveDeferredValue(item, controllers, settlements, applyingSettlements)
|
|
3187
|
+
);
|
|
3188
|
+
}
|
|
3189
|
+
if (!value || typeof value !== "object") return value;
|
|
3190
|
+
const prototype = Object.getPrototypeOf(value);
|
|
3191
|
+
if (prototype !== Object.prototype && prototype !== null) return value;
|
|
3192
|
+
const output = {};
|
|
3193
|
+
for (const [key, item] of Object.entries(value)) {
|
|
3194
|
+
output[key] = reviveDeferredValue(item, controllers, settlements, applyingSettlements);
|
|
3195
|
+
}
|
|
3196
|
+
return output;
|
|
3197
|
+
}
|
|
3198
|
+
__name(reviveDeferredValue, "reviveDeferredValue");
|
|
3199
|
+
function getControlledDeferred(id, controllers) {
|
|
3200
|
+
const existing = controllers.get(id);
|
|
3201
|
+
if (existing) return existing;
|
|
3202
|
+
let nativeResolve;
|
|
3203
|
+
let nativeReject;
|
|
3204
|
+
const promise = new Promise((resolve, reject) => {
|
|
3205
|
+
nativeResolve = resolve;
|
|
3206
|
+
nativeReject = reject;
|
|
3207
|
+
});
|
|
3208
|
+
promise.status = "pending";
|
|
3209
|
+
promise.catch(() => void 0);
|
|
3210
|
+
const controlled = {
|
|
3211
|
+
promise,
|
|
3212
|
+
resolve(value) {
|
|
3213
|
+
if (promise.status !== "pending") return;
|
|
3214
|
+
promise.status = "fulfilled";
|
|
3215
|
+
promise.value = value;
|
|
3216
|
+
nativeResolve(value);
|
|
3217
|
+
},
|
|
3218
|
+
reject(error) {
|
|
3219
|
+
if (promise.status !== "pending") return;
|
|
3220
|
+
promise.status = "rejected";
|
|
3221
|
+
promise.reason = error;
|
|
3222
|
+
nativeReject(error);
|
|
3223
|
+
}
|
|
3224
|
+
};
|
|
3225
|
+
controllers.set(id, controlled);
|
|
3226
|
+
return controlled;
|
|
3227
|
+
}
|
|
3228
|
+
__name(getControlledDeferred, "getControlledDeferred");
|
|
3229
|
+
function isDeferredMarker(value) {
|
|
3230
|
+
return Boolean(
|
|
3231
|
+
value && typeof value === "object" && Object.keys(value).length === 1 && typeof value[FARM_DEFERRED_MARKER] === "string"
|
|
3232
|
+
);
|
|
3233
|
+
}
|
|
3234
|
+
__name(isDeferredMarker, "isDeferredMarker");
|
|
3235
|
+
function parseDeferredMessage(line) {
|
|
3236
|
+
try {
|
|
3237
|
+
return JSON.parse(line);
|
|
3238
|
+
} catch {
|
|
3239
|
+
throw new DeferredDataError("Deferred route data response contains invalid JSON");
|
|
3240
|
+
}
|
|
3241
|
+
}
|
|
3242
|
+
__name(parseDeferredMessage, "parseDeferredMessage");
|
|
3243
|
+
function rejectPendingDeferred(controllers, message) {
|
|
3244
|
+
for (const controller of controllers.values()) {
|
|
3245
|
+
if (controller.promise.status === "pending") {
|
|
3246
|
+
controller.reject(new DeferredDataError(message));
|
|
3247
|
+
}
|
|
3248
|
+
}
|
|
3249
|
+
}
|
|
3250
|
+
__name(rejectPendingDeferred, "rejectPendingDeferred");
|
|
3251
|
+
|
|
3252
|
+
// src/deployment.ts
|
|
3253
|
+
var FARM_DEPLOYMENT_ID_HEADER = "x-farm-deployment-id";
|
|
3254
|
+
var FARM_DEPLOYMENT_MISMATCH_HEADER = "x-farm-deployment-mismatch";
|
|
3255
|
+
var FARM_DEPLOYMENT_MISMATCH_CODE = "FARM_DEPLOYMENT_MISMATCH";
|
|
3256
|
+
var FARM_DEPLOYMENT_MISMATCH_STATUS = 409;
|
|
3257
|
+
var _FarmDeploymentMismatchError = class _FarmDeploymentMismatchError extends Error {
|
|
3258
|
+
constructor(clientDeploymentId, serverDeploymentId) {
|
|
3259
|
+
super("The application was updated while this page was open. Refresh before trying again.");
|
|
3260
|
+
this.clientDeploymentId = clientDeploymentId;
|
|
3261
|
+
this.serverDeploymentId = serverDeploymentId;
|
|
3262
|
+
this.name = "FarmDeploymentMismatchError";
|
|
3263
|
+
this.code = FARM_DEPLOYMENT_MISMATCH_CODE;
|
|
3264
|
+
this.retryable = false;
|
|
3265
|
+
}
|
|
3266
|
+
};
|
|
3267
|
+
__name(_FarmDeploymentMismatchError, "FarmDeploymentMismatchError");
|
|
3268
|
+
var FarmDeploymentMismatchError = _FarmDeploymentMismatchError;
|
|
3269
|
+
function createFarmDeploymentRequestHeaders(deploymentId, init) {
|
|
3270
|
+
const headers = new Headers(init);
|
|
3271
|
+
if (deploymentId) {
|
|
3272
|
+
headers.set(FARM_DEPLOYMENT_ID_HEADER, deploymentId);
|
|
3273
|
+
}
|
|
3274
|
+
return headers;
|
|
3275
|
+
}
|
|
3276
|
+
__name(createFarmDeploymentRequestHeaders, "createFarmDeploymentRequestHeaders");
|
|
3277
|
+
function getFarmResponseDeploymentId(response) {
|
|
3278
|
+
return response.headers.get(FARM_DEPLOYMENT_ID_HEADER)?.trim() || void 0;
|
|
3279
|
+
}
|
|
3280
|
+
__name(getFarmResponseDeploymentId, "getFarmResponseDeploymentId");
|
|
3281
|
+
function isFarmDeploymentMismatchResponse(response, clientDeploymentId) {
|
|
3282
|
+
const serverDeploymentId = getFarmResponseDeploymentId(response);
|
|
3283
|
+
if (clientDeploymentId && serverDeploymentId && clientDeploymentId !== serverDeploymentId) {
|
|
3284
|
+
return true;
|
|
3285
|
+
}
|
|
3286
|
+
return response.status === FARM_DEPLOYMENT_MISMATCH_STATUS && response.headers.get(FARM_DEPLOYMENT_MISMATCH_HEADER) === "1";
|
|
3287
|
+
}
|
|
3288
|
+
__name(isFarmDeploymentMismatchResponse, "isFarmDeploymentMismatchResponse");
|
|
3289
|
+
function createFarmDeploymentMismatchError(response, clientDeploymentId) {
|
|
3290
|
+
return new FarmDeploymentMismatchError(
|
|
3291
|
+
clientDeploymentId,
|
|
3292
|
+
getFarmResponseDeploymentId(response) || "unknown"
|
|
3293
|
+
);
|
|
3294
|
+
}
|
|
3295
|
+
__name(createFarmDeploymentMismatchError, "createFarmDeploymentMismatchError");
|
|
3296
|
+
|
|
3297
|
+
// src/client/spa-router.ts
|
|
3298
|
+
var FARM_PAGE_STATE_KEY = "__farmPageState";
|
|
3299
|
+
var IDLE_NAVIGATION_STATE = {
|
|
3300
|
+
state: "idle",
|
|
3301
|
+
pending: false,
|
|
3302
|
+
from: null,
|
|
3303
|
+
to: null,
|
|
3304
|
+
action: null,
|
|
3305
|
+
startedAt: null
|
|
3306
|
+
};
|
|
3307
|
+
var routerInstance = null;
|
|
3308
|
+
var _SPARouter = class _SPARouter {
|
|
3309
|
+
constructor(options = {}) {
|
|
3310
|
+
this.cache = /* @__PURE__ */ new Map();
|
|
3311
|
+
this.prefetchingUrls = /* @__PURE__ */ new Set();
|
|
3312
|
+
this.observers = /* @__PURE__ */ new Map();
|
|
3313
|
+
this.blockers = /* @__PURE__ */ new Set();
|
|
3314
|
+
this.navigationListeners = /* @__PURE__ */ new Set();
|
|
3315
|
+
this.navigationState = IDLE_NAVIGATION_STATE;
|
|
3316
|
+
this.scrollElements = /* @__PURE__ */ new Map();
|
|
3317
|
+
this.options = {
|
|
3318
|
+
prefetchTimeout: options.prefetchTimeout ?? 100,
|
|
3319
|
+
cacheMaxAge: options.cacheMaxAge ?? 3e4,
|
|
3320
|
+
// 30 seconds
|
|
3321
|
+
scrollRestoration: options.scrollRestoration ?? true,
|
|
3322
|
+
shouldUseDocumentNavigation: options.shouldUseDocumentNavigation ?? (() => false),
|
|
3323
|
+
deploymentId: options.deploymentId ?? readBrowserDeploymentId()
|
|
3324
|
+
};
|
|
3325
|
+
if (typeof window !== "undefined") {
|
|
3326
|
+
window.addEventListener("popstate", this.handlePopState.bind(this));
|
|
3327
|
+
window.addEventListener("beforeunload", (event) => {
|
|
3328
|
+
if (this.blockers.size > 0) {
|
|
3329
|
+
event.preventDefault();
|
|
3330
|
+
event.returnValue = "";
|
|
3331
|
+
}
|
|
3332
|
+
this.saveScrollPosition(window.location.pathname);
|
|
3333
|
+
});
|
|
3334
|
+
}
|
|
3335
|
+
}
|
|
3336
|
+
/**
|
|
3337
|
+
* Set the navigation handler that updates React
|
|
3338
|
+
*/
|
|
3339
|
+
setNavigationHandler(handler) {
|
|
3340
|
+
this.onNavigate = handler;
|
|
3341
|
+
}
|
|
3342
|
+
/**
|
|
3343
|
+
* Connect Farm's browser plugin lifecycle to SPA navigation.
|
|
3344
|
+
*/
|
|
3345
|
+
setClientPluginManager(manager) {
|
|
3346
|
+
this.clientPlugins = manager;
|
|
3347
|
+
}
|
|
3348
|
+
/**
|
|
3349
|
+
* Navigate to a new URL
|
|
3350
|
+
*/
|
|
3351
|
+
async navigate(href, options = {}) {
|
|
3352
|
+
const { replace = false, scroll = true, state, viewTransition = false } = options;
|
|
3353
|
+
const url = new URL(href, window.location.origin);
|
|
3354
|
+
const pathname = url.pathname;
|
|
3355
|
+
const search = url.search;
|
|
3356
|
+
const fullPath = pathname + search;
|
|
3357
|
+
if (isFarmLocaleChangeHref(url.toString()) || this.options.shouldUseDocumentNavigation(pathname)) {
|
|
3358
|
+
if (replace) window.location.replace(url.toString());
|
|
3359
|
+
else window.location.assign(url.toString());
|
|
3360
|
+
return;
|
|
3361
|
+
}
|
|
3362
|
+
if (pathname === window.location.pathname && search === window.location.search) {
|
|
3363
|
+
if (url.hash) {
|
|
3364
|
+
window.location.hash = url.hash;
|
|
3365
|
+
}
|
|
3366
|
+
return;
|
|
3367
|
+
}
|
|
3368
|
+
const from = window.location.pathname + window.location.search;
|
|
3369
|
+
if (await this.shouldBlockNavigation({ from, to: fullPath, action: replace ? "replace" : "push" })) {
|
|
3370
|
+
return;
|
|
3371
|
+
}
|
|
3372
|
+
if (this.options.scrollRestoration) {
|
|
3373
|
+
this.saveScrollPosition(window.location.pathname);
|
|
3374
|
+
}
|
|
3375
|
+
this.startNavigation({
|
|
3376
|
+
from,
|
|
3377
|
+
to: createNavigationLocation(url),
|
|
3378
|
+
action: replace ? "replace" : "push"
|
|
3379
|
+
});
|
|
3380
|
+
let clientNavigation;
|
|
3381
|
+
try {
|
|
3382
|
+
clientNavigation = await this.clientPlugins?.beginNavigation({
|
|
3383
|
+
from,
|
|
3384
|
+
to: url,
|
|
3385
|
+
action: replace ? "replace" : "push"
|
|
3386
|
+
});
|
|
3387
|
+
const pageData = await this.fetchPageData(fullPath);
|
|
3388
|
+
if (clientNavigation) {
|
|
3389
|
+
await this.clientPlugins?.markNavigationLoaded(clientNavigation, pageData);
|
|
3390
|
+
}
|
|
3391
|
+
if (pageData.isClientComponent === false) {
|
|
3392
|
+
this.finishNavigation();
|
|
3393
|
+
window.location.assign(pageData.canonicalPath || fullPath);
|
|
3394
|
+
return;
|
|
3395
|
+
}
|
|
3396
|
+
await this.runViewTransition(
|
|
3397
|
+
viewTransition,
|
|
3398
|
+
() => this.commitNavigation({
|
|
3399
|
+
fullPath,
|
|
3400
|
+
pageData,
|
|
3401
|
+
pathname,
|
|
3402
|
+
replace,
|
|
3403
|
+
scroll,
|
|
3404
|
+
state,
|
|
3405
|
+
url
|
|
3406
|
+
})
|
|
3407
|
+
);
|
|
3408
|
+
if (clientNavigation) {
|
|
3409
|
+
await this.clientPlugins?.resolveNavigation(clientNavigation);
|
|
3410
|
+
void this.clientPlugins?.scheduleNavigationRendered(clientNavigation);
|
|
3411
|
+
}
|
|
3412
|
+
this.finishNavigation();
|
|
3413
|
+
} catch (error) {
|
|
3414
|
+
if (clientNavigation) {
|
|
3415
|
+
await this.clientPlugins?.failNavigation(clientNavigation, error);
|
|
3416
|
+
}
|
|
3417
|
+
this.finishNavigation();
|
|
3418
|
+
console.error("[Farm.js] Navigation error:", error);
|
|
3419
|
+
window.location.href = href;
|
|
3420
|
+
}
|
|
3421
|
+
}
|
|
3422
|
+
/**
|
|
3423
|
+
* Prefetch a URL
|
|
3424
|
+
*/
|
|
3425
|
+
async prefetch(href) {
|
|
3426
|
+
if (isFarmLocaleChangeHref(href)) return;
|
|
3427
|
+
const url = new URL(href, window.location.origin);
|
|
3428
|
+
const fullPath = url.pathname + url.search;
|
|
3429
|
+
if (this.prefetchingUrls.has(fullPath)) return;
|
|
3430
|
+
if (this.isCached(fullPath)) return;
|
|
3431
|
+
this.prefetchingUrls.add(fullPath);
|
|
3432
|
+
try {
|
|
3433
|
+
await this.fetchPageData(fullPath, false);
|
|
3434
|
+
} catch (error) {
|
|
3435
|
+
console.warn("[Farm.js] Prefetch failed:", href, error);
|
|
3436
|
+
} finally {
|
|
3437
|
+
this.prefetchingUrls.delete(fullPath);
|
|
3438
|
+
}
|
|
3439
|
+
}
|
|
3440
|
+
/**
|
|
3441
|
+
* Observe an element for viewport intersection (prefetch when visible)
|
|
3442
|
+
*/
|
|
3443
|
+
observeForPrefetch(element) {
|
|
3444
|
+
if (typeof IntersectionObserver === "undefined") return;
|
|
3445
|
+
const href = element.getAttribute("href");
|
|
3446
|
+
if (!href || this.isExternalUrl(href)) return;
|
|
3447
|
+
const observer = new IntersectionObserver(
|
|
3448
|
+
(entries) => {
|
|
3449
|
+
for (const entry of entries) {
|
|
3450
|
+
if (entry.isIntersecting) {
|
|
3451
|
+
setTimeout(() => {
|
|
3452
|
+
this.prefetch(href);
|
|
3453
|
+
}, this.options.prefetchTimeout);
|
|
3454
|
+
observer.unobserve(element);
|
|
3455
|
+
this.observers.delete(element);
|
|
3456
|
+
}
|
|
3457
|
+
}
|
|
3458
|
+
},
|
|
3459
|
+
{ rootMargin: "200px" }
|
|
3460
|
+
// Start prefetching when 200px from viewport
|
|
3461
|
+
);
|
|
3462
|
+
observer.observe(element);
|
|
3463
|
+
this.observers.set(element, observer);
|
|
3464
|
+
}
|
|
3465
|
+
/**
|
|
3466
|
+
* Stop observing an element
|
|
3467
|
+
*/
|
|
3468
|
+
unobserveForPrefetch(element) {
|
|
3469
|
+
const observer = this.observers.get(element);
|
|
3470
|
+
if (observer) {
|
|
3471
|
+
observer.unobserve(element);
|
|
3472
|
+
this.observers.delete(element);
|
|
3473
|
+
}
|
|
3474
|
+
}
|
|
3475
|
+
addBlocker(blocker) {
|
|
3476
|
+
this.blockers.add(blocker);
|
|
3477
|
+
return () => {
|
|
3478
|
+
this.blockers.delete(blocker);
|
|
3479
|
+
};
|
|
3480
|
+
}
|
|
3481
|
+
getNavigationState() {
|
|
3482
|
+
return this.navigationState;
|
|
3483
|
+
}
|
|
3484
|
+
subscribeNavigation(listener) {
|
|
3485
|
+
this.navigationListeners.add(listener);
|
|
3486
|
+
listener(this.navigationState);
|
|
3487
|
+
return () => {
|
|
3488
|
+
this.navigationListeners.delete(listener);
|
|
3489
|
+
};
|
|
3490
|
+
}
|
|
3491
|
+
registerScrollElement(key, element) {
|
|
3492
|
+
this.scrollElements.set(key, element);
|
|
3493
|
+
this.restoreScrollElement(window.location.pathname, key, element);
|
|
3494
|
+
return () => {
|
|
3495
|
+
if (this.scrollElements.get(key) === element) {
|
|
3496
|
+
this.scrollElements.delete(key);
|
|
3497
|
+
}
|
|
3498
|
+
};
|
|
3499
|
+
}
|
|
3500
|
+
pushState(state, href) {
|
|
3501
|
+
this.writePageState("push", state, href);
|
|
3502
|
+
}
|
|
3503
|
+
replaceState(state, href) {
|
|
3504
|
+
this.writePageState("replace", state, href);
|
|
3505
|
+
}
|
|
3506
|
+
async commitNavigation(options) {
|
|
3507
|
+
const historyPath = options.pageData.canonicalPath || options.fullPath;
|
|
3508
|
+
const historyState = createHistoryState(historyPath, options.state);
|
|
3509
|
+
if (options.replace) {
|
|
3510
|
+
window.history.replaceState(historyState, "", historyPath);
|
|
3511
|
+
} else {
|
|
3512
|
+
window.history.pushState(historyState, "", historyPath);
|
|
3513
|
+
}
|
|
3514
|
+
if (options.pageData.metadata?.title) {
|
|
3515
|
+
document.title = options.pageData.metadata.title;
|
|
3516
|
+
}
|
|
3517
|
+
if (options.pageData.metadata?.description) {
|
|
3518
|
+
let metaDesc = document.querySelector('meta[name="description"]');
|
|
3519
|
+
if (!metaDesc) {
|
|
3520
|
+
metaDesc = document.createElement("meta");
|
|
3521
|
+
metaDesc.setAttribute("name", "description");
|
|
3522
|
+
document.head.appendChild(metaDesc);
|
|
3523
|
+
}
|
|
3524
|
+
metaDesc.setAttribute("content", options.pageData.metadata.description);
|
|
3525
|
+
}
|
|
3526
|
+
_hydrateFarmI18n(options.pageData.i18n);
|
|
3527
|
+
if (this.onNavigate) {
|
|
3528
|
+
await this.onNavigate(options.pageData);
|
|
3529
|
+
}
|
|
3530
|
+
if (options.scroll) {
|
|
3531
|
+
if (options.url.hash) {
|
|
3532
|
+
const element = document.querySelector(options.url.hash);
|
|
3533
|
+
if (element) {
|
|
3534
|
+
element.scrollIntoView();
|
|
3535
|
+
}
|
|
3536
|
+
} else {
|
|
3537
|
+
window.scrollTo(0, 0);
|
|
3538
|
+
}
|
|
3539
|
+
} else if (this.options.scrollRestoration) {
|
|
3540
|
+
this.restoreScrollPosition(options.pathname);
|
|
3541
|
+
}
|
|
3542
|
+
}
|
|
3543
|
+
async runViewTransition(mode, callback) {
|
|
3544
|
+
if (!mode || typeof document === "undefined") {
|
|
3545
|
+
await callback();
|
|
3546
|
+
return;
|
|
3547
|
+
}
|
|
3548
|
+
const startViewTransition = document.startViewTransition;
|
|
3549
|
+
if (typeof startViewTransition !== "function") {
|
|
3550
|
+
await callback();
|
|
3551
|
+
return;
|
|
3552
|
+
}
|
|
3553
|
+
const transition = startViewTransition.call(document, () => callback());
|
|
3554
|
+
const updateDone = transition?.updateCallbackDone || transition?.ready;
|
|
3555
|
+
if (updateDone && typeof updateDone.then === "function") {
|
|
3556
|
+
await updateDone;
|
|
3557
|
+
}
|
|
3558
|
+
transition?.finished?.catch?.(() => void 0);
|
|
3559
|
+
}
|
|
3560
|
+
/**
|
|
3561
|
+
* Fetch page data from cache or server
|
|
3562
|
+
*/
|
|
3563
|
+
async fetchPageData(path, recover = true) {
|
|
3564
|
+
const cached = this.cache.get(path);
|
|
3565
|
+
if (cached && Date.now() - cached.timestamp < this.options.cacheMaxAge) {
|
|
3566
|
+
return cached.data;
|
|
3567
|
+
}
|
|
3568
|
+
const response = await fetch(`/__farm/page-data?path=${encodeURIComponent(path)}`, {
|
|
3569
|
+
headers: createFarmDeploymentRequestHeaders(this.options.deploymentId, {
|
|
3570
|
+
Accept: "application/x-farm-deferred+json, application/json",
|
|
3571
|
+
"X-Farm-SPA": "1"
|
|
3572
|
+
})
|
|
3573
|
+
});
|
|
3574
|
+
if (isFarmDeploymentMismatchResponse(response, this.options.deploymentId)) {
|
|
3575
|
+
const error = createFarmDeploymentMismatchError(
|
|
3576
|
+
response,
|
|
3577
|
+
this.options.deploymentId || "unknown"
|
|
3578
|
+
);
|
|
3579
|
+
dispatchDeploymentMismatch(error);
|
|
3580
|
+
if (recover) {
|
|
3581
|
+
window.location.assign(path);
|
|
3582
|
+
}
|
|
3583
|
+
throw error;
|
|
3584
|
+
}
|
|
3585
|
+
if (!response.ok) {
|
|
3586
|
+
throw new Error(`Failed to fetch page data: ${response.status}`);
|
|
3587
|
+
}
|
|
3588
|
+
const data = await readDeferredDataResponse(response);
|
|
3589
|
+
this.cache.set(path, {
|
|
3590
|
+
data,
|
|
3591
|
+
timestamp: Date.now()
|
|
3592
|
+
});
|
|
3593
|
+
return data;
|
|
3594
|
+
}
|
|
3595
|
+
/**
|
|
3596
|
+
* Handle browser back/forward navigation
|
|
3597
|
+
*/
|
|
3598
|
+
async handlePopState(event) {
|
|
3599
|
+
if (document.documentElement.dataset.farmDocsRuntime === "true") return;
|
|
3600
|
+
const path = window.location.pathname + window.location.search;
|
|
3601
|
+
if (await this.shouldBlockNavigation({
|
|
3602
|
+
from: event.state?.path || path,
|
|
3603
|
+
to: path,
|
|
3604
|
+
action: "pop"
|
|
3605
|
+
})) {
|
|
3606
|
+
return;
|
|
3607
|
+
}
|
|
3608
|
+
this.startNavigation({
|
|
3609
|
+
from: event.state?.path || path,
|
|
3610
|
+
to: createNavigationLocation(new URL(window.location.href)),
|
|
3611
|
+
action: "pop"
|
|
3612
|
+
});
|
|
3613
|
+
let clientNavigation;
|
|
3614
|
+
try {
|
|
3615
|
+
clientNavigation = await this.clientPlugins?.beginNavigation({
|
|
3616
|
+
from: null,
|
|
3617
|
+
to: window.location.href,
|
|
3618
|
+
action: "pop"
|
|
3619
|
+
});
|
|
3620
|
+
const pageData = await this.fetchPageData(path);
|
|
3621
|
+
if (clientNavigation) {
|
|
3622
|
+
await this.clientPlugins?.markNavigationLoaded(clientNavigation, pageData);
|
|
3623
|
+
}
|
|
3624
|
+
if (pageData.metadata?.title) {
|
|
3625
|
+
document.title = pageData.metadata.title;
|
|
3626
|
+
}
|
|
3627
|
+
_hydrateFarmI18n(pageData.i18n);
|
|
3628
|
+
if (this.onNavigate) {
|
|
3629
|
+
await this.onNavigate(pageData);
|
|
3630
|
+
}
|
|
3631
|
+
if (this.options.scrollRestoration) {
|
|
3632
|
+
this.restoreScrollPosition(window.location.pathname);
|
|
3633
|
+
}
|
|
3634
|
+
if (clientNavigation) {
|
|
3635
|
+
await this.clientPlugins?.resolveNavigation(clientNavigation);
|
|
3636
|
+
void this.clientPlugins?.scheduleNavigationRendered(clientNavigation);
|
|
3637
|
+
}
|
|
3638
|
+
this.finishNavigation();
|
|
3639
|
+
} catch (error) {
|
|
3640
|
+
if (clientNavigation) {
|
|
3641
|
+
await this.clientPlugins?.failNavigation(clientNavigation, error);
|
|
3642
|
+
}
|
|
3643
|
+
this.finishNavigation();
|
|
3644
|
+
console.error("[Farm.js] Popstate navigation error:", error);
|
|
3645
|
+
window.location.reload();
|
|
3646
|
+
}
|
|
3647
|
+
}
|
|
3648
|
+
/**
|
|
3649
|
+
* Check if URL is cached
|
|
3650
|
+
*/
|
|
3651
|
+
isCached(path) {
|
|
3652
|
+
const cached = this.cache.get(path);
|
|
3653
|
+
return cached !== void 0 && Date.now() - cached.timestamp < this.options.cacheMaxAge;
|
|
3654
|
+
}
|
|
3655
|
+
/**
|
|
3656
|
+
* Check if URL is external
|
|
3657
|
+
*/
|
|
3658
|
+
isExternalUrl(href) {
|
|
3659
|
+
return href.startsWith("http://") || href.startsWith("https://") || href.startsWith("//");
|
|
3660
|
+
}
|
|
3661
|
+
async shouldBlockNavigation(context) {
|
|
3662
|
+
for (const blocker of this.blockers) {
|
|
3663
|
+
if (await blocker(context)) {
|
|
3664
|
+
return true;
|
|
3665
|
+
}
|
|
3666
|
+
}
|
|
3667
|
+
return false;
|
|
3668
|
+
}
|
|
3669
|
+
startNavigation(options) {
|
|
3670
|
+
this.setNavigationState({
|
|
3671
|
+
state: "loading",
|
|
3672
|
+
pending: true,
|
|
3673
|
+
from: options.from,
|
|
3674
|
+
to: options.to,
|
|
3675
|
+
action: options.action,
|
|
3676
|
+
startedAt: Date.now()
|
|
3677
|
+
});
|
|
3678
|
+
}
|
|
3679
|
+
finishNavigation() {
|
|
3680
|
+
this.setNavigationState(IDLE_NAVIGATION_STATE);
|
|
3681
|
+
}
|
|
3682
|
+
setNavigationState(state) {
|
|
3683
|
+
this.navigationState = state;
|
|
3684
|
+
for (const listener of this.navigationListeners) {
|
|
3685
|
+
listener(state);
|
|
3686
|
+
}
|
|
3687
|
+
}
|
|
3688
|
+
writePageState(action, state, href) {
|
|
3689
|
+
if (typeof window === "undefined") return;
|
|
3690
|
+
const url = href ? new URL(href, window.location.origin).toString() : window.location.href;
|
|
3691
|
+
const nextState = createHistoryState(
|
|
3692
|
+
new URL(url).pathname + new URL(url).search,
|
|
3693
|
+
state,
|
|
3694
|
+
window.history.state
|
|
3695
|
+
);
|
|
3696
|
+
if (action === "replace") {
|
|
3697
|
+
window.history.replaceState(nextState, "", url);
|
|
3698
|
+
} else {
|
|
3699
|
+
window.history.pushState(nextState, "", url);
|
|
3700
|
+
}
|
|
3701
|
+
window.dispatchEvent(new PopStateEvent("popstate", { state: nextState }));
|
|
3702
|
+
}
|
|
3703
|
+
/**
|
|
3704
|
+
* Save scroll position for a path
|
|
3705
|
+
*/
|
|
3706
|
+
saveScrollPosition(path) {
|
|
3707
|
+
try {
|
|
3708
|
+
sessionStorage.setItem(
|
|
3709
|
+
`farm-scroll-${path}`,
|
|
3710
|
+
JSON.stringify({ x: window.scrollX, y: window.scrollY })
|
|
3711
|
+
);
|
|
3712
|
+
for (const [key, element] of this.scrollElements) {
|
|
3713
|
+
sessionStorage.setItem(
|
|
3714
|
+
getScrollElementStorageKey(path, key),
|
|
3715
|
+
JSON.stringify({ x: element.scrollLeft, y: element.scrollTop })
|
|
3716
|
+
);
|
|
3717
|
+
}
|
|
3718
|
+
} catch {
|
|
3719
|
+
}
|
|
3720
|
+
}
|
|
3721
|
+
/**
|
|
3722
|
+
* Restore scroll position for a path
|
|
3723
|
+
*/
|
|
3724
|
+
restoreScrollPosition(path) {
|
|
3725
|
+
try {
|
|
3726
|
+
const saved = sessionStorage.getItem(`farm-scroll-${path}`);
|
|
3727
|
+
if (saved) {
|
|
3728
|
+
const { x, y } = JSON.parse(saved);
|
|
3729
|
+
setTimeout(() => window.scrollTo(x, y), 0);
|
|
3730
|
+
}
|
|
3731
|
+
for (const [key, element] of this.scrollElements) {
|
|
3732
|
+
this.restoreScrollElement(path, key, element);
|
|
3733
|
+
}
|
|
3734
|
+
} catch {
|
|
3735
|
+
}
|
|
3736
|
+
}
|
|
3737
|
+
restoreScrollElement(path, key, element) {
|
|
3738
|
+
try {
|
|
3739
|
+
const saved = sessionStorage.getItem(getScrollElementStorageKey(path, key));
|
|
3740
|
+
if (!saved) return;
|
|
3741
|
+
const { x, y } = JSON.parse(saved);
|
|
3742
|
+
setTimeout(() => {
|
|
3743
|
+
element.scrollLeft = x;
|
|
3744
|
+
element.scrollTop = y;
|
|
3745
|
+
}, 0);
|
|
3746
|
+
} catch {
|
|
3747
|
+
}
|
|
3748
|
+
}
|
|
3749
|
+
/**
|
|
3750
|
+
* Clear the page cache
|
|
3751
|
+
*/
|
|
3752
|
+
clearCache() {
|
|
3753
|
+
this.cache.clear();
|
|
3754
|
+
}
|
|
3755
|
+
};
|
|
3756
|
+
__name(_SPARouter, "SPARouter");
|
|
3757
|
+
var SPARouter = _SPARouter;
|
|
3758
|
+
function readBrowserDeploymentId() {
|
|
3759
|
+
if (typeof window === "undefined") return void 0;
|
|
3760
|
+
const runtimeId = window.__FARM_DEPLOYMENT_ID__;
|
|
3761
|
+
if (typeof runtimeId === "string" && runtimeId) return runtimeId;
|
|
3762
|
+
return document.querySelector('meta[name="farm-deployment-id"]')?.content;
|
|
3763
|
+
}
|
|
3764
|
+
__name(readBrowserDeploymentId, "readBrowserDeploymentId");
|
|
3765
|
+
function dispatchDeploymentMismatch(error) {
|
|
3766
|
+
if (typeof window === "undefined" || typeof CustomEvent === "undefined") return;
|
|
3767
|
+
window.dispatchEvent(new CustomEvent("farm:deployment-mismatch", { detail: error }));
|
|
3768
|
+
}
|
|
3769
|
+
__name(dispatchDeploymentMismatch, "dispatchDeploymentMismatch");
|
|
3770
|
+
function getRouter2() {
|
|
3771
|
+
if (typeof window === "undefined") {
|
|
3772
|
+
return new SPARouter();
|
|
3773
|
+
}
|
|
3774
|
+
const installedRouter = window.__FARM_SPA_ROUTER__;
|
|
3775
|
+
if (installedRouter) {
|
|
3776
|
+
routerInstance = installedRouter;
|
|
3777
|
+
return installedRouter;
|
|
3778
|
+
}
|
|
3779
|
+
if (!routerInstance) {
|
|
3780
|
+
routerInstance = new SPARouter();
|
|
3781
|
+
}
|
|
3782
|
+
return routerInstance;
|
|
3783
|
+
}
|
|
3784
|
+
__name(getRouter2, "getRouter");
|
|
3785
|
+
function navigateTo(href, options) {
|
|
3786
|
+
return getRouter2().navigate(href, options);
|
|
3787
|
+
}
|
|
3788
|
+
__name(navigateTo, "navigateTo");
|
|
3789
|
+
function prefetch(href) {
|
|
3790
|
+
return getRouter2().prefetch(href);
|
|
3791
|
+
}
|
|
3792
|
+
__name(prefetch, "prefetch");
|
|
3793
|
+
function pushState(state, href) {
|
|
3794
|
+
getRouter2().pushState(state, href);
|
|
3795
|
+
}
|
|
3796
|
+
__name(pushState, "pushState");
|
|
3797
|
+
function replaceState(state, href) {
|
|
3798
|
+
getRouter2().replaceState(state, href);
|
|
3799
|
+
}
|
|
3800
|
+
__name(replaceState, "replaceState");
|
|
3801
|
+
function readPageState() {
|
|
3802
|
+
if (typeof window === "undefined") return null;
|
|
3803
|
+
const state = window.history.state;
|
|
3804
|
+
if (!state || typeof state !== "object") return null;
|
|
3805
|
+
return state[FARM_PAGE_STATE_KEY] ?? null;
|
|
3806
|
+
}
|
|
3807
|
+
__name(readPageState, "readPageState");
|
|
3808
|
+
function createHistoryState(path, pageState, currentState) {
|
|
3809
|
+
const base = currentState && typeof currentState === "object" ? { ...currentState } : {};
|
|
3810
|
+
return {
|
|
3811
|
+
...base,
|
|
3812
|
+
path,
|
|
3813
|
+
[FARM_PAGE_STATE_KEY]: pageState
|
|
3814
|
+
};
|
|
3815
|
+
}
|
|
3816
|
+
__name(createHistoryState, "createHistoryState");
|
|
3817
|
+
function createNavigationLocation(url) {
|
|
3818
|
+
return {
|
|
3819
|
+
href: url.href,
|
|
3820
|
+
pathname: url.pathname,
|
|
3821
|
+
search: url.search,
|
|
3822
|
+
hash: url.hash
|
|
3823
|
+
};
|
|
3824
|
+
}
|
|
3825
|
+
__name(createNavigationLocation, "createNavigationLocation");
|
|
3826
|
+
function getScrollElementStorageKey(path, key) {
|
|
3827
|
+
return `farm-scroll-${path}:${key}`;
|
|
3828
|
+
}
|
|
3829
|
+
__name(getScrollElementStorageKey, "getScrollElementStorageKey");
|
|
3830
|
+
|
|
3831
|
+
// src/client/router.ts
|
|
3832
|
+
function useRouter(options = {}) {
|
|
3833
|
+
const basePath = options.basePath || "";
|
|
3834
|
+
const routes = options.routes;
|
|
3835
|
+
const routeKey = routes?.map((route2) => typeof route2 === "string" ? route2 : route2.path).join("\n") || "";
|
|
3836
|
+
const routeMatcher = (0, import_react4.useMemo)(
|
|
3837
|
+
() => routeKey ? createFarmRouter(routeKey.split("\n")) : null,
|
|
3838
|
+
[routeKey]
|
|
3839
|
+
);
|
|
3840
|
+
const [state, setState] = (0, import_react4.useState)(() => {
|
|
3841
|
+
return readRouterState(basePath, routeMatcher);
|
|
3842
|
+
});
|
|
3843
|
+
(0, import_react4.useEffect)(() => {
|
|
3844
|
+
if (typeof window === "undefined") return;
|
|
3845
|
+
const handlePopState = /* @__PURE__ */ __name(() => {
|
|
3846
|
+
setState(readRouterState(basePath, routeMatcher));
|
|
3847
|
+
}, "handlePopState");
|
|
3848
|
+
handlePopState();
|
|
3849
|
+
window.addEventListener("popstate", handlePopState);
|
|
3850
|
+
return () => window.removeEventListener("popstate", handlePopState);
|
|
3851
|
+
}, [basePath, routeMatcher]);
|
|
3852
|
+
const push = /* @__PURE__ */ __name((href) => {
|
|
3853
|
+
if (typeof window === "undefined") return;
|
|
3854
|
+
const url = href.startsWith("/") ? basePath + href : href;
|
|
3855
|
+
window.history.pushState(null, "", url);
|
|
3856
|
+
window.dispatchEvent(new PopStateEvent("popstate"));
|
|
3857
|
+
}, "push");
|
|
3858
|
+
const replace = /* @__PURE__ */ __name((href) => {
|
|
3859
|
+
if (typeof window === "undefined") return;
|
|
3860
|
+
const url = href.startsWith("/") ? basePath + href : href;
|
|
3861
|
+
window.history.replaceState(null, "", url);
|
|
3862
|
+
window.dispatchEvent(new PopStateEvent("popstate"));
|
|
3863
|
+
}, "replace");
|
|
3864
|
+
const pushState2 = /* @__PURE__ */ __name((pageState, href) => {
|
|
3865
|
+
if (typeof window === "undefined") return;
|
|
3866
|
+
getRouter2().pushState(pageState, resolveClientHref(href, basePath));
|
|
3867
|
+
}, "pushState");
|
|
3868
|
+
const replaceState2 = /* @__PURE__ */ __name((pageState, href) => {
|
|
3869
|
+
if (typeof window === "undefined") return;
|
|
3870
|
+
getRouter2().replaceState(pageState, resolveClientHref(href, basePath));
|
|
3871
|
+
}, "replaceState");
|
|
3872
|
+
const back = /* @__PURE__ */ __name(() => {
|
|
3873
|
+
if (typeof window !== "undefined") {
|
|
3874
|
+
window.history.back();
|
|
3875
|
+
}
|
|
3876
|
+
}, "back");
|
|
3877
|
+
const forward = /* @__PURE__ */ __name(() => {
|
|
3878
|
+
if (typeof window !== "undefined") {
|
|
3879
|
+
window.history.forward();
|
|
3880
|
+
}
|
|
3881
|
+
}, "forward");
|
|
3882
|
+
return {
|
|
3883
|
+
...state,
|
|
3884
|
+
push,
|
|
3885
|
+
replace,
|
|
3886
|
+
pushState: pushState2,
|
|
3887
|
+
replaceState: replaceState2,
|
|
3888
|
+
back,
|
|
3889
|
+
forward
|
|
3890
|
+
};
|
|
3891
|
+
}
|
|
3892
|
+
__name(useRouter, "useRouter");
|
|
3893
|
+
function usePageState() {
|
|
3894
|
+
const [state, setState] = (0, import_react4.useState)(() => readPageState());
|
|
3895
|
+
(0, import_react4.useEffect)(() => {
|
|
3896
|
+
if (typeof window === "undefined") return;
|
|
3897
|
+
const handlePopState = /* @__PURE__ */ __name(() => {
|
|
3898
|
+
setState(readPageState());
|
|
3899
|
+
}, "handlePopState");
|
|
3900
|
+
handlePopState();
|
|
3901
|
+
window.addEventListener("popstate", handlePopState);
|
|
3902
|
+
return () => window.removeEventListener("popstate", handlePopState);
|
|
3903
|
+
}, []);
|
|
3904
|
+
return state;
|
|
3905
|
+
}
|
|
3906
|
+
__name(usePageState, "usePageState");
|
|
3907
|
+
function useNavigation() {
|
|
3908
|
+
const [state, setState] = (0, import_react4.useState)(
|
|
3909
|
+
() => getRouter2().getNavigationState()
|
|
3910
|
+
);
|
|
3911
|
+
(0, import_react4.useEffect)(() => {
|
|
3912
|
+
if (typeof window === "undefined") return;
|
|
3913
|
+
return getRouter2().subscribeNavigation(setState);
|
|
3914
|
+
}, []);
|
|
3915
|
+
return state;
|
|
3916
|
+
}
|
|
3917
|
+
__name(useNavigation, "useNavigation");
|
|
3918
|
+
function useBlocker(options) {
|
|
3919
|
+
const optionsRef = (0, import_react4.useRef)(options);
|
|
3920
|
+
optionsRef.current = options;
|
|
3921
|
+
const active = Boolean(options.when);
|
|
3922
|
+
(0, import_react4.useEffect)(() => {
|
|
3923
|
+
if (typeof window === "undefined" || !active) {
|
|
3924
|
+
return;
|
|
3925
|
+
}
|
|
3926
|
+
return getRouter2().addBlocker(async (context) => {
|
|
3927
|
+
const current = optionsRef.current;
|
|
3928
|
+
const when = typeof current.when === "function" ? current.when(context) : current.when;
|
|
3929
|
+
if (!when) return false;
|
|
3930
|
+
if (current.shouldBlock && !await current.shouldBlock(context)) {
|
|
3931
|
+
return false;
|
|
3932
|
+
}
|
|
3933
|
+
if (current.message && typeof window.confirm === "function") {
|
|
3934
|
+
return !window.confirm(current.message);
|
|
3935
|
+
}
|
|
3936
|
+
return true;
|
|
3937
|
+
});
|
|
3938
|
+
}, [active]);
|
|
3939
|
+
return { active };
|
|
3940
|
+
}
|
|
3941
|
+
__name(useBlocker, "useBlocker");
|
|
3942
|
+
function useScrollRestoration(key) {
|
|
3943
|
+
const ref = (0, import_react4.useRef)(null);
|
|
3944
|
+
(0, import_react4.useEffect)(() => {
|
|
3945
|
+
const element = ref.current;
|
|
3946
|
+
if (!element) return;
|
|
3947
|
+
return getRouter2().registerScrollElement(key, element);
|
|
3948
|
+
}, [key]);
|
|
3949
|
+
return ref;
|
|
3950
|
+
}
|
|
3951
|
+
__name(useScrollRestoration, "useScrollRestoration");
|
|
3952
|
+
function readRouterState(basePath, routeMatcher) {
|
|
3953
|
+
if (typeof window === "undefined") {
|
|
3954
|
+
return {
|
|
3955
|
+
pathname: "/",
|
|
3956
|
+
searchParams: new URLSearchParams(),
|
|
3957
|
+
params: {},
|
|
3958
|
+
pageState: null
|
|
3959
|
+
};
|
|
3960
|
+
}
|
|
3961
|
+
const url = new URL(window.location.href);
|
|
3962
|
+
const pathname = normalizeClientPathname(url.pathname, basePath);
|
|
3963
|
+
const i18n = getFarmI18nClientState();
|
|
3964
|
+
const routePathname = i18n ? stripFarmLocaleFromPathname(pathname, i18n) : pathname;
|
|
3965
|
+
return {
|
|
3966
|
+
pathname,
|
|
3967
|
+
searchParams: url.searchParams,
|
|
3968
|
+
params: routeMatcher?.match(routePathname)?.params || {},
|
|
3969
|
+
pageState: readPageState()
|
|
3970
|
+
};
|
|
3971
|
+
}
|
|
3972
|
+
__name(readRouterState, "readRouterState");
|
|
3973
|
+
function normalizeClientPathname(pathname, basePath) {
|
|
3974
|
+
const normalizedBase = basePath.replace(/\/+$/, "");
|
|
3975
|
+
const isUnderBase = normalizedBase && (pathname === normalizedBase || pathname.startsWith(`${normalizedBase}/`));
|
|
3976
|
+
const withoutBase = isUnderBase ? pathname.slice(normalizedBase.length) || "/" : pathname;
|
|
3977
|
+
return withoutBase || "/";
|
|
3978
|
+
}
|
|
3979
|
+
__name(normalizeClientPathname, "normalizeClientPathname");
|
|
3980
|
+
function resolveClientHref(href, basePath) {
|
|
3981
|
+
if (!href) return void 0;
|
|
3982
|
+
return href.startsWith("/") ? basePath + href : href;
|
|
3983
|
+
}
|
|
3984
|
+
__name(resolveClientHref, "resolveClientHref");
|
|
3985
|
+
|
|
3986
|
+
// src/client/chunk-recovery.ts
|
|
3987
|
+
var DEFAULT_MAX_AGE_MS = 3e4;
|
|
3988
|
+
var STORAGE_KEY_PREFIX = "farm:chunk-recovery:";
|
|
3989
|
+
var CHUNK_ERROR_PATTERNS = [
|
|
3990
|
+
/ChunkLoadError/i,
|
|
3991
|
+
/Loading chunk [\w-]+ failed/i,
|
|
3992
|
+
/Loading CSS chunk [\w-]+ failed/i,
|
|
3993
|
+
/CSS_CHUNK_LOAD_FAILED/i,
|
|
3994
|
+
/failed to fetch dynamically imported module/i,
|
|
3995
|
+
/error loading dynamically imported module/i,
|
|
3996
|
+
/importing a module script failed/i,
|
|
3997
|
+
/unable to preload CSS/i,
|
|
3998
|
+
/module script failed/i
|
|
3999
|
+
];
|
|
4000
|
+
function isChunkLoadError(errorLike) {
|
|
4001
|
+
const values = collectErrorText(errorLike);
|
|
4002
|
+
if (values.some((value) => CHUNK_ERROR_PATTERNS.some((pattern) => pattern.test(value)))) {
|
|
4003
|
+
return true;
|
|
4004
|
+
}
|
|
4005
|
+
const targetUrl = getEventTargetAssetUrl(errorLike);
|
|
4006
|
+
return Boolean(targetUrl && /\.(?:m?js|css)(?:[?#].*)?$/i.test(targetUrl));
|
|
4007
|
+
}
|
|
4008
|
+
__name(isChunkLoadError, "isChunkLoadError");
|
|
4009
|
+
function installChunkErrorRecovery(options = {}) {
|
|
4010
|
+
if (typeof window === "undefined") {
|
|
4011
|
+
return () => {
|
|
4012
|
+
};
|
|
4013
|
+
}
|
|
4014
|
+
const recover = /* @__PURE__ */ __name((errorLike) => {
|
|
4015
|
+
if (!isChunkLoadError(errorLike)) {
|
|
4016
|
+
return;
|
|
4017
|
+
}
|
|
4018
|
+
if (!markRecovered(options)) {
|
|
4019
|
+
return;
|
|
4020
|
+
}
|
|
4021
|
+
options.onRecover?.(errorLike);
|
|
4022
|
+
getReload(options)();
|
|
4023
|
+
}, "recover");
|
|
4024
|
+
const onError = /* @__PURE__ */ __name((event) => {
|
|
4025
|
+
recover(getErrorEventPayload(event));
|
|
4026
|
+
}, "onError");
|
|
4027
|
+
const onUnhandledRejection = /* @__PURE__ */ __name((event) => {
|
|
4028
|
+
recover(event.reason);
|
|
4029
|
+
}, "onUnhandledRejection");
|
|
4030
|
+
window.addEventListener("error", onError, true);
|
|
4031
|
+
window.addEventListener("unhandledrejection", onUnhandledRejection);
|
|
4032
|
+
return () => {
|
|
4033
|
+
window.removeEventListener("error", onError, true);
|
|
4034
|
+
window.removeEventListener("unhandledrejection", onUnhandledRejection);
|
|
4035
|
+
};
|
|
4036
|
+
}
|
|
4037
|
+
__name(installChunkErrorRecovery, "installChunkErrorRecovery");
|
|
4038
|
+
function markRecovered(options) {
|
|
4039
|
+
const now2 = getNow(options);
|
|
4040
|
+
const maxAgeMs = options.maxAgeMs ?? DEFAULT_MAX_AGE_MS;
|
|
4041
|
+
const storage = getStorage(options);
|
|
4042
|
+
const key = getStorageKey(options);
|
|
4043
|
+
if (!storage) {
|
|
4044
|
+
return true;
|
|
4045
|
+
}
|
|
4046
|
+
try {
|
|
4047
|
+
const previous = Number(storage.getItem(key));
|
|
4048
|
+
if (Number.isFinite(previous) && previous > 0 && now2 - previous < maxAgeMs) {
|
|
4049
|
+
return false;
|
|
4050
|
+
}
|
|
4051
|
+
storage.setItem(key, String(now2));
|
|
4052
|
+
return true;
|
|
4053
|
+
} catch {
|
|
4054
|
+
return true;
|
|
4055
|
+
}
|
|
4056
|
+
}
|
|
4057
|
+
__name(markRecovered, "markRecovered");
|
|
4058
|
+
function getErrorEventPayload(event) {
|
|
4059
|
+
if ("error" in event && event.error) {
|
|
4060
|
+
return event.error;
|
|
4061
|
+
}
|
|
4062
|
+
if ("message" in event && event.message) {
|
|
4063
|
+
return event.message;
|
|
4064
|
+
}
|
|
4065
|
+
return event;
|
|
4066
|
+
}
|
|
4067
|
+
__name(getErrorEventPayload, "getErrorEventPayload");
|
|
4068
|
+
function collectErrorText(value, seen = /* @__PURE__ */ new Set()) {
|
|
4069
|
+
if (value == null || seen.has(value)) {
|
|
4070
|
+
return [];
|
|
4071
|
+
}
|
|
4072
|
+
seen.add(value);
|
|
4073
|
+
if (typeof value === "string") {
|
|
4074
|
+
return [value];
|
|
4075
|
+
}
|
|
4076
|
+
if (typeof value === "number" || typeof value === "boolean") {
|
|
4077
|
+
return [String(value)];
|
|
4078
|
+
}
|
|
4079
|
+
if (typeof value !== "object") {
|
|
4080
|
+
return [];
|
|
4081
|
+
}
|
|
4082
|
+
const record = value;
|
|
4083
|
+
const output = [];
|
|
4084
|
+
for (const key of ["name", "message", "code", "type", "request", "src", "href"]) {
|
|
4085
|
+
const candidate = record[key];
|
|
4086
|
+
if (typeof candidate === "string") {
|
|
4087
|
+
output.push(candidate);
|
|
4088
|
+
}
|
|
4089
|
+
}
|
|
4090
|
+
if ("reason" in record) {
|
|
4091
|
+
output.push(...collectErrorText(record.reason, seen));
|
|
4092
|
+
}
|
|
4093
|
+
if ("error" in record) {
|
|
4094
|
+
output.push(...collectErrorText(record.error, seen));
|
|
4095
|
+
}
|
|
4096
|
+
return output;
|
|
4097
|
+
}
|
|
4098
|
+
__name(collectErrorText, "collectErrorText");
|
|
4099
|
+
function getEventTargetAssetUrl(value) {
|
|
4100
|
+
if (!value || typeof value !== "object") {
|
|
4101
|
+
return void 0;
|
|
4102
|
+
}
|
|
4103
|
+
const target = value.target;
|
|
4104
|
+
if (!target || typeof target !== "object") {
|
|
4105
|
+
return void 0;
|
|
4106
|
+
}
|
|
4107
|
+
const tagName = typeof target.tagName === "string" ? target.tagName.toLowerCase() : "";
|
|
4108
|
+
if (tagName !== "script" && tagName !== "link") {
|
|
4109
|
+
return void 0;
|
|
4110
|
+
}
|
|
4111
|
+
return typeof target.src === "string" && target.src ? target.src : typeof target.href === "string" && target.href ? target.href : void 0;
|
|
4112
|
+
}
|
|
4113
|
+
__name(getEventTargetAssetUrl, "getEventTargetAssetUrl");
|
|
4114
|
+
function getStorage(options) {
|
|
4115
|
+
if ("storage" in options) {
|
|
4116
|
+
return options.storage;
|
|
4117
|
+
}
|
|
4118
|
+
try {
|
|
4119
|
+
return window.sessionStorage;
|
|
4120
|
+
} catch {
|
|
4121
|
+
return null;
|
|
4122
|
+
}
|
|
4123
|
+
}
|
|
4124
|
+
__name(getStorage, "getStorage");
|
|
4125
|
+
function getStorageKey(options) {
|
|
4126
|
+
if (options.storageKey) {
|
|
4127
|
+
return options.storageKey;
|
|
4128
|
+
}
|
|
4129
|
+
const location = getLocation(options);
|
|
4130
|
+
return `${STORAGE_KEY_PREFIX}${location.pathname}${location.search}`;
|
|
4131
|
+
}
|
|
4132
|
+
__name(getStorageKey, "getStorageKey");
|
|
4133
|
+
function getLocation(options) {
|
|
4134
|
+
return options.location ?? window.location;
|
|
4135
|
+
}
|
|
4136
|
+
__name(getLocation, "getLocation");
|
|
4137
|
+
function getReload(options) {
|
|
4138
|
+
if (options.reload) {
|
|
4139
|
+
return options.reload;
|
|
4140
|
+
}
|
|
4141
|
+
const location = getLocation(options);
|
|
4142
|
+
return () => location.reload();
|
|
4143
|
+
}
|
|
4144
|
+
__name(getReload, "getReload");
|
|
4145
|
+
function getNow(options) {
|
|
4146
|
+
return options.now ? options.now() : Date.now();
|
|
4147
|
+
}
|
|
4148
|
+
__name(getNow, "getNow");
|
|
4149
|
+
|
|
4150
|
+
// src/client/plugin.ts
|
|
4151
|
+
var PERFORMANCE_ENTRY_TYPES = [
|
|
4152
|
+
"navigation",
|
|
4153
|
+
"paint",
|
|
4154
|
+
"largest-contentful-paint",
|
|
4155
|
+
"layout-shift",
|
|
4156
|
+
"event"
|
|
4157
|
+
];
|
|
4158
|
+
var _FarmClientPluginManager = class _FarmClientPluginManager {
|
|
4159
|
+
constructor(registrations, options) {
|
|
4160
|
+
this.instances = [];
|
|
4161
|
+
this.performanceObservers = [];
|
|
4162
|
+
this.navigationSequence = 0;
|
|
4163
|
+
this.starting = false;
|
|
4164
|
+
this.started = false;
|
|
4165
|
+
this.closed = false;
|
|
4166
|
+
this.reportedErrors = /* @__PURE__ */ new WeakSet();
|
|
4167
|
+
this.handleWindowError = /* @__PURE__ */ __name((event) => {
|
|
4168
|
+
const error = event.error ?? new Error(event.message || "Unknown browser error");
|
|
4169
|
+
void this.reportError(error, "window");
|
|
4170
|
+
}, "handleWindowError");
|
|
4171
|
+
this.handleUnhandledRejection = /* @__PURE__ */ __name((event) => {
|
|
4172
|
+
void this.reportError(event.reason, "unhandled-rejection");
|
|
4173
|
+
}, "handleUnhandledRejection");
|
|
4174
|
+
this.handlePageHide = /* @__PURE__ */ __name(() => {
|
|
4175
|
+
void this.close("pagehide");
|
|
4176
|
+
}, "handlePageHide");
|
|
4177
|
+
this.registrations = sortRegistrations(registrations);
|
|
4178
|
+
this.options = {
|
|
4179
|
+
...options,
|
|
4180
|
+
isDev: options.isDev ?? false,
|
|
4181
|
+
isProd: options.isProd ?? !options.isDev,
|
|
4182
|
+
window: options.window ?? (typeof window !== "undefined" ? window : void 0)
|
|
4183
|
+
};
|
|
4184
|
+
}
|
|
4185
|
+
start() {
|
|
4186
|
+
if (this.startPromise) return this.startPromise;
|
|
4187
|
+
this.startPromise = Promise.resolve().then(() => this.startInternal());
|
|
4188
|
+
return this.startPromise;
|
|
4189
|
+
}
|
|
4190
|
+
async beginHydration(input) {
|
|
4191
|
+
await this.start();
|
|
4192
|
+
const session = {
|
|
4193
|
+
...input,
|
|
4194
|
+
location: this.getLocation(),
|
|
4195
|
+
startedAt: now()
|
|
4196
|
+
};
|
|
4197
|
+
await this.runHook(
|
|
4198
|
+
"hydration.before",
|
|
4199
|
+
(instance) => instance.plugin.hydration?.before?.({
|
|
4200
|
+
...this.createStateEvent(instance),
|
|
4201
|
+
...session
|
|
4202
|
+
})
|
|
4203
|
+
);
|
|
4204
|
+
return session;
|
|
4205
|
+
}
|
|
4206
|
+
async completeHydration(session, options = {}) {
|
|
4207
|
+
await this.runHook(
|
|
4208
|
+
"hydration.after",
|
|
4209
|
+
(instance) => instance.plugin.hydration?.after?.({
|
|
4210
|
+
...this.createStateEvent(instance),
|
|
4211
|
+
...session,
|
|
4212
|
+
durationMs: now() - session.startedAt,
|
|
4213
|
+
recovered: options.recovered ?? false
|
|
4214
|
+
})
|
|
4215
|
+
);
|
|
4216
|
+
}
|
|
4217
|
+
async failHydration(session, error) {
|
|
4218
|
+
await this.reportError(error, "hydration", void 0, session.location);
|
|
4219
|
+
}
|
|
4220
|
+
async beginNavigation(input) {
|
|
4221
|
+
await this.start();
|
|
4222
|
+
this.currentNavigation?.controller.abort("superseded");
|
|
4223
|
+
const controller = new AbortController();
|
|
4224
|
+
const session = {
|
|
4225
|
+
id: `navigation:${++this.navigationSequence}`,
|
|
4226
|
+
from: input.from === null ? null : toClientLocation(input.from ?? this.getLocation().href, this.getBaseUrl()),
|
|
4227
|
+
to: toClientLocation(input.to, this.getBaseUrl()),
|
|
4228
|
+
action: input.action,
|
|
4229
|
+
signal: controller.signal,
|
|
4230
|
+
startedAt: now(),
|
|
4231
|
+
route: input.route
|
|
4232
|
+
};
|
|
4233
|
+
this.currentNavigation = { controller, session };
|
|
4234
|
+
await this.runHook(
|
|
4235
|
+
"navigation.before",
|
|
4236
|
+
(instance) => instance.plugin.navigation?.before?.({
|
|
4237
|
+
...this.createStateEvent(instance),
|
|
4238
|
+
...session
|
|
4239
|
+
})
|
|
4240
|
+
);
|
|
4241
|
+
return session;
|
|
4242
|
+
}
|
|
4243
|
+
async markNavigationLoaded(session, data) {
|
|
4244
|
+
if (session.signal.aborted) return;
|
|
4245
|
+
await this.runHook(
|
|
4246
|
+
"navigation.loaded",
|
|
4247
|
+
(instance) => instance.plugin.navigation?.loaded?.({
|
|
4248
|
+
...this.createStateEvent(instance),
|
|
4249
|
+
...session,
|
|
4250
|
+
data,
|
|
4251
|
+
durationMs: now() - session.startedAt
|
|
4252
|
+
})
|
|
4253
|
+
);
|
|
4254
|
+
}
|
|
4255
|
+
async resolveNavigation(session) {
|
|
4256
|
+
if (session.signal.aborted) return;
|
|
4257
|
+
await this.runHook(
|
|
4258
|
+
"navigation.resolved",
|
|
4259
|
+
(instance) => instance.plugin.navigation?.resolved?.({
|
|
4260
|
+
...this.createStateEvent(instance),
|
|
4261
|
+
...session,
|
|
4262
|
+
durationMs: now() - session.startedAt
|
|
4263
|
+
})
|
|
4264
|
+
);
|
|
4265
|
+
}
|
|
4266
|
+
scheduleNavigationRendered(session) {
|
|
4267
|
+
if (session.signal.aborted) return Promise.resolve();
|
|
4268
|
+
const clientWindow = this.options.window;
|
|
4269
|
+
const schedule = clientWindow?.requestAnimationFrame ? (callback) => clientWindow.requestAnimationFrame(() => clientWindow.requestAnimationFrame(callback)) : (callback) => setTimeout(callback, 0);
|
|
4270
|
+
return new Promise((resolve) => {
|
|
4271
|
+
schedule(() => {
|
|
4272
|
+
if (session.signal.aborted || this.closed) {
|
|
4273
|
+
resolve();
|
|
4274
|
+
return;
|
|
4275
|
+
}
|
|
4276
|
+
void this.runHook(
|
|
4277
|
+
"navigation.rendered",
|
|
4278
|
+
(instance) => instance.plugin.navigation?.rendered?.({
|
|
4279
|
+
...this.createStateEvent(instance),
|
|
4280
|
+
...session,
|
|
4281
|
+
durationMs: now() - session.startedAt
|
|
4282
|
+
})
|
|
4283
|
+
).finally(() => {
|
|
4284
|
+
if (this.currentNavigation?.session === session) {
|
|
4285
|
+
this.currentNavigation = void 0;
|
|
4286
|
+
}
|
|
4287
|
+
resolve();
|
|
4288
|
+
});
|
|
4289
|
+
});
|
|
4290
|
+
});
|
|
4291
|
+
}
|
|
4292
|
+
async failNavigation(session, error) {
|
|
4293
|
+
if (!session.signal.aborted) {
|
|
4294
|
+
await this.runHook(
|
|
4295
|
+
"navigation.error",
|
|
4296
|
+
(instance) => instance.plugin.navigation?.error?.({
|
|
4297
|
+
...this.createStateEvent(instance),
|
|
4298
|
+
...session,
|
|
4299
|
+
durationMs: now() - session.startedAt,
|
|
4300
|
+
error
|
|
4301
|
+
})
|
|
4302
|
+
);
|
|
4303
|
+
await this.reportError(error, "navigation", session, session.to);
|
|
4304
|
+
}
|
|
4305
|
+
if (this.currentNavigation?.session === session) {
|
|
4306
|
+
this.currentNavigation = void 0;
|
|
4307
|
+
}
|
|
4308
|
+
}
|
|
4309
|
+
async reportError(error, phase, navigation, location = this.getLocation()) {
|
|
4310
|
+
if (this.closed) return;
|
|
4311
|
+
if (isObject(error)) {
|
|
4312
|
+
if (this.reportedErrors.has(error)) return;
|
|
4313
|
+
this.reportedErrors.add(error);
|
|
4314
|
+
}
|
|
4315
|
+
if (!this.started && !this.starting) await this.start();
|
|
4316
|
+
await this.runErrorHooks({ error, phase, navigation, location });
|
|
4317
|
+
}
|
|
4318
|
+
close(reason = "manual") {
|
|
4319
|
+
if (this.closePromise) return this.closePromise;
|
|
4320
|
+
this.closePromise = this.closeInternal(reason);
|
|
4321
|
+
return this.closePromise;
|
|
4322
|
+
}
|
|
4323
|
+
getPlugins() {
|
|
4324
|
+
return this.instances.map(({ registration }) => ({
|
|
4325
|
+
name: registration.name,
|
|
4326
|
+
version: registration.version
|
|
4327
|
+
}));
|
|
4328
|
+
}
|
|
4329
|
+
async startInternal() {
|
|
4330
|
+
if (this.started || this.closed) return;
|
|
4331
|
+
this.starting = true;
|
|
4332
|
+
try {
|
|
4333
|
+
for (const registration of this.registrations) {
|
|
4334
|
+
try {
|
|
4335
|
+
const definition = registration.definition;
|
|
4336
|
+
if (!definition || typeof definition !== "object") {
|
|
4337
|
+
throw new TypeError(
|
|
4338
|
+
`Client plugin "${registration.name}" does not define a lifecycle object`
|
|
4339
|
+
);
|
|
4340
|
+
}
|
|
4341
|
+
const instance = {
|
|
4342
|
+
registration,
|
|
4343
|
+
plugin: definition,
|
|
4344
|
+
state: void 0
|
|
4345
|
+
};
|
|
4346
|
+
instance.state = await definition.setup?.(this.createSetupEvent(instance));
|
|
4347
|
+
this.instances.push(instance);
|
|
4348
|
+
} catch (error) {
|
|
4349
|
+
this.logHookError(registration.name, "setup", error);
|
|
4350
|
+
await this.runErrorHooks({
|
|
4351
|
+
error,
|
|
4352
|
+
phase: "setup",
|
|
4353
|
+
location: this.getLocation()
|
|
4354
|
+
});
|
|
4355
|
+
}
|
|
4356
|
+
}
|
|
4357
|
+
this.started = true;
|
|
4358
|
+
this.installBrowserListeners();
|
|
4359
|
+
this.installPerformanceObservers();
|
|
4360
|
+
} finally {
|
|
4361
|
+
this.starting = false;
|
|
4362
|
+
}
|
|
4363
|
+
}
|
|
4364
|
+
installBrowserListeners() {
|
|
4365
|
+
const clientWindow = this.options.window;
|
|
4366
|
+
if (!clientWindow) return;
|
|
4367
|
+
if (this.instances.some(({ plugin }) => plugin.error)) {
|
|
4368
|
+
clientWindow.addEventListener("error", this.handleWindowError);
|
|
4369
|
+
clientWindow.addEventListener("unhandledrejection", this.handleUnhandledRejection);
|
|
4370
|
+
}
|
|
4371
|
+
clientWindow.addEventListener("pagehide", this.handlePageHide, {
|
|
4372
|
+
once: true
|
|
4373
|
+
});
|
|
4374
|
+
}
|
|
4375
|
+
installPerformanceObservers() {
|
|
4376
|
+
if (!this.instances.some(({ plugin }) => plugin.performance)) return;
|
|
4377
|
+
const Observer = typeof PerformanceObserver !== "undefined" ? PerformanceObserver : void 0;
|
|
4378
|
+
if (!Observer) return;
|
|
4379
|
+
const supported = new Set(Observer.supportedEntryTypes || []);
|
|
4380
|
+
for (const type of PERFORMANCE_ENTRY_TYPES) {
|
|
4381
|
+
if (!supported.has(type)) continue;
|
|
4382
|
+
try {
|
|
4383
|
+
const observer = new Observer((list) => {
|
|
4384
|
+
for (const entry of list.getEntries()) {
|
|
4385
|
+
void this.runHook(
|
|
4386
|
+
"performance",
|
|
4387
|
+
(instance) => instance.plugin.performance?.({
|
|
4388
|
+
...this.createStateEvent(instance),
|
|
4389
|
+
entry,
|
|
4390
|
+
location: this.getLocation()
|
|
4391
|
+
})
|
|
4392
|
+
);
|
|
4393
|
+
}
|
|
4394
|
+
});
|
|
4395
|
+
observer.observe({ type, buffered: true });
|
|
4396
|
+
this.performanceObservers.push(observer);
|
|
4397
|
+
} catch (error) {
|
|
4398
|
+
void this.reportError(error, "performance");
|
|
4399
|
+
}
|
|
4400
|
+
}
|
|
4401
|
+
}
|
|
4402
|
+
async closeInternal(reason) {
|
|
4403
|
+
if (this.closed) return;
|
|
4404
|
+
if (this.startPromise) await this.startPromise;
|
|
4405
|
+
this.closed = true;
|
|
4406
|
+
this.currentNavigation?.controller.abort(reason);
|
|
4407
|
+
this.currentNavigation = void 0;
|
|
4408
|
+
const clientWindow = this.options.window;
|
|
4409
|
+
clientWindow?.removeEventListener("error", this.handleWindowError);
|
|
4410
|
+
clientWindow?.removeEventListener("unhandledrejection", this.handleUnhandledRejection);
|
|
4411
|
+
clientWindow?.removeEventListener("pagehide", this.handlePageHide);
|
|
4412
|
+
for (const observer of this.performanceObservers) observer.disconnect();
|
|
4413
|
+
this.performanceObservers.length = 0;
|
|
4414
|
+
for (const instance of [...this.instances].reverse()) {
|
|
4415
|
+
try {
|
|
4416
|
+
await instance.plugin.close?.({
|
|
4417
|
+
...this.createStateEvent(instance),
|
|
4418
|
+
reason
|
|
4419
|
+
});
|
|
4420
|
+
} catch (error) {
|
|
4421
|
+
this.logHookError(instance.registration.name, "close", error);
|
|
4422
|
+
}
|
|
4423
|
+
}
|
|
4424
|
+
}
|
|
4425
|
+
async runHook(hook, invoke) {
|
|
4426
|
+
for (const instance of this.instances) {
|
|
4427
|
+
try {
|
|
4428
|
+
await invoke(instance);
|
|
4429
|
+
} catch (error) {
|
|
4430
|
+
this.logHookError(instance.registration.name, hook, error);
|
|
4431
|
+
await this.runErrorHooks(
|
|
4432
|
+
{
|
|
4433
|
+
error,
|
|
4434
|
+
phase: `plugin:${hook}`,
|
|
4435
|
+
location: this.getLocation()
|
|
4436
|
+
},
|
|
4437
|
+
instance
|
|
4438
|
+
);
|
|
4439
|
+
}
|
|
4440
|
+
}
|
|
4441
|
+
}
|
|
4442
|
+
async runErrorHooks(event, excluded) {
|
|
4443
|
+
for (const instance of this.instances) {
|
|
4444
|
+
if (instance === excluded || !instance.plugin.error) continue;
|
|
4445
|
+
try {
|
|
4446
|
+
await instance.plugin.error({
|
|
4447
|
+
...this.createStateEvent(instance),
|
|
4448
|
+
...event
|
|
4449
|
+
});
|
|
4450
|
+
} catch (error) {
|
|
4451
|
+
this.logHookError(instance.registration.name, "error", error);
|
|
4452
|
+
}
|
|
4453
|
+
}
|
|
4454
|
+
}
|
|
4455
|
+
createSetupEvent(instance) {
|
|
4456
|
+
return {
|
|
4457
|
+
plugin: {
|
|
4458
|
+
name: instance.registration.name,
|
|
4459
|
+
version: instance.registration.version
|
|
4460
|
+
},
|
|
4461
|
+
public: readonlyPublicData(instance.registration.public),
|
|
4462
|
+
router: this.options.router,
|
|
4463
|
+
isDev: Boolean(this.options.isDev),
|
|
4464
|
+
isProd: Boolean(this.options.isProd),
|
|
4465
|
+
deploymentId: this.options.deploymentId
|
|
4466
|
+
};
|
|
4467
|
+
}
|
|
4468
|
+
createStateEvent(instance) {
|
|
4469
|
+
return {
|
|
4470
|
+
...this.createSetupEvent(instance),
|
|
4471
|
+
state: instance.state
|
|
4472
|
+
};
|
|
4473
|
+
}
|
|
4474
|
+
getLocation() {
|
|
4475
|
+
const href = this.options.window?.location.href ?? "http://localhost/";
|
|
4476
|
+
return toClientLocation(href, href);
|
|
4477
|
+
}
|
|
4478
|
+
getBaseUrl() {
|
|
4479
|
+
return this.options.window?.location.href ?? "http://localhost/";
|
|
4480
|
+
}
|
|
4481
|
+
logHookError(name, hook, error) {
|
|
4482
|
+
console.error(`[Farm.js] Client plugin "${name}" failed in ${hook}:`, error);
|
|
4483
|
+
}
|
|
4484
|
+
};
|
|
4485
|
+
__name(_FarmClientPluginManager, "FarmClientPluginManager");
|
|
4486
|
+
var FarmClientPluginManager = _FarmClientPluginManager;
|
|
4487
|
+
function createClientPluginManager(registrations, options) {
|
|
4488
|
+
return new FarmClientPluginManager(registrations, options);
|
|
4489
|
+
}
|
|
4490
|
+
__name(createClientPluginManager, "createClientPluginManager");
|
|
4491
|
+
function sortRegistrations(registrations) {
|
|
4492
|
+
const rank = /* @__PURE__ */ __name((enforce) => enforce === "pre" ? 0 : enforce === "post" ? 2 : 1, "rank");
|
|
4493
|
+
return registrations.map((registration, index) => ({ registration, index })).sort(
|
|
4494
|
+
(left, right) => rank(left.registration.enforce) - rank(right.registration.enforce) || left.index - right.index
|
|
4495
|
+
).map(({ registration }) => registration);
|
|
4496
|
+
}
|
|
4497
|
+
__name(sortRegistrations, "sortRegistrations");
|
|
4498
|
+
function toClientLocation(input, base) {
|
|
4499
|
+
if (typeof input === "object" && "href" in input && "pathname" in input) {
|
|
4500
|
+
return {
|
|
4501
|
+
href: input.href,
|
|
4502
|
+
pathname: input.pathname,
|
|
4503
|
+
search: input.search,
|
|
4504
|
+
hash: input.hash
|
|
4505
|
+
};
|
|
4506
|
+
}
|
|
4507
|
+
const url = new URL(input, base);
|
|
4508
|
+
return {
|
|
4509
|
+
href: url.href,
|
|
4510
|
+
pathname: url.pathname,
|
|
4511
|
+
search: url.search,
|
|
4512
|
+
hash: url.hash
|
|
4513
|
+
};
|
|
4514
|
+
}
|
|
4515
|
+
__name(toClientLocation, "toClientLocation");
|
|
4516
|
+
function readonlyPublicData(value) {
|
|
4517
|
+
if (value && typeof value === "object") {
|
|
4518
|
+
return Object.freeze(value);
|
|
4519
|
+
}
|
|
4520
|
+
return value;
|
|
4521
|
+
}
|
|
4522
|
+
__name(readonlyPublicData, "readonlyPublicData");
|
|
4523
|
+
function now() {
|
|
4524
|
+
return typeof performance !== "undefined" ? performance.now() : Date.now();
|
|
4525
|
+
}
|
|
4526
|
+
__name(now, "now");
|
|
4527
|
+
function isObject(value) {
|
|
4528
|
+
return typeof value === "object" && value !== null || typeof value === "function";
|
|
4529
|
+
}
|
|
4530
|
+
__name(isObject, "isObject");
|
|
4531
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
4532
|
+
0 && (module.exports = {
|
|
4533
|
+
FarmClientPluginManager,
|
|
4534
|
+
IntegrationClientError,
|
|
4535
|
+
Link,
|
|
4536
|
+
SPARouter,
|
|
4537
|
+
api,
|
|
4538
|
+
createAPIClient,
|
|
4539
|
+
createClientPluginManager,
|
|
4540
|
+
createIntegrationApi,
|
|
4541
|
+
createIntegrationClient,
|
|
4542
|
+
createIntegrationClients,
|
|
4543
|
+
createIntegrationServerClient,
|
|
4544
|
+
createIntegrations,
|
|
4545
|
+
createServerAPIClient,
|
|
4546
|
+
createStore,
|
|
4547
|
+
defineIntegrationAPI,
|
|
4548
|
+
defineIntegrationAPIOperation,
|
|
4549
|
+
endpoint,
|
|
4550
|
+
fetchServerQuery,
|
|
4551
|
+
getIntegrationAPIManifest,
|
|
4552
|
+
getRouter,
|
|
4553
|
+
installChunkErrorRecovery,
|
|
4554
|
+
integrationClients,
|
|
4555
|
+
integrationsClient,
|
|
4556
|
+
integrationsServer,
|
|
4557
|
+
isChunkLoadError,
|
|
4558
|
+
navigateTo,
|
|
4559
|
+
prefetch,
|
|
4560
|
+
prefetchServerQuery,
|
|
4561
|
+
pushState,
|
|
4562
|
+
readPageState,
|
|
4563
|
+
replaceState,
|
|
4564
|
+
useBlocker,
|
|
4565
|
+
useNavigation,
|
|
4566
|
+
usePageState,
|
|
4567
|
+
useRouter,
|
|
4568
|
+
useScrollRestoration,
|
|
4569
|
+
useServerQuery
|
|
4570
|
+
});
|
|
4571
|
+
//# sourceMappingURL=client.cjs.map
|