@thomasfosterau/effect-sveltekit 0.3.1 → 0.4.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.
Files changed (95) hide show
  1. package/README.md +3 -3
  2. package/dist/Hooks.d.ts +4 -5
  3. package/dist/Hooks.js +3 -1
  4. package/dist/Hooks.js.map +1 -1
  5. package/dist/Navigation.d.ts +1 -3
  6. package/dist/Navigation.js +1 -1
  7. package/dist/Remote.d.ts +1 -3
  8. package/dist/Remote.js +1 -1
  9. package/dist/Remote.js.map +1 -1
  10. package/dist/State.d.ts +1 -3
  11. package/dist/State.js +1 -1
  12. package/dist/adapter/assets.d.ts +7 -5
  13. package/dist/adapter/assets.js +3 -3
  14. package/dist/adapter/assets.js.map +1 -1
  15. package/dist/adapter/handler.d.ts +4 -5
  16. package/dist/adapter/handler.js +12 -12
  17. package/dist/adapter/handler.js.map +1 -1
  18. package/dist/adapter/index.d.ts +1 -2
  19. package/dist/adapter/index.js +3 -3
  20. package/dist/adapter/index.js.map +1 -1
  21. package/dist/adapter/serve.d.ts +0 -1
  22. package/dist/adapter/serve.js +4 -4
  23. package/dist/adapter/serve.js.map +1 -1
  24. package/dist/api-client.d.ts +5 -6
  25. package/dist/api-client.js +2 -2
  26. package/dist/api-client.js.map +1 -1
  27. package/dist/app-runtime.d.ts +1 -2
  28. package/dist/app-runtime.js +3 -2
  29. package/dist/app-runtime.js.map +1 -1
  30. package/dist/client/Hooks.d.ts +1 -3
  31. package/dist/client/Hooks.js +1 -1
  32. package/dist/config.d.ts +2 -3
  33. package/dist/config.js +5 -5
  34. package/dist/config.js.map +1 -1
  35. package/dist/errors.d.ts +88 -0
  36. package/dist/errors.js +126 -0
  37. package/dist/errors.js.map +1 -0
  38. package/dist/forms.d.ts +2 -3
  39. package/dist/forms.js +1 -1
  40. package/dist/index.d.ts +2 -1
  41. package/dist/index.js +2 -1
  42. package/dist/internal/app-state.d.ts +1 -2
  43. package/dist/internal/app-state.js +1 -1
  44. package/dist/internal/auto.d.ts +0 -1
  45. package/dist/internal/auto.js.map +1 -1
  46. package/dist/internal/enhance.d.ts +0 -1
  47. package/dist/internal/enhance.js.map +1 -1
  48. package/dist/internal/error.js +1 -1
  49. package/dist/internal/remote-run.d.ts +2 -2
  50. package/dist/internal/remote-run.js.map +1 -1
  51. package/dist/internal/remote-validators.js +1 -1
  52. package/dist/internal/route-params.d.ts +0 -1
  53. package/dist/kit.d.ts +2 -3
  54. package/dist/realtime.d.ts +3 -5
  55. package/dist/realtime.js +1 -1
  56. package/dist/realtime.js.map +1 -1
  57. package/dist/remote-functions.d.ts +2 -3
  58. package/dist/remote-functions.js +2 -2
  59. package/dist/remote-functions.js.map +1 -1
  60. package/dist/remote-reactive.d.ts +1 -2
  61. package/dist/remote-reactive.js +1 -1
  62. package/dist/remote-reactive.js.map +1 -1
  63. package/dist/request-parse.d.ts +1 -2
  64. package/dist/request-parse.js.map +1 -1
  65. package/dist/request-runtime.d.ts +0 -1
  66. package/dist/request-runtime.js.map +1 -1
  67. package/dist/request-services.d.ts +0 -1
  68. package/dist/request-services.js.map +1 -1
  69. package/dist/response-headers.d.ts +24 -0
  70. package/dist/response-headers.js +35 -0
  71. package/dist/response-headers.js.map +1 -0
  72. package/dist/runtime.d.ts +2 -3
  73. package/dist/runtime.js +3 -3
  74. package/dist/runtime.js.map +1 -1
  75. package/dist/server/Endpoint.d.ts +18 -15
  76. package/dist/server/Endpoint.js +10 -9
  77. package/dist/server/Endpoint.js.map +1 -1
  78. package/dist/server/Hooks.d.ts +1 -3
  79. package/dist/server/Hooks.js +1 -1
  80. package/dist/server/Hooks.js.map +1 -1
  81. package/dist/server.d.ts +5 -4
  82. package/dist/server.js +5 -3
  83. package/dist/server.js.map +1 -1
  84. package/dist/streamed-load.d.ts +0 -1
  85. package/dist/streamed-load.js.map +1 -1
  86. package/dist/testing.d.ts +0 -1
  87. package/dist/testing.js.map +1 -1
  88. package/dist/transport.d.ts +0 -1
  89. package/dist/universal.d.ts +3 -4
  90. package/dist/universal.js +3 -3
  91. package/dist/universal.js.map +1 -1
  92. package/dist/vite.d.ts +0 -1
  93. package/dist/vite.js +2 -2
  94. package/dist/vite.js.map +1 -1
  95. package/package.json +8 -5
package/README.md CHANGED
@@ -13,9 +13,9 @@ for the Svelte runes hooks.
13
13
  ## Installation
14
14
 
15
15
  ```bash
16
- npm install @thomasfosterau/effect-sveltekit effect@beta svelte @sveltejs/kit
16
+ npm install @thomasfosterau/effect-sveltekit effect@rc svelte @sveltejs/kit
17
17
  # the Effect deployment adapter additionally needs:
18
- npm install @effect/platform-node@beta
18
+ npm install @effect/platform-node@rc
19
19
  ```
20
20
 
21
21
  ## Entry points
@@ -75,7 +75,7 @@ export const load = (event) => Effect.succeed({ id: event.params.id });
75
75
  namespaces.
76
76
  - **Effect deployment adapter** — the generated app is a platform-neutral
77
77
  Effect `HttpApp` (`makeHandlerWith`): serve it as a production Node HTTP server
78
- (`effect/unstable/http` + `@effect/platform-node`, the default) or as a Web
78
+ (`effect/http` + `@effect/platform-node`, the default) or as a Web
79
79
  `fetch` handler on Cloudflare Workers (`effectAdapter({ target: "fetch" })` /
80
80
  `toWebHandler`). Asset serving is a pluggable `AssetSource`
81
81
  (`AssetSource.fileSystem` for Node, `AssetSource.cloudflareAssets(env.ASSETS)`
package/dist/Hooks.d.ts CHANGED
@@ -1,11 +1,10 @@
1
1
  import { MarkerTransporterOptions, TransportEntry, markerTransporter, transport, transporter } from "./transport.js";
2
+ import { responseHeadersTransporter } from "./response-headers.js";
2
3
  import { Effect } from "effect";
3
- import * as HttpClient from "effect/unstable/http/HttpClient";
4
+ import * as HttpClient from "effect/http/HttpClient";
4
5
  import { Reroute } from "@sveltejs/kit";
5
-
6
- //#region src/Hooks.d.ts
7
6
  declare namespace Hooks_d_exports {
8
- export { MarkerTransporterOptions, TransportEntry, markerTransporter, reroute, transport, transporter };
7
+ export { MarkerTransporterOptions, TransportEntry, markerTransporter, reroute, responseHeadersTransporter, transport, transporter };
9
8
  }
10
9
  /**
11
10
  * Wraps an Effect-based function as the SvelteKit universal
@@ -29,5 +28,5 @@ declare function reroute(fn: (event: {
29
28
  fetch: typeof globalThis.fetch;
30
29
  }) => Effect.Effect<string | void, unknown, HttpClient.HttpClient>): Reroute;
31
30
  //#endregion
32
- export { Hooks_d_exports };
31
+ export { Hooks_d_exports, type MarkerTransporterOptions, type TransportEntry, markerTransporter, reroute, responseHeadersTransporter, transport, transporter };
33
32
  //# sourceMappingURL=Hooks.d.ts.map
package/dist/Hooks.js CHANGED
@@ -1,11 +1,13 @@
1
1
  import { __exportAll } from "./_virtual/_rolldown/runtime.js";
2
2
  import { defaultUniversalRuntime } from "./internal/default-runtime.js";
3
3
  import { markerTransporter, transport, transporter } from "./transport.js";
4
+ import { responseHeadersTransporter } from "./response-headers.js";
4
5
  import "effect";
5
6
  //#region src/Hooks.ts
6
7
  var Hooks_exports = /* @__PURE__ */ __exportAll({
7
8
  markerTransporter: () => markerTransporter,
8
9
  reroute: () => reroute,
10
+ responseHeadersTransporter: () => responseHeadersTransporter,
9
11
  transport: () => transport,
10
12
  transporter: () => transporter
11
13
  });
@@ -30,6 +32,6 @@ function reroute(fn) {
30
32
  return (event) => defaultUniversalRuntime().runPromise(event.fetch, fn(event));
31
33
  }
32
34
  //#endregion
33
- export { Hooks_exports };
35
+ export { Hooks_exports, markerTransporter, reroute, responseHeadersTransporter, transport, transporter };
34
36
 
35
37
  //# sourceMappingURL=Hooks.js.map
package/dist/Hooks.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"Hooks.js","names":[],"sources":["../src/Hooks.ts"],"sourcesContent":["/**\n * Effect helpers for SvelteKit's universal hooks (`src/hooks.ts`), exposed as\n * the `Hooks` namespace of `@thomasfosterau/effect-sveltekit`.\n *\n * The `reroute` hook is expressed as an Effect (running on the universal\n * runtime, with an `HttpClient` backed by the event's `fetch`), and the\n * universal `transport` hook is built from Effect schemas via {@link transport}\n * / {@link transporter}.\n *\n * @example\n * ```ts\n * // src/hooks.ts\n * import { Hooks } from '@thomasfosterau/effect-sveltekit';\n * import { Effect, Schema } from 'effect';\n *\n * export const reroute = Hooks.reroute((event) =>\n * Effect.succeed(event.url.pathname === '/old' ? '/new' : undefined),\n * );\n *\n * export const transport = Hooks.transport({\n * Option: Schema.Option(Schema.Number),\n * Date: Schema.Date,\n * });\n * ```\n */\n\nimport type { Reroute } from \"@sveltejs/kit\";\nimport { Effect } from \"effect\";\nimport type * as HttpClient from \"effect/unstable/http/HttpClient\";\nimport { defaultUniversalRuntime } from \"./internal/default-runtime.js\";\n\n/**\n * Wraps an Effect-based function as the SvelteKit universal\n * [`reroute`](https://svelte.dev/docs/kit/hooks#Universal-hooks-reroute) hook,\n * which rewrites the URL before routing. The effect runs on both the server and\n * the client and gets an `HttpClient` backed by the event's `fetch`.\n *\n * @example\n * ```ts\n * // src/hooks.ts\n * import { Hooks } from '@thomasfosterau/effect-sveltekit';\n * import { Effect } from 'effect';\n *\n * export const reroute = Hooks.reroute((event) =>\n * Effect.succeed(event.url.pathname === '/old' ? '/new' : undefined),\n * );\n * ```\n */\nexport function reroute(\n fn: (event: {\n url: URL;\n fetch: typeof globalThis.fetch;\n }) => Effect.Effect<string | void, unknown, HttpClient.HttpClient>,\n): Reroute {\n return (event) => defaultUniversalRuntime().runPromise(event.fetch, fn(event));\n}\n\n/**\n * The universal `transport` hook built from Effect schemas: `transport`\n * assembles a whole `transport` object from a record of entries, `transporter`\n * builds a single round-tripping entry from a `Schema.Codec`, and\n * `markerTransporter` builds a deliberately-lossy entry for a non-POJO wrapper\n * whose contents should not round-trip. See {@link transport} for details.\n */\nexport {\n transport,\n transporter,\n markerTransporter,\n type MarkerTransporterOptions,\n type TransportEntry,\n} from \"./transport.js\";\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgDA,SAAgB,QACd,IAIS;CACT,QAAQ,UAAU,wBAAwB,EAAE,WAAW,MAAM,OAAO,GAAG,KAAK,CAAC;AAC/E"}
1
+ {"version":3,"file":"Hooks.js","names":[],"sources":["../src/Hooks.ts"],"sourcesContent":["/**\n * Effect helpers for SvelteKit's universal hooks (`src/hooks.ts`), exposed as\n * the `Hooks` namespace of `@thomasfosterau/effect-sveltekit`.\n *\n * The `reroute` hook is expressed as an Effect (running on the universal\n * runtime, with an `HttpClient` backed by the event's `fetch`), and the\n * universal `transport` hook is built from Effect schemas via {@link transport}\n * / {@link transporter}.\n *\n * @example\n * ```ts\n * // src/hooks.ts\n * import { Hooks } from '@thomasfosterau/effect-sveltekit';\n * import { Effect, Schema } from 'effect';\n *\n * export const reroute = Hooks.reroute((event) =>\n * Effect.succeed(event.url.pathname === '/old' ? '/new' : undefined),\n * );\n *\n * export const transport = Hooks.transport({\n * Option: Schema.Option(Schema.Number),\n * Date: Schema.Date,\n * });\n * ```\n */\n\nimport type { Reroute } from \"@sveltejs/kit\";\nimport { Effect } from \"effect\";\nimport type * as HttpClient from \"effect/http/HttpClient\";\nimport { defaultUniversalRuntime } from \"./internal/default-runtime.js\";\n\n/**\n * Wraps an Effect-based function as the SvelteKit universal\n * [`reroute`](https://svelte.dev/docs/kit/hooks#Universal-hooks-reroute) hook,\n * which rewrites the URL before routing. The effect runs on both the server and\n * the client and gets an `HttpClient` backed by the event's `fetch`.\n *\n * @example\n * ```ts\n * // src/hooks.ts\n * import { Hooks } from '@thomasfosterau/effect-sveltekit';\n * import { Effect } from 'effect';\n *\n * export const reroute = Hooks.reroute((event) =>\n * Effect.succeed(event.url.pathname === '/old' ? '/new' : undefined),\n * );\n * ```\n */\nexport function reroute(\n fn: (event: {\n url: URL;\n fetch: typeof globalThis.fetch;\n }) => Effect.Effect<string | void, unknown, HttpClient.HttpClient>,\n): Reroute {\n return (event) => defaultUniversalRuntime().runPromise(event.fetch, fn(event));\n}\n\n/**\n * The universal `transport` hook built from Effect schemas: `transport`\n * assembles a whole `transport` object from a record of entries, `transporter`\n * builds a single round-tripping entry from a `Schema.Codec`, and\n * `markerTransporter` builds a deliberately-lossy entry for a non-POJO wrapper\n * whose contents should not round-trip. See {@link transport} for details.\n */\nexport {\n transport,\n transporter,\n markerTransporter,\n type MarkerTransporterOptions,\n type TransportEntry,\n} from \"./transport.js\";\n\n/**\n * The `transport` entry for the {@link ResponseHeaders} response-headers buffer\n * (`Hooks.transport({ ResponseHeaders: Hooks.responseHeadersTransporter })`).\n */\nexport { responseHeadersTransporter } from \"./response-headers.js\";\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgDA,SAAgB,QACd,IAIS;CACT,QAAQ,UAAU,wBAAwB,CAAC,CAAC,WAAW,MAAM,OAAO,GAAG,KAAK,CAAC;AAC/E"}
@@ -1,8 +1,6 @@
1
1
  import { Effect, Stream } from "effect";
2
2
  import { AfterNavigate, BeforeNavigate, OnNavigate } from "@sveltejs/kit";
3
3
  import { goto, invalidate, preloadData, refreshAll } from "$app/navigation";
4
-
5
- //#region src/Navigation.d.ts
6
4
  declare namespace Navigation_d_exports {
7
5
  export { afterNavigate$1 as afterNavigate, beforeNavigate$1 as beforeNavigate, goto$1 as goto, invalidate$1 as invalidate, invalidateAll$1 as invalidateAll, onNavigate$1 as onNavigate, preloadCode$1 as preloadCode, preloadData$1 as preloadData, refreshAll$1 as refreshAll };
8
6
  }
@@ -106,5 +104,5 @@ declare function afterNavigate$1(): Stream.Stream<AfterNavigate>;
106
104
  */
107
105
  declare function onNavigate$1(fn: (navigation: OnNavigate) => Effect.Effect<(() => void) | void>, runEffect?: <X>(effect: Effect.Effect<X>) => Promise<X>): void;
108
106
  //#endregion
109
- export { Navigation_d_exports };
107
+ export { Navigation_d_exports, afterNavigate$1 as afterNavigate, beforeNavigate$1 as beforeNavigate, goto$1 as goto, invalidate$1 as invalidate, invalidateAll$1 as invalidateAll, onNavigate$1 as onNavigate, preloadCode$1 as preloadCode, preloadData$1 as preloadData, refreshAll$1 as refreshAll };
110
108
  //# sourceMappingURL=Navigation.d.ts.map
@@ -150,6 +150,6 @@ function onNavigate$1(fn, runEffect = Effect.runPromise) {
150
150
  onNavigateWith(onNavigate, fn, runEffect);
151
151
  }
152
152
  //#endregion
153
- export { Navigation_exports };
153
+ export { Navigation_exports, afterNavigate$1 as afterNavigate, beforeNavigate$1 as beforeNavigate, goto$1 as goto, invalidate$1 as invalidate, invalidateAll$1 as invalidateAll, onNavigate$1 as onNavigate, preloadCode$1 as preloadCode, preloadData$1 as preloadData, refreshAll$1 as refreshAll };
154
154
 
155
155
  //# sourceMappingURL=Navigation.js.map
package/dist/Remote.d.ts CHANGED
@@ -1,7 +1,5 @@
1
1
  import { Effect, Stream } from "effect";
2
2
  import { RemoteCommand, RemoteLiveQuery, RemotePrerenderFunction, RemoteQuery, RemoteQueryFunction, RemoteQueryOverride } from "@sveltejs/kit";
3
-
4
- //#region src/Remote.d.ts
5
3
  declare namespace Remote_d_exports {
6
4
  export { RemoteSubmit, callCommand, callCommandWithUpdates, callPrerender, callQuery, liveQueryStream, submitForm, submitFormWithUpdates };
7
5
  }
@@ -48,5 +46,5 @@ declare function submitFormWithUpdates(submit: RemoteSubmit, ...queries: Array<R
48
46
  */
49
47
  declare function liveQueryStream<Output>(query: RemoteLiveQuery<Output>): Stream.Stream<Output, unknown>;
50
48
  //#endregion
51
- export { Remote_d_exports };
49
+ export { RemoteSubmit, Remote_d_exports, callCommand, callCommandWithUpdates, callPrerender, callQuery, liveQueryStream, submitForm, submitFormWithUpdates };
52
50
  //# sourceMappingURL=Remote.d.ts.map
package/dist/Remote.js CHANGED
@@ -62,6 +62,6 @@ function liveQueryStream(query) {
62
62
  return Stream.fromAsyncIterable(query, (error) => error);
63
63
  }
64
64
  //#endregion
65
- export { Remote_exports };
65
+ export { Remote_exports, callCommand, callCommandWithUpdates, callPrerender, callQuery, liveQueryStream, submitForm, submitFormWithUpdates };
66
66
 
67
67
  //# sourceMappingURL=Remote.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Remote.js","names":[],"sources":["../src/Remote.ts"],"sourcesContent":["import type {\n RemoteCommand,\n RemoteLiveQuery,\n RemotePrerenderFunction,\n RemoteQuery,\n RemoteQueryFunction,\n RemoteQueryOverride,\n} from \"@sveltejs/kit\";\nimport { Effect, Stream } from \"effect\";\n\nfunction fromRemotePromise<A>(thunk: () => PromiseLike<A>): Effect.Effect<A, unknown, never> {\n return Effect.promise(() => Promise.resolve(thunk()));\n}\n\nexport function callQuery<Output>(\n query: RemoteQueryFunction<void, Output>,\n): Effect.Effect<Output, unknown, never>;\nexport function callQuery<Input, Output>(\n query: RemoteQueryFunction<Input, Output>,\n input: Input,\n): Effect.Effect<Output, unknown, never>;\nexport function callQuery<Input, Output>(\n query: RemoteQueryFunction<Input, Output>,\n input?: Input,\n): Effect.Effect<Output, unknown, never> {\n if (arguments.length === 1) {\n return fromRemotePromise(() =>\n (query as unknown as RemoteQueryFunction<void, Output>)(undefined),\n );\n }\n\n return fromRemotePromise(() => query(input as Input));\n}\n\nexport function callCommand<Output>(\n command: RemoteCommand<void, Output>,\n): Effect.Effect<Output, unknown, never>;\nexport function callCommand<Input, Output>(\n command: RemoteCommand<Input, Output>,\n input: Input,\n): Effect.Effect<Output, unknown, never>;\nexport function callCommand<Input, Output>(\n command: RemoteCommand<Input, Output>,\n input?: Input,\n): Effect.Effect<Output, unknown, never> {\n if (arguments.length === 1) {\n return fromRemotePromise(() => (command as unknown as RemoteCommand<void, Output>)(undefined));\n }\n\n return fromRemotePromise(() => command(input as Input));\n}\n\n/**\n * Calls a remote command and refreshes the given queries in the same round\n * trip (SvelteKit's single-flight mutations).\n *\n * Newer SvelteKit versions cache remote query instances, so a command that\n * changes data those queries depend on must list them here (or call\n * `query.refresh()` afterwards) for their cached values to update.\n */\nexport function callCommandWithUpdates<Input, Output>(\n command: RemoteCommand<Input, Output>,\n input: Input,\n ...queries: Array<RemoteQuery<any> | RemoteQueryOverride>\n): Effect.Effect<Output, unknown, never> {\n return fromRemotePromise(() => command(input).updates(...queries));\n}\n\nexport function callPrerender<Output>(\n prerender: RemotePrerenderFunction<void, Output>,\n): Effect.Effect<Output, unknown, never>;\nexport function callPrerender<Input, Output>(\n prerender: RemotePrerenderFunction<Input, Output>,\n input: Input,\n): Effect.Effect<Output, unknown, never>;\nexport function callPrerender<Input, Output>(\n prerender: RemotePrerenderFunction<Input, Output>,\n input?: Input,\n): Effect.Effect<Output, unknown, never> {\n if (arguments.length === 1) {\n return fromRemotePromise(() =>\n (prerender as unknown as RemotePrerenderFunction<void, Output>)(undefined),\n );\n }\n\n return fromRemotePromise(() => prerender(input as Input));\n}\n\n/**\n * The shape of an enhanced remote form `submit` function. The promise result\n * is left open (SvelteKit returns `Promise<void>` in older versions and\n * `Promise<boolean>` in newer ones).\n */\nexport type RemoteSubmit = () => PromiseLike<unknown> & {\n updates: (...queries: Array<RemoteQuery<any> | RemoteQueryOverride>) => PromiseLike<unknown>;\n};\n\nexport function submitForm(\n submit: () => PromiseLike<unknown>,\n): Effect.Effect<void, unknown, never> {\n return Effect.asVoid(fromRemotePromise(() => submit()));\n}\n\nexport function submitFormWithUpdates(\n submit: RemoteSubmit,\n ...queries: Array<RemoteQuery<any> | RemoteQueryOverride>\n): Effect.Effect<void, unknown, never> {\n return Effect.asVoid(fromRemotePromise(() => submit().updates(...queries)));\n}\n\n/**\n * Consumes a SvelteKit live query (`query.live(...)`) as an Effect `Stream`.\n *\n * A `RemoteLiveQuery<T>` is an `AsyncIterable<T>` that yields every update\n * pushed from the server; this turns it into a `Stream` so live data can drive\n * Effect pipelines (and, via `useStream`, Svelte runes).\n *\n * @example\n * ```ts\n * import { Remote } from '@thomasfosterau/effect-sveltekit';\n * import { messages } from './chat.remote';\n * import { useStream } from '@thomasfosterau/effect-svelte';\n *\n * const feed = useStream(Remote.liveQueryStream(messages()));\n * ```\n */\nexport function liveQueryStream<Output>(\n query: RemoteLiveQuery<Output>,\n): Stream.Stream<Output, unknown> {\n return Stream.fromAsyncIterable(query, (error) => error);\n}\n"],"mappings":";;;;;;;;;;;;AAUA,SAAS,kBAAqB,OAA+D;CAC3F,OAAO,OAAO,cAAc,QAAQ,QAAQ,MAAM,CAAC,CAAC;AACtD;AASA,SAAgB,UACd,OACA,OACuC;CACvC,IAAI,UAAU,WAAW,GACvB,OAAO,wBACJ,MAAuD,KAAA,CAAS,CACnE;CAGF,OAAO,wBAAwB,MAAM,KAAc,CAAC;AACtD;AASA,SAAgB,YACd,SACA,OACuC;CACvC,IAAI,UAAU,WAAW,GACvB,OAAO,wBAAyB,QAAmD,KAAA,CAAS,CAAC;CAG/F,OAAO,wBAAwB,QAAQ,KAAc,CAAC;AACxD;;;;;;;;;AAUA,SAAgB,uBACd,SACA,OACA,GAAG,SACoC;CACvC,OAAO,wBAAwB,QAAQ,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC;AACnE;AASA,SAAgB,cACd,WACA,OACuC;CACvC,IAAI,UAAU,WAAW,GACvB,OAAO,wBACJ,UAA+D,KAAA,CAAS,CAC3E;CAGF,OAAO,wBAAwB,UAAU,KAAc,CAAC;AAC1D;AAWA,SAAgB,WACd,QACqC;CACrC,OAAO,OAAO,OAAO,wBAAwB,OAAO,CAAC,CAAC;AACxD;AAEA,SAAgB,sBACd,QACA,GAAG,SACkC;CACrC,OAAO,OAAO,OAAO,wBAAwB,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,CAAC;AAC5E;;;;;;;;;;;;;;;;;AAkBA,SAAgB,gBACd,OACgC;CAChC,OAAO,OAAO,kBAAkB,QAAQ,UAAU,KAAK;AACzD"}
1
+ {"version":3,"file":"Remote.js","names":[],"sources":["../src/Remote.ts"],"sourcesContent":["import type {\n RemoteCommand,\n RemoteLiveQuery,\n RemotePrerenderFunction,\n RemoteQuery,\n RemoteQueryFunction,\n RemoteQueryOverride,\n} from \"@sveltejs/kit\";\nimport { Effect, Stream } from \"effect\";\n\nfunction fromRemotePromise<A>(thunk: () => PromiseLike<A>): Effect.Effect<A, unknown, never> {\n return Effect.promise(() => Promise.resolve(thunk()));\n}\n\nexport function callQuery<Output>(\n query: RemoteQueryFunction<void, Output>,\n): Effect.Effect<Output, unknown, never>;\nexport function callQuery<Input, Output>(\n query: RemoteQueryFunction<Input, Output>,\n input: Input,\n): Effect.Effect<Output, unknown, never>;\nexport function callQuery<Input, Output>(\n query: RemoteQueryFunction<Input, Output>,\n input?: Input,\n): Effect.Effect<Output, unknown, never> {\n if (arguments.length === 1) {\n return fromRemotePromise(() =>\n (query as unknown as RemoteQueryFunction<void, Output>)(undefined),\n );\n }\n\n return fromRemotePromise(() => query(input as Input));\n}\n\nexport function callCommand<Output>(\n command: RemoteCommand<void, Output>,\n): Effect.Effect<Output, unknown, never>;\nexport function callCommand<Input, Output>(\n command: RemoteCommand<Input, Output>,\n input: Input,\n): Effect.Effect<Output, unknown, never>;\nexport function callCommand<Input, Output>(\n command: RemoteCommand<Input, Output>,\n input?: Input,\n): Effect.Effect<Output, unknown, never> {\n if (arguments.length === 1) {\n return fromRemotePromise(() => (command as unknown as RemoteCommand<void, Output>)(undefined));\n }\n\n return fromRemotePromise(() => command(input as Input));\n}\n\n/**\n * Calls a remote command and refreshes the given queries in the same round\n * trip (SvelteKit's single-flight mutations).\n *\n * Newer SvelteKit versions cache remote query instances, so a command that\n * changes data those queries depend on must list them here (or call\n * `query.refresh()` afterwards) for their cached values to update.\n */\nexport function callCommandWithUpdates<Input, Output>(\n command: RemoteCommand<Input, Output>,\n input: Input,\n ...queries: Array<RemoteQuery<any> | RemoteQueryOverride>\n): Effect.Effect<Output, unknown, never> {\n return fromRemotePromise(() => command(input).updates(...queries));\n}\n\nexport function callPrerender<Output>(\n prerender: RemotePrerenderFunction<void, Output>,\n): Effect.Effect<Output, unknown, never>;\nexport function callPrerender<Input, Output>(\n prerender: RemotePrerenderFunction<Input, Output>,\n input: Input,\n): Effect.Effect<Output, unknown, never>;\nexport function callPrerender<Input, Output>(\n prerender: RemotePrerenderFunction<Input, Output>,\n input?: Input,\n): Effect.Effect<Output, unknown, never> {\n if (arguments.length === 1) {\n return fromRemotePromise(() =>\n (prerender as unknown as RemotePrerenderFunction<void, Output>)(undefined),\n );\n }\n\n return fromRemotePromise(() => prerender(input as Input));\n}\n\n/**\n * The shape of an enhanced remote form `submit` function. The promise result\n * is left open (SvelteKit returns `Promise<void>` in older versions and\n * `Promise<boolean>` in newer ones).\n */\nexport type RemoteSubmit = () => PromiseLike<unknown> & {\n updates: (...queries: Array<RemoteQuery<any> | RemoteQueryOverride>) => PromiseLike<unknown>;\n};\n\nexport function submitForm(\n submit: () => PromiseLike<unknown>,\n): Effect.Effect<void, unknown, never> {\n return Effect.asVoid(fromRemotePromise(() => submit()));\n}\n\nexport function submitFormWithUpdates(\n submit: RemoteSubmit,\n ...queries: Array<RemoteQuery<any> | RemoteQueryOverride>\n): Effect.Effect<void, unknown, never> {\n return Effect.asVoid(fromRemotePromise(() => submit().updates(...queries)));\n}\n\n/**\n * Consumes a SvelteKit live query (`query.live(...)`) as an Effect `Stream`.\n *\n * A `RemoteLiveQuery<T>` is an `AsyncIterable<T>` that yields every update\n * pushed from the server; this turns it into a `Stream` so live data can drive\n * Effect pipelines (and, via `useStream`, Svelte runes).\n *\n * @example\n * ```ts\n * import { Remote } from '@thomasfosterau/effect-sveltekit';\n * import { messages } from './chat.remote';\n * import { useStream } from '@thomasfosterau/effect-svelte';\n *\n * const feed = useStream(Remote.liveQueryStream(messages()));\n * ```\n */\nexport function liveQueryStream<Output>(\n query: RemoteLiveQuery<Output>,\n): Stream.Stream<Output, unknown> {\n return Stream.fromAsyncIterable(query, (error) => error);\n}\n"],"mappings":";;;;;;;;;;;;AAUA,SAAS,kBAAqB,OAA+D;CAC3F,OAAO,OAAO,cAAc,QAAQ,QAAQ,MAAM,CAAC,CAAC;AACtD;AASA,SAAgB,UACd,OACA,OACuC;CACvC,IAAI,UAAU,WAAW,GACvB,OAAO,wBACJ,MAAuD,KAAA,CAAS,CACnE;CAGF,OAAO,wBAAwB,MAAM,KAAc,CAAC;AACtD;AASA,SAAgB,YACd,SACA,OACuC;CACvC,IAAI,UAAU,WAAW,GACvB,OAAO,wBAAyB,QAAmD,KAAA,CAAS,CAAC;CAG/F,OAAO,wBAAwB,QAAQ,KAAc,CAAC;AACxD;;;;;;;;;AAUA,SAAgB,uBACd,SACA,OACA,GAAG,SACoC;CACvC,OAAO,wBAAwB,QAAQ,KAAK,CAAC,CAAC,QAAQ,GAAG,OAAO,CAAC;AACnE;AASA,SAAgB,cACd,WACA,OACuC;CACvC,IAAI,UAAU,WAAW,GACvB,OAAO,wBACJ,UAA+D,KAAA,CAAS,CAC3E;CAGF,OAAO,wBAAwB,UAAU,KAAc,CAAC;AAC1D;AAWA,SAAgB,WACd,QACqC;CACrC,OAAO,OAAO,OAAO,wBAAwB,OAAO,CAAC,CAAC;AACxD;AAEA,SAAgB,sBACd,QACA,GAAG,SACkC;CACrC,OAAO,OAAO,OAAO,wBAAwB,OAAO,CAAC,CAAC,QAAQ,GAAG,OAAO,CAAC,CAAC;AAC5E;;;;;;;;;;;;;;;;;AAkBA,SAAgB,gBACd,OACgC;CAChC,OAAO,OAAO,kBAAkB,QAAQ,UAAU,KAAK;AACzD"}
package/dist/State.d.ts CHANGED
@@ -1,8 +1,6 @@
1
1
  import { PageSnapshot } from "./internal/app-state.js";
2
2
  import { Stream } from "effect";
3
3
  import { Page } from "@sveltejs/kit";
4
-
5
- //#region src/State.d.ts
6
4
  declare namespace State_d_exports {
7
5
  export { PageSnapshot, page };
8
6
  }
@@ -13,5 +11,5 @@ declare namespace State_d_exports {
13
11
  */
14
12
  declare function page(): Stream.Stream<PageSnapshot<Page>>;
15
13
  //#endregion
16
- export { State_d_exports };
14
+ export { type PageSnapshot, State_d_exports, page };
17
15
  //# sourceMappingURL=State.d.ts.map
package/dist/State.js CHANGED
@@ -60,6 +60,6 @@ function page$1() {
60
60
  }, () => page);
61
61
  }
62
62
  //#endregion
63
- export { State_exports };
63
+ export { State_exports, page$1 as page };
64
64
 
65
65
  //# sourceMappingURL=State.js.map
@@ -1,9 +1,8 @@
1
1
  import { Effect, Option } from "effect";
2
2
  import * as FileSystem from "effect/FileSystem";
3
3
  import * as Path from "effect/Path";
4
- import * as HttpPlatform from "effect/unstable/http/HttpPlatform";
5
- import * as HttpServerResponse from "effect/unstable/http/HttpServerResponse";
6
-
4
+ import * as HttpPlatform from "effect/http/HttpPlatform";
5
+ import * as HttpServerResponse from "effect/http/HttpServerResponse";
7
6
  //#region src/adapter/assets.d.ts
8
7
  /**
9
8
  * A source of static assets. `serveAsset` returns the response for an asset
@@ -20,8 +19,11 @@ type FileSystemAssetServices = FileSystem.FileSystem | Path.Path | HttpPlatform.
20
19
  /** The {@link AssetSource} constructors, grouped for the adapter API. */
21
20
  declare const AssetSource: {
22
21
  fileSystem: (config: {
23
- /** Absolute path of the build output directory (contains `client/`, `prerendered/`). */readonly dir: string; /** The configured `manifest.appPath` — its `immutable/` subtree gets immutable caching. */
24
- readonly appPath: string; /** The set of prerendered paths exported by the build output. */
22
+ /** Absolute path of the build output directory (contains `client/`, `prerendered/`). */
23
+ readonly dir: string;
24
+ /** The configured `manifest.appPath` — its `immutable/` subtree gets immutable caching. */
25
+ readonly appPath: string;
26
+ /** The set of prerendered paths exported by the build output. */
25
27
  readonly prerendered: ReadonlySet<string>;
26
28
  }) => AssetSource<FileSystemAssetServices>;
27
29
  cloudflareAssets: (assets: {
@@ -1,8 +1,8 @@
1
1
  import { Effect, Option } from "effect";
2
2
  import * as FileSystem from "effect/FileSystem";
3
3
  import * as Path from "effect/Path";
4
- import "effect/unstable/http/HttpPlatform";
5
- import * as HttpServerResponse from "effect/unstable/http/HttpServerResponse";
4
+ import "effect/http/HttpPlatform";
5
+ import * as HttpServerResponse from "effect/http/HttpServerResponse";
6
6
  //#region src/adapter/assets.ts
7
7
  /**
8
8
  * Pluggable asset serving for the Effect SvelteKit adapter.
@@ -82,6 +82,6 @@ const AssetSource = {
82
82
  cloudflareAssets
83
83
  };
84
84
  //#endregion
85
- export { AssetSource };
85
+ export { AssetSource, cloudflareAssets, fileSystem };
86
86
 
87
87
  //# sourceMappingURL=assets.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"assets.js","names":[],"sources":["../../src/adapter/assets.ts"],"sourcesContent":["/**\n * Pluggable asset serving for the Effect SvelteKit adapter.\n *\n * The SSR core ({@link makeHandler}) is platform-neutral: it falls through to an\n * injected {@link AssetSource} for static client assets and prerendered pages,\n * rather than reading the file system directly. This lets the same SvelteKit\n * `HttpApp` run on a Node server (assets from disk) or on Cloudflare Workers\n * (assets from the `env.ASSETS` binding, or any custom source — R2, KV, a CDN\n * passthrough).\n *\n * Ship several sources as equals and let the adapter (or the caller) pick:\n *\n * - {@link fileSystem} — serve `client/` + `prerendered/` from disk (Node\n * default). Requires `FileSystem` / `Path` / `HttpPlatform`.\n * - {@link cloudflareAssets} — serve from a Workers static-assets binding\n * (`env.ASSETS`). Requires nothing.\n */\n\nimport { Effect, Option } from \"effect\";\nimport * as FileSystem from \"effect/FileSystem\";\nimport * as Path from \"effect/Path\";\nimport * as HttpPlatform from \"effect/unstable/http/HttpPlatform\";\nimport * as HttpServerResponse from \"effect/unstable/http/HttpServerResponse\";\n\n/**\n * A source of static assets. `serveAsset` returns the response for an asset\n * request, or `Option.none()` when the request is not an asset (so the SSR core\n * continues to server-side rendering). `R` is the set of services the source\n * needs (e.g. `FileSystem | Path | HttpPlatform` for {@link fileSystem}, or\n * `never` for {@link cloudflareAssets}).\n */\nexport interface AssetSource<R = never> {\n readonly serveAsset: (\n request: Request,\n pathname: string,\n ) => Effect.Effect<Option.Option<HttpServerResponse.HttpServerResponse>, never, R>;\n}\n\n/** The services a file-system {@link AssetSource} requires. */\nexport type FileSystemAssetServices = FileSystem.FileSystem | Path.Path | HttpPlatform.HttpPlatform;\n\nconst IMMUTABLE_HEADERS = { \"cache-control\": \"public, max-age=31536000, immutable\" };\n\n/**\n * Serve static client assets and prerendered pages from a build directory on\n * disk (the Node default). `dir` contains `client/` and `prerendered/`.\n */\nexport const fileSystem = (config: {\n /** Absolute path of the build output directory (contains `client/`, `prerendered/`). */\n readonly dir: string;\n /** The configured `manifest.appPath` — its `immutable/` subtree gets immutable caching. */\n readonly appPath: string;\n /** The set of prerendered paths exported by the build output. */\n readonly prerendered: ReadonlySet<string>;\n}): AssetSource<FileSystemAssetServices> => ({\n serveAsset: (request, pathname) =>\n Effect.gen(function* () {\n // Only GET/HEAD reach static assets.\n if (request.method !== \"GET\" && request.method !== \"HEAD\") return Option.none();\n\n const path = yield* Path.Path;\n const fs = yield* FileSystem.FileSystem;\n\n const clientDir = path.join(config.dir, \"client\");\n const prerenderedDir = path.join(config.dir, \"prerendered\");\n const immutablePrefix = `/${config.appPath}/immutable/`;\n\n /**\n * Serve a file from `root` if `pathname` resolves to an existing file\n * inside it (rejecting path traversal). `Option.none()` otherwise.\n */\n const serveFile = (\n root: string,\n candidate: string,\n headers?: Record<string, string>,\n ): Effect.Effect<\n Option.Option<HttpServerResponse.HttpServerResponse>,\n never,\n FileSystemAssetServices\n > =>\n Effect.gen(function* () {\n const filePath = path.join(root, candidate);\n const relative = path.relative(root, filePath);\n if (relative.startsWith(\"..\") || path.isAbsolute(relative)) return Option.none();\n\n const stat = yield* fs.stat(filePath).pipe(Effect.option);\n if (Option.isNone(stat) || stat.value.type !== \"File\") return Option.none();\n\n const response = yield* HttpServerResponse.file(filePath, { headers }).pipe(Effect.orDie);\n return Option.some(response);\n });\n\n // 1. Static client assets (hashed build assets get immutable caching).\n const isImmutable = pathname.startsWith(immutablePrefix);\n const asset = yield* serveFile(\n clientDir,\n pathname,\n isImmutable ? IMMUTABLE_HEADERS : undefined,\n );\n if (Option.isSome(asset)) return asset;\n\n // 2. Prerendered pages.\n if (config.prerendered.has(pathname) || config.prerendered.has(pathname + \"/\")) {\n const candidates =\n pathname === \"/\"\n ? [\"/index.html\"]\n : pathname.endsWith(\"/\")\n ? [`${pathname}index.html`, `${pathname.slice(0, -1)}.html`]\n : [pathname, `${pathname}.html`, `${pathname}/index.html`];\n for (const candidate of candidates) {\n const page = yield* serveFile(prerenderedDir, candidate);\n if (Option.isSome(page)) return page;\n }\n }\n\n return Option.none();\n }),\n});\n\n/**\n * Serve static assets from a Cloudflare Workers static-assets binding (commonly\n * `env.ASSETS`). The binding's `fetch` resolves client assets and prerendered\n * pages uploaded by the deployment; a 404 from it means \"not an asset\", so the\n * SSR core continues to server-side rendering.\n *\n * This is one provided convenience, not the assumption: pass any object with a\n * `fetch` (R2, KV, a CDN passthrough) or a custom {@link AssetSource}.\n */\nexport const cloudflareAssets = (assets: {\n fetch: (request: Request) => Promise<Response> | Response;\n}): AssetSource => ({\n serveAsset: (request) =>\n Effect.gen(function* () {\n if (request.method !== \"GET\" && request.method !== \"HEAD\") return Option.none();\n const response = yield* Effect.promise(async () => assets.fetch(request));\n if (response.status === 404) return Option.none();\n return Option.some(HttpServerResponse.fromWeb(response));\n }),\n});\n\n/** The {@link AssetSource} constructors, grouped for the adapter API. */\nexport const AssetSource = {\n fileSystem,\n cloudflareAssets,\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAyCA,MAAM,oBAAoB,EAAE,iBAAiB,sCAAsC;;;;;AAMnF,MAAa,cAAc,YAOkB,EAC3C,aAAa,SAAS,aACpB,OAAO,IAAI,aAAa;CAEtB,IAAI,QAAQ,WAAW,SAAS,QAAQ,WAAW,QAAQ,OAAO,OAAO,KAAK;CAE9E,MAAM,OAAO,OAAO,KAAK;CACzB,MAAM,KAAK,OAAO,WAAW;CAE7B,MAAM,YAAY,KAAK,KAAK,OAAO,KAAK,QAAQ;CAChD,MAAM,iBAAiB,KAAK,KAAK,OAAO,KAAK,aAAa;CAC1D,MAAM,kBAAkB,IAAI,OAAO,QAAQ;;;;;CAM3C,MAAM,aACJ,MACA,WACA,YAMA,OAAO,IAAI,aAAa;EACtB,MAAM,WAAW,KAAK,KAAK,MAAM,SAAS;EAC1C,MAAM,WAAW,KAAK,SAAS,MAAM,QAAQ;EAC7C,IAAI,SAAS,WAAW,IAAI,KAAK,KAAK,WAAW,QAAQ,GAAG,OAAO,OAAO,KAAK;EAE/E,MAAM,OAAO,OAAO,GAAG,KAAK,QAAQ,EAAE,KAAK,OAAO,MAAM;EACxD,IAAI,OAAO,OAAO,IAAI,KAAK,KAAK,MAAM,SAAS,QAAQ,OAAO,OAAO,KAAK;EAE1E,MAAM,WAAW,OAAO,mBAAmB,KAAK,UAAU,EAAE,QAAQ,CAAC,EAAE,KAAK,OAAO,KAAK;EACxF,OAAO,OAAO,KAAK,QAAQ;CAC7B,CAAC;CAIH,MAAM,QAAQ,OAAO,UACnB,WACA,UAHkB,SAAS,WAAW,eAI5B,IAAI,oBAAoB,KAAA,CACpC;CACA,IAAI,OAAO,OAAO,KAAK,GAAG,OAAO;CAGjC,IAAI,OAAO,YAAY,IAAI,QAAQ,KAAK,OAAO,YAAY,IAAI,WAAW,GAAG,GAAG;EAC9E,MAAM,aACJ,aAAa,MACT,CAAC,aAAa,IACd,SAAS,SAAS,GAAG,IACnB,CAAC,GAAG,SAAS,aAAa,GAAG,SAAS,MAAM,GAAG,EAAE,EAAE,MAAM,IACzD;GAAC;GAAU,GAAG,SAAS;GAAQ,GAAG,SAAS;EAAY;EAC/D,KAAK,MAAM,aAAa,YAAY;GAClC,MAAM,OAAO,OAAO,UAAU,gBAAgB,SAAS;GACvD,IAAI,OAAO,OAAO,IAAI,GAAG,OAAO;EAClC;CACF;CAEA,OAAO,OAAO,KAAK;AACrB,CAAC,EACL;;;;;;;;;;AAWA,MAAa,oBAAoB,YAEb,EAClB,aAAa,YACX,OAAO,IAAI,aAAa;CACtB,IAAI,QAAQ,WAAW,SAAS,QAAQ,WAAW,QAAQ,OAAO,OAAO,KAAK;CAC9E,MAAM,WAAW,OAAO,OAAO,QAAQ,YAAY,OAAO,MAAM,OAAO,CAAC;CACxE,IAAI,SAAS,WAAW,KAAK,OAAO,OAAO,KAAK;CAChD,OAAO,OAAO,KAAK,mBAAmB,QAAQ,QAAQ,CAAC;AACzD,CAAC,EACL;;AAGA,MAAa,cAAc;CACzB;CACA;AACF"}
1
+ {"version":3,"file":"assets.js","names":[],"sources":["../../src/adapter/assets.ts"],"sourcesContent":["/**\n * Pluggable asset serving for the Effect SvelteKit adapter.\n *\n * The SSR core ({@link makeHandler}) is platform-neutral: it falls through to an\n * injected {@link AssetSource} for static client assets and prerendered pages,\n * rather than reading the file system directly. This lets the same SvelteKit\n * `HttpApp` run on a Node server (assets from disk) or on Cloudflare Workers\n * (assets from the `env.ASSETS` binding, or any custom source — R2, KV, a CDN\n * passthrough).\n *\n * Ship several sources as equals and let the adapter (or the caller) pick:\n *\n * - {@link fileSystem} — serve `client/` + `prerendered/` from disk (Node\n * default). Requires `FileSystem` / `Path` / `HttpPlatform`.\n * - {@link cloudflareAssets} — serve from a Workers static-assets binding\n * (`env.ASSETS`). Requires nothing.\n */\n\nimport { Effect, Option } from \"effect\";\nimport * as FileSystem from \"effect/FileSystem\";\nimport * as Path from \"effect/Path\";\nimport * as HttpPlatform from \"effect/http/HttpPlatform\";\nimport * as HttpServerResponse from \"effect/http/HttpServerResponse\";\n\n/**\n * A source of static assets. `serveAsset` returns the response for an asset\n * request, or `Option.none()` when the request is not an asset (so the SSR core\n * continues to server-side rendering). `R` is the set of services the source\n * needs (e.g. `FileSystem | Path | HttpPlatform` for {@link fileSystem}, or\n * `never` for {@link cloudflareAssets}).\n */\nexport interface AssetSource<R = never> {\n readonly serveAsset: (\n request: Request,\n pathname: string,\n ) => Effect.Effect<Option.Option<HttpServerResponse.HttpServerResponse>, never, R>;\n}\n\n/** The services a file-system {@link AssetSource} requires. */\nexport type FileSystemAssetServices = FileSystem.FileSystem | Path.Path | HttpPlatform.HttpPlatform;\n\nconst IMMUTABLE_HEADERS = { \"cache-control\": \"public, max-age=31536000, immutable\" };\n\n/**\n * Serve static client assets and prerendered pages from a build directory on\n * disk (the Node default). `dir` contains `client/` and `prerendered/`.\n */\nexport const fileSystem = (config: {\n /** Absolute path of the build output directory (contains `client/`, `prerendered/`). */\n readonly dir: string;\n /** The configured `manifest.appPath` — its `immutable/` subtree gets immutable caching. */\n readonly appPath: string;\n /** The set of prerendered paths exported by the build output. */\n readonly prerendered: ReadonlySet<string>;\n}): AssetSource<FileSystemAssetServices> => ({\n serveAsset: (request, pathname) =>\n Effect.gen(function* () {\n // Only GET/HEAD reach static assets.\n if (request.method !== \"GET\" && request.method !== \"HEAD\") return Option.none();\n\n const path = yield* Path.Path;\n const fs = yield* FileSystem.FileSystem;\n\n const clientDir = path.join(config.dir, \"client\");\n const prerenderedDir = path.join(config.dir, \"prerendered\");\n const immutablePrefix = `/${config.appPath}/immutable/`;\n\n /**\n * Serve a file from `root` if `pathname` resolves to an existing file\n * inside it (rejecting path traversal). `Option.none()` otherwise.\n */\n const serveFile = (\n root: string,\n candidate: string,\n headers?: Record<string, string>,\n ): Effect.Effect<\n Option.Option<HttpServerResponse.HttpServerResponse>,\n never,\n FileSystemAssetServices\n > =>\n Effect.gen(function* () {\n const filePath = path.join(root, candidate);\n const relative = path.relative(root, filePath);\n if (relative.startsWith(\"..\") || path.isAbsolute(relative)) return Option.none();\n\n const stat = yield* fs.stat(filePath).pipe(Effect.option);\n if (Option.isNone(stat) || stat.value.type !== \"File\") return Option.none();\n\n const response = yield* HttpServerResponse.file(filePath, { headers }).pipe(Effect.orDie);\n return Option.some(response);\n });\n\n // 1. Static client assets (hashed build assets get immutable caching).\n const isImmutable = pathname.startsWith(immutablePrefix);\n const asset = yield* serveFile(\n clientDir,\n pathname,\n isImmutable ? IMMUTABLE_HEADERS : undefined,\n );\n if (Option.isSome(asset)) return asset;\n\n // 2. Prerendered pages.\n if (config.prerendered.has(pathname) || config.prerendered.has(pathname + \"/\")) {\n const candidates =\n pathname === \"/\"\n ? [\"/index.html\"]\n : pathname.endsWith(\"/\")\n ? [`${pathname}index.html`, `${pathname.slice(0, -1)}.html`]\n : [pathname, `${pathname}.html`, `${pathname}/index.html`];\n for (const candidate of candidates) {\n const page = yield* serveFile(prerenderedDir, candidate);\n if (Option.isSome(page)) return page;\n }\n }\n\n return Option.none();\n }),\n});\n\n/**\n * Serve static assets from a Cloudflare Workers static-assets binding (commonly\n * `env.ASSETS`). The binding's `fetch` resolves client assets and prerendered\n * pages uploaded by the deployment; a 404 from it means \"not an asset\", so the\n * SSR core continues to server-side rendering.\n *\n * This is one provided convenience, not the assumption: pass any object with a\n * `fetch` (R2, KV, a CDN passthrough) or a custom {@link AssetSource}.\n */\nexport const cloudflareAssets = (assets: {\n fetch: (request: Request) => Promise<Response> | Response;\n}): AssetSource => ({\n serveAsset: (request) =>\n Effect.gen(function* () {\n if (request.method !== \"GET\" && request.method !== \"HEAD\") return Option.none();\n const response = yield* Effect.promise(async () => assets.fetch(request));\n if (response.status === 404) return Option.none();\n return Option.some(HttpServerResponse.fromWeb(response));\n }),\n});\n\n/** The {@link AssetSource} constructors, grouped for the adapter API. */\nexport const AssetSource = {\n fileSystem,\n cloudflareAssets,\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAyCA,MAAM,oBAAoB,EAAE,iBAAiB,sCAAsC;;;;;AAMnF,MAAa,cAAc,YAOkB,EAC3C,aAAa,SAAS,aACpB,OAAO,IAAI,aAAa;CAEtB,IAAI,QAAQ,WAAW,SAAS,QAAQ,WAAW,QAAQ,OAAO,OAAO,KAAK;CAE9E,MAAM,OAAO,OAAO,KAAK;CACzB,MAAM,KAAK,OAAO,WAAW;CAE7B,MAAM,YAAY,KAAK,KAAK,OAAO,KAAK,QAAQ;CAChD,MAAM,iBAAiB,KAAK,KAAK,OAAO,KAAK,aAAa;CAC1D,MAAM,kBAAkB,IAAI,OAAO,QAAQ;;;;;CAM3C,MAAM,aACJ,MACA,WACA,YAMA,OAAO,IAAI,aAAa;EACtB,MAAM,WAAW,KAAK,KAAK,MAAM,SAAS;EAC1C,MAAM,WAAW,KAAK,SAAS,MAAM,QAAQ;EAC7C,IAAI,SAAS,WAAW,IAAI,KAAK,KAAK,WAAW,QAAQ,GAAG,OAAO,OAAO,KAAK;EAE/E,MAAM,OAAO,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,KAAK,OAAO,MAAM;EACxD,IAAI,OAAO,OAAO,IAAI,KAAK,KAAK,MAAM,SAAS,QAAQ,OAAO,OAAO,KAAK;EAE1E,MAAM,WAAW,OAAO,mBAAmB,KAAK,UAAU,EAAE,QAAQ,CAAC,CAAC,CAAC,KAAK,OAAO,KAAK;EACxF,OAAO,OAAO,KAAK,QAAQ;CAC7B,CAAC;CAIH,MAAM,QAAQ,OAAO,UACnB,WACA,UAHkB,SAAS,WAAW,eAI5B,IAAI,oBAAoB,KAAA,CACpC;CACA,IAAI,OAAO,OAAO,KAAK,GAAG,OAAO;CAGjC,IAAI,OAAO,YAAY,IAAI,QAAQ,KAAK,OAAO,YAAY,IAAI,WAAW,GAAG,GAAG;EAC9E,MAAM,aACJ,aAAa,MACT,CAAC,aAAa,IACd,SAAS,SAAS,GAAG,IACnB,CAAC,GAAG,SAAS,aAAa,GAAG,SAAS,MAAM,GAAG,EAAE,EAAE,MAAM,IACzD;GAAC;GAAU,GAAG,SAAS;GAAQ,GAAG,SAAS;EAAY;EAC/D,KAAK,MAAM,aAAa,YAAY;GAClC,MAAM,OAAO,OAAO,UAAU,gBAAgB,SAAS;GACvD,IAAI,OAAO,OAAO,IAAI,GAAG,OAAO;EAClC;CACF;CAEA,OAAO,OAAO,KAAK;AACrB,CAAC,EACL;;;;;;;;;;AAWA,MAAa,oBAAoB,YAEb,EAClB,aAAa,YACX,OAAO,IAAI,aAAa;CACtB,IAAI,QAAQ,WAAW,SAAS,QAAQ,WAAW,QAAQ,OAAO,OAAO,KAAK;CAC9E,MAAM,WAAW,OAAO,OAAO,QAAQ,YAAY,OAAO,MAAM,OAAO,CAAC;CACxE,IAAI,SAAS,WAAW,KAAK,OAAO,OAAO,KAAK;CAChD,OAAO,OAAO,KAAK,mBAAmB,QAAQ,QAAQ,CAAC;AACzD,CAAC,EACL;;AAGA,MAAa,cAAc;CACzB;CACA;AACF"}
@@ -1,9 +1,8 @@
1
1
  import { AssetSource, FileSystemAssetServices } from "./assets.js";
2
2
  import { Effect, Layer } from "effect";
3
3
  import { SSRManifest, Server } from "@sveltejs/kit";
4
- import * as HttpServerRequest from "effect/unstable/http/HttpServerRequest";
5
- import * as HttpServerResponse from "effect/unstable/http/HttpServerResponse";
6
-
4
+ import * as HttpServerRequest from "effect/http/HttpServerRequest";
5
+ import * as HttpServerResponse from "effect/http/HttpServerResponse";
7
6
  //#region src/adapter/handler.d.ts
8
7
  /**
9
8
  * The services required by the SvelteKit HTTP application when serving assets
@@ -66,9 +65,9 @@ interface SvelteKitNeutralHandlerOptions<RAssets> {
66
65
  *
67
66
  * @example
68
67
  * ```ts
69
- * // Mounting SvelteKit inside an existing effect/unstable/http server:
68
+ * // Mounting SvelteKit inside an existing effect/http server:
70
69
  * import { handler } from "./build/handler.js";
71
- * import * as HttpServer from "effect/unstable/http/HttpServer";
70
+ * import * as HttpServer from "effect/http/HttpServer";
72
71
  * import { NodeHttpServer, NodeRuntime } from "@effect/platform-node";
73
72
  * import { Effect, Layer } from "effect";
74
73
  * import { createServer } from "node:http";
@@ -2,19 +2,19 @@ import { AssetSource } from "./assets.js";
2
2
  import { Config, Effect, Option, Stream } from "effect";
3
3
  import * as FileSystem from "effect/FileSystem";
4
4
  import * as Path from "effect/Path";
5
- import * as HttpEffect from "effect/unstable/http/HttpEffect";
6
- import * as HttpMethod from "effect/unstable/http/HttpMethod";
7
- import * as HttpServerRequest from "effect/unstable/http/HttpServerRequest";
8
- import * as HttpServerResponse from "effect/unstable/http/HttpServerResponse";
5
+ import * as HttpEffect from "effect/http/HttpEffect";
6
+ import * as HttpMethod from "effect/http/HttpMethod";
7
+ import * as HttpServerRequest from "effect/http/HttpServerRequest";
8
+ import * as HttpServerResponse from "effect/http/HttpServerResponse";
9
9
  //#region src/adapter/handler.ts
10
10
  /** Runtime configuration, read from the environment (compatible with adapter-node). */
11
11
  const handlerConfig = (prefix) => Config.all({
12
- origin: Config.option(Config.string(`${prefix}ORIGIN`)),
13
- protocolHeader: Config.option(Config.string(`${prefix}PROTOCOL_HEADER`)),
14
- hostHeader: Config.option(Config.string(`${prefix}HOST_HEADER`)),
15
- portHeader: Config.option(Config.string(`${prefix}PORT_HEADER`)),
16
- addressHeader: Config.option(Config.string(`${prefix}ADDRESS_HEADER`)),
17
- xffDepth: Config.int(`${prefix}XFF_DEPTH`).pipe(Config.withDefault(1))
12
+ origin: Config.option(Config.String(`${prefix}ORIGIN`)),
13
+ protocolHeader: Config.option(Config.String(`${prefix}PROTOCOL_HEADER`)),
14
+ hostHeader: Config.option(Config.String(`${prefix}HOST_HEADER`)),
15
+ portHeader: Config.option(Config.String(`${prefix}PORT_HEADER`)),
16
+ addressHeader: Config.option(Config.String(`${prefix}ADDRESS_HEADER`)),
17
+ xffDepth: Config.Int(`${prefix}XFF_DEPTH`).pipe(Config.withDefault(1))
18
18
  });
19
19
  /** Compute the request origin from configuration and headers (adapter-node semantics). */
20
20
  const originOf = (request, config) => {
@@ -69,9 +69,9 @@ const toWebRequest = (request, url, context) => {
69
69
  *
70
70
  * @example
71
71
  * ```ts
72
- * // Mounting SvelteKit inside an existing effect/unstable/http server:
72
+ * // Mounting SvelteKit inside an existing effect/http server:
73
73
  * import { handler } from "./build/handler.js";
74
- * import * as HttpServer from "effect/unstable/http/HttpServer";
74
+ * import * as HttpServer from "effect/http/HttpServer";
75
75
  * import { NodeHttpServer, NodeRuntime } from "@effect/platform-node";
76
76
  * import { Effect, Layer } from "effect";
77
77
  * import { createServer } from "node:http";
@@ -1 +1 @@
1
- {"version":3,"file":"handler.js","names":[],"sources":["../../src/adapter/handler.ts"],"sourcesContent":["/**\n * Runtime handler for the Effect SvelteKit adapter.\n *\n * `makeHandler` turns a built SvelteKit app (the `Server` class and manifest\n * emitted by `vite build`) into an Effect HTTP application that serves\n * static client assets, prerendered pages, and server-side rendered routes from\n * disk — the Node default.\n *\n * {@link makeHandlerWith} is the platform-neutral core: it takes an injected\n * {@link AssetSource} (where assets come from) and a `read` capability (how to\n * read server assets), so the same SvelteKit `HttpApp` can run on a Node server\n * or on Cloudflare Workers (assets from `env.ASSETS`).\n *\n * The returned app is an ordinary Effect value: it can be served with the\n * generated `build/index.js` entry (see `./serve.js`), mounted inside any\n * existing `effect/unstable/http` HTTP server, or converted to a `fetch` handler\n * (see {@link toWebHandler}).\n */\n\nimport type { SSRManifest, Server as SvelteKitServer } from \"@sveltejs/kit\";\nimport * as FileSystem from \"effect/FileSystem\";\nimport * as HttpMethod from \"effect/unstable/http/HttpMethod\";\nimport * as HttpEffect from \"effect/unstable/http/HttpEffect\";\nimport * as HttpServerRequest from \"effect/unstable/http/HttpServerRequest\";\nimport * as HttpServerResponse from \"effect/unstable/http/HttpServerResponse\";\nimport * as Path from \"effect/Path\";\nimport { Config, Context, Effect, Layer, Option, Stream } from \"effect\";\nimport { AssetSource, type FileSystemAssetServices } from \"./assets.js\";\n\nexport { AssetSource, type FileSystemAssetServices } from \"./assets.js\";\n\n/**\n * The services required by the SvelteKit HTTP application when serving assets\n * from the file system (the Node default). All of them are provided by\n * `NodeHttpServer.layer` from `@effect/platform-node`.\n */\nexport type SvelteKitHttpAppServices = FileSystemAssetServices;\n\n/**\n * The SvelteKit application as a composable Effect HTTP handler: an effect that\n * produces an {@link HttpServerResponse.HttpServerResponse} for the current\n * request. The `HttpServerRequest` is supplied per request by the server. `R`\n * is the asset source's services (defaults to the file-system services).\n */\nexport type SvelteKitHttpApp<R = SvelteKitHttpAppServices> = Effect.Effect<\n HttpServerResponse.HttpServerResponse,\n never,\n R | HttpServerRequest.HttpServerRequest\n>;\n\nexport interface SvelteKitHandlerOptions {\n /** The SvelteKit `Server` class exported by the build output (`./server/index.js`). */\n readonly Server: typeof SvelteKitServer;\n /** The SSR manifest exported by the build output (`./manifest.js`). */\n readonly manifest: SSRManifest;\n /** The set of prerendered paths exported by the build output (`./manifest.js`). */\n readonly prerendered: ReadonlySet<string>;\n /** The configured `paths.base`, exported by the build output (`./manifest.js`). */\n readonly base: string;\n /** Absolute path of the build output directory (contains `client/`, `server/`, `prerendered/`). */\n readonly dir: string;\n /** Environment variables passed to the SvelteKit server (e.g. `process.env`). */\n readonly env?: Record<string, string | undefined>;\n /** Prefix for the runtime configuration environment variables (ORIGIN, ...). */\n readonly envPrefix?: string;\n}\n\n/** Options for the platform-neutral SSR core, {@link makeHandlerWith}. */\nexport interface SvelteKitNeutralHandlerOptions<RAssets> {\n /** The SvelteKit `Server` class exported by the build output. */\n readonly Server: typeof SvelteKitServer;\n /** The SSR manifest exported by the build output. */\n readonly manifest: SSRManifest;\n /** Environment variables passed to the SvelteKit server. */\n readonly env?: Record<string, string | undefined> | undefined;\n /** Prefix for the runtime configuration environment variables (ORIGIN, ...). */\n readonly envPrefix?: string | undefined;\n /** Where static client assets and prerendered pages come from. */\n readonly assets: AssetSource<RAssets>;\n /**\n * How to read a server asset (backs `read()` from `$app/server`). On Node\n * this streams from `<dir>/server`; on Workers, back it with the platform's\n * own mechanism.\n */\n readonly read: (file: string) => ReadableStream<Uint8Array>;\n}\n\n/** Runtime configuration, read from the environment (compatible with adapter-node). */\nconst handlerConfig = (prefix: string) =>\n Config.all({\n origin: Config.option(Config.string(`${prefix}ORIGIN`)),\n protocolHeader: Config.option(Config.string(`${prefix}PROTOCOL_HEADER`)),\n hostHeader: Config.option(Config.string(`${prefix}HOST_HEADER`)),\n portHeader: Config.option(Config.string(`${prefix}PORT_HEADER`)),\n addressHeader: Config.option(Config.string(`${prefix}ADDRESS_HEADER`)),\n xffDepth: Config.int(`${prefix}XFF_DEPTH`).pipe(Config.withDefault(1)),\n });\n\ntype HandlerConfig = Effect.Success<ReturnType<typeof handlerConfig>>;\n\n/** Compute the request origin from configuration and headers (adapter-node semantics). */\nconst originOf = (request: HttpServerRequest.HttpServerRequest, config: HandlerConfig): string => {\n if (Option.isSome(config.origin)) return config.origin.value;\n\n const headers = request.headers;\n const protocolHeader = Option.getOrUndefined(config.protocolHeader)?.toLowerCase();\n const hostHeader = Option.getOrUndefined(config.hostHeader)?.toLowerCase() ?? \"host\";\n const portHeader = Option.getOrUndefined(config.portHeader)?.toLowerCase();\n\n const protocol = (protocolHeader && headers[protocolHeader]) || \"http\";\n const host = headers[hostHeader] ?? \"localhost\";\n const port = portHeader ? headers[portHeader] : undefined;\n\n return port ? `${protocol}://${host.split(\":\")[0]}:${port}` : `${protocol}://${host}`;\n};\n\n/** Resolve the client address, honouring ADDRESS_HEADER / XFF_DEPTH if configured. */\nconst clientAddressOf = (\n request: HttpServerRequest.HttpServerRequest,\n config: HandlerConfig,\n): string => {\n const addressHeader = Option.getOrUndefined(config.addressHeader)?.toLowerCase();\n if (addressHeader) {\n const value = request.headers[addressHeader];\n if (value) {\n if (addressHeader === \"x-forwarded-for\") {\n const addresses = value.split(\",\").map((address) => address.trim());\n if (config.xffDepth < 1 || config.xffDepth > addresses.length) {\n return addresses[0] ?? \"\";\n }\n return addresses[addresses.length - config.xffDepth]!;\n }\n return value;\n }\n }\n return Option.getOrElse(request.remoteAddress, () => \"\");\n};\n\n/** Build a web `Request` for SvelteKit from an `HttpServerRequest`. */\nconst toWebRequest = (\n request: HttpServerRequest.HttpServerRequest,\n url: URL,\n context: Context.Context<never>,\n): Request => {\n // `Headers` is a redactable record-like value; copy the enumerable string\n // entries into a plain record for the web `Request` constructor.\n const init: RequestInit & { duplex?: \"half\" } = {\n method: request.method,\n headers: { ...request.headers },\n };\n if (HttpMethod.hasBody(request.method)) {\n init.body = Stream.toReadableStreamWith(request.stream, context);\n init.duplex = \"half\";\n }\n return new Request(url, init);\n};\n\n/**\n * Creates the SvelteKit HTTP handler.\n *\n * The returned effect initialises the SvelteKit server (running your app's\n * server `init` hook) and yields an HTTP handler that:\n *\n * 1. serves static client assets from `<dir>/client` (with immutable cache\n * headers for hashed build assets),\n * 2. serves prerendered pages from `<dir>/prerendered`,\n * 3. falls back to server-side rendering via the SvelteKit server.\n *\n * @example\n * ```ts\n * // Mounting SvelteKit inside an existing effect/unstable/http server:\n * import { handler } from \"./build/handler.js\";\n * import * as HttpServer from \"effect/unstable/http/HttpServer\";\n * import { NodeHttpServer, NodeRuntime } from \"@effect/platform-node\";\n * import { Effect, Layer } from \"effect\";\n * import { createServer } from \"node:http\";\n *\n * const serverLayer = Layer.unwrap(\n * Effect.map(handler, (app) => HttpServer.serve(app))\n * ).pipe(Layer.provide(NodeHttpServer.layer(createServer, { port: 3000 })));\n *\n * NodeRuntime.runMain(Layer.launch(serverLayer));\n * ```\n */\nexport const makeHandler = (\n options: SvelteKitHandlerOptions,\n): Effect.Effect<SvelteKitHttpApp, never, SvelteKitHttpAppServices> =>\n Effect.gen(function* () {\n const fs = yield* FileSystem.FileSystem;\n const path = yield* Path.Path;\n const context = yield* Effect.context<never>();\n\n const serverDir = path.join(options.dir, \"server\");\n\n return yield* makeHandlerWith<SvelteKitHttpAppServices>({\n Server: options.Server,\n manifest: options.manifest,\n env: options.env,\n envPrefix: options.envPrefix,\n // `read` backs the `read()` helper from `$app/server`, streaming server\n // assets from the build output.\n read: (file) => Stream.toReadableStreamWith(fs.stream(path.join(serverDir, file)), context),\n assets: AssetSource.fileSystem({\n dir: options.dir,\n appPath: options.manifest.appPath,\n prerendered: options.prerendered,\n }),\n });\n });\n\n/**\n * The platform-neutral SSR core. Like {@link makeHandler}, but the asset source\n * and the server-asset `read` capability are injected, so the same SvelteKit\n * `HttpApp` can run on Node (file-system assets) or on Cloudflare Workers\n * (`AssetSource.cloudflareAssets(env.ASSETS)`).\n *\n * The returned app:\n *\n * 1. falls through to the injected {@link AssetSource} for static client assets\n * and prerendered pages (GET/HEAD), then\n * 2. server-side renders via the SvelteKit server.\n *\n * @example\n * ```ts\n * // Workers: a fetch handler with assets from env.ASSETS\n * import { makeHandlerWith, AssetSource, toWebHandler } from \"...adapter/handler\";\n * import { Server } from \"./server/index.js\";\n * import { manifest } from \"./manifest.js\";\n *\n * export default {\n * fetch: (request, env, ctx) =>\n * toWebHandler(\n * makeHandlerWith({\n * Server, manifest, env,\n * assets: AssetSource.cloudflareAssets(env.ASSETS),\n * read: () => { throw new Error(\"read() not supported on this deployment\"); },\n * }),\n * )(request),\n * };\n * ```\n */\nexport const makeHandlerWith = <RAssets = never>(\n options: SvelteKitNeutralHandlerOptions<RAssets>,\n): Effect.Effect<SvelteKitHttpApp<RAssets>, never, never> =>\n Effect.gen(function* () {\n const config = yield* handlerConfig(options.envPrefix ?? \"\").pipe(Effect.orDie);\n\n // Initialise the SvelteKit server. `read` backs `read()` from `$app/server`.\n const server = new options.Server(options.manifest);\n yield* Effect.promise(() =>\n server.init({\n env: (options.env ?? {}) as Record<string, string>,\n read: options.read,\n }),\n );\n\n // The HTTP handler itself, evaluated once per request.\n return Effect.gen(function* () {\n const request = yield* HttpServerRequest.HttpServerRequest;\n const requestContext = yield* Effect.context<never>();\n\n const origin = originOf(request, config);\n const url = new URL(request.url, origin);\n\n let pathname: string;\n try {\n pathname = decodeURIComponent(url.pathname);\n } catch {\n return HttpServerResponse.empty({ status: 400 });\n }\n\n // 1. Static client assets / prerendered pages, via the injected source.\n // Only GET/HEAD reach assets; build a body-less request for the source.\n if (request.method === \"GET\" || request.method === \"HEAD\") {\n const assetRequest = new Request(url, {\n method: request.method,\n headers: { ...request.headers },\n });\n const asset = yield* options.assets.serveAsset(assetRequest, pathname);\n if (Option.isSome(asset)) return asset.value;\n }\n\n // 2. Server-side rendering.\n const webRequest = toWebRequest(request, url, requestContext);\n const response = yield* Effect.promise(() =>\n server.respond(webRequest, {\n getClientAddress: () => clientAddressOf(request, config),\n }),\n );\n return HttpServerResponse.fromWeb(response);\n });\n });\n\n/**\n * Convert a SvelteKit `HttpApp` to a Web `fetch` handler, providing the asset\n * source's services with `layer`. Use this for a Workers `fetch` export or any\n * runtime that speaks the Web platform.\n *\n * @example\n * ```ts\n * const fetchHandler = toWebHandler(\n * makeHandlerWith({ ..., assets: AssetSource.cloudflareAssets(env.ASSETS) }),\n * Layer.empty,\n * );\n * ```\n */\nexport const toWebHandler = <RAssets, E>(\n app: Effect.Effect<SvelteKitHttpApp<RAssets>, never, never>,\n layer: Layer.Layer<RAssets, E>,\n): ((request: Request) => Promise<Response>) => {\n // Build the app (server.init) and the per-request web handler once, lazily on\n // the first request, then dispatch each request through it.\n let built: Promise<(request: Request) => Promise<Response>> | undefined;\n const build = (): Promise<(request: Request) => Promise<Response>> =>\n (built ??= Effect.runPromise(app).then(\n (inner) =>\n HttpEffect.toWebHandlerLayer(inner, layer).handler as (\n request: Request,\n ) => Promise<Response>,\n ));\n return async (request) => (await build())(request);\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"handler.js","names":[],"sources":["../../src/adapter/handler.ts"],"sourcesContent":["/**\n * Runtime handler for the Effect SvelteKit adapter.\n *\n * `makeHandler` turns a built SvelteKit app (the `Server` class and manifest\n * emitted by `vite build`) into an Effect HTTP application that serves\n * static client assets, prerendered pages, and server-side rendered routes from\n * disk — the Node default.\n *\n * {@link makeHandlerWith} is the platform-neutral core: it takes an injected\n * {@link AssetSource} (where assets come from) and a `read` capability (how to\n * read server assets), so the same SvelteKit `HttpApp` can run on a Node server\n * or on Cloudflare Workers (assets from `env.ASSETS`).\n *\n * The returned app is an ordinary Effect value: it can be served with the\n * generated `build/index.js` entry (see `./serve.js`), mounted inside any\n * existing `effect/http` HTTP server, or converted to a `fetch` handler\n * (see {@link toWebHandler}).\n */\n\nimport type { SSRManifest, Server as SvelteKitServer } from \"@sveltejs/kit\";\nimport * as FileSystem from \"effect/FileSystem\";\nimport * as HttpMethod from \"effect/http/HttpMethod\";\nimport * as HttpEffect from \"effect/http/HttpEffect\";\nimport * as HttpServerRequest from \"effect/http/HttpServerRequest\";\nimport * as HttpServerResponse from \"effect/http/HttpServerResponse\";\nimport * as Path from \"effect/Path\";\nimport { Config, Context, Effect, Layer, Option, Stream } from \"effect\";\nimport { AssetSource, type FileSystemAssetServices } from \"./assets.js\";\n\nexport { AssetSource, type FileSystemAssetServices } from \"./assets.js\";\n\n/**\n * The services required by the SvelteKit HTTP application when serving assets\n * from the file system (the Node default). All of them are provided by\n * `NodeHttpServer.layer` from `@effect/platform-node`.\n */\nexport type SvelteKitHttpAppServices = FileSystemAssetServices;\n\n/**\n * The SvelteKit application as a composable Effect HTTP handler: an effect that\n * produces an {@link HttpServerResponse.HttpServerResponse} for the current\n * request. The `HttpServerRequest` is supplied per request by the server. `R`\n * is the asset source's services (defaults to the file-system services).\n */\nexport type SvelteKitHttpApp<R = SvelteKitHttpAppServices> = Effect.Effect<\n HttpServerResponse.HttpServerResponse,\n never,\n R | HttpServerRequest.HttpServerRequest\n>;\n\nexport interface SvelteKitHandlerOptions {\n /** The SvelteKit `Server` class exported by the build output (`./server/index.js`). */\n readonly Server: typeof SvelteKitServer;\n /** The SSR manifest exported by the build output (`./manifest.js`). */\n readonly manifest: SSRManifest;\n /** The set of prerendered paths exported by the build output (`./manifest.js`). */\n readonly prerendered: ReadonlySet<string>;\n /** The configured `paths.base`, exported by the build output (`./manifest.js`). */\n readonly base: string;\n /** Absolute path of the build output directory (contains `client/`, `server/`, `prerendered/`). */\n readonly dir: string;\n /** Environment variables passed to the SvelteKit server (e.g. `process.env`). */\n readonly env?: Record<string, string | undefined>;\n /** Prefix for the runtime configuration environment variables (ORIGIN, ...). */\n readonly envPrefix?: string;\n}\n\n/** Options for the platform-neutral SSR core, {@link makeHandlerWith}. */\nexport interface SvelteKitNeutralHandlerOptions<RAssets> {\n /** The SvelteKit `Server` class exported by the build output. */\n readonly Server: typeof SvelteKitServer;\n /** The SSR manifest exported by the build output. */\n readonly manifest: SSRManifest;\n /** Environment variables passed to the SvelteKit server. */\n readonly env?: Record<string, string | undefined> | undefined;\n /** Prefix for the runtime configuration environment variables (ORIGIN, ...). */\n readonly envPrefix?: string | undefined;\n /** Where static client assets and prerendered pages come from. */\n readonly assets: AssetSource<RAssets>;\n /**\n * How to read a server asset (backs `read()` from `$app/server`). On Node\n * this streams from `<dir>/server`; on Workers, back it with the platform's\n * own mechanism.\n */\n readonly read: (file: string) => ReadableStream<Uint8Array>;\n}\n\n/** Runtime configuration, read from the environment (compatible with adapter-node). */\nconst handlerConfig = (prefix: string) =>\n Config.all({\n origin: Config.option(Config.String(`${prefix}ORIGIN`)),\n protocolHeader: Config.option(Config.String(`${prefix}PROTOCOL_HEADER`)),\n hostHeader: Config.option(Config.String(`${prefix}HOST_HEADER`)),\n portHeader: Config.option(Config.String(`${prefix}PORT_HEADER`)),\n addressHeader: Config.option(Config.String(`${prefix}ADDRESS_HEADER`)),\n xffDepth: Config.Int(`${prefix}XFF_DEPTH`).pipe(Config.withDefault(1)),\n });\n\ntype HandlerConfig = Effect.Success<ReturnType<typeof handlerConfig>>;\n\n/** Compute the request origin from configuration and headers (adapter-node semantics). */\nconst originOf = (request: HttpServerRequest.HttpServerRequest, config: HandlerConfig): string => {\n if (Option.isSome(config.origin)) return config.origin.value;\n\n const headers = request.headers;\n const protocolHeader = Option.getOrUndefined(config.protocolHeader)?.toLowerCase();\n const hostHeader = Option.getOrUndefined(config.hostHeader)?.toLowerCase() ?? \"host\";\n const portHeader = Option.getOrUndefined(config.portHeader)?.toLowerCase();\n\n const protocol = (protocolHeader && headers[protocolHeader]) || \"http\";\n const host = headers[hostHeader] ?? \"localhost\";\n const port = portHeader ? headers[portHeader] : undefined;\n\n return port ? `${protocol}://${host.split(\":\")[0]}:${port}` : `${protocol}://${host}`;\n};\n\n/** Resolve the client address, honouring ADDRESS_HEADER / XFF_DEPTH if configured. */\nconst clientAddressOf = (\n request: HttpServerRequest.HttpServerRequest,\n config: HandlerConfig,\n): string => {\n const addressHeader = Option.getOrUndefined(config.addressHeader)?.toLowerCase();\n if (addressHeader) {\n const value = request.headers[addressHeader];\n if (value) {\n if (addressHeader === \"x-forwarded-for\") {\n const addresses = value.split(\",\").map((address) => address.trim());\n if (config.xffDepth < 1 || config.xffDepth > addresses.length) {\n return addresses[0] ?? \"\";\n }\n return addresses[addresses.length - config.xffDepth]!;\n }\n return value;\n }\n }\n return Option.getOrElse(request.remoteAddress, () => \"\");\n};\n\n/** Build a web `Request` for SvelteKit from an `HttpServerRequest`. */\nconst toWebRequest = (\n request: HttpServerRequest.HttpServerRequest,\n url: URL,\n context: Context.Context<never>,\n): Request => {\n // `Headers` is a redactable record-like value; copy the enumerable string\n // entries into a plain record for the web `Request` constructor.\n const init: RequestInit & { duplex?: \"half\" } = {\n method: request.method,\n headers: { ...request.headers },\n };\n if (HttpMethod.hasBody(request.method)) {\n init.body = Stream.toReadableStreamWith(request.stream, context);\n init.duplex = \"half\";\n }\n return new Request(url, init);\n};\n\n/**\n * Creates the SvelteKit HTTP handler.\n *\n * The returned effect initialises the SvelteKit server (running your app's\n * server `init` hook) and yields an HTTP handler that:\n *\n * 1. serves static client assets from `<dir>/client` (with immutable cache\n * headers for hashed build assets),\n * 2. serves prerendered pages from `<dir>/prerendered`,\n * 3. falls back to server-side rendering via the SvelteKit server.\n *\n * @example\n * ```ts\n * // Mounting SvelteKit inside an existing effect/http server:\n * import { handler } from \"./build/handler.js\";\n * import * as HttpServer from \"effect/http/HttpServer\";\n * import { NodeHttpServer, NodeRuntime } from \"@effect/platform-node\";\n * import { Effect, Layer } from \"effect\";\n * import { createServer } from \"node:http\";\n *\n * const serverLayer = Layer.unwrap(\n * Effect.map(handler, (app) => HttpServer.serve(app))\n * ).pipe(Layer.provide(NodeHttpServer.layer(createServer, { port: 3000 })));\n *\n * NodeRuntime.runMain(Layer.launch(serverLayer));\n * ```\n */\nexport const makeHandler = (\n options: SvelteKitHandlerOptions,\n): Effect.Effect<SvelteKitHttpApp, never, SvelteKitHttpAppServices> =>\n Effect.gen(function* () {\n const fs = yield* FileSystem.FileSystem;\n const path = yield* Path.Path;\n const context = yield* Effect.context<never>();\n\n const serverDir = path.join(options.dir, \"server\");\n\n return yield* makeHandlerWith<SvelteKitHttpAppServices>({\n Server: options.Server,\n manifest: options.manifest,\n env: options.env,\n envPrefix: options.envPrefix,\n // `read` backs the `read()` helper from `$app/server`, streaming server\n // assets from the build output.\n read: (file) => Stream.toReadableStreamWith(fs.stream(path.join(serverDir, file)), context),\n assets: AssetSource.fileSystem({\n dir: options.dir,\n appPath: options.manifest.appPath,\n prerendered: options.prerendered,\n }),\n });\n });\n\n/**\n * The platform-neutral SSR core. Like {@link makeHandler}, but the asset source\n * and the server-asset `read` capability are injected, so the same SvelteKit\n * `HttpApp` can run on Node (file-system assets) or on Cloudflare Workers\n * (`AssetSource.cloudflareAssets(env.ASSETS)`).\n *\n * The returned app:\n *\n * 1. falls through to the injected {@link AssetSource} for static client assets\n * and prerendered pages (GET/HEAD), then\n * 2. server-side renders via the SvelteKit server.\n *\n * @example\n * ```ts\n * // Workers: a fetch handler with assets from env.ASSETS\n * import { makeHandlerWith, AssetSource, toWebHandler } from \"...adapter/handler\";\n * import { Server } from \"./server/index.js\";\n * import { manifest } from \"./manifest.js\";\n *\n * export default {\n * fetch: (request, env, ctx) =>\n * toWebHandler(\n * makeHandlerWith({\n * Server, manifest, env,\n * assets: AssetSource.cloudflareAssets(env.ASSETS),\n * read: () => { throw new Error(\"read() not supported on this deployment\"); },\n * }),\n * )(request),\n * };\n * ```\n */\nexport const makeHandlerWith = <RAssets = never>(\n options: SvelteKitNeutralHandlerOptions<RAssets>,\n): Effect.Effect<SvelteKitHttpApp<RAssets>, never, never> =>\n Effect.gen(function* () {\n const config = yield* handlerConfig(options.envPrefix ?? \"\").pipe(Effect.orDie);\n\n // Initialise the SvelteKit server. `read` backs `read()` from `$app/server`.\n const server = new options.Server(options.manifest);\n yield* Effect.promise(() =>\n server.init({\n env: (options.env ?? {}) as Record<string, string>,\n read: options.read,\n }),\n );\n\n // The HTTP handler itself, evaluated once per request.\n return Effect.gen(function* () {\n const request = yield* HttpServerRequest.HttpServerRequest;\n const requestContext = yield* Effect.context<never>();\n\n const origin = originOf(request, config);\n const url = new URL(request.url, origin);\n\n let pathname: string;\n try {\n pathname = decodeURIComponent(url.pathname);\n } catch {\n return HttpServerResponse.empty({ status: 400 });\n }\n\n // 1. Static client assets / prerendered pages, via the injected source.\n // Only GET/HEAD reach assets; build a body-less request for the source.\n if (request.method === \"GET\" || request.method === \"HEAD\") {\n const assetRequest = new Request(url, {\n method: request.method,\n headers: { ...request.headers },\n });\n const asset = yield* options.assets.serveAsset(assetRequest, pathname);\n if (Option.isSome(asset)) return asset.value;\n }\n\n // 2. Server-side rendering.\n const webRequest = toWebRequest(request, url, requestContext);\n const response = yield* Effect.promise(() =>\n server.respond(webRequest, {\n getClientAddress: () => clientAddressOf(request, config),\n }),\n );\n return HttpServerResponse.fromWeb(response);\n });\n });\n\n/**\n * Convert a SvelteKit `HttpApp` to a Web `fetch` handler, providing the asset\n * source's services with `layer`. Use this for a Workers `fetch` export or any\n * runtime that speaks the Web platform.\n *\n * @example\n * ```ts\n * const fetchHandler = toWebHandler(\n * makeHandlerWith({ ..., assets: AssetSource.cloudflareAssets(env.ASSETS) }),\n * Layer.empty,\n * );\n * ```\n */\nexport const toWebHandler = <RAssets, E>(\n app: Effect.Effect<SvelteKitHttpApp<RAssets>, never, never>,\n layer: Layer.Layer<RAssets, E>,\n): ((request: Request) => Promise<Response>) => {\n // Build the app (server.init) and the per-request web handler once, lazily on\n // the first request, then dispatch each request through it.\n let built: Promise<(request: Request) => Promise<Response>> | undefined;\n const build = (): Promise<(request: Request) => Promise<Response>> =>\n (built ??= Effect.runPromise(app).then(\n (inner) =>\n HttpEffect.toWebHandlerLayer(inner, layer).handler as (\n request: Request,\n ) => Promise<Response>,\n ));\n return async (request) => (await build())(request);\n};\n"],"mappings":"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"}
@@ -1,5 +1,4 @@
1
1
  import { Adapter } from "@sveltejs/kit";
2
-
3
2
  //#region src/adapter/index.d.ts
4
3
  interface EffectAdapterOptions {
5
4
  /**
@@ -29,7 +28,7 @@ interface EffectAdapterOptions {
29
28
  * `env.ASSETS` binding via `AssetSource.cloudflareAssets`.
30
29
  *
31
30
  * Both targets also write `build/handler.js` (the SvelteKit `HttpApp`), so you
32
- * can compose your own entry for any `effect/unstable/http` runtime.
31
+ * can compose your own entry for any `effect/http` runtime.
33
32
  *
34
33
  * @default "node"
35
34
  */
@@ -4,7 +4,7 @@ import { writeFileSync } from "node:fs";
4
4
  * Effect deployment adapter for SvelteKit.
5
5
  *
6
6
  * Like `@sveltejs/adapter-node`, but the production server is an
7
- * `effect/unstable/http` HTTP server: requests are handled by an Effect HTTP
7
+ * `effect/http` HTTP server: requests are handled by an Effect HTTP
8
8
  * handler, configuration is read through `Config`, and startup/shutdown is
9
9
  * managed by Effect layers and scopes (SIGINT/SIGTERM trigger a graceful
10
10
  * shutdown that runs all finalizers).
@@ -24,7 +24,7 @@ import { writeFileSync } from "node:fs";
24
24
  *
25
25
  * - `index.js` — runs the production server: `node build`
26
26
  * - `handler.js` — exports the SvelteKit app as a composable Effect HTTP
27
- * handler, for mounting inside an existing `effect/unstable/http` server
27
+ * handler, for mounting inside an existing `effect/http` server
28
28
  * - `client/`, `server/`, `prerendered/`, `manifest.js` — the built app
29
29
  *
30
30
  * Unlike `adapter-node`, the server output is not bundled: the deployment
@@ -48,7 +48,7 @@ const dir = dirname(fileURLToPath(import.meta.url));
48
48
  * The SvelteKit application as a composable Effect HTTP handler.
49
49
  *
50
50
  * Serve it with the generated index.js, or mount it inside any
51
- * \`effect/unstable/http\` HTTP server.
51
+ * \`effect/http\` HTTP server.
52
52
  */
53
53
  export const handler = makeHandler({
54
54
  Server,
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../src/adapter/index.ts"],"sourcesContent":["/**\n * Effect deployment adapter for SvelteKit.\n *\n * Like `@sveltejs/adapter-node`, but the production server is an\n * `effect/unstable/http` HTTP server: requests are handled by an Effect HTTP\n * handler, configuration is read through `Config`, and startup/shutdown is\n * managed by Effect layers and scopes (SIGINT/SIGTERM trigger a graceful\n * shutdown that runs all finalizers).\n *\n * ```js\n * // svelte.config.js\n * import adapter from \"@thomasfosterau/effect-sveltekit/adapter\";\n *\n * const config = {\n * kit: { adapter: adapter() },\n * };\n *\n * export default config;\n * ```\n *\n * The build output (`build/` by default) contains:\n *\n * - `index.js` — runs the production server: `node build`\n * - `handler.js` — exports the SvelteKit app as a composable Effect HTTP\n * handler, for mounting inside an existing `effect/unstable/http` server\n * - `client/`, `server/`, `prerendered/`, `manifest.js` — the built app\n *\n * Unlike `adapter-node`, the server output is not bundled: the deployment\n * needs `node_modules` with the app's production dependencies installed\n * (including `@thomasfosterau/effect-sveltekit`, `effect`, and\n * `@effect/platform-node`).\n */\n\nimport { writeFileSync } from \"node:fs\";\nimport type { Adapter } from \"@sveltejs/kit\";\n\nexport interface EffectAdapterOptions {\n /**\n * The directory to write the production build to.\n * @default \"build\"\n */\n readonly out?: string;\n /**\n * Precompress static assets and prerendered pages with gzip and brotli.\n * @default true\n */\n readonly precompress?: boolean;\n /**\n * Prefix for the environment variables the production server reads\n * (`PORT`, `HOST`, `ORIGIN`, `PROTOCOL_HEADER`, `HOST_HEADER`,\n * `PORT_HEADER`, `ADDRESS_HEADER`, `XFF_DEPTH`).\n * @default \"\"\n */\n readonly envPrefix?: string;\n /**\n * The deployment target for the generated entry:\n *\n * - `\"node\"` (default) — a production Node HTTP server (`node build`) on\n * `@effect/platform-node`, serving assets from disk.\n * - `\"fetch\"` — a Web `fetch` handler suitable for Cloudflare Workers\n * (`build/index.js` exports `default { fetch }`), serving assets from the\n * `env.ASSETS` binding via `AssetSource.cloudflareAssets`.\n *\n * Both targets also write `build/handler.js` (the SvelteKit `HttpApp`), so you\n * can compose your own entry for any `effect/unstable/http` runtime.\n *\n * @default \"node\"\n */\n readonly target?: \"node\" | \"fetch\";\n}\n\nconst PACKAGE = \"@thomasfosterau/effect-sveltekit\";\n\n/** Template for the generated `<out>/handler.js`. */\nconst handlerTemplate = (envPrefix: string): string => `\\\nimport { dirname } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport process from \"node:process\";\nimport { makeHandler } from \"${PACKAGE}/adapter/handler\";\nimport { Server } from \"./server/index.js\";\nimport { manifest, prerendered, base } from \"./manifest.js\";\n\nconst dir = dirname(fileURLToPath(import.meta.url));\n\n/**\n * The SvelteKit application as a composable Effect HTTP handler.\n *\n * Serve it with the generated index.js, or mount it inside any\n * \\`effect/unstable/http\\` HTTP server.\n */\nexport const handler = makeHandler({\n Server,\n manifest,\n prerendered,\n base,\n dir,\n env: process.env,\n envPrefix: ${JSON.stringify(envPrefix)},\n});\n`;\n\n/** Template for the generated Node `<out>/index.js`. */\nconst nodeEntryTemplate = (envPrefix: string): string => `\\\nimport { serve } from \"${PACKAGE}/adapter/serve\";\nimport { handler } from \"./handler.js\";\n\nserve(handler, { envPrefix: ${JSON.stringify(envPrefix)} });\n`;\n\n/**\n * Template for the generated Cloudflare Workers `<out>/index.js`.\n *\n * Exports a module worker (`default { fetch }`). Static client assets and\n * prerendered pages are served from the `ASSETS` binding; everything else is\n * server-side rendered by the SvelteKit `HttpApp`.\n */\nconst fetchEntryTemplate = (envPrefix: string): string => `\\\nimport { Layer } from \"effect\";\nimport { makeHandlerWith, AssetSource, toWebHandler } from \"${PACKAGE}/adapter/handler\";\nimport { Server } from \"./server/index.js\";\nimport { manifest } from \"./manifest.js\";\n\nlet fetchHandler;\n\nexport default {\n /** @param {Request} request @param {Record<string, any>} env @param {any} ctx */\n fetch(request, env, ctx) {\n fetchHandler ??= toWebHandler(\n makeHandlerWith({\n Server,\n manifest,\n env,\n envPrefix: ${JSON.stringify(envPrefix)},\n // Static assets come from the Workers ASSETS binding (configure it to\n // serve the uploaded \\`client/\\` + \\`prerendered/\\` output).\n assets: AssetSource.cloudflareAssets(env.ASSETS),\n // \\`read()\\` from \\`$app/server\\` is not backed by a file system on workerd.\n read: (file) => {\n throw new Error(\\`read() is not supported on this deployment (\\${file})\\`);\n },\n }),\n Layer.empty,\n );\n return fetchHandler(request);\n },\n};\n`;\n\n/**\n * Creates the Effect SvelteKit adapter.\n */\nexport function effectAdapter(options: EffectAdapterOptions = {}): Adapter {\n const { out = \"build\", precompress = true, envPrefix = \"\", target = \"node\" } = options;\n\n return {\n name: `${PACKAGE}/adapter`,\n\n async adapt(builder) {\n const base = builder.config.kit.paths.base;\n\n builder.rimraf(out);\n builder.mkdirp(out);\n\n builder.log.minor(\"Copying assets\");\n builder.writeClient(`${out}/client${base}`);\n builder.writePrerendered(`${out}/prerendered${base}`);\n\n if (precompress) {\n builder.log.minor(\"Compressing assets\");\n await Promise.all([\n builder.compress(`${out}/client`),\n builder.compress(`${out}/prerendered`),\n ]);\n }\n\n builder.log.minor(\"Building server\");\n builder.writeServer(`${out}/server`);\n\n writeFileSync(\n `${out}/manifest.js`,\n [\n `export const manifest = ${builder.generateManifest({ relativePath: \"./server\" })};`,\n `export const prerendered = new Set(${JSON.stringify(builder.prerendered.paths)});`,\n `export const base = ${JSON.stringify(base)};`,\n ].join(\"\\n\\n\"),\n );\n\n builder.log.minor(\"Writing server entry\");\n writeFileSync(`${out}/handler.js`, handlerTemplate(envPrefix));\n writeFileSync(\n `${out}/index.js`,\n target === \"fetch\" ? fetchEntryTemplate(envPrefix) : nodeEntryTemplate(envPrefix),\n );\n },\n\n supports: {\n // On Node, `read()` from `$app/server` is backed by the platform\n // FileSystem. On the `fetch` (Workers) target it has no file system, so\n // routes using `read()` are unsupported there.\n read: () => target !== \"fetch\",\n },\n };\n}\n\nexport default effectAdapter;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuEA,MAAM,UAAU;;AAGhB,MAAM,mBAAmB,cAA8B;;;;+BAIxB,QAAQ;;;;;;;;;;;;;;;;;;;eAmBxB,KAAK,UAAU,SAAS,EAAE;;;;AAKzC,MAAM,qBAAqB,cAA8B;yBAChC,QAAQ;;;8BAGH,KAAK,UAAU,SAAS,EAAE;;;;;;;;;AAUxD,MAAM,sBAAsB,cAA8B;;8DAEI,QAAQ;;;;;;;;;;;;;;qBAcjD,KAAK,UAAU,SAAS,EAAE;;;;;;;;;;;;;;;;;;AAmB/C,SAAgB,cAAc,UAAgC,CAAC,GAAY;CACzE,MAAM,EAAE,MAAM,SAAS,cAAc,MAAM,YAAY,IAAI,SAAS,WAAW;CAE/E,OAAO;EACL,MAAM,GAAG,QAAQ;EAEjB,MAAM,MAAM,SAAS;GACnB,MAAM,OAAO,QAAQ,OAAO,IAAI,MAAM;GAEtC,QAAQ,OAAO,GAAG;GAClB,QAAQ,OAAO,GAAG;GAElB,QAAQ,IAAI,MAAM,gBAAgB;GAClC,QAAQ,YAAY,GAAG,IAAI,SAAS,MAAM;GAC1C,QAAQ,iBAAiB,GAAG,IAAI,cAAc,MAAM;GAEpD,IAAI,aAAa;IACf,QAAQ,IAAI,MAAM,oBAAoB;IACtC,MAAM,QAAQ,IAAI,CAChB,QAAQ,SAAS,GAAG,IAAI,QAAQ,GAChC,QAAQ,SAAS,GAAG,IAAI,aAAa,CACvC,CAAC;GACH;GAEA,QAAQ,IAAI,MAAM,iBAAiB;GACnC,QAAQ,YAAY,GAAG,IAAI,QAAQ;GAEnC,cACE,GAAG,IAAI,eACP;IACE,2BAA2B,QAAQ,iBAAiB,EAAE,cAAc,WAAW,CAAC,EAAE;IAClF,sCAAsC,KAAK,UAAU,QAAQ,YAAY,KAAK,EAAE;IAChF,uBAAuB,KAAK,UAAU,IAAI,EAAE;GAC9C,EAAE,KAAK,MAAM,CACf;GAEA,QAAQ,IAAI,MAAM,sBAAsB;GACxC,cAAc,GAAG,IAAI,cAAc,gBAAgB,SAAS,CAAC;GAC7D,cACE,GAAG,IAAI,YACP,WAAW,UAAU,mBAAmB,SAAS,IAAI,kBAAkB,SAAS,CAClF;EACF;EAEA,UAAU,EAIR,YAAY,WAAW,QACzB;CACF;AACF"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/adapter/index.ts"],"sourcesContent":["/**\n * Effect deployment adapter for SvelteKit.\n *\n * Like `@sveltejs/adapter-node`, but the production server is an\n * `effect/http` HTTP server: requests are handled by an Effect HTTP\n * handler, configuration is read through `Config`, and startup/shutdown is\n * managed by Effect layers and scopes (SIGINT/SIGTERM trigger a graceful\n * shutdown that runs all finalizers).\n *\n * ```js\n * // svelte.config.js\n * import adapter from \"@thomasfosterau/effect-sveltekit/adapter\";\n *\n * const config = {\n * kit: { adapter: adapter() },\n * };\n *\n * export default config;\n * ```\n *\n * The build output (`build/` by default) contains:\n *\n * - `index.js` — runs the production server: `node build`\n * - `handler.js` — exports the SvelteKit app as a composable Effect HTTP\n * handler, for mounting inside an existing `effect/http` server\n * - `client/`, `server/`, `prerendered/`, `manifest.js` — the built app\n *\n * Unlike `adapter-node`, the server output is not bundled: the deployment\n * needs `node_modules` with the app's production dependencies installed\n * (including `@thomasfosterau/effect-sveltekit`, `effect`, and\n * `@effect/platform-node`).\n */\n\nimport { writeFileSync } from \"node:fs\";\nimport type { Adapter } from \"@sveltejs/kit\";\n\nexport interface EffectAdapterOptions {\n /**\n * The directory to write the production build to.\n * @default \"build\"\n */\n readonly out?: string;\n /**\n * Precompress static assets and prerendered pages with gzip and brotli.\n * @default true\n */\n readonly precompress?: boolean;\n /**\n * Prefix for the environment variables the production server reads\n * (`PORT`, `HOST`, `ORIGIN`, `PROTOCOL_HEADER`, `HOST_HEADER`,\n * `PORT_HEADER`, `ADDRESS_HEADER`, `XFF_DEPTH`).\n * @default \"\"\n */\n readonly envPrefix?: string;\n /**\n * The deployment target for the generated entry:\n *\n * - `\"node\"` (default) — a production Node HTTP server (`node build`) on\n * `@effect/platform-node`, serving assets from disk.\n * - `\"fetch\"` — a Web `fetch` handler suitable for Cloudflare Workers\n * (`build/index.js` exports `default { fetch }`), serving assets from the\n * `env.ASSETS` binding via `AssetSource.cloudflareAssets`.\n *\n * Both targets also write `build/handler.js` (the SvelteKit `HttpApp`), so you\n * can compose your own entry for any `effect/http` runtime.\n *\n * @default \"node\"\n */\n readonly target?: \"node\" | \"fetch\";\n}\n\nconst PACKAGE = \"@thomasfosterau/effect-sveltekit\";\n\n/** Template for the generated `<out>/handler.js`. */\nconst handlerTemplate = (envPrefix: string): string => `\\\nimport { dirname } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport process from \"node:process\";\nimport { makeHandler } from \"${PACKAGE}/adapter/handler\";\nimport { Server } from \"./server/index.js\";\nimport { manifest, prerendered, base } from \"./manifest.js\";\n\nconst dir = dirname(fileURLToPath(import.meta.url));\n\n/**\n * The SvelteKit application as a composable Effect HTTP handler.\n *\n * Serve it with the generated index.js, or mount it inside any\n * \\`effect/http\\` HTTP server.\n */\nexport const handler = makeHandler({\n Server,\n manifest,\n prerendered,\n base,\n dir,\n env: process.env,\n envPrefix: ${JSON.stringify(envPrefix)},\n});\n`;\n\n/** Template for the generated Node `<out>/index.js`. */\nconst nodeEntryTemplate = (envPrefix: string): string => `\\\nimport { serve } from \"${PACKAGE}/adapter/serve\";\nimport { handler } from \"./handler.js\";\n\nserve(handler, { envPrefix: ${JSON.stringify(envPrefix)} });\n`;\n\n/**\n * Template for the generated Cloudflare Workers `<out>/index.js`.\n *\n * Exports a module worker (`default { fetch }`). Static client assets and\n * prerendered pages are served from the `ASSETS` binding; everything else is\n * server-side rendered by the SvelteKit `HttpApp`.\n */\nconst fetchEntryTemplate = (envPrefix: string): string => `\\\nimport { Layer } from \"effect\";\nimport { makeHandlerWith, AssetSource, toWebHandler } from \"${PACKAGE}/adapter/handler\";\nimport { Server } from \"./server/index.js\";\nimport { manifest } from \"./manifest.js\";\n\nlet fetchHandler;\n\nexport default {\n /** @param {Request} request @param {Record<string, any>} env @param {any} ctx */\n fetch(request, env, ctx) {\n fetchHandler ??= toWebHandler(\n makeHandlerWith({\n Server,\n manifest,\n env,\n envPrefix: ${JSON.stringify(envPrefix)},\n // Static assets come from the Workers ASSETS binding (configure it to\n // serve the uploaded \\`client/\\` + \\`prerendered/\\` output).\n assets: AssetSource.cloudflareAssets(env.ASSETS),\n // \\`read()\\` from \\`$app/server\\` is not backed by a file system on workerd.\n read: (file) => {\n throw new Error(\\`read() is not supported on this deployment (\\${file})\\`);\n },\n }),\n Layer.empty,\n );\n return fetchHandler(request);\n },\n};\n`;\n\n/**\n * Creates the Effect SvelteKit adapter.\n */\nexport function effectAdapter(options: EffectAdapterOptions = {}): Adapter {\n const { out = \"build\", precompress = true, envPrefix = \"\", target = \"node\" } = options;\n\n return {\n name: `${PACKAGE}/adapter`,\n\n async adapt(builder) {\n const base = builder.config.kit.paths.base;\n\n builder.rimraf(out);\n builder.mkdirp(out);\n\n builder.log.minor(\"Copying assets\");\n builder.writeClient(`${out}/client${base}`);\n builder.writePrerendered(`${out}/prerendered${base}`);\n\n if (precompress) {\n builder.log.minor(\"Compressing assets\");\n await Promise.all([\n builder.compress(`${out}/client`),\n builder.compress(`${out}/prerendered`),\n ]);\n }\n\n builder.log.minor(\"Building server\");\n builder.writeServer(`${out}/server`);\n\n writeFileSync(\n `${out}/manifest.js`,\n [\n `export const manifest = ${builder.generateManifest({ relativePath: \"./server\" })};`,\n `export const prerendered = new Set(${JSON.stringify(builder.prerendered.paths)});`,\n `export const base = ${JSON.stringify(base)};`,\n ].join(\"\\n\\n\"),\n );\n\n builder.log.minor(\"Writing server entry\");\n writeFileSync(`${out}/handler.js`, handlerTemplate(envPrefix));\n writeFileSync(\n `${out}/index.js`,\n target === \"fetch\" ? fetchEntryTemplate(envPrefix) : nodeEntryTemplate(envPrefix),\n );\n },\n\n supports: {\n // On Node, `read()` from `$app/server` is backed by the platform\n // FileSystem. On the `fetch` (Workers) target it has no file system, so\n // routes using `read()` are unsupported there.\n read: () => target !== \"fetch\",\n },\n };\n}\n\nexport default effectAdapter;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuEA,MAAM,UAAU;;AAGhB,MAAM,mBAAmB,cAA8B;;;;+BAIxB,QAAQ;;;;;;;;;;;;;;;;;;;eAmBxB,KAAK,UAAU,SAAS,EAAE;;;;AAKzC,MAAM,qBAAqB,cAA8B;yBAChC,QAAQ;;;8BAGH,KAAK,UAAU,SAAS,EAAE;;;;;;;;;AAUxD,MAAM,sBAAsB,cAA8B;;8DAEI,QAAQ;;;;;;;;;;;;;;qBAcjD,KAAK,UAAU,SAAS,EAAE;;;;;;;;;;;;;;;;;;AAmB/C,SAAgB,cAAc,UAAgC,CAAC,GAAY;CACzE,MAAM,EAAE,MAAM,SAAS,cAAc,MAAM,YAAY,IAAI,SAAS,WAAW;CAE/E,OAAO;EACL,MAAM,GAAG,QAAQ;EAEjB,MAAM,MAAM,SAAS;GACnB,MAAM,OAAO,QAAQ,OAAO,IAAI,MAAM;GAEtC,QAAQ,OAAO,GAAG;GAClB,QAAQ,OAAO,GAAG;GAElB,QAAQ,IAAI,MAAM,gBAAgB;GAClC,QAAQ,YAAY,GAAG,IAAI,SAAS,MAAM;GAC1C,QAAQ,iBAAiB,GAAG,IAAI,cAAc,MAAM;GAEpD,IAAI,aAAa;IACf,QAAQ,IAAI,MAAM,oBAAoB;IACtC,MAAM,QAAQ,IAAI,CAChB,QAAQ,SAAS,GAAG,IAAI,QAAQ,GAChC,QAAQ,SAAS,GAAG,IAAI,aAAa,CACvC,CAAC;GACH;GAEA,QAAQ,IAAI,MAAM,iBAAiB;GACnC,QAAQ,YAAY,GAAG,IAAI,QAAQ;GAEnC,cACE,GAAG,IAAI,eACP;IACE,2BAA2B,QAAQ,iBAAiB,EAAE,cAAc,WAAW,CAAC,EAAE;IAClF,sCAAsC,KAAK,UAAU,QAAQ,YAAY,KAAK,EAAE;IAChF,uBAAuB,KAAK,UAAU,IAAI,EAAE;GAC9C,CAAC,CAAC,KAAK,MAAM,CACf;GAEA,QAAQ,IAAI,MAAM,sBAAsB;GACxC,cAAc,GAAG,IAAI,cAAc,gBAAgB,SAAS,CAAC;GAC7D,cACE,GAAG,IAAI,YACP,WAAW,UAAU,mBAAmB,SAAS,IAAI,kBAAkB,SAAS,CAClF;EACF;EAEA,UAAU,EAIR,YAAY,WAAW,QACzB;CACF;AACF"}
@@ -1,7 +1,6 @@
1
1
  import { SvelteKitHttpApp } from "./handler.js";
2
2
  import { Effect, Layer } from "effect";
3
3
  import * as NodeHttpServer from "@effect/platform-node/NodeHttpServer";
4
-
5
4
  //#region src/adapter/serve.d.ts
6
5
  interface ServeOptions {
7
6
  /** Prefix for the configuration environment variables (PORT, HOST, ...). */
@@ -1,7 +1,7 @@
1
1
  import { Config, Effect, Layer } from "effect";
2
2
  import { createServer } from "node:http";
3
- import * as HttpMiddleware from "effect/unstable/http/HttpMiddleware";
4
- import * as HttpServer from "effect/unstable/http/HttpServer";
3
+ import * as HttpMiddleware from "effect/http/HttpMiddleware";
4
+ import * as HttpServer from "effect/http/HttpServer";
5
5
  import * as NodeHttpServer from "@effect/platform-node/NodeHttpServer";
6
6
  import * as NodeRuntime from "@effect/platform-node/NodeRuntime";
7
7
  //#region src/adapter/serve.ts
@@ -28,8 +28,8 @@ const layer = (handler, options = {}) => {
28
28
  const prefix = options.envPrefix ?? "";
29
29
  const serveLayer = Layer.unwrap(Effect.map(handler, (app) => options.disableLogger ? HttpServer.serve(app) : HttpServer.serve(app, HttpMiddleware.logger)));
30
30
  const listenLayer = NodeHttpServer.layerConfig(createServer, {
31
- port: Config.int(`${prefix}PORT`).pipe(Config.withDefault(3e3)),
32
- host: Config.string(`${prefix}HOST`).pipe(Config.withDefault("0.0.0.0"))
31
+ port: Config.Int(`${prefix}PORT`).pipe(Config.withDefault(3e3)),
32
+ host: Config.String(`${prefix}HOST`).pipe(Config.withDefault("0.0.0.0"))
33
33
  });
34
34
  const withListener = serveLayer.pipe(HttpServer.withLogAddress, Layer.provide(listenLayer));
35
35
  return options.layer ? Layer.merge(withListener, options.layer) : withListener;
@@ -1 +1 @@
1
- {"version":3,"file":"serve.js","names":[],"sources":["../../src/adapter/serve.ts"],"sourcesContent":["/**\n * Production server entry for the Effect SvelteKit adapter.\n *\n * The adapter's generated `build/index.js` calls {@link serve} with the\n * handler from `build/handler.js`. The server runs on\n * `@effect/platform-node`'s `NodeHttpServer`, with configuration read from\n * the environment and graceful shutdown handled by Effect scopes.\n *\n * For full control (custom layers, tracing, additional routes), skip the\n * generated entry and compose {@link layer} — or the handler itself — into\n * your own Effect application.\n */\n\nimport { createServer } from \"node:http\";\nimport * as HttpMiddleware from \"effect/unstable/http/HttpMiddleware\";\nimport * as HttpServer from \"effect/unstable/http/HttpServer\";\nimport * as NodeHttpServer from \"@effect/platform-node/NodeHttpServer\";\nimport * as NodeRuntime from \"@effect/platform-node/NodeRuntime\";\nimport { Config, Effect, Layer } from \"effect\";\nimport type { SvelteKitHttpApp } from \"./handler.js\";\n\nexport interface ServeOptions {\n /** Prefix for the configuration environment variables (PORT, HOST, ...). */\n readonly envPrefix?: string;\n /**\n * Additional layer merged into the server context, e.g. tracing or logging\n * layers.\n */\n readonly layer?: Layer.Layer<never, never>;\n /**\n * Disable the default request logger middleware.\n */\n readonly disableLogger?: boolean;\n}\n\n/**\n * Builds the full server layer for a SvelteKit HttpApp: HTTP listener\n * (`PORT` / `HOST` environment variables), request logging, and the\n * platform services the handler needs.\n *\n * Launch it with `Layer.launch`, or merge it into a larger application.\n */\nexport const layer = (\n handler: Effect.Effect<SvelteKitHttpApp, never, NodeHttpServerServices>,\n options: ServeOptions = {},\n): Layer.Layer<never, unknown> => {\n const prefix = options.envPrefix ?? \"\";\n\n const serveLayer = Layer.unwrap(\n Effect.map(handler, (app) =>\n options.disableLogger ? HttpServer.serve(app) : HttpServer.serve(app, HttpMiddleware.logger),\n ),\n );\n\n const listenLayer = NodeHttpServer.layerConfig(createServer, {\n port: Config.int(`${prefix}PORT`).pipe(Config.withDefault(3000)),\n host: Config.string(`${prefix}HOST`).pipe(Config.withDefault(\"0.0.0.0\")),\n });\n\n const withListener = serveLayer.pipe(HttpServer.withLogAddress, Layer.provide(listenLayer));\n\n return options.layer ? Layer.merge(withListener, options.layer) : withListener;\n};\n\n/** The services provided to the handler effect by `NodeHttpServer.layerConfig`. */\ntype NodeHttpServerServices = Layer.Success<ReturnType<typeof NodeHttpServer.layerConfig>>;\n\n/**\n * Starts the production server and runs it until the process receives\n * SIGINT/SIGTERM, at which point the server (and every Effect resource) is\n * shut down gracefully.\n *\n * @example\n * ```ts\n * // build/index.js (generated by the adapter)\n * import { handler } from \"./handler.js\";\n * import { serve } from \"@thomasfosterau/effect-sveltekit/adapter/serve\";\n *\n * serve(handler);\n * ```\n */\nexport const serve = (\n handler: Effect.Effect<SvelteKitHttpApp, never, NodeHttpServerServices>,\n options: ServeOptions = {},\n): void => {\n NodeRuntime.runMain(Layer.launch(layer(handler, options)));\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AA0CA,MAAa,SACX,SACA,UAAwB,CAAC,MACO;CAChC,MAAM,SAAS,QAAQ,aAAa;CAEpC,MAAM,aAAa,MAAM,OACvB,OAAO,IAAI,UAAU,QACnB,QAAQ,gBAAgB,WAAW,MAAM,GAAG,IAAI,WAAW,MAAM,KAAK,eAAe,MAAM,CAC7F,CACF;CAEA,MAAM,cAAc,eAAe,YAAY,cAAc;EAC3D,MAAM,OAAO,IAAI,GAAG,OAAO,KAAK,EAAE,KAAK,OAAO,YAAY,GAAI,CAAC;EAC/D,MAAM,OAAO,OAAO,GAAG,OAAO,KAAK,EAAE,KAAK,OAAO,YAAY,SAAS,CAAC;CACzE,CAAC;CAED,MAAM,eAAe,WAAW,KAAK,WAAW,gBAAgB,MAAM,QAAQ,WAAW,CAAC;CAE1F,OAAO,QAAQ,QAAQ,MAAM,MAAM,cAAc,QAAQ,KAAK,IAAI;AACpE;;;;;;;;;;;;;;;AAmBA,MAAa,SACX,SACA,UAAwB,CAAC,MAChB;CACT,YAAY,QAAQ,MAAM,OAAO,MAAM,SAAS,OAAO,CAAC,CAAC;AAC3D"}
1
+ {"version":3,"file":"serve.js","names":[],"sources":["../../src/adapter/serve.ts"],"sourcesContent":["/**\n * Production server entry for the Effect SvelteKit adapter.\n *\n * The adapter's generated `build/index.js` calls {@link serve} with the\n * handler from `build/handler.js`. The server runs on\n * `@effect/platform-node`'s `NodeHttpServer`, with configuration read from\n * the environment and graceful shutdown handled by Effect scopes.\n *\n * For full control (custom layers, tracing, additional routes), skip the\n * generated entry and compose {@link layer} — or the handler itself — into\n * your own Effect application.\n */\n\nimport { createServer } from \"node:http\";\nimport * as HttpMiddleware from \"effect/http/HttpMiddleware\";\nimport * as HttpServer from \"effect/http/HttpServer\";\nimport * as NodeHttpServer from \"@effect/platform-node/NodeHttpServer\";\nimport * as NodeRuntime from \"@effect/platform-node/NodeRuntime\";\nimport { Config, Effect, Layer } from \"effect\";\nimport type { SvelteKitHttpApp } from \"./handler.js\";\n\nexport interface ServeOptions {\n /** Prefix for the configuration environment variables (PORT, HOST, ...). */\n readonly envPrefix?: string;\n /**\n * Additional layer merged into the server context, e.g. tracing or logging\n * layers.\n */\n readonly layer?: Layer.Layer<never, never>;\n /**\n * Disable the default request logger middleware.\n */\n readonly disableLogger?: boolean;\n}\n\n/**\n * Builds the full server layer for a SvelteKit HttpApp: HTTP listener\n * (`PORT` / `HOST` environment variables), request logging, and the\n * platform services the handler needs.\n *\n * Launch it with `Layer.launch`, or merge it into a larger application.\n */\nexport const layer = (\n handler: Effect.Effect<SvelteKitHttpApp, never, NodeHttpServerServices>,\n options: ServeOptions = {},\n): Layer.Layer<never, unknown> => {\n const prefix = options.envPrefix ?? \"\";\n\n const serveLayer = Layer.unwrap(\n Effect.map(handler, (app) =>\n options.disableLogger ? HttpServer.serve(app) : HttpServer.serve(app, HttpMiddleware.logger),\n ),\n );\n\n const listenLayer = NodeHttpServer.layerConfig(createServer, {\n port: Config.Int(`${prefix}PORT`).pipe(Config.withDefault(3000)),\n host: Config.String(`${prefix}HOST`).pipe(Config.withDefault(\"0.0.0.0\")),\n });\n\n const withListener = serveLayer.pipe(HttpServer.withLogAddress, Layer.provide(listenLayer));\n\n return options.layer ? Layer.merge(withListener, options.layer) : withListener;\n};\n\n/** The services provided to the handler effect by `NodeHttpServer.layerConfig`. */\ntype NodeHttpServerServices = Layer.Success<ReturnType<typeof NodeHttpServer.layerConfig>>;\n\n/**\n * Starts the production server and runs it until the process receives\n * SIGINT/SIGTERM, at which point the server (and every Effect resource) is\n * shut down gracefully.\n *\n * @example\n * ```ts\n * // build/index.js (generated by the adapter)\n * import { handler } from \"./handler.js\";\n * import { serve } from \"@thomasfosterau/effect-sveltekit/adapter/serve\";\n *\n * serve(handler);\n * ```\n */\nexport const serve = (\n handler: Effect.Effect<SvelteKitHttpApp, never, NodeHttpServerServices>,\n options: ServeOptions = {},\n): void => {\n NodeRuntime.runMain(Layer.launch(layer(handler, options)));\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AA0CA,MAAa,SACX,SACA,UAAwB,CAAC,MACO;CAChC,MAAM,SAAS,QAAQ,aAAa;CAEpC,MAAM,aAAa,MAAM,OACvB,OAAO,IAAI,UAAU,QACnB,QAAQ,gBAAgB,WAAW,MAAM,GAAG,IAAI,WAAW,MAAM,KAAK,eAAe,MAAM,CAC7F,CACF;CAEA,MAAM,cAAc,eAAe,YAAY,cAAc;EAC3D,MAAM,OAAO,IAAI,GAAG,OAAO,KAAK,CAAC,CAAC,KAAK,OAAO,YAAY,GAAI,CAAC;EAC/D,MAAM,OAAO,OAAO,GAAG,OAAO,KAAK,CAAC,CAAC,KAAK,OAAO,YAAY,SAAS,CAAC;CACzE,CAAC;CAED,MAAM,eAAe,WAAW,KAAK,WAAW,gBAAgB,MAAM,QAAQ,WAAW,CAAC;CAE1F,OAAO,QAAQ,QAAQ,MAAM,MAAM,cAAc,QAAQ,KAAK,IAAI;AACpE;;;;;;;;;;;;;;;AAmBA,MAAa,SACX,SACA,UAAwB,CAAC,MAChB;CACT,YAAY,QAAQ,MAAM,OAAO,MAAM,SAAS,OAAO,CAAC,CAAC;AAC3D"}
@@ -1,9 +1,8 @@
1
1
  import { Effect } from "effect";
2
- import * as HttpClient from "effect/unstable/http/HttpClient";
3
- import * as HttpApiClient from "effect/unstable/httpapi/HttpApiClient";
4
- import * as HttpApi from "effect/unstable/httpapi/HttpApi";
5
- import * as HttpApiGroup from "effect/unstable/httpapi/HttpApiGroup";
6
-
2
+ import * as HttpClient from "effect/http/HttpClient";
3
+ import * as HttpApiClient from "effect/http-api/HttpApiClient";
4
+ import * as HttpApi from "effect/http-api/HttpApi";
5
+ import * as HttpApiGroup from "effect/http-api/HttpApiGroup";
7
6
  //#region src/api-client.d.ts
8
7
  /** Options for {@link apiClient}. */
9
8
  interface ApiClientOptions {
@@ -26,7 +25,7 @@ interface ApiClientOptions {
26
25
  * via `FetchHttpClient`. Yields the client from an `Effect`; the only remaining
27
26
  * requirement is any client middleware the API declares.
28
27
  */
29
- declare const apiClient: <ApiId extends string, Groups extends HttpApiGroup.Any>(api: HttpApi.HttpApi<ApiId, Groups>, options?: ApiClientOptions) => Effect.Effect<HttpApiClient.Client<Groups>, never, HttpApiGroup.MiddlewareClient<Groups>>;
28
+ declare const apiClient: <ApiId extends string, Groups extends HttpApiGroup.Constraint>(api: HttpApi.HttpApi<ApiId, Groups>, options?: ApiClientOptions) => Effect.Effect<HttpApiClient.Client<Groups>, never, HttpApiGroup.MiddlewareClient<Groups>>;
30
29
  //#endregion
31
30
  export { ApiClientOptions, apiClient };
32
31
  //# sourceMappingURL=api-client.d.ts.map