@fragno-dev/upload 0.1.1
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.md +16 -0
- package/README.md +43 -0
- package/bin/run.js +5 -0
- package/dist/browser/client/clients.js +49 -0
- package/dist/browser/client/clients.js.map +1 -0
- package/dist/browser/client/helpers.d.ts +51 -0
- package/dist/browser/client/helpers.d.ts.map +1 -0
- package/dist/browser/client/helpers.js +242 -0
- package/dist/browser/client/helpers.js.map +1 -0
- package/dist/browser/client/node_modules/.pnpm/@nanostores_query@0.3.4_nanostores@1.1.0/node_modules/@nanostores/query/dist/nanoquery.js +354 -0
- package/dist/browser/client/node_modules/.pnpm/@nanostores_query@0.3.4_nanostores@1.1.0/node_modules/@nanostores/query/dist/nanoquery.js.map +1 -0
- package/dist/browser/client/node_modules/.pnpm/@nanostores_solid@1.1.1_nanostores@1.1.0_solid-js@1.9.10/node_modules/@nanostores/solid/dist/index.js +14 -0
- package/dist/browser/client/node_modules/.pnpm/@nanostores_solid@1.1.1_nanostores@1.1.0_solid-js@1.9.10/node_modules/@nanostores/solid/dist/index.js.map +1 -0
- package/dist/browser/client/node_modules/.pnpm/nanoevents@9.1.0/node_modules/nanoevents/index.js +17 -0
- package/dist/browser/client/node_modules/.pnpm/nanoevents@9.1.0/node_modules/nanoevents/index.js.map +1 -0
- package/dist/browser/client/node_modules/.pnpm/nanostores@1.1.0/node_modules/nanostores/atom/index.js +62 -0
- package/dist/browser/client/node_modules/.pnpm/nanostores@1.1.0/node_modules/nanostores/atom/index.js.map +1 -0
- package/dist/browser/client/node_modules/.pnpm/nanostores@1.1.0/node_modules/nanostores/clean-stores/index.js +6 -0
- package/dist/browser/client/node_modules/.pnpm/nanostores@1.1.0/node_modules/nanostores/clean-stores/index.js.map +1 -0
- package/dist/browser/client/node_modules/.pnpm/nanostores@1.1.0/node_modules/nanostores/computed/index.js +50 -0
- package/dist/browser/client/node_modules/.pnpm/nanostores@1.1.0/node_modules/nanostores/computed/index.js.map +1 -0
- package/dist/browser/client/node_modules/.pnpm/nanostores@1.1.0/node_modules/nanostores/lifecycle/index.js +99 -0
- package/dist/browser/client/node_modules/.pnpm/nanostores@1.1.0/node_modules/nanostores/lifecycle/index.js.map +1 -0
- package/dist/browser/client/node_modules/.pnpm/nanostores@1.1.0/node_modules/nanostores/listen-keys/index.js +11 -0
- package/dist/browser/client/node_modules/.pnpm/nanostores@1.1.0/node_modules/nanostores/listen-keys/index.js.map +1 -0
- package/dist/browser/client/node_modules/.pnpm/nanostores@1.1.0/node_modules/nanostores/map/index.js +25 -0
- package/dist/browser/client/node_modules/.pnpm/nanostores@1.1.0/node_modules/nanostores/map/index.js.map +1 -0
- package/dist/browser/client/node_modules/.pnpm/nanostores@1.1.0/node_modules/nanostores/task/index.js +24 -0
- package/dist/browser/client/node_modules/.pnpm/nanostores@1.1.0/node_modules/nanostores/task/index.js.map +1 -0
- package/dist/browser/client/packages/fragment-upload/src/definition.js +49 -0
- package/dist/browser/client/packages/fragment-upload/src/definition.js.map +1 -0
- package/dist/browser/client/packages/fragment-upload/src/keys.d.ts +7 -0
- package/dist/browser/client/packages/fragment-upload/src/keys.d.ts.map +1 -0
- package/dist/browser/client/packages/fragment-upload/src/keys.js +28 -0
- package/dist/browser/client/packages/fragment-upload/src/keys.js.map +1 -0
- package/dist/browser/client/packages/fragment-upload/src/routes/files.js +98 -0
- package/dist/browser/client/packages/fragment-upload/src/routes/files.js.map +1 -0
- package/dist/browser/client/packages/fragment-upload/src/routes/index.js +9 -0
- package/dist/browser/client/packages/fragment-upload/src/routes/index.js.map +1 -0
- package/dist/browser/client/packages/fragment-upload/src/routes/shared.js +41 -0
- package/dist/browser/client/packages/fragment-upload/src/routes/shared.js.map +1 -0
- package/dist/browser/client/packages/fragment-upload/src/routes/uploads.js +186 -0
- package/dist/browser/client/packages/fragment-upload/src/routes/uploads.js.map +1 -0
- package/dist/browser/client/packages/fragment-upload/src/schema.js +8 -0
- package/dist/browser/client/packages/fragment-upload/src/schema.js.map +1 -0
- package/dist/browser/client/packages/fragment-upload/src/storage/types.d.ts +9 -0
- package/dist/browser/client/packages/fragment-upload/src/storage/types.d.ts.map +1 -0
- package/dist/browser/client/packages/fragment-upload/src/types.d.ts +31 -0
- package/dist/browser/client/packages/fragment-upload/src/types.d.ts.map +1 -0
- package/dist/browser/client/packages/fragno/dist/api/error.js +48 -0
- package/dist/browser/client/packages/fragno/dist/api/error.js.map +1 -0
- package/dist/browser/client/packages/fragno/dist/api/internal/path.js +76 -0
- package/dist/browser/client/packages/fragno/dist/api/internal/path.js.map +1 -0
- package/dist/browser/client/packages/fragno/dist/api/internal/response-stream.js +81 -0
- package/dist/browser/client/packages/fragno/dist/api/internal/response-stream.js.map +1 -0
- package/dist/browser/client/packages/fragno/dist/api/internal/route.js +10 -0
- package/dist/browser/client/packages/fragno/dist/api/internal/route.js.map +1 -0
- package/dist/browser/client/packages/fragno/dist/api/request-input-context.js +185 -0
- package/dist/browser/client/packages/fragno/dist/api/request-input-context.js.map +1 -0
- package/dist/browser/client/packages/fragno/dist/api/request-output-context.js +119 -0
- package/dist/browser/client/packages/fragno/dist/api/request-output-context.js.map +1 -0
- package/dist/browser/client/packages/fragno/dist/api/route.js +17 -0
- package/dist/browser/client/packages/fragno/dist/api/route.js.map +1 -0
- package/dist/browser/client/packages/fragno/dist/client/client-error.js +92 -0
- package/dist/browser/client/packages/fragno/dist/client/client-error.js.map +1 -0
- package/dist/browser/client/packages/fragno/dist/client/client.js +495 -0
- package/dist/browser/client/packages/fragno/dist/client/client.js.map +1 -0
- package/dist/browser/client/packages/fragno/dist/client/client.svelte.js +120 -0
- package/dist/browser/client/packages/fragno/dist/client/client.svelte.js.map +1 -0
- package/dist/browser/client/packages/fragno/dist/client/internal/fetcher-merge.js +36 -0
- package/dist/browser/client/packages/fragno/dist/client/internal/fetcher-merge.js.map +1 -0
- package/dist/browser/client/packages/fragno/dist/client/internal/ndjson-streaming.js +139 -0
- package/dist/browser/client/packages/fragno/dist/client/internal/ndjson-streaming.js.map +1 -0
- package/dist/browser/client/packages/fragno/dist/client/react.js +70 -0
- package/dist/browser/client/packages/fragno/dist/client/react.js.map +1 -0
- package/dist/browser/client/packages/fragno/dist/client/solid.js +108 -0
- package/dist/browser/client/packages/fragno/dist/client/solid.js.map +1 -0
- package/dist/browser/client/packages/fragno/dist/client/vanilla.js +96 -0
- package/dist/browser/client/packages/fragno/dist/client/vanilla.js.map +1 -0
- package/dist/browser/client/packages/fragno/dist/client/vue.js +120 -0
- package/dist/browser/client/packages/fragno/dist/client/vue.js.map +1 -0
- package/dist/browser/client/packages/fragno/dist/util/async.js +40 -0
- package/dist/browser/client/packages/fragno/dist/util/async.js.map +1 -0
- package/dist/browser/client/packages/fragno/dist/util/content-type.js +49 -0
- package/dist/browser/client/packages/fragno/dist/util/content-type.js.map +1 -0
- package/dist/browser/client/packages/fragno/dist/util/nanostores.js +31 -0
- package/dist/browser/client/packages/fragno/dist/util/nanostores.js.map +1 -0
- package/dist/browser/client/packages/fragno/dist/util/ssr.js +18 -0
- package/dist/browser/client/packages/fragno/dist/util/ssr.js.map +1 -0
- package/dist/browser/client/react.d.ts +295 -0
- package/dist/browser/client/react.d.ts.map +1 -0
- package/dist/browser/client/react.js +11 -0
- package/dist/browser/client/react.js.map +1 -0
- package/dist/browser/client/solid.d.ts +303 -0
- package/dist/browser/client/solid.d.ts.map +1 -0
- package/dist/browser/client/solid.js +11 -0
- package/dist/browser/client/solid.js.map +1 -0
- package/dist/browser/client/svelte.d.ts +295 -0
- package/dist/browser/client/svelte.d.ts.map +1 -0
- package/dist/browser/client/svelte.js +11 -0
- package/dist/browser/client/svelte.js.map +1 -0
- package/dist/browser/client/vanilla.d.ts +296 -0
- package/dist/browser/client/vanilla.d.ts.map +1 -0
- package/dist/browser/client/vanilla.js +11 -0
- package/dist/browser/client/vanilla.js.map +1 -0
- package/dist/browser/client/vue.d.ts +295 -0
- package/dist/browser/client/vue.d.ts.map +1 -0
- package/dist/browser/client/vue.js +11 -0
- package/dist/browser/client/vue.js.map +1 -0
- package/dist/browser/index-BdjKPO4J.d.ts +177 -0
- package/dist/browser/index-BdjKPO4J.d.ts.map +1 -0
- package/dist/browser/index.js +3 -0
- package/dist/browser/src-vdNJUbjT.js +1982 -0
- package/dist/browser/src-vdNJUbjT.js.map +1 -0
- package/dist/cli/commands/files/delete.d.ts +40 -0
- package/dist/cli/commands/files/delete.d.ts.map +1 -0
- package/dist/cli/commands/files/delete.js +31 -0
- package/dist/cli/commands/files/delete.js.map +1 -0
- package/dist/cli/commands/files/download-url.d.ts +40 -0
- package/dist/cli/commands/files/download-url.d.ts.map +1 -0
- package/dist/cli/commands/files/download-url.js +31 -0
- package/dist/cli/commands/files/download-url.js.map +1 -0
- package/dist/cli/commands/files/download.d.ts +49 -0
- package/dist/cli/commands/files/download.d.ts.map +1 -0
- package/dist/cli/commands/files/download.js +65 -0
- package/dist/cli/commands/files/download.js.map +1 -0
- package/dist/cli/commands/files/get.d.ts +40 -0
- package/dist/cli/commands/files/get.d.ts.map +1 -0
- package/dist/cli/commands/files/get.js +31 -0
- package/dist/cli/commands/files/get.js.map +1 -0
- package/dist/cli/commands/files/list.d.ts +56 -0
- package/dist/cli/commands/files/list.d.ts.map +1 -0
- package/dist/cli/commands/files/list.js +53 -0
- package/dist/cli/commands/files/list.js.map +1 -0
- package/dist/cli/commands/files/update.d.ts +56 -0
- package/dist/cli/commands/files/update.d.ts.map +1 -0
- package/dist/cli/commands/files/update.js +53 -0
- package/dist/cli/commands/files/update.js.map +1 -0
- package/dist/cli/commands/files/upload.d.ts +73 -0
- package/dist/cli/commands/files/upload.d.ts.map +1 -0
- package/dist/cli/commands/files/upload.js +87 -0
- package/dist/cli/commands/files/upload.js.map +1 -0
- package/dist/cli/commands/uploads/abort.d.ts +37 -0
- package/dist/cli/commands/uploads/abort.d.ts.map +1 -0
- package/dist/cli/commands/uploads/abort.js +26 -0
- package/dist/cli/commands/uploads/abort.js.map +1 -0
- package/dist/cli/commands/uploads/complete.d.ts +41 -0
- package/dist/cli/commands/uploads/complete.d.ts.map +1 -0
- package/dist/cli/commands/uploads/complete.js +45 -0
- package/dist/cli/commands/uploads/complete.js.map +1 -0
- package/dist/cli/commands/uploads/content.d.ts +46 -0
- package/dist/cli/commands/uploads/content.d.ts.map +1 -0
- package/dist/cli/commands/uploads/content.js +43 -0
- package/dist/cli/commands/uploads/content.js.map +1 -0
- package/dist/cli/commands/uploads/create.d.ts +72 -0
- package/dist/cli/commands/uploads/create.d.ts.map +1 -0
- package/dist/cli/commands/uploads/create.js +84 -0
- package/dist/cli/commands/uploads/create.js.map +1 -0
- package/dist/cli/commands/uploads/get.d.ts +37 -0
- package/dist/cli/commands/uploads/get.d.ts.map +1 -0
- package/dist/cli/commands/uploads/get.js +26 -0
- package/dist/cli/commands/uploads/get.js.map +1 -0
- package/dist/cli/commands/uploads/parts-complete.d.ts +41 -0
- package/dist/cli/commands/uploads/parts-complete.d.ts.map +1 -0
- package/dist/cli/commands/uploads/parts-complete.js +44 -0
- package/dist/cli/commands/uploads/parts-complete.js.map +1 -0
- package/dist/cli/commands/uploads/parts-list.d.ts +37 -0
- package/dist/cli/commands/uploads/parts-list.d.ts.map +1 -0
- package/dist/cli/commands/uploads/parts-list.js +26 -0
- package/dist/cli/commands/uploads/parts-list.js.map +1 -0
- package/dist/cli/commands/uploads/parts-urls.d.ts +46 -0
- package/dist/cli/commands/uploads/parts-urls.d.ts.map +1 -0
- package/dist/cli/commands/uploads/parts-urls.js +57 -0
- package/dist/cli/commands/uploads/parts-urls.js.map +1 -0
- package/dist/cli/commands/uploads/progress.d.ts +45 -0
- package/dist/cli/commands/uploads/progress.d.ts.map +1 -0
- package/dist/cli/commands/uploads/progress.js +40 -0
- package/dist/cli/commands/uploads/progress.js.map +1 -0
- package/dist/cli/commands/uploads/transfer.d.ts +73 -0
- package/dist/cli/commands/uploads/transfer.d.ts.map +1 -0
- package/dist/cli/commands/uploads/transfer.js +170 -0
- package/dist/cli/commands/uploads/transfer.js.map +1 -0
- package/dist/cli/index.d.ts +27 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +198 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/keys.js +32 -0
- package/dist/cli/keys.js.map +1 -0
- package/dist/cli/utils/client.js +174 -0
- package/dist/cli/utils/client.js.map +1 -0
- package/dist/cli/utils/options.js +135 -0
- package/dist/cli/utils/options.js.map +1 -0
- package/dist/node/cli/commands/files/delete.d.ts +40 -0
- package/dist/node/cli/commands/files/delete.d.ts.map +1 -0
- package/dist/node/cli/commands/files/delete.js +31 -0
- package/dist/node/cli/commands/files/delete.js.map +1 -0
- package/dist/node/cli/commands/files/download-url.d.ts +40 -0
- package/dist/node/cli/commands/files/download-url.d.ts.map +1 -0
- package/dist/node/cli/commands/files/download-url.js +31 -0
- package/dist/node/cli/commands/files/download-url.js.map +1 -0
- package/dist/node/cli/commands/files/download.d.ts +49 -0
- package/dist/node/cli/commands/files/download.d.ts.map +1 -0
- package/dist/node/cli/commands/files/download.js +65 -0
- package/dist/node/cli/commands/files/download.js.map +1 -0
- package/dist/node/cli/commands/files/get.d.ts +40 -0
- package/dist/node/cli/commands/files/get.d.ts.map +1 -0
- package/dist/node/cli/commands/files/get.js +31 -0
- package/dist/node/cli/commands/files/get.js.map +1 -0
- package/dist/node/cli/commands/files/list.d.ts +56 -0
- package/dist/node/cli/commands/files/list.d.ts.map +1 -0
- package/dist/node/cli/commands/files/list.js +53 -0
- package/dist/node/cli/commands/files/list.js.map +1 -0
- package/dist/node/cli/commands/files/update.d.ts +56 -0
- package/dist/node/cli/commands/files/update.d.ts.map +1 -0
- package/dist/node/cli/commands/files/update.js +53 -0
- package/dist/node/cli/commands/files/update.js.map +1 -0
- package/dist/node/cli/commands/files/upload.d.ts +73 -0
- package/dist/node/cli/commands/files/upload.d.ts.map +1 -0
- package/dist/node/cli/commands/files/upload.js +87 -0
- package/dist/node/cli/commands/files/upload.js.map +1 -0
- package/dist/node/cli/commands/uploads/abort.d.ts +37 -0
- package/dist/node/cli/commands/uploads/abort.d.ts.map +1 -0
- package/dist/node/cli/commands/uploads/abort.js +26 -0
- package/dist/node/cli/commands/uploads/abort.js.map +1 -0
- package/dist/node/cli/commands/uploads/complete.d.ts +41 -0
- package/dist/node/cli/commands/uploads/complete.d.ts.map +1 -0
- package/dist/node/cli/commands/uploads/complete.js +45 -0
- package/dist/node/cli/commands/uploads/complete.js.map +1 -0
- package/dist/node/cli/commands/uploads/content.d.ts +46 -0
- package/dist/node/cli/commands/uploads/content.d.ts.map +1 -0
- package/dist/node/cli/commands/uploads/content.js +43 -0
- package/dist/node/cli/commands/uploads/content.js.map +1 -0
- package/dist/node/cli/commands/uploads/create.d.ts +72 -0
- package/dist/node/cli/commands/uploads/create.d.ts.map +1 -0
- package/dist/node/cli/commands/uploads/create.js +84 -0
- package/dist/node/cli/commands/uploads/create.js.map +1 -0
- package/dist/node/cli/commands/uploads/get.d.ts +37 -0
- package/dist/node/cli/commands/uploads/get.d.ts.map +1 -0
- package/dist/node/cli/commands/uploads/get.js +26 -0
- package/dist/node/cli/commands/uploads/get.js.map +1 -0
- package/dist/node/cli/commands/uploads/parts-complete.d.ts +41 -0
- package/dist/node/cli/commands/uploads/parts-complete.d.ts.map +1 -0
- package/dist/node/cli/commands/uploads/parts-complete.js +44 -0
- package/dist/node/cli/commands/uploads/parts-complete.js.map +1 -0
- package/dist/node/cli/commands/uploads/parts-list.d.ts +37 -0
- package/dist/node/cli/commands/uploads/parts-list.d.ts.map +1 -0
- package/dist/node/cli/commands/uploads/parts-list.js +26 -0
- package/dist/node/cli/commands/uploads/parts-list.js.map +1 -0
- package/dist/node/cli/commands/uploads/parts-urls.d.ts +46 -0
- package/dist/node/cli/commands/uploads/parts-urls.d.ts.map +1 -0
- package/dist/node/cli/commands/uploads/parts-urls.js +57 -0
- package/dist/node/cli/commands/uploads/parts-urls.js.map +1 -0
- package/dist/node/cli/commands/uploads/progress.d.ts +45 -0
- package/dist/node/cli/commands/uploads/progress.d.ts.map +1 -0
- package/dist/node/cli/commands/uploads/progress.js +40 -0
- package/dist/node/cli/commands/uploads/progress.js.map +1 -0
- package/dist/node/cli/commands/uploads/transfer.d.ts +73 -0
- package/dist/node/cli/commands/uploads/transfer.d.ts.map +1 -0
- package/dist/node/cli/commands/uploads/transfer.js +170 -0
- package/dist/node/cli/commands/uploads/transfer.js.map +1 -0
- package/dist/node/cli/index.d.ts +27 -0
- package/dist/node/cli/index.d.ts.map +1 -0
- package/dist/node/cli/index.js +198 -0
- package/dist/node/cli/index.js.map +1 -0
- package/dist/node/cli/utils/client.js +174 -0
- package/dist/node/cli/utils/client.js.map +1 -0
- package/dist/node/cli/utils/options.js +135 -0
- package/dist/node/cli/utils/options.js.map +1 -0
- package/dist/node/client/clients.d.ts +295 -0
- package/dist/node/client/clients.d.ts.map +1 -0
- package/dist/node/client/clients.js +49 -0
- package/dist/node/client/clients.js.map +1 -0
- package/dist/node/client/helpers.d.ts +51 -0
- package/dist/node/client/helpers.d.ts.map +1 -0
- package/dist/node/client/helpers.js +242 -0
- package/dist/node/client/helpers.js.map +1 -0
- package/dist/node/client/react.d.ts +295 -0
- package/dist/node/client/react.d.ts.map +1 -0
- package/dist/node/client/react.js +11 -0
- package/dist/node/client/react.js.map +1 -0
- package/dist/node/client/solid.d.ts +303 -0
- package/dist/node/client/solid.d.ts.map +1 -0
- package/dist/node/client/solid.js +11 -0
- package/dist/node/client/solid.js.map +1 -0
- package/dist/node/client/svelte.d.ts +295 -0
- package/dist/node/client/svelte.d.ts.map +1 -0
- package/dist/node/client/svelte.js +11 -0
- package/dist/node/client/svelte.js.map +1 -0
- package/dist/node/client/vanilla.d.ts +296 -0
- package/dist/node/client/vanilla.d.ts.map +1 -0
- package/dist/node/client/vanilla.js +11 -0
- package/dist/node/client/vanilla.js.map +1 -0
- package/dist/node/client/vue.d.ts +295 -0
- package/dist/node/client/vue.d.ts.map +1 -0
- package/dist/node/client/vue.js +11 -0
- package/dist/node/client/vue.js.map +1 -0
- package/dist/node/config.d.ts +41 -0
- package/dist/node/config.d.ts.map +1 -0
- package/dist/node/config.js +26 -0
- package/dist/node/config.js.map +1 -0
- package/dist/node/definition.d.ts +829 -0
- package/dist/node/definition.d.ts.map +1 -0
- package/dist/node/definition.js +59 -0
- package/dist/node/definition.js.map +1 -0
- package/dist/node/index.d.ts +1246 -0
- package/dist/node/index.d.ts.map +1 -0
- package/dist/node/index.js +19 -0
- package/dist/node/index.js.map +1 -0
- package/dist/node/keys.d.ts +12 -0
- package/dist/node/keys.d.ts.map +1 -0
- package/dist/node/keys.js +63 -0
- package/dist/node/keys.js.map +1 -0
- package/dist/node/routes/files.js +450 -0
- package/dist/node/routes/files.js.map +1 -0
- package/dist/node/routes/index.d.ts +2023 -0
- package/dist/node/routes/index.d.ts.map +1 -0
- package/dist/node/routes/index.js +9 -0
- package/dist/node/routes/index.js.map +1 -0
- package/dist/node/routes/shared.js +66 -0
- package/dist/node/routes/shared.js.map +1 -0
- package/dist/node/routes/uploads.js +454 -0
- package/dist/node/routes/uploads.js.map +1 -0
- package/dist/node/schema.d.ts +14 -0
- package/dist/node/schema.d.ts.map +1 -0
- package/dist/node/schema.js +30 -0
- package/dist/node/schema.js.map +1 -0
- package/dist/node/services/files.d.ts +20 -0
- package/dist/node/services/files.d.ts.map +1 -0
- package/dist/node/services/files.js +93 -0
- package/dist/node/services/files.js.map +1 -0
- package/dist/node/services/helpers.js +36 -0
- package/dist/node/services/helpers.js.map +1 -0
- package/dist/node/services/index.js +4 -0
- package/dist/node/services/uploads.d.ts +50 -0
- package/dist/node/services/uploads.d.ts.map +1 -0
- package/dist/node/services/uploads.js +358 -0
- package/dist/node/services/uploads.js.map +1 -0
- package/dist/node/storage/fs.d.ts +16 -0
- package/dist/node/storage/fs.d.ts.map +1 -0
- package/dist/node/storage/fs.js +94 -0
- package/dist/node/storage/fs.js.map +1 -0
- package/dist/node/storage/r2.d.ts +103 -0
- package/dist/node/storage/r2.d.ts.map +1 -0
- package/dist/node/storage/r2.js +23 -0
- package/dist/node/storage/r2.js.map +1 -0
- package/dist/node/storage/s3.d.ts +44 -0
- package/dist/node/storage/s3.d.ts.map +1 -0
- package/dist/node/storage/s3.js +398 -0
- package/dist/node/storage/s3.js.map +1 -0
- package/dist/node/storage/types.d.ts +118 -0
- package/dist/node/storage/types.d.ts.map +1 -0
- package/dist/node/types.d.ts +32 -0
- package/dist/node/types.d.ts.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +105 -0
|
@@ -0,0 +1,495 @@
|
|
|
1
|
+
import { task } from "../../../../node_modules/.pnpm/nanostores@1.1.0/node_modules/nanostores/task/index.js";
|
|
2
|
+
import { computed } from "../../../../node_modules/.pnpm/nanostores@1.1.0/node_modules/nanostores/computed/index.js";
|
|
3
|
+
import { SSR_ENABLED, addStore, getInitialData } from "../util/ssr.js";
|
|
4
|
+
import { unwrapObject } from "../util/nanostores.js";
|
|
5
|
+
import { resolveRouteFactories } from "../api/route.js";
|
|
6
|
+
import { getMountRoute } from "../api/internal/route.js";
|
|
7
|
+
import { RequestInputContext } from "../api/request-input-context.js";
|
|
8
|
+
import { RequestOutputContext } from "../api/request-output-context.js";
|
|
9
|
+
import { buildPath, extractPathParams } from "../api/internal/path.js";
|
|
10
|
+
import { FragnoClientApiError, FragnoClientError, FragnoClientFetchAbortError, FragnoClientFetchError, FragnoClientFetchNetworkError, FragnoClientUnknownApiError } from "./client-error.js";
|
|
11
|
+
import { parseContentType } from "../util/content-type.js";
|
|
12
|
+
import { handleNdjsonStreamingFirstItem } from "./internal/ndjson-streaming.js";
|
|
13
|
+
import { mergeFetcherConfigs } from "./internal/fetcher-merge.js";
|
|
14
|
+
import { nanoquery } from "../../../../node_modules/.pnpm/@nanostores_query@0.3.4_nanostores@1.1.0/node_modules/@nanostores/query/dist/nanoquery.js";
|
|
15
|
+
|
|
16
|
+
//#region ../fragno/dist/client/client.js
|
|
17
|
+
/**
|
|
18
|
+
* Symbols used to identify hook types
|
|
19
|
+
*/
|
|
20
|
+
const GET_HOOK_SYMBOL = Symbol("fragno-get-hook");
|
|
21
|
+
const MUTATOR_HOOK_SYMBOL = Symbol("fragno-mutator-hook");
|
|
22
|
+
const STORE_SYMBOL = Symbol("fragno-store");
|
|
23
|
+
/**
|
|
24
|
+
* Check if a value contains files that should be sent as FormData.
|
|
25
|
+
* @internal
|
|
26
|
+
*/
|
|
27
|
+
function containsFiles(value) {
|
|
28
|
+
if (value instanceof File || value instanceof Blob) return true;
|
|
29
|
+
if (value instanceof FormData) return true;
|
|
30
|
+
if (typeof value === "object" && value !== null) return Object.values(value).some((v) => v instanceof File || v instanceof Blob || v instanceof FormData);
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Convert an object containing files to FormData.
|
|
35
|
+
* Handles nested File/Blob values by appending them directly.
|
|
36
|
+
* Other values are JSON-stringified.
|
|
37
|
+
* @internal
|
|
38
|
+
*/
|
|
39
|
+
function toFormData(value) {
|
|
40
|
+
const formData = new FormData();
|
|
41
|
+
for (const [key, val] of Object.entries(value)) if (val instanceof File) formData.append(key, val, val.name);
|
|
42
|
+
else if (val instanceof Blob) formData.append(key, val);
|
|
43
|
+
else if (val !== void 0 && val !== null) formData.append(key, typeof val === "string" ? val : JSON.stringify(val));
|
|
44
|
+
return formData;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Prepare request body and headers for sending.
|
|
48
|
+
* Handles FormData (file uploads) vs JSON data.
|
|
49
|
+
* @internal
|
|
50
|
+
*/
|
|
51
|
+
function prepareRequestBody(body, contentType) {
|
|
52
|
+
if (body === void 0) return { body: void 0 };
|
|
53
|
+
if (contentType === "application/octet-stream") {
|
|
54
|
+
if (body instanceof ReadableStream || body instanceof Blob || body instanceof File || body instanceof ArrayBuffer || body instanceof Uint8Array) return {
|
|
55
|
+
body,
|
|
56
|
+
headers: { "Content-Type": "application/octet-stream" }
|
|
57
|
+
};
|
|
58
|
+
throw new Error("Octet-stream routes only accept Blob, File, ArrayBuffer, Uint8Array, or ReadableStream bodies.");
|
|
59
|
+
}
|
|
60
|
+
if (body instanceof FormData) return { body };
|
|
61
|
+
if (body instanceof File) {
|
|
62
|
+
const formData = new FormData();
|
|
63
|
+
formData.append("file", body, body.name);
|
|
64
|
+
return { body: formData };
|
|
65
|
+
}
|
|
66
|
+
if (body instanceof Blob) {
|
|
67
|
+
const formData = new FormData();
|
|
68
|
+
formData.append("file", body);
|
|
69
|
+
return { body: formData };
|
|
70
|
+
}
|
|
71
|
+
if (typeof body === "object" && body !== null && containsFiles(body)) return { body: toFormData(body) };
|
|
72
|
+
return {
|
|
73
|
+
body: JSON.stringify(body),
|
|
74
|
+
headers: { "Content-Type": "application/json" }
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Merge request headers from multiple sources.
|
|
79
|
+
* Returns undefined if there are no headers to merge.
|
|
80
|
+
* @internal
|
|
81
|
+
*/
|
|
82
|
+
function mergeRequestHeaders(...headerSources) {
|
|
83
|
+
const result = {};
|
|
84
|
+
let hasHeaders = false;
|
|
85
|
+
for (const source of headerSources) {
|
|
86
|
+
if (!source) continue;
|
|
87
|
+
if (source instanceof Headers) for (const [key, value] of source.entries()) {
|
|
88
|
+
result[key] = value;
|
|
89
|
+
hasHeaders = true;
|
|
90
|
+
}
|
|
91
|
+
else if (Array.isArray(source)) for (const [key, value] of source) {
|
|
92
|
+
result[key] = value;
|
|
93
|
+
hasHeaders = true;
|
|
94
|
+
}
|
|
95
|
+
else for (const [key, value] of Object.entries(source)) {
|
|
96
|
+
result[key] = value;
|
|
97
|
+
hasHeaders = true;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return hasHeaders ? result : void 0;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* @internal
|
|
104
|
+
*/
|
|
105
|
+
function buildUrl(config, params) {
|
|
106
|
+
const { baseUrl = "", mountRoute, path } = config;
|
|
107
|
+
const { pathParams, queryParams } = params ?? {};
|
|
108
|
+
const normalizedPathParams = unwrapObject(pathParams);
|
|
109
|
+
const normalizedQueryParams = unwrapObject(queryParams) ?? {};
|
|
110
|
+
const filteredQueryParams = Object.fromEntries(Object.entries(normalizedQueryParams).filter(([_, value]) => value !== void 0));
|
|
111
|
+
const searchParams = new URLSearchParams(filteredQueryParams);
|
|
112
|
+
return `${baseUrl}${mountRoute}${buildPath(path, normalizedPathParams ?? {})}${searchParams.toString() ? `?${searchParams.toString()}` : ""}`;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* This method returns an array, which can be passed directly to nanostores.
|
|
116
|
+
*
|
|
117
|
+
* The returned array is always: path, pathParams (In order they appear in the path), queryParams (In alphabetical order)
|
|
118
|
+
* Missing pathParams are replaced with "<missing>".
|
|
119
|
+
* Atoms with undefined values are wrapped in computed atoms that map undefined to "" to avoid nanoquery treating the key as incomplete.
|
|
120
|
+
* @param path
|
|
121
|
+
* @param params
|
|
122
|
+
* @returns
|
|
123
|
+
* @internal
|
|
124
|
+
*/
|
|
125
|
+
function getCacheKey(method, path, params) {
|
|
126
|
+
if (!params) return [method, path];
|
|
127
|
+
const { pathParams, queryParams } = params;
|
|
128
|
+
const pathParamValues = extractPathParams(path).map((name) => pathParams?.[name] ?? "<missing>");
|
|
129
|
+
const queryParamValues = queryParams ? Object.keys(queryParams).sort().map((key) => {
|
|
130
|
+
const value = queryParams[key];
|
|
131
|
+
if (value && typeof value === "object" && "get" in value) return /* @__PURE__ */ computed(value, (v) => v ?? "");
|
|
132
|
+
return value ?? "";
|
|
133
|
+
}) : [];
|
|
134
|
+
return [
|
|
135
|
+
method,
|
|
136
|
+
path,
|
|
137
|
+
...pathParamValues,
|
|
138
|
+
...queryParamValues
|
|
139
|
+
];
|
|
140
|
+
}
|
|
141
|
+
function isStreamingResponse(response) {
|
|
142
|
+
const contentType = parseContentType(response.headers.get("content-type"));
|
|
143
|
+
if (!contentType) return false;
|
|
144
|
+
if (!(response.headers.get("transfer-encoding") === "chunked")) return false;
|
|
145
|
+
if (contentType.subtype === "octet-stream") return "octet-stream";
|
|
146
|
+
if (contentType.subtype === "x-ndjson") return "ndjson";
|
|
147
|
+
return false;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* @internal
|
|
151
|
+
*/
|
|
152
|
+
function isGetHook(hook) {
|
|
153
|
+
return typeof hook === "object" && hook !== null && GET_HOOK_SYMBOL in hook && hook[GET_HOOK_SYMBOL] === true;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* @internal
|
|
157
|
+
*/
|
|
158
|
+
function isMutatorHook(hook) {
|
|
159
|
+
return typeof hook === "object" && hook !== null && MUTATOR_HOOK_SYMBOL in hook && hook[MUTATOR_HOOK_SYMBOL] === true;
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* @internal
|
|
163
|
+
*/
|
|
164
|
+
function isStore(obj) {
|
|
165
|
+
return typeof obj === "object" && obj !== null && STORE_SYMBOL in obj && obj[STORE_SYMBOL] === true;
|
|
166
|
+
}
|
|
167
|
+
var ClientBuilder = class {
|
|
168
|
+
#publicConfig;
|
|
169
|
+
#fragmentConfig;
|
|
170
|
+
#fetcherConfig;
|
|
171
|
+
#cache = /* @__PURE__ */ new Map();
|
|
172
|
+
#createFetcherStore;
|
|
173
|
+
#createMutatorStore;
|
|
174
|
+
#invalidateKeys;
|
|
175
|
+
constructor(publicConfig, fragmentConfig) {
|
|
176
|
+
this.#publicConfig = publicConfig;
|
|
177
|
+
this.#fragmentConfig = fragmentConfig;
|
|
178
|
+
this.#fetcherConfig = publicConfig.fetcherConfig;
|
|
179
|
+
const [createFetcherStore, createMutatorStore, { invalidateKeys }] = nanoquery({ cache: this.#cache });
|
|
180
|
+
this.#createFetcherStore = createFetcherStore;
|
|
181
|
+
this.#createMutatorStore = createMutatorStore;
|
|
182
|
+
this.#invalidateKeys = invalidateKeys;
|
|
183
|
+
}
|
|
184
|
+
get cacheEntries() {
|
|
185
|
+
return Object.fromEntries(this.#cache.entries());
|
|
186
|
+
}
|
|
187
|
+
createStore(obj) {
|
|
188
|
+
return {
|
|
189
|
+
obj,
|
|
190
|
+
[STORE_SYMBOL]: true
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Build a URL for a custom backend call using the configured baseUrl and mountRoute.
|
|
195
|
+
* Useful for fragment authors who need to make custom fetch calls.
|
|
196
|
+
*/
|
|
197
|
+
buildUrl(path, params) {
|
|
198
|
+
return buildUrl({
|
|
199
|
+
baseUrl: this.#publicConfig.baseUrl ?? "",
|
|
200
|
+
mountRoute: getMountRoute({
|
|
201
|
+
name: this.#fragmentConfig.name,
|
|
202
|
+
mountRoute: this.#publicConfig.mountRoute
|
|
203
|
+
}),
|
|
204
|
+
path
|
|
205
|
+
}, {
|
|
206
|
+
pathParams: params?.path,
|
|
207
|
+
queryParams: params?.query
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Get the configured fetcher function for custom backend calls.
|
|
212
|
+
* Returns fetch with merged options applied.
|
|
213
|
+
*/
|
|
214
|
+
getFetcher() {
|
|
215
|
+
return {
|
|
216
|
+
fetcher: this.#getFetcher(),
|
|
217
|
+
defaultOptions: this.#getFetcherOptions()
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
#getFetcher() {
|
|
221
|
+
if (this.#fetcherConfig?.type === "function") return this.#fetcherConfig.fetcher;
|
|
222
|
+
return fetch;
|
|
223
|
+
}
|
|
224
|
+
#getFetcherOptions() {
|
|
225
|
+
if (this.#fetcherConfig?.type === "options") return this.#fetcherConfig.options;
|
|
226
|
+
}
|
|
227
|
+
createHook(path, options) {
|
|
228
|
+
const route = this.#fragmentConfig.routes.find((r) => r.path === path && r.method === "GET" && r.outputSchema !== void 0);
|
|
229
|
+
if (!route) throw new Error(`Route '${path}' not found or is not a GET route with an output schema.`);
|
|
230
|
+
return this.#createRouteQueryHook(route, options);
|
|
231
|
+
}
|
|
232
|
+
createMutator(method, path, onInvalidate) {
|
|
233
|
+
const route = this.#fragmentConfig.routes.find((r) => r.method !== "GET" && r.path === path && r.method === method);
|
|
234
|
+
if (!route) throw new Error(`Route '${path}' not found or is a GET route with an input and output schema.`);
|
|
235
|
+
return this.#createRouteQueryMutator(route, onInvalidate);
|
|
236
|
+
}
|
|
237
|
+
#createRouteQueryHook(route, options = {}) {
|
|
238
|
+
if (route.method !== "GET") throw new Error(`Only GET routes are supported for hooks. Route '${route.path}' is a ${route.method} route.`);
|
|
239
|
+
if (!route.outputSchema) throw new Error(`Output schema is required for GET routes. Route '${route.path}' has no output schema.`);
|
|
240
|
+
const baseUrl = this.#publicConfig.baseUrl ?? "";
|
|
241
|
+
const mountRoute = getMountRoute({
|
|
242
|
+
name: this.#fragmentConfig.name,
|
|
243
|
+
mountRoute: this.#publicConfig.mountRoute
|
|
244
|
+
});
|
|
245
|
+
const fetcher = this.#getFetcher();
|
|
246
|
+
const fetcherOptions = this.#getFetcherOptions();
|
|
247
|
+
async function callServerSideHandler(params) {
|
|
248
|
+
const { pathParams, queryParams } = params ?? {};
|
|
249
|
+
const normalizedPathParams = unwrapObject(pathParams);
|
|
250
|
+
const normalizedQueryParams = unwrapObject(queryParams) ?? {};
|
|
251
|
+
const filteredQueryParams = Object.fromEntries(Object.entries(normalizedQueryParams).filter(([_, value]) => value !== void 0));
|
|
252
|
+
const searchParams = new URLSearchParams(filteredQueryParams);
|
|
253
|
+
return await route.handler(RequestInputContext.fromSSRContext({
|
|
254
|
+
method: route.method,
|
|
255
|
+
path: route.path,
|
|
256
|
+
pathParams: normalizedPathParams,
|
|
257
|
+
searchParams
|
|
258
|
+
}), new RequestOutputContext(route.outputSchema));
|
|
259
|
+
}
|
|
260
|
+
async function executeQuery(params) {
|
|
261
|
+
const { pathParams, queryParams } = params ?? {};
|
|
262
|
+
if (typeof window === "undefined") return task(async () => callServerSideHandler({
|
|
263
|
+
pathParams,
|
|
264
|
+
queryParams
|
|
265
|
+
}));
|
|
266
|
+
const url = buildUrl({
|
|
267
|
+
baseUrl,
|
|
268
|
+
mountRoute,
|
|
269
|
+
path: route.path
|
|
270
|
+
}, {
|
|
271
|
+
pathParams,
|
|
272
|
+
queryParams
|
|
273
|
+
});
|
|
274
|
+
let response;
|
|
275
|
+
try {
|
|
276
|
+
response = fetcherOptions ? await fetcher(url, fetcherOptions) : await fetcher(url);
|
|
277
|
+
} catch (error) {
|
|
278
|
+
throw FragnoClientFetchError.fromUnknownFetchError(error);
|
|
279
|
+
}
|
|
280
|
+
if (!response.ok) throw await FragnoClientApiError.fromResponse(response);
|
|
281
|
+
return response;
|
|
282
|
+
}
|
|
283
|
+
return {
|
|
284
|
+
route,
|
|
285
|
+
store: (args) => {
|
|
286
|
+
const { path, query } = args ?? {};
|
|
287
|
+
const key = getCacheKey(route.method, route.path, {
|
|
288
|
+
pathParams: path,
|
|
289
|
+
queryParams: query
|
|
290
|
+
});
|
|
291
|
+
const store = this.#createFetcherStore(key, {
|
|
292
|
+
fetcher: async () => {
|
|
293
|
+
if (SSR_ENABLED) {
|
|
294
|
+
const initialData = getInitialData(key.map((d) => typeof d === "string" ? d : d.get()).join(""));
|
|
295
|
+
if (initialData) return initialData;
|
|
296
|
+
}
|
|
297
|
+
const response = await executeQuery({
|
|
298
|
+
pathParams: path,
|
|
299
|
+
queryParams: query
|
|
300
|
+
});
|
|
301
|
+
const isStreaming = isStreamingResponse(response);
|
|
302
|
+
if (!isStreaming) return response.json();
|
|
303
|
+
if (typeof window === "undefined") return [];
|
|
304
|
+
if (isStreaming === "ndjson") {
|
|
305
|
+
const { firstItem } = await handleNdjsonStreamingFirstItem(response, {
|
|
306
|
+
setData: (value) => {
|
|
307
|
+
store.set({
|
|
308
|
+
...store.get(),
|
|
309
|
+
loading: !(Array.isArray(value) && value.length > 0),
|
|
310
|
+
data: value
|
|
311
|
+
});
|
|
312
|
+
},
|
|
313
|
+
setError: (value) => {
|
|
314
|
+
store.set({
|
|
315
|
+
...store.get(),
|
|
316
|
+
error: value
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
});
|
|
320
|
+
return [firstItem];
|
|
321
|
+
}
|
|
322
|
+
if (isStreaming === "octet-stream") throw new Error("Octet-stream streaming is not supported.");
|
|
323
|
+
throw new Error("Unreachable");
|
|
324
|
+
},
|
|
325
|
+
onErrorRetry: options?.onErrorRetry,
|
|
326
|
+
dedupeTime: Infinity
|
|
327
|
+
});
|
|
328
|
+
if (typeof window === "undefined") addStore(store);
|
|
329
|
+
return store;
|
|
330
|
+
},
|
|
331
|
+
query: async (args) => {
|
|
332
|
+
const { path, query } = args ?? {};
|
|
333
|
+
const response = await executeQuery({
|
|
334
|
+
pathParams: path,
|
|
335
|
+
queryParams: query
|
|
336
|
+
});
|
|
337
|
+
const isStreaming = isStreamingResponse(response);
|
|
338
|
+
if (!isStreaming) return await response.json();
|
|
339
|
+
if (isStreaming === "ndjson") {
|
|
340
|
+
const { streamingPromise } = await handleNdjsonStreamingFirstItem(response);
|
|
341
|
+
return await streamingPromise;
|
|
342
|
+
}
|
|
343
|
+
if (isStreaming === "octet-stream") throw new Error("Octet-stream streaming is not supported.");
|
|
344
|
+
throw new Error("Unreachable");
|
|
345
|
+
},
|
|
346
|
+
[GET_HOOK_SYMBOL]: true
|
|
347
|
+
};
|
|
348
|
+
}
|
|
349
|
+
#createRouteQueryMutator(route, onInvalidate = (invalidate, params) => invalidate("GET", route.path, params)) {
|
|
350
|
+
const method = route.method;
|
|
351
|
+
const baseUrl = this.#publicConfig.baseUrl ?? "";
|
|
352
|
+
const mountRoute = getMountRoute({
|
|
353
|
+
name: this.#fragmentConfig.name,
|
|
354
|
+
mountRoute: this.#publicConfig.mountRoute
|
|
355
|
+
});
|
|
356
|
+
const fetcher = this.#getFetcher();
|
|
357
|
+
const fetcherOptions = this.#getFetcherOptions();
|
|
358
|
+
async function executeMutateQuery({ body, path, query }) {
|
|
359
|
+
if (typeof window === "undefined") return task(async () => route.handler(RequestInputContext.fromSSRContext({
|
|
360
|
+
inputSchema: route.inputSchema,
|
|
361
|
+
method,
|
|
362
|
+
path: route.path,
|
|
363
|
+
pathParams: path ?? {},
|
|
364
|
+
searchParams: new URLSearchParams(query),
|
|
365
|
+
body
|
|
366
|
+
}), new RequestOutputContext(route.outputSchema)));
|
|
367
|
+
const url = buildUrl({
|
|
368
|
+
baseUrl,
|
|
369
|
+
mountRoute,
|
|
370
|
+
path: route.path
|
|
371
|
+
}, {
|
|
372
|
+
pathParams: path,
|
|
373
|
+
queryParams: query
|
|
374
|
+
});
|
|
375
|
+
let response;
|
|
376
|
+
try {
|
|
377
|
+
const { body: preparedBody, headers: bodyHeaders } = prepareRequestBody(body, route.contentType);
|
|
378
|
+
const mergedHeaders = mergeRequestHeaders(fetcherOptions?.headers, bodyHeaders);
|
|
379
|
+
const requestOptions = {
|
|
380
|
+
...fetcherOptions,
|
|
381
|
+
method,
|
|
382
|
+
body: preparedBody,
|
|
383
|
+
...mergedHeaders ? { headers: mergedHeaders } : {}
|
|
384
|
+
};
|
|
385
|
+
if (preparedBody instanceof ReadableStream) requestOptions.duplex = "half";
|
|
386
|
+
response = await fetcher(url, requestOptions);
|
|
387
|
+
} catch (error) {
|
|
388
|
+
throw FragnoClientFetchError.fromUnknownFetchError(error);
|
|
389
|
+
}
|
|
390
|
+
if (!response.ok) throw await FragnoClientApiError.fromResponse(response);
|
|
391
|
+
return response;
|
|
392
|
+
}
|
|
393
|
+
const mutatorStore = this.#createMutatorStore(async ({ data }) => {
|
|
394
|
+
if (typeof window === "undefined") {}
|
|
395
|
+
const { body, path, query } = data;
|
|
396
|
+
if (typeof body === "undefined" && route.inputSchema !== void 0) throw new Error("Body is required.");
|
|
397
|
+
const response = await executeMutateQuery({
|
|
398
|
+
body,
|
|
399
|
+
path,
|
|
400
|
+
query
|
|
401
|
+
});
|
|
402
|
+
onInvalidate(this.#invalidate.bind(this), {
|
|
403
|
+
pathParams: path ?? {},
|
|
404
|
+
queryParams: query
|
|
405
|
+
});
|
|
406
|
+
if (response.status === 201 || response.status === 204) return;
|
|
407
|
+
const isStreaming = isStreamingResponse(response);
|
|
408
|
+
if (!isStreaming) return response.json();
|
|
409
|
+
if (typeof window === "undefined") return [];
|
|
410
|
+
if (isStreaming === "ndjson") {
|
|
411
|
+
const { firstItem } = await handleNdjsonStreamingFirstItem(response, {
|
|
412
|
+
setData: (value) => {
|
|
413
|
+
mutatorStore.set({
|
|
414
|
+
...mutatorStore.get(),
|
|
415
|
+
loading: !(Array.isArray(value) && value.length > 0),
|
|
416
|
+
data: value
|
|
417
|
+
});
|
|
418
|
+
},
|
|
419
|
+
setError: (value) => {
|
|
420
|
+
mutatorStore.set({
|
|
421
|
+
...mutatorStore.get(),
|
|
422
|
+
error: value
|
|
423
|
+
});
|
|
424
|
+
}
|
|
425
|
+
});
|
|
426
|
+
return [firstItem];
|
|
427
|
+
}
|
|
428
|
+
if (isStreaming === "octet-stream") throw new Error("Octet-stream streaming is not supported.");
|
|
429
|
+
throw new Error("Unreachable");
|
|
430
|
+
}, { onError: (error) => {
|
|
431
|
+
console.error("Error in mutatorStore", error);
|
|
432
|
+
} });
|
|
433
|
+
const mutateQuery = async (data) => {
|
|
434
|
+
const { body, path, query } = data;
|
|
435
|
+
if (typeof body === "undefined" && route.inputSchema !== void 0) throw new Error("Body is required for mutateQuery");
|
|
436
|
+
const response = await executeMutateQuery({
|
|
437
|
+
body,
|
|
438
|
+
path,
|
|
439
|
+
query
|
|
440
|
+
});
|
|
441
|
+
if (response.status === 201 || response.status === 204) return;
|
|
442
|
+
const isStreaming = isStreamingResponse(response);
|
|
443
|
+
if (!isStreaming) return response.json();
|
|
444
|
+
if (isStreaming === "ndjson") {
|
|
445
|
+
const { streamingPromise } = await handleNdjsonStreamingFirstItem(response);
|
|
446
|
+
return await streamingPromise;
|
|
447
|
+
}
|
|
448
|
+
if (isStreaming === "octet-stream") throw new Error("Octet-stream streaming is not supported for mutations");
|
|
449
|
+
throw new Error("Unreachable");
|
|
450
|
+
};
|
|
451
|
+
return {
|
|
452
|
+
route,
|
|
453
|
+
mutateQuery,
|
|
454
|
+
mutatorStore,
|
|
455
|
+
[MUTATOR_HOOK_SYMBOL]: true
|
|
456
|
+
};
|
|
457
|
+
}
|
|
458
|
+
#invalidate(method, path, params) {
|
|
459
|
+
const prefix = getCacheKey(method, path, {
|
|
460
|
+
pathParams: params?.pathParams,
|
|
461
|
+
queryParams: params?.queryParams
|
|
462
|
+
}).map((k) => typeof k === "string" ? k : k.get()).join("");
|
|
463
|
+
this.#invalidateKeys((key) => key.startsWith(prefix));
|
|
464
|
+
}
|
|
465
|
+
};
|
|
466
|
+
/**
|
|
467
|
+
* Create a client builder for fragments using the new fragment definition API.
|
|
468
|
+
* This is the same as createClientBuilder but works with FragmentDefinition.
|
|
469
|
+
*/
|
|
470
|
+
function createClientBuilder(definition, publicConfig, routesOrFactories, authorFetcherConfig) {
|
|
471
|
+
const routes = resolveRouteFactories({
|
|
472
|
+
config: {},
|
|
473
|
+
deps: {},
|
|
474
|
+
services: {},
|
|
475
|
+
serviceDeps: {}
|
|
476
|
+
}, routesOrFactories);
|
|
477
|
+
const fragmentConfig = {
|
|
478
|
+
name: definition.name,
|
|
479
|
+
routes
|
|
480
|
+
};
|
|
481
|
+
const mountRoute = getMountRoute({
|
|
482
|
+
name: definition.name,
|
|
483
|
+
mountRoute: publicConfig.mountRoute
|
|
484
|
+
});
|
|
485
|
+
const mergedFetcherConfig = mergeFetcherConfigs(authorFetcherConfig, publicConfig.fetcherConfig);
|
|
486
|
+
return new ClientBuilder({
|
|
487
|
+
...publicConfig,
|
|
488
|
+
mountRoute,
|
|
489
|
+
fetcherConfig: mergedFetcherConfig
|
|
490
|
+
}, fragmentConfig);
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
//#endregion
|
|
494
|
+
export { createClientBuilder, isGetHook, isMutatorHook, isStore };
|
|
495
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","names":["resolveRouteFactories","getMountRoute","RequestInputContext","RequestOutputContext","buildPath","extractPathParams","FragnoClientApiError","FragnoClientError","FragnoClientFetchAbortError","FragnoClientFetchError","FragnoClientFetchNetworkError","FragnoClientUnknownApiError","parseContentType","handleNdjsonStreamingFirstItem","SSR_ENABLED","addStore","getInitialData","unwrapObject","mergeFetcherConfigs","computed","task","nanoquery","GET_HOOK_SYMBOL","Symbol","MUTATOR_HOOK_SYMBOL","STORE_SYMBOL","containsFiles","value","File","Blob","FormData","Object","values","some","v","toFormData","formData","key","val","entries","append","name","JSON","stringify","prepareRequestBody","body","contentType","ReadableStream","ArrayBuffer","Uint8Array","headers","Error","mergeRequestHeaders","headerSources","result","hasHeaders","source","Headers","Array","isArray","buildUrl","config","params","baseUrl","mountRoute","path","pathParams","queryParams","normalizedPathParams","normalizedQueryParams","filteredQueryParams","fromEntries","filter","_","searchParams","URLSearchParams","toString","getCacheKey","method","pathParamValues","map","queryParamValues","keys","sort","isStreamingResponse","response","get","subtype","isGetHook","hook","isMutatorHook","isStore","obj","ClientBuilder","publicConfig","fragmentConfig","fetcherConfig","cache","Map","createFetcherStore","createMutatorStore","invalidateKeys","constructor","cacheEntries","createStore","query","getFetcher","fetcher","defaultOptions","getFetcherOptions","#getFetcher","type","fetch","#getFetcherOptions","options","createHook","route","routes","find","r","outputSchema","createRouteQueryHook","createMutator","onInvalidate","createRouteQueryMutator","#createRouteQueryHook","fetcherOptions","callServerSideHandler","handler","fromSSRContext","executeQuery","window","url","error","fromUnknownFetchError","ok","fromResponse","store","args","initialData","d","join","isStreaming","json","firstItem","setData","set","loading","length","data","setError","onErrorRetry","dedupeTime","Infinity","streamingPromise","#createRouteQueryMutator","invalidate","executeMutateQuery","inputSchema","preparedBody","bodyHeaders","mergedHeaders","requestOptions","duplex","mutatorStore","bind","status","onError","console","mutateQuery","#invalidate","prefix","k","startsWith","createClientBuilder","definition","routesOrFactories","authorFetcherConfig","deps","services","serviceDeps","mergedFetcherConfig"],"sources":["../../../../../../../../fragno/dist/client/client.js"],"sourcesContent":["import { resolveRouteFactories } from \"../api/route.js\";\nimport { getMountRoute } from \"../api/internal/route.js\";\nimport { RequestInputContext } from \"../api/request-input-context.js\";\nimport { RequestOutputContext } from \"../api/request-output-context.js\";\nimport { buildPath, extractPathParams } from \"../api/internal/path.js\";\nimport { FragnoClientApiError, FragnoClientError, FragnoClientFetchAbortError, FragnoClientFetchError, FragnoClientFetchNetworkError, FragnoClientUnknownApiError } from \"./client-error.js\";\nimport { parseContentType } from \"../util/content-type.js\";\nimport { handleNdjsonStreamingFirstItem } from \"./internal/ndjson-streaming.js\";\nimport { SSR_ENABLED, addStore, getInitialData } from \"../util/ssr.js\";\nimport { unwrapObject } from \"../util/nanostores.js\";\nimport { mergeFetcherConfigs } from \"./internal/fetcher-merge.js\";\nimport { computed, task } from \"nanostores\";\nimport { nanoquery } from \"@nanostores/query\";\n\n//#region src/client/client.ts\n/**\n* Symbols used to identify hook types\n*/\nconst GET_HOOK_SYMBOL = Symbol(\"fragno-get-hook\");\nconst MUTATOR_HOOK_SYMBOL = Symbol(\"fragno-mutator-hook\");\nconst STORE_SYMBOL = Symbol(\"fragno-store\");\n/**\n* Check if a value contains files that should be sent as FormData.\n* @internal\n*/\nfunction containsFiles(value) {\n\tif (value instanceof File || value instanceof Blob) return true;\n\tif (value instanceof FormData) return true;\n\tif (typeof value === \"object\" && value !== null) return Object.values(value).some((v) => v instanceof File || v instanceof Blob || v instanceof FormData);\n\treturn false;\n}\n/**\n* Convert an object containing files to FormData.\n* Handles nested File/Blob values by appending them directly.\n* Other values are JSON-stringified.\n* @internal\n*/\nfunction toFormData(value) {\n\tconst formData = new FormData();\n\tfor (const [key, val] of Object.entries(value)) if (val instanceof File) formData.append(key, val, val.name);\n\telse if (val instanceof Blob) formData.append(key, val);\n\telse if (val !== void 0 && val !== null) formData.append(key, typeof val === \"string\" ? val : JSON.stringify(val));\n\treturn formData;\n}\n/**\n* Prepare request body and headers for sending.\n* Handles FormData (file uploads) vs JSON data.\n* @internal\n*/\nfunction prepareRequestBody(body, contentType) {\n\tif (body === void 0) return { body: void 0 };\n\tif (contentType === \"application/octet-stream\") {\n\t\tif (body instanceof ReadableStream || body instanceof Blob || body instanceof File || body instanceof ArrayBuffer || body instanceof Uint8Array) return {\n\t\t\tbody,\n\t\t\theaders: { \"Content-Type\": \"application/octet-stream\" }\n\t\t};\n\t\tthrow new Error(\"Octet-stream routes only accept Blob, File, ArrayBuffer, Uint8Array, or ReadableStream bodies.\");\n\t}\n\tif (body instanceof FormData) return { body };\n\tif (body instanceof File) {\n\t\tconst formData = new FormData();\n\t\tformData.append(\"file\", body, body.name);\n\t\treturn { body: formData };\n\t}\n\tif (body instanceof Blob) {\n\t\tconst formData = new FormData();\n\t\tformData.append(\"file\", body);\n\t\treturn { body: formData };\n\t}\n\tif (typeof body === \"object\" && body !== null && containsFiles(body)) return { body: toFormData(body) };\n\treturn {\n\t\tbody: JSON.stringify(body),\n\t\theaders: { \"Content-Type\": \"application/json\" }\n\t};\n}\n/**\n* Merge request headers from multiple sources.\n* Returns undefined if there are no headers to merge.\n* @internal\n*/\nfunction mergeRequestHeaders(...headerSources) {\n\tconst result = {};\n\tlet hasHeaders = false;\n\tfor (const source of headerSources) {\n\t\tif (!source) continue;\n\t\tif (source instanceof Headers) for (const [key, value] of source.entries()) {\n\t\t\tresult[key] = value;\n\t\t\thasHeaders = true;\n\t\t}\n\t\telse if (Array.isArray(source)) for (const [key, value] of source) {\n\t\t\tresult[key] = value;\n\t\t\thasHeaders = true;\n\t\t}\n\t\telse for (const [key, value] of Object.entries(source)) {\n\t\t\tresult[key] = value;\n\t\t\thasHeaders = true;\n\t\t}\n\t}\n\treturn hasHeaders ? result : void 0;\n}\n/**\n* @internal\n*/\nfunction buildUrl(config, params) {\n\tconst { baseUrl = \"\", mountRoute, path } = config;\n\tconst { pathParams, queryParams } = params ?? {};\n\tconst normalizedPathParams = unwrapObject(pathParams);\n\tconst normalizedQueryParams = unwrapObject(queryParams) ?? {};\n\tconst filteredQueryParams = Object.fromEntries(Object.entries(normalizedQueryParams).filter(([_, value]) => value !== void 0));\n\tconst searchParams = new URLSearchParams(filteredQueryParams);\n\treturn `${baseUrl}${mountRoute}${buildPath(path, normalizedPathParams ?? {})}${searchParams.toString() ? `?${searchParams.toString()}` : \"\"}`;\n}\n/**\n* This method returns an array, which can be passed directly to nanostores.\n*\n* The returned array is always: path, pathParams (In order they appear in the path), queryParams (In alphabetical order)\n* Missing pathParams are replaced with \"<missing>\".\n* Atoms with undefined values are wrapped in computed atoms that map undefined to \"\" to avoid nanoquery treating the key as incomplete.\n* @param path\n* @param params\n* @returns\n* @internal\n*/\nfunction getCacheKey(method, path, params) {\n\tif (!params) return [method, path];\n\tconst { pathParams, queryParams } = params;\n\tconst pathParamValues = extractPathParams(path).map((name) => pathParams?.[name] ?? \"<missing>\");\n\tconst queryParamValues = queryParams ? Object.keys(queryParams).sort().map((key) => {\n\t\tconst value = queryParams[key];\n\t\tif (value && typeof value === \"object\" && \"get\" in value) return computed(value, (v) => v ?? \"\");\n\t\treturn value ?? \"\";\n\t}) : [];\n\treturn [\n\t\tmethod,\n\t\tpath,\n\t\t...pathParamValues,\n\t\t...queryParamValues\n\t];\n}\nfunction isStreamingResponse(response) {\n\tconst contentType = parseContentType(response.headers.get(\"content-type\"));\n\tif (!contentType) return false;\n\tif (!(response.headers.get(\"transfer-encoding\") === \"chunked\")) return false;\n\tif (contentType.subtype === \"octet-stream\") return \"octet-stream\";\n\tif (contentType.subtype === \"x-ndjson\") return \"ndjson\";\n\treturn false;\n}\n/**\n* @internal\n*/\nfunction isGetHook(hook) {\n\treturn typeof hook === \"object\" && hook !== null && GET_HOOK_SYMBOL in hook && hook[GET_HOOK_SYMBOL] === true;\n}\n/**\n* @internal\n*/\nfunction isMutatorHook(hook) {\n\treturn typeof hook === \"object\" && hook !== null && MUTATOR_HOOK_SYMBOL in hook && hook[MUTATOR_HOOK_SYMBOL] === true;\n}\n/**\n* @internal\n*/\nfunction isStore(obj) {\n\treturn typeof obj === \"object\" && obj !== null && STORE_SYMBOL in obj && obj[STORE_SYMBOL] === true;\n}\nvar ClientBuilder = class {\n\t#publicConfig;\n\t#fragmentConfig;\n\t#fetcherConfig;\n\t#cache = /* @__PURE__ */ new Map();\n\t#createFetcherStore;\n\t#createMutatorStore;\n\t#invalidateKeys;\n\tconstructor(publicConfig, fragmentConfig) {\n\t\tthis.#publicConfig = publicConfig;\n\t\tthis.#fragmentConfig = fragmentConfig;\n\t\tthis.#fetcherConfig = publicConfig.fetcherConfig;\n\t\tconst [createFetcherStore, createMutatorStore, { invalidateKeys }] = nanoquery({ cache: this.#cache });\n\t\tthis.#createFetcherStore = createFetcherStore;\n\t\tthis.#createMutatorStore = createMutatorStore;\n\t\tthis.#invalidateKeys = invalidateKeys;\n\t}\n\tget cacheEntries() {\n\t\treturn Object.fromEntries(this.#cache.entries());\n\t}\n\tcreateStore(obj) {\n\t\treturn {\n\t\t\tobj,\n\t\t\t[STORE_SYMBOL]: true\n\t\t};\n\t}\n\t/**\n\t* Build a URL for a custom backend call using the configured baseUrl and mountRoute.\n\t* Useful for fragment authors who need to make custom fetch calls.\n\t*/\n\tbuildUrl(path, params) {\n\t\treturn buildUrl({\n\t\t\tbaseUrl: this.#publicConfig.baseUrl ?? \"\",\n\t\t\tmountRoute: getMountRoute({\n\t\t\t\tname: this.#fragmentConfig.name,\n\t\t\t\tmountRoute: this.#publicConfig.mountRoute\n\t\t\t}),\n\t\t\tpath\n\t\t}, {\n\t\t\tpathParams: params?.path,\n\t\t\tqueryParams: params?.query\n\t\t});\n\t}\n\t/**\n\t* Get the configured fetcher function for custom backend calls.\n\t* Returns fetch with merged options applied.\n\t*/\n\tgetFetcher() {\n\t\treturn {\n\t\t\tfetcher: this.#getFetcher(),\n\t\t\tdefaultOptions: this.#getFetcherOptions()\n\t\t};\n\t}\n\t#getFetcher() {\n\t\tif (this.#fetcherConfig?.type === \"function\") return this.#fetcherConfig.fetcher;\n\t\treturn fetch;\n\t}\n\t#getFetcherOptions() {\n\t\tif (this.#fetcherConfig?.type === \"options\") return this.#fetcherConfig.options;\n\t}\n\tcreateHook(path, options) {\n\t\tconst route = this.#fragmentConfig.routes.find((r) => r.path === path && r.method === \"GET\" && r.outputSchema !== void 0);\n\t\tif (!route) throw new Error(`Route '${path}' not found or is not a GET route with an output schema.`);\n\t\treturn this.#createRouteQueryHook(route, options);\n\t}\n\tcreateMutator(method, path, onInvalidate) {\n\t\tconst route = this.#fragmentConfig.routes.find((r) => r.method !== \"GET\" && r.path === path && r.method === method);\n\t\tif (!route) throw new Error(`Route '${path}' not found or is a GET route with an input and output schema.`);\n\t\treturn this.#createRouteQueryMutator(route, onInvalidate);\n\t}\n\t#createRouteQueryHook(route, options = {}) {\n\t\tif (route.method !== \"GET\") throw new Error(`Only GET routes are supported for hooks. Route '${route.path}' is a ${route.method} route.`);\n\t\tif (!route.outputSchema) throw new Error(`Output schema is required for GET routes. Route '${route.path}' has no output schema.`);\n\t\tconst baseUrl = this.#publicConfig.baseUrl ?? \"\";\n\t\tconst mountRoute = getMountRoute({\n\t\t\tname: this.#fragmentConfig.name,\n\t\t\tmountRoute: this.#publicConfig.mountRoute\n\t\t});\n\t\tconst fetcher = this.#getFetcher();\n\t\tconst fetcherOptions = this.#getFetcherOptions();\n\t\tasync function callServerSideHandler(params) {\n\t\t\tconst { pathParams, queryParams } = params ?? {};\n\t\t\tconst normalizedPathParams = unwrapObject(pathParams);\n\t\t\tconst normalizedQueryParams = unwrapObject(queryParams) ?? {};\n\t\t\tconst filteredQueryParams = Object.fromEntries(Object.entries(normalizedQueryParams).filter(([_, value]) => value !== void 0));\n\t\t\tconst searchParams = new URLSearchParams(filteredQueryParams);\n\t\t\treturn await route.handler(RequestInputContext.fromSSRContext({\n\t\t\t\tmethod: route.method,\n\t\t\t\tpath: route.path,\n\t\t\t\tpathParams: normalizedPathParams,\n\t\t\t\tsearchParams\n\t\t\t}), new RequestOutputContext(route.outputSchema));\n\t\t}\n\t\tasync function executeQuery(params) {\n\t\t\tconst { pathParams, queryParams } = params ?? {};\n\t\t\tif (typeof window === \"undefined\") return task(async () => callServerSideHandler({\n\t\t\t\tpathParams,\n\t\t\t\tqueryParams\n\t\t\t}));\n\t\t\tconst url = buildUrl({\n\t\t\t\tbaseUrl,\n\t\t\t\tmountRoute,\n\t\t\t\tpath: route.path\n\t\t\t}, {\n\t\t\t\tpathParams,\n\t\t\t\tqueryParams\n\t\t\t});\n\t\t\tlet response;\n\t\t\ttry {\n\t\t\t\tresponse = fetcherOptions ? await fetcher(url, fetcherOptions) : await fetcher(url);\n\t\t\t} catch (error) {\n\t\t\t\tthrow FragnoClientFetchError.fromUnknownFetchError(error);\n\t\t\t}\n\t\t\tif (!response.ok) throw await FragnoClientApiError.fromResponse(response);\n\t\t\treturn response;\n\t\t}\n\t\treturn {\n\t\t\troute,\n\t\t\tstore: (args) => {\n\t\t\t\tconst { path, query } = args ?? {};\n\t\t\t\tconst key = getCacheKey(route.method, route.path, {\n\t\t\t\t\tpathParams: path,\n\t\t\t\t\tqueryParams: query\n\t\t\t\t});\n\t\t\t\tconst store = this.#createFetcherStore(key, {\n\t\t\t\t\tfetcher: async () => {\n\t\t\t\t\t\tif (SSR_ENABLED) {\n\t\t\t\t\t\t\tconst initialData = getInitialData(key.map((d) => typeof d === \"string\" ? d : d.get()).join(\"\"));\n\t\t\t\t\t\t\tif (initialData) return initialData;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst response = await executeQuery({\n\t\t\t\t\t\t\tpathParams: path,\n\t\t\t\t\t\t\tqueryParams: query\n\t\t\t\t\t\t});\n\t\t\t\t\t\tconst isStreaming = isStreamingResponse(response);\n\t\t\t\t\t\tif (!isStreaming) return response.json();\n\t\t\t\t\t\tif (typeof window === \"undefined\") return [];\n\t\t\t\t\t\tif (isStreaming === \"ndjson\") {\n\t\t\t\t\t\t\tconst { firstItem } = await handleNdjsonStreamingFirstItem(response, {\n\t\t\t\t\t\t\t\tsetData: (value) => {\n\t\t\t\t\t\t\t\t\tstore.set({\n\t\t\t\t\t\t\t\t\t\t...store.get(),\n\t\t\t\t\t\t\t\t\t\tloading: !(Array.isArray(value) && value.length > 0),\n\t\t\t\t\t\t\t\t\t\tdata: value\n\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tsetError: (value) => {\n\t\t\t\t\t\t\t\t\tstore.set({\n\t\t\t\t\t\t\t\t\t\t...store.get(),\n\t\t\t\t\t\t\t\t\t\terror: value\n\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\treturn [firstItem];\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (isStreaming === \"octet-stream\") throw new Error(\"Octet-stream streaming is not supported.\");\n\t\t\t\t\t\tthrow new Error(\"Unreachable\");\n\t\t\t\t\t},\n\t\t\t\t\tonErrorRetry: options?.onErrorRetry,\n\t\t\t\t\tdedupeTime: Infinity\n\t\t\t\t});\n\t\t\t\tif (typeof window === \"undefined\") addStore(store);\n\t\t\t\treturn store;\n\t\t\t},\n\t\t\tquery: async (args) => {\n\t\t\t\tconst { path, query } = args ?? {};\n\t\t\t\tconst response = await executeQuery({\n\t\t\t\t\tpathParams: path,\n\t\t\t\t\tqueryParams: query\n\t\t\t\t});\n\t\t\t\tconst isStreaming = isStreamingResponse(response);\n\t\t\t\tif (!isStreaming) return await response.json();\n\t\t\t\tif (isStreaming === \"ndjson\") {\n\t\t\t\t\tconst { streamingPromise } = await handleNdjsonStreamingFirstItem(response);\n\t\t\t\t\treturn await streamingPromise;\n\t\t\t\t}\n\t\t\t\tif (isStreaming === \"octet-stream\") throw new Error(\"Octet-stream streaming is not supported.\");\n\t\t\t\tthrow new Error(\"Unreachable\");\n\t\t\t},\n\t\t\t[GET_HOOK_SYMBOL]: true\n\t\t};\n\t}\n\t#createRouteQueryMutator(route, onInvalidate = (invalidate, params) => invalidate(\"GET\", route.path, params)) {\n\t\tconst method = route.method;\n\t\tconst baseUrl = this.#publicConfig.baseUrl ?? \"\";\n\t\tconst mountRoute = getMountRoute({\n\t\t\tname: this.#fragmentConfig.name,\n\t\t\tmountRoute: this.#publicConfig.mountRoute\n\t\t});\n\t\tconst fetcher = this.#getFetcher();\n\t\tconst fetcherOptions = this.#getFetcherOptions();\n\t\tasync function executeMutateQuery({ body, path, query }) {\n\t\t\tif (typeof window === \"undefined\") return task(async () => route.handler(RequestInputContext.fromSSRContext({\n\t\t\t\tinputSchema: route.inputSchema,\n\t\t\t\tmethod,\n\t\t\t\tpath: route.path,\n\t\t\t\tpathParams: path ?? {},\n\t\t\t\tsearchParams: new URLSearchParams(query),\n\t\t\t\tbody\n\t\t\t}), new RequestOutputContext(route.outputSchema)));\n\t\t\tconst url = buildUrl({\n\t\t\t\tbaseUrl,\n\t\t\t\tmountRoute,\n\t\t\t\tpath: route.path\n\t\t\t}, {\n\t\t\t\tpathParams: path,\n\t\t\t\tqueryParams: query\n\t\t\t});\n\t\t\tlet response;\n\t\t\ttry {\n\t\t\t\tconst { body: preparedBody, headers: bodyHeaders } = prepareRequestBody(body, route.contentType);\n\t\t\t\tconst mergedHeaders = mergeRequestHeaders(fetcherOptions?.headers, bodyHeaders);\n\t\t\t\tconst requestOptions = {\n\t\t\t\t\t...fetcherOptions,\n\t\t\t\t\tmethod,\n\t\t\t\t\tbody: preparedBody,\n\t\t\t\t\t...mergedHeaders ? { headers: mergedHeaders } : {}\n\t\t\t\t};\n\t\t\t\tif (preparedBody instanceof ReadableStream) requestOptions.duplex = \"half\";\n\t\t\t\tresponse = await fetcher(url, requestOptions);\n\t\t\t} catch (error) {\n\t\t\t\tthrow FragnoClientFetchError.fromUnknownFetchError(error);\n\t\t\t}\n\t\t\tif (!response.ok) throw await FragnoClientApiError.fromResponse(response);\n\t\t\treturn response;\n\t\t}\n\t\tconst mutatorStore = this.#createMutatorStore(async ({ data }) => {\n\t\t\tif (typeof window === \"undefined\") {}\n\t\t\tconst { body, path, query } = data;\n\t\t\tif (typeof body === \"undefined\" && route.inputSchema !== void 0) throw new Error(\"Body is required.\");\n\t\t\tconst response = await executeMutateQuery({\n\t\t\t\tbody,\n\t\t\t\tpath,\n\t\t\t\tquery\n\t\t\t});\n\t\t\tonInvalidate(this.#invalidate.bind(this), {\n\t\t\t\tpathParams: path ?? {},\n\t\t\t\tqueryParams: query\n\t\t\t});\n\t\t\tif (response.status === 201 || response.status === 204) return;\n\t\t\tconst isStreaming = isStreamingResponse(response);\n\t\t\tif (!isStreaming) return response.json();\n\t\t\tif (typeof window === \"undefined\") return [];\n\t\t\tif (isStreaming === \"ndjson\") {\n\t\t\t\tconst { firstItem } = await handleNdjsonStreamingFirstItem(response, {\n\t\t\t\t\tsetData: (value) => {\n\t\t\t\t\t\tmutatorStore.set({\n\t\t\t\t\t\t\t...mutatorStore.get(),\n\t\t\t\t\t\t\tloading: !(Array.isArray(value) && value.length > 0),\n\t\t\t\t\t\t\tdata: value\n\t\t\t\t\t\t});\n\t\t\t\t\t},\n\t\t\t\t\tsetError: (value) => {\n\t\t\t\t\t\tmutatorStore.set({\n\t\t\t\t\t\t\t...mutatorStore.get(),\n\t\t\t\t\t\t\terror: value\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\treturn [firstItem];\n\t\t\t}\n\t\t\tif (isStreaming === \"octet-stream\") throw new Error(\"Octet-stream streaming is not supported.\");\n\t\t\tthrow new Error(\"Unreachable\");\n\t\t}, { onError: (error) => {\n\t\t\tconsole.error(\"Error in mutatorStore\", error);\n\t\t} });\n\t\tconst mutateQuery = (async (data) => {\n\t\t\tconst { body, path, query } = data;\n\t\t\tif (typeof body === \"undefined\" && route.inputSchema !== void 0) throw new Error(\"Body is required for mutateQuery\");\n\t\t\tconst response = await executeMutateQuery({\n\t\t\t\tbody,\n\t\t\t\tpath,\n\t\t\t\tquery\n\t\t\t});\n\t\t\tif (response.status === 201 || response.status === 204) return;\n\t\t\tconst isStreaming = isStreamingResponse(response);\n\t\t\tif (!isStreaming) return response.json();\n\t\t\tif (isStreaming === \"ndjson\") {\n\t\t\t\tconst { streamingPromise } = await handleNdjsonStreamingFirstItem(response);\n\t\t\t\treturn await streamingPromise;\n\t\t\t}\n\t\t\tif (isStreaming === \"octet-stream\") throw new Error(\"Octet-stream streaming is not supported for mutations\");\n\t\t\tthrow new Error(\"Unreachable\");\n\t\t});\n\t\treturn {\n\t\t\troute,\n\t\t\tmutateQuery,\n\t\t\tmutatorStore,\n\t\t\t[MUTATOR_HOOK_SYMBOL]: true\n\t\t};\n\t}\n\t#invalidate(method, path, params) {\n\t\tconst prefix = getCacheKey(method, path, {\n\t\t\tpathParams: params?.pathParams,\n\t\t\tqueryParams: params?.queryParams\n\t\t}).map((k) => typeof k === \"string\" ? k : k.get()).join(\"\");\n\t\tthis.#invalidateKeys((key) => key.startsWith(prefix));\n\t}\n};\n/**\n* Create a client builder for fragments using the new fragment definition API.\n* This is the same as createClientBuilder but works with FragmentDefinition.\n*/\nfunction createClientBuilder(definition, publicConfig, routesOrFactories, authorFetcherConfig) {\n\tconst routes = resolveRouteFactories({\n\t\tconfig: {},\n\t\tdeps: {},\n\t\tservices: {},\n\t\tserviceDeps: {}\n\t}, routesOrFactories);\n\tconst fragmentConfig = {\n\t\tname: definition.name,\n\t\troutes\n\t};\n\tconst mountRoute = getMountRoute({\n\t\tname: definition.name,\n\t\tmountRoute: publicConfig.mountRoute\n\t});\n\tconst mergedFetcherConfig = mergeFetcherConfigs(authorFetcherConfig, publicConfig.fetcherConfig);\n\treturn new ClientBuilder({\n\t\t...publicConfig,\n\t\tmountRoute,\n\t\tfetcherConfig: mergedFetcherConfig\n\t}, fragmentConfig);\n}\n\n//#endregion\nexport { ClientBuilder, FragnoClientApiError, FragnoClientError, FragnoClientFetchAbortError, FragnoClientFetchError, FragnoClientFetchNetworkError, FragnoClientUnknownApiError, buildUrl, createClientBuilder, getCacheKey, isGetHook, isMutatorHook, isStore };\n//# sourceMappingURL=client.js.map"],"mappings":"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"}
|