@thomasfosterau/effect-sveltekit 0.0.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 (77) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +66 -0
  3. package/dist/Hooks.d.ts +33 -0
  4. package/dist/Hooks.js +34 -0
  5. package/dist/Hooks.js.map +1 -0
  6. package/dist/Navigation.d.ts +110 -0
  7. package/dist/Navigation.js +155 -0
  8. package/dist/Navigation.js.map +1 -0
  9. package/dist/Remote.d.ts +52 -0
  10. package/dist/Remote.js +67 -0
  11. package/dist/Remote.js.map +1 -0
  12. package/dist/State.d.ts +17 -0
  13. package/dist/State.js +65 -0
  14. package/dist/State.js.map +1 -0
  15. package/dist/_virtual/_rolldown/runtime.js +13 -0
  16. package/dist/adapter/handler.d.ts +67 -0
  17. package/dist/adapter/handler.js +158 -0
  18. package/dist/adapter/handler.js.map +1 -0
  19. package/dist/adapter/index.d.ts +29 -0
  20. package/dist/adapter/index.js +105 -0
  21. package/dist/adapter/index.js.map +1 -0
  22. package/dist/adapter/serve.d.ts +46 -0
  23. package/dist/adapter/serve.js +57 -0
  24. package/dist/adapter/serve.js.map +1 -0
  25. package/dist/app-runtime.d.ts +212 -0
  26. package/dist/app-runtime.js +173 -0
  27. package/dist/app-runtime.js.map +1 -0
  28. package/dist/client/Hooks.d.ts +48 -0
  29. package/dist/client/Hooks.js +61 -0
  30. package/dist/client/Hooks.js.map +1 -0
  31. package/dist/client.d.ts +6 -0
  32. package/dist/client.js +6 -0
  33. package/dist/config.d.ts +17 -0
  34. package/dist/config.js +51 -0
  35. package/dist/config.js.map +1 -0
  36. package/dist/index.d.ts +6 -0
  37. package/dist/index.js +6 -0
  38. package/dist/internal/app-state.d.ts +39 -0
  39. package/dist/internal/app-state.js +52 -0
  40. package/dist/internal/app-state.js.map +1 -0
  41. package/dist/internal/auto.d.ts +70 -0
  42. package/dist/internal/auto.js +161 -0
  43. package/dist/internal/auto.js.map +1 -0
  44. package/dist/internal/default-runtime.js +21 -0
  45. package/dist/internal/default-runtime.js.map +1 -0
  46. package/dist/internal/error.js +31 -0
  47. package/dist/internal/error.js.map +1 -0
  48. package/dist/internal/navigation-events.js +41 -0
  49. package/dist/internal/navigation-events.js.map +1 -0
  50. package/dist/remote-reactive.d.ts +38 -0
  51. package/dist/remote-reactive.js +44 -0
  52. package/dist/remote-reactive.js.map +1 -0
  53. package/dist/remote.server.d.ts +48 -0
  54. package/dist/remote.server.js +90 -0
  55. package/dist/remote.server.js.map +1 -0
  56. package/dist/runtime.d.ts +130 -0
  57. package/dist/runtime.js +143 -0
  58. package/dist/runtime.js.map +1 -0
  59. package/dist/server/Endpoint.d.ts +101 -0
  60. package/dist/server/Endpoint.js +109 -0
  61. package/dist/server/Endpoint.js.map +1 -0
  62. package/dist/server/Hooks.d.ts +97 -0
  63. package/dist/server/Hooks.js +108 -0
  64. package/dist/server/Hooks.js.map +1 -0
  65. package/dist/server.d.ts +108 -0
  66. package/dist/server.js +131 -0
  67. package/dist/server.js.map +1 -0
  68. package/dist/transport.d.ts +23 -0
  69. package/dist/transport.js +34 -0
  70. package/dist/transport.js.map +1 -0
  71. package/dist/universal.d.ts +35 -0
  72. package/dist/universal.js +36 -0
  73. package/dist/universal.js.map +1 -0
  74. package/dist/vite.d.ts +42 -0
  75. package/dist/vite.js +242 -0
  76. package/dist/vite.js.map +1 -0
  77. package/package.json +101 -0
@@ -0,0 +1,90 @@
1
+ import { SvelteKitRuntime } from "./runtime.js";
2
+ import "effect";
3
+ import "effect/unstable/http/HttpClient";
4
+ import * as AppServer from "$app/server";
5
+ //#region src/remote.server.ts
6
+ function runRemoteEffect(effect) {
7
+ const event = AppServer.getRequestEvent();
8
+ return SvelteKitRuntime.forRequest(event).runPromise(effect);
9
+ }
10
+ function unavailable(name) {
11
+ throw new Error(`${name} is not available in the installed SvelteKit version. Update @sveltejs/kit to use this API.`);
12
+ }
13
+ /**
14
+ * Detects a Standard Schema validator via its `~standard` marker property.
15
+ *
16
+ * This cannot be a simple `typeof value === "function"` check on the handler
17
+ * position: some Standard Schema implementations (such as Effect's
18
+ * `Schema.toStandardSchemaV1`) return callable class values, which would be
19
+ * mistaken for handler functions.
20
+ */
21
+ const isStandardSchema = (value) => value !== null && (typeof value === "object" || typeof value === "function") && "~standard" in value;
22
+ /** True when the argument is the no-validation handler overload. */
23
+ const isBareHandler = (value) => typeof value === "function" && !isStandardSchema(value);
24
+ function query(arg1, arg2) {
25
+ if (isBareHandler(arg1)) {
26
+ const handler = arg1;
27
+ return AppServer.query(() => runRemoteEffect(handler()));
28
+ }
29
+ if (!arg2) throw new Error("query requires a handler function when a schema is provided");
30
+ return AppServer.query(arg1, (arg) => runRemoteEffect(arg2(arg)));
31
+ }
32
+ function queryBatch(validate, fn) {
33
+ return AppServer.query.batch(validate, (args) => runRemoteEffect(fn(args)));
34
+ }
35
+ const appServerCompat = AppServer;
36
+ const queryCompat = AppServer.query;
37
+ function getQueryLive() {
38
+ const live = queryCompat.live;
39
+ if (typeof live !== "function") unavailable("query.live");
40
+ return live;
41
+ }
42
+ function getRequested() {
43
+ const requestedFn = appServerCompat.requested;
44
+ if (typeof requestedFn !== "function") unavailable("requested");
45
+ return requestedFn;
46
+ }
47
+ function queryLive(validate, fn) {
48
+ return getQueryLive()(validate, (arg) => runRemoteEffect(fn(arg)));
49
+ }
50
+ function form(arg1, arg2) {
51
+ if (isBareHandler(arg1)) {
52
+ const handler = arg1;
53
+ return AppServer.form(() => runRemoteEffect(handler()));
54
+ }
55
+ if (!arg2) throw new Error("form requires a handler function when a schema is provided");
56
+ return AppServer.form(arg1, (data, issue) => runRemoteEffect(arg2(data, issue)));
57
+ }
58
+ function command(arg1, arg2) {
59
+ if (isBareHandler(arg1)) {
60
+ const handler = arg1;
61
+ return AppServer.command(() => runRemoteEffect(handler()));
62
+ }
63
+ if (!arg2) throw new Error("command requires a handler function when a schema is provided");
64
+ return AppServer.command(arg1, (arg) => runRemoteEffect(arg2(arg)));
65
+ }
66
+ function prerender(arg1, arg2, arg3) {
67
+ if (isBareHandler(arg1)) {
68
+ const handler = arg1;
69
+ return AppServer.prerender(() => runRemoteEffect(handler()), arg2);
70
+ }
71
+ if (typeof arg2 !== "function") throw new Error("prerender requires a handler function when a schema is provided");
72
+ return AppServer.prerender(arg1, (arg) => runRemoteEffect(arg2(arg)), arg3);
73
+ }
74
+ function requested(...args) {
75
+ return getRequested()(...args);
76
+ }
77
+ const RemoteFunction = {
78
+ query: Object.assign(query, {
79
+ batch: queryBatch,
80
+ live: queryLive
81
+ }),
82
+ form,
83
+ command,
84
+ prerender,
85
+ requested
86
+ };
87
+ //#endregion
88
+ export { RemoteFunction };
89
+
90
+ //# sourceMappingURL=remote.server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remote.server.js","names":[],"sources":["../src/remote.server.ts"],"sourcesContent":["import * as AppServer from \"$app/server\";\nimport type {\n RemoteCommand,\n RemoteForm,\n RemoteFormInput,\n RemotePrerenderFunction,\n RemoteQueryFunction,\n InvalidField,\n} from \"@sveltejs/kit\";\nimport type { StandardSchemaV1 } from \"@standard-schema/spec\";\nimport * as HttpClient from \"effect/unstable/http/HttpClient\";\nimport { Effect } from \"effect\";\nimport { SvelteKitRuntime, SvelteKitRequestEvent } from \"./runtime.js\";\n\ntype SvelteKitEffectEnv = HttpClient.HttpClient | SvelteKitRequestEvent;\n\nfunction runRemoteEffect<A, E, R extends SvelteKitEffectEnv>(\n effect: Effect.Effect<A, E, R>,\n): Promise<A> {\n const event = AppServer.getRequestEvent();\n const runtime = SvelteKitRuntime.forRequest(event);\n return runtime.runPromise(effect);\n}\n\nfunction unavailable(name: string): never {\n throw new Error(\n `${name} is not available in the installed SvelteKit version. Update @sveltejs/kit to use this API.`,\n );\n}\n\ntype UnknownEffect = Effect.Effect<unknown, unknown, SvelteKitEffectEnv>;\ntype EffectHandler = (arg: unknown) => UnknownEffect;\ntype EffectFormHandler = (data: unknown, issue: unknown) => UnknownEffect;\ntype EffectVoidHandler = () => UnknownEffect;\n\n/**\n * Detects a Standard Schema validator via its `~standard` marker property.\n *\n * This cannot be a simple `typeof value === \"function\"` check on the handler\n * position: some Standard Schema implementations (such as Effect's\n * `Schema.toStandardSchemaV1`) return callable class values, which would be\n * mistaken for handler functions.\n */\nconst isStandardSchema = (value: unknown): value is StandardSchemaV1 =>\n value !== null &&\n (typeof value === \"object\" || typeof value === \"function\") &&\n \"~standard\" in value;\n\n/** True when the argument is the no-validation handler overload. */\nconst isBareHandler = (value: unknown): value is EffectVoidHandler =>\n typeof value === \"function\" && !isStandardSchema(value);\n\nexport function query<Output>(\n fn: () => Effect.Effect<Output, unknown, SvelteKitEffectEnv>,\n): RemoteQueryFunction<void, Output>;\nexport function query<Input, Output>(\n validate: \"unchecked\",\n fn: (arg: Input) => Effect.Effect<Output, unknown, SvelteKitEffectEnv>,\n): RemoteQueryFunction<Input, Output>;\nexport function query<Schema extends StandardSchemaV1, Output>(\n schema: Schema,\n fn: (\n arg: StandardSchemaV1.InferOutput<Schema>,\n ) => Effect.Effect<Output, unknown, SvelteKitEffectEnv>,\n): RemoteQueryFunction<StandardSchemaV1.InferInput<Schema>, Output>;\nexport function query(\n arg1: unknown,\n arg2?: (arg: unknown) => Effect.Effect<unknown, unknown, SvelteKitEffectEnv>,\n): any {\n if (isBareHandler(arg1)) {\n const handler = arg1;\n return AppServer.query(() => runRemoteEffect(handler()));\n }\n\n if (!arg2) {\n throw new Error(\"query requires a handler function when a schema is provided\");\n }\n\n return AppServer.query(arg1 as \"unchecked\", (arg: unknown) => runRemoteEffect(arg2(arg)));\n}\n\nexport function queryBatch<Input, Output>(\n validate: \"unchecked\",\n fn: (\n args: Input[],\n ) => Effect.Effect<(arg: Input, idx: number) => Output, unknown, SvelteKitEffectEnv>,\n): RemoteQueryFunction<Input, Output>;\nexport function queryBatch<Schema extends StandardSchemaV1, Output>(\n schema: Schema,\n fn: (\n args: StandardSchemaV1.InferOutput<Schema>[],\n ) => Effect.Effect<\n (arg: StandardSchemaV1.InferOutput<Schema>, idx: number) => Output,\n unknown,\n SvelteKitEffectEnv\n >,\n): RemoteQueryFunction<StandardSchemaV1.InferInput<Schema>, Output>;\nexport function queryBatch(\n validate: unknown,\n fn: (\n args: unknown[],\n ) => Effect.Effect<(arg: unknown, idx: number) => unknown, unknown, SvelteKitEffectEnv>,\n): any {\n return AppServer.query.batch(validate as \"unchecked\", (args: unknown[]) =>\n runRemoteEffect(fn(args)),\n );\n}\n\ntype QueryLiveFactory = (\n validate: unknown,\n fn: (arg: unknown) => Promise<AsyncIterable<unknown>> | AsyncIterable<unknown>,\n) => unknown;\n\ntype QueryWithCompat = typeof AppServer.query & {\n live?: QueryLiveFactory;\n};\n\ntype AppServerWithCompat = typeof AppServer & {\n requested?: (...args: unknown[]) => unknown;\n};\n\nconst appServerCompat = AppServer as AppServerWithCompat;\nconst queryCompat = AppServer.query as QueryWithCompat;\n\nfunction getQueryLive(): QueryLiveFactory {\n const live = queryCompat.live;\n\n if (typeof live !== \"function\") {\n unavailable(\"query.live\");\n }\n\n return live;\n}\n\nfunction getRequested(): (...args: unknown[]) => unknown {\n const requestedFn = appServerCompat.requested;\n\n if (typeof requestedFn !== \"function\") {\n unavailable(\"requested\");\n }\n\n return requestedFn;\n}\n\nexport function queryLive<Input, Output>(\n validate: \"unchecked\",\n fn: (arg: Input) => Effect.Effect<AsyncIterable<Output>, unknown, SvelteKitEffectEnv>,\n): RemoteQueryFunction<Input, Output>;\nexport function queryLive<Schema extends StandardSchemaV1, Output>(\n schema: Schema,\n fn: (\n arg: StandardSchemaV1.InferOutput<Schema>,\n ) => Effect.Effect<AsyncIterable<Output>, unknown, SvelteKitEffectEnv>,\n): RemoteQueryFunction<StandardSchemaV1.InferInput<Schema>, Output>;\nexport function queryLive(\n validate: unknown,\n fn: (arg: unknown) => Effect.Effect<AsyncIterable<unknown>, unknown, SvelteKitEffectEnv>,\n): any {\n const live = getQueryLive();\n return live(validate, (arg) => runRemoteEffect(fn(arg)));\n}\n\nexport function form<Output>(\n fn: () => Effect.Effect<Output, unknown, SvelteKitEffectEnv>,\n): RemoteForm<void, Output>;\nexport function form<Input extends RemoteFormInput, Output>(\n validate: \"unchecked\",\n fn: (\n data: Input,\n issue: InvalidField<Input>,\n ) => Effect.Effect<Output, unknown, SvelteKitEffectEnv>,\n): RemoteForm<Input, Output>;\nexport function form<Schema extends StandardSchemaV1<RemoteFormInput, Record<string, any>>, Output>(\n validate: Schema,\n fn: (\n data: StandardSchemaV1.InferOutput<Schema>,\n issue: InvalidField<StandardSchemaV1.InferInput<Schema>>,\n ) => Effect.Effect<Output, unknown, SvelteKitEffectEnv>,\n): RemoteForm<StandardSchemaV1.InferInput<Schema>, Output>;\nexport function form(arg1: unknown, arg2?: unknown): any {\n if (isBareHandler(arg1)) {\n const handler = arg1;\n return AppServer.form(() => runRemoteEffect(handler()));\n }\n\n if (!arg2) {\n throw new Error(\"form requires a handler function when a schema is provided\");\n }\n\n return AppServer.form(arg1 as \"unchecked\", (data: unknown, issue: unknown) =>\n runRemoteEffect((arg2 as EffectFormHandler)(data, issue)),\n );\n}\n\nexport function command<Output>(\n fn: () => Effect.Effect<Output, unknown, SvelteKitEffectEnv>,\n): RemoteCommand<void, Output>;\nexport function command<Input, Output>(\n validate: \"unchecked\",\n fn: (arg: Input) => Effect.Effect<Output, unknown, SvelteKitEffectEnv>,\n): RemoteCommand<Input, Output>;\nexport function command<Schema extends StandardSchemaV1, Output>(\n validate: Schema,\n fn: (\n arg: StandardSchemaV1.InferOutput<Schema>,\n ) => Effect.Effect<Output, unknown, SvelteKitEffectEnv>,\n): RemoteCommand<StandardSchemaV1.InferInput<Schema>, Output>;\nexport function command(\n arg1: unknown,\n arg2?: (arg: unknown) => Effect.Effect<unknown, unknown, SvelteKitEffectEnv>,\n): any {\n if (isBareHandler(arg1)) {\n const handler = arg1;\n return AppServer.command(() => runRemoteEffect(handler()));\n }\n\n if (!arg2) {\n throw new Error(\"command requires a handler function when a schema is provided\");\n }\n\n return AppServer.command(arg1 as \"unchecked\", (arg: unknown) => runRemoteEffect(arg2(arg)));\n}\n\nexport function prerender<Output>(\n fn: () => Effect.Effect<Output, unknown, SvelteKitEffectEnv>,\n options?: {\n inputs?: () => Promise<void[]> | void[];\n dynamic?: boolean;\n },\n): RemotePrerenderFunction<void, Output>;\nexport function prerender<Input, Output>(\n validate: \"unchecked\",\n fn: (arg: Input) => Effect.Effect<Output, unknown, SvelteKitEffectEnv>,\n options?: {\n inputs?: () => Promise<Input[]> | Input[];\n dynamic?: boolean;\n },\n): RemotePrerenderFunction<Input, Output>;\nexport function prerender<Schema extends StandardSchemaV1, Output>(\n schema: Schema,\n fn: (\n arg: StandardSchemaV1.InferOutput<Schema>,\n ) => Effect.Effect<Output, unknown, SvelteKitEffectEnv>,\n options?: {\n inputs?: () =>\n | Promise<StandardSchemaV1.InferInput<Schema>[]>\n | StandardSchemaV1.InferInput<Schema>[];\n dynamic?: boolean;\n },\n): RemotePrerenderFunction<StandardSchemaV1.InferInput<Schema>, Output>;\nexport function prerender(\n arg1: unknown,\n arg2?:\n | ((arg: unknown) => Effect.Effect<unknown, unknown, SvelteKitEffectEnv>)\n | {\n inputs?: () => Promise<unknown[]> | unknown[];\n dynamic?: boolean;\n },\n arg3?: {\n inputs?: () => Promise<unknown[]> | unknown[];\n dynamic?: boolean;\n },\n): any {\n if (isBareHandler(arg1)) {\n const handler = arg1;\n return AppServer.prerender(\n () => runRemoteEffect(handler()),\n arg2 as { inputs?: () => Promise<void[]> | void[]; dynamic?: boolean } | undefined,\n );\n }\n\n if (typeof arg2 !== \"function\") {\n throw new Error(\"prerender requires a handler function when a schema is provided\");\n }\n\n return AppServer.prerender(\n arg1 as \"unchecked\",\n (arg: unknown) => runRemoteEffect((arg2 as EffectHandler)(arg)),\n arg3,\n );\n}\n\nexport function requested<Result = unknown>(...args: unknown[]): Result {\n const requestedFn = getRequested();\n return requestedFn(...args) as Result;\n}\n\ntype QueryNamespace = {\n <Output>(\n fn: () => Effect.Effect<Output, unknown, SvelteKitEffectEnv>,\n ): RemoteQueryFunction<void, Output>;\n <Input, Output>(\n validate: \"unchecked\",\n fn: (arg: Input) => Effect.Effect<Output, unknown, SvelteKitEffectEnv>,\n ): RemoteQueryFunction<Input, Output>;\n <Schema extends StandardSchemaV1, Output>(\n schema: Schema,\n fn: (\n arg: StandardSchemaV1.InferOutput<Schema>,\n ) => Effect.Effect<Output, unknown, SvelteKitEffectEnv>,\n ): RemoteQueryFunction<StandardSchemaV1.InferInput<Schema>, Output>;\n batch: typeof queryBatch;\n live: typeof queryLive;\n};\n\nconst queryWithHelpers = Object.assign(query, {\n batch: queryBatch,\n live: queryLive,\n}) as QueryNamespace;\n\nexport const RemoteFunction = {\n query: queryWithHelpers,\n form,\n command,\n prerender,\n requested,\n};\n"],"mappings":";;;;;AAgBA,SAAS,gBACP,QACY;CACZ,MAAM,QAAQ,UAAU,gBAAgB;CAExC,OADgB,iBAAiB,WAAW,KAC/B,EAAE,WAAW,MAAM;AAClC;AAEA,SAAS,YAAY,MAAqB;CACxC,MAAM,IAAI,MACR,GAAG,KAAK,4FACV;AACF;;;;;;;;;AAeA,MAAM,oBAAoB,UACxB,UAAU,SACT,OAAO,UAAU,YAAY,OAAO,UAAU,eAC/C,eAAe;;AAGjB,MAAM,iBAAiB,UACrB,OAAO,UAAU,cAAc,CAAC,iBAAiB,KAAK;AAexD,SAAgB,MACd,MACA,MACK;CACL,IAAI,cAAc,IAAI,GAAG;EACvB,MAAM,UAAU;EAChB,OAAO,UAAU,YAAY,gBAAgB,QAAQ,CAAC,CAAC;CACzD;CAEA,IAAI,CAAC,MACH,MAAM,IAAI,MAAM,6DAA6D;CAG/E,OAAO,UAAU,MAAM,OAAsB,QAAiB,gBAAgB,KAAK,GAAG,CAAC,CAAC;AAC1F;AAkBA,SAAgB,WACd,UACA,IAGK;CACL,OAAO,UAAU,MAAM,MAAM,WAA0B,SACrD,gBAAgB,GAAG,IAAI,CAAC,CAC1B;AACF;AAeA,MAAM,kBAAkB;AACxB,MAAM,cAAc,UAAU;AAE9B,SAAS,eAAiC;CACxC,MAAM,OAAO,YAAY;CAEzB,IAAI,OAAO,SAAS,YAClB,YAAY,YAAY;CAG1B,OAAO;AACT;AAEA,SAAS,eAAgD;CACvD,MAAM,cAAc,gBAAgB;CAEpC,IAAI,OAAO,gBAAgB,YACzB,YAAY,WAAW;CAGzB,OAAO;AACT;AAYA,SAAgB,UACd,UACA,IACK;CAEL,OADa,aACH,EAAE,WAAW,QAAQ,gBAAgB,GAAG,GAAG,CAAC,CAAC;AACzD;AAmBA,SAAgB,KAAK,MAAe,MAAqB;CACvD,IAAI,cAAc,IAAI,GAAG;EACvB,MAAM,UAAU;EAChB,OAAO,UAAU,WAAW,gBAAgB,QAAQ,CAAC,CAAC;CACxD;CAEA,IAAI,CAAC,MACH,MAAM,IAAI,MAAM,4DAA4D;CAG9E,OAAO,UAAU,KAAK,OAAsB,MAAe,UACzD,gBAAiB,KAA2B,MAAM,KAAK,CAAC,CAC1D;AACF;AAeA,SAAgB,QACd,MACA,MACK;CACL,IAAI,cAAc,IAAI,GAAG;EACvB,MAAM,UAAU;EAChB,OAAO,UAAU,cAAc,gBAAgB,QAAQ,CAAC,CAAC;CAC3D;CAEA,IAAI,CAAC,MACH,MAAM,IAAI,MAAM,+DAA+D;CAGjF,OAAO,UAAU,QAAQ,OAAsB,QAAiB,gBAAgB,KAAK,GAAG,CAAC,CAAC;AAC5F;AA6BA,SAAgB,UACd,MACA,MAMA,MAIK;CACL,IAAI,cAAc,IAAI,GAAG;EACvB,MAAM,UAAU;EAChB,OAAO,UAAU,gBACT,gBAAgB,QAAQ,CAAC,GAC/B,IACF;CACF;CAEA,IAAI,OAAO,SAAS,YAClB,MAAM,IAAI,MAAM,iEAAiE;CAGnF,OAAO,UAAU,UACf,OACC,QAAiB,gBAAiB,KAAuB,GAAG,CAAC,GAC9D,IACF;AACF;AAEA,SAAgB,UAA4B,GAAG,MAAyB;CAEtE,OADoB,aACH,EAAE,GAAG,IAAI;AAC5B;AAyBA,MAAa,iBAAiB;CAC5B,OANuB,OAAO,OAAO,OAAO;EAC5C,OAAO;EACP,MAAM;CACR,CAGS;CACP;CACA;CACA;CACA;AACF"}
@@ -0,0 +1,130 @@
1
+ import { Context, Effect, Layer, ManagedRuntime } from "effect";
2
+ import * as HttpClient from "effect/unstable/http/HttpClient";
3
+ import { RequestEvent } from "@sveltejs/kit";
4
+
5
+ //#region src/runtime.d.ts
6
+ declare const SvelteKitRequestEvent_base: Context.ServiceClass<SvelteKitRequestEvent, "SvelteKitRequestEvent", RequestEvent<Record<string, string>, string | null>>;
7
+ /**
8
+ * Service that provides access to the current SvelteKit RequestEvent.
9
+ * This allows Effect code to access request-specific data like cookies, headers, etc.
10
+ */
11
+ declare class SvelteKitRequestEvent extends SvelteKitRequestEvent_base {}
12
+ /**
13
+ * Custom runtime for SvelteKit server-side helpers.
14
+ *
15
+ * This runtime is designed for SvelteKit server-side execution and provides:
16
+ * - HttpClient for making HTTP requests
17
+ * - FetchHttpClient using the platform's fetch implementation
18
+ * - SvelteKitRequestEvent for accessing SvelteKit-specific request data
19
+ *
20
+ * @example
21
+ * ```ts
22
+ * import { SvelteKitRuntime } from '@thomasfosterau/effect-sveltekit/server';
23
+ * import { Effect } from 'effect';
24
+ * import * as HttpClient from 'effect/unstable/http/HttpClient';
25
+ *
26
+ * export const load = (event) => {
27
+ * const runtime = SvelteKitRuntime.forRequest(event);
28
+ * return runtime.runPromise(
29
+ * Effect.gen(function* () {
30
+ * // Access HttpClient from the runtime
31
+ * const client = yield* HttpClient.HttpClient;
32
+ * const response = yield* client.get("https://api.example.com/data");
33
+ * return { data: response };
34
+ * })
35
+ * );
36
+ * };
37
+ * ```
38
+ */
39
+ declare class SvelteKitRuntime {
40
+ /**
41
+ * Creates a layer with platform services for a specific request.
42
+ * This includes FetchHttpClient and access to the RequestEvent.
43
+ *
44
+ * @param event - The SvelteKit RequestEvent
45
+ * @returns A layer providing platform services
46
+ */
47
+ private static createRequestLayer;
48
+ /**
49
+ * Creates a runtime for a specific SvelteKit request.
50
+ * This runtime includes all platform services configured for the request.
51
+ *
52
+ * @param event - The SvelteKit RequestEvent
53
+ * @returns A managed runtime with platform services
54
+ */
55
+ static forRequest(event: RequestEvent): ManagedRuntime.ManagedRuntime<HttpClient.HttpClient | SvelteKitRequestEvent, never>;
56
+ /**
57
+ * Extends the request runtime with additional services.
58
+ *
59
+ * @param event - The SvelteKit RequestEvent
60
+ * @param layer - Additional layer to merge
61
+ * @returns A managed runtime with both platform and custom services
62
+ *
63
+ * @example
64
+ * ```ts
65
+ * import { SvelteKitRuntime } from '@thomasfosterau/effect-sveltekit/server';
66
+ * import { Layer, Context } from 'effect';
67
+ *
68
+ * class Database extends Context.Service<Database, {
69
+ * query: (sql: string) => Effect.Effect<unknown>
70
+ * }>()("Database") {}
71
+ *
72
+ * const dbLayer = Layer.succeed(Database, {
73
+ * query: (sql) => Effect.succeed([])
74
+ * });
75
+ *
76
+ * export const load = (event) => {
77
+ * const runtime = SvelteKitRuntime.extend(event, dbLayer);
78
+ * // Use runtime...
79
+ * };
80
+ * ```
81
+ */
82
+ static extend<R, E>(event: RequestEvent, layer: Layer.Layer<R, E>): ManagedRuntime.ManagedRuntime<R | HttpClient.HttpClient | SvelteKitRequestEvent, E>;
83
+ /**
84
+ * Creates a runtime that provides `HttpClient` backed by the given fetch
85
+ * implementation, without a `SvelteKitRequestEvent`.
86
+ *
87
+ * This is used for universal `load` functions running on the client, where
88
+ * there is no `RequestEvent` but the load event still exposes `fetch`.
89
+ *
90
+ * @param fetchFn - The fetch implementation to back HttpClient with
91
+ * @returns A managed runtime providing HttpClient
92
+ */
93
+ static forFetch(fetchFn: typeof globalThis.fetch): ManagedRuntime.ManagedRuntime<HttpClient.HttpClient, never>;
94
+ /**
95
+ * The base layer for SvelteKit without request-specific services.
96
+ * Use this for effects that don't need access to the request.
97
+ */
98
+ static readonly baseLayer: Layer.Layer<never, never, never>;
99
+ /**
100
+ * Creates a runtime from a custom layer.
101
+ *
102
+ * @param layer - The layer to use for the runtime
103
+ * @returns A managed runtime
104
+ */
105
+ static make<R, E>(layer: Layer.Layer<R, E>): ManagedRuntime.ManagedRuntime<R, E>;
106
+ }
107
+ /**
108
+ * Helper to run an effect with the SvelteKit runtime for a specific request.
109
+ * This automatically sets up and tears down the runtime.
110
+ *
111
+ * @param event - The SvelteKit RequestEvent
112
+ * @param effect - The effect to run
113
+ * @returns A promise with the result
114
+ *
115
+ * @example
116
+ * ```ts
117
+ * import { runWithSvelteKitRuntime } from '@thomasfosterau/effect-sveltekit/server';
118
+ * import { Effect } from 'effect';
119
+ *
120
+ * export const load = async (event) => {
121
+ * return await runWithSvelteKitRuntime(event,
122
+ * Effect.succeed({ message: "Hello!" })
123
+ * );
124
+ * };
125
+ * ```
126
+ */
127
+ declare function runWithSvelteKitRuntime<A, E>(event: RequestEvent, effect: Effect.Effect<A, E, HttpClient.HttpClient | SvelteKitRequestEvent>): Promise<A>;
128
+ //#endregion
129
+ export { SvelteKitRequestEvent, SvelteKitRuntime, runWithSvelteKitRuntime };
130
+ //# sourceMappingURL=runtime.d.ts.map
@@ -0,0 +1,143 @@
1
+ import { Context, Layer, ManagedRuntime } from "effect";
2
+ import * as FetchHttpClient from "effect/unstable/http/FetchHttpClient";
3
+ import "effect/unstable/http/HttpClient";
4
+ //#region src/runtime.ts
5
+ /**
6
+ * Service that provides access to the current SvelteKit RequestEvent.
7
+ * This allows Effect code to access request-specific data like cookies, headers, etc.
8
+ */
9
+ var SvelteKitRequestEvent = class extends Context.Service()("SvelteKitRequestEvent") {};
10
+ /**
11
+ * Custom runtime for SvelteKit server-side helpers.
12
+ *
13
+ * This runtime is designed for SvelteKit server-side execution and provides:
14
+ * - HttpClient for making HTTP requests
15
+ * - FetchHttpClient using the platform's fetch implementation
16
+ * - SvelteKitRequestEvent for accessing SvelteKit-specific request data
17
+ *
18
+ * @example
19
+ * ```ts
20
+ * import { SvelteKitRuntime } from '@thomasfosterau/effect-sveltekit/server';
21
+ * import { Effect } from 'effect';
22
+ * import * as HttpClient from 'effect/unstable/http/HttpClient';
23
+ *
24
+ * export const load = (event) => {
25
+ * const runtime = SvelteKitRuntime.forRequest(event);
26
+ * return runtime.runPromise(
27
+ * Effect.gen(function* () {
28
+ * // Access HttpClient from the runtime
29
+ * const client = yield* HttpClient.HttpClient;
30
+ * const response = yield* client.get("https://api.example.com/data");
31
+ * return { data: response };
32
+ * })
33
+ * );
34
+ * };
35
+ * ```
36
+ */
37
+ var SvelteKitRuntime = class {
38
+ /**
39
+ * Creates a layer with platform services for a specific request.
40
+ * This includes FetchHttpClient and access to the RequestEvent.
41
+ *
42
+ * @param event - The SvelteKit RequestEvent
43
+ * @returns A layer providing platform services
44
+ */
45
+ static createRequestLayer(event) {
46
+ const httpClientLayer = FetchHttpClient.layer.pipe(Layer.provide(Layer.succeed(FetchHttpClient.Fetch, event.fetch)));
47
+ const requestEventLayer = Layer.succeed(SvelteKitRequestEvent, event);
48
+ return Layer.merge(httpClientLayer, requestEventLayer);
49
+ }
50
+ /**
51
+ * Creates a runtime for a specific SvelteKit request.
52
+ * This runtime includes all platform services configured for the request.
53
+ *
54
+ * @param event - The SvelteKit RequestEvent
55
+ * @returns A managed runtime with platform services
56
+ */
57
+ static forRequest(event) {
58
+ return ManagedRuntime.make(this.createRequestLayer(event));
59
+ }
60
+ /**
61
+ * Extends the request runtime with additional services.
62
+ *
63
+ * @param event - The SvelteKit RequestEvent
64
+ * @param layer - Additional layer to merge
65
+ * @returns A managed runtime with both platform and custom services
66
+ *
67
+ * @example
68
+ * ```ts
69
+ * import { SvelteKitRuntime } from '@thomasfosterau/effect-sveltekit/server';
70
+ * import { Layer, Context } from 'effect';
71
+ *
72
+ * class Database extends Context.Service<Database, {
73
+ * query: (sql: string) => Effect.Effect<unknown>
74
+ * }>()("Database") {}
75
+ *
76
+ * const dbLayer = Layer.succeed(Database, {
77
+ * query: (sql) => Effect.succeed([])
78
+ * });
79
+ *
80
+ * export const load = (event) => {
81
+ * const runtime = SvelteKitRuntime.extend(event, dbLayer);
82
+ * // Use runtime...
83
+ * };
84
+ * ```
85
+ */
86
+ static extend(event, layer) {
87
+ return ManagedRuntime.make(Layer.merge(this.createRequestLayer(event), layer));
88
+ }
89
+ /**
90
+ * Creates a runtime that provides `HttpClient` backed by the given fetch
91
+ * implementation, without a `SvelteKitRequestEvent`.
92
+ *
93
+ * This is used for universal `load` functions running on the client, where
94
+ * there is no `RequestEvent` but the load event still exposes `fetch`.
95
+ *
96
+ * @param fetchFn - The fetch implementation to back HttpClient with
97
+ * @returns A managed runtime providing HttpClient
98
+ */
99
+ static forFetch(fetchFn) {
100
+ return ManagedRuntime.make(FetchHttpClient.layer.pipe(Layer.provide(Layer.succeed(FetchHttpClient.Fetch, fetchFn))));
101
+ }
102
+ /**
103
+ * The base layer for SvelteKit without request-specific services.
104
+ * Use this for effects that don't need access to the request.
105
+ */
106
+ static baseLayer = Layer.empty;
107
+ /**
108
+ * Creates a runtime from a custom layer.
109
+ *
110
+ * @param layer - The layer to use for the runtime
111
+ * @returns A managed runtime
112
+ */
113
+ static make(layer) {
114
+ return ManagedRuntime.make(layer);
115
+ }
116
+ };
117
+ /**
118
+ * Helper to run an effect with the SvelteKit runtime for a specific request.
119
+ * This automatically sets up and tears down the runtime.
120
+ *
121
+ * @param event - The SvelteKit RequestEvent
122
+ * @param effect - The effect to run
123
+ * @returns A promise with the result
124
+ *
125
+ * @example
126
+ * ```ts
127
+ * import { runWithSvelteKitRuntime } from '@thomasfosterau/effect-sveltekit/server';
128
+ * import { Effect } from 'effect';
129
+ *
130
+ * export const load = async (event) => {
131
+ * return await runWithSvelteKitRuntime(event,
132
+ * Effect.succeed({ message: "Hello!" })
133
+ * );
134
+ * };
135
+ * ```
136
+ */
137
+ function runWithSvelteKitRuntime(event, effect) {
138
+ return SvelteKitRuntime.forRequest(event).runPromise(effect);
139
+ }
140
+ //#endregion
141
+ export { SvelteKitRequestEvent, SvelteKitRuntime, runWithSvelteKitRuntime };
142
+
143
+ //# sourceMappingURL=runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.js","names":[],"sources":["../src/runtime.ts"],"sourcesContent":["import { Layer, ManagedRuntime, Context, Effect } from \"effect\";\nimport * as HttpClient from \"effect/unstable/http/HttpClient\";\nimport * as FetchHttpClient from \"effect/unstable/http/FetchHttpClient\";\nimport type { RequestEvent } from \"@sveltejs/kit\";\n\n/**\n * Service that provides access to the current SvelteKit RequestEvent.\n * This allows Effect code to access request-specific data like cookies, headers, etc.\n */\nexport class SvelteKitRequestEvent extends Context.Service<SvelteKitRequestEvent, RequestEvent>()(\n \"SvelteKitRequestEvent\",\n) {}\n\n/**\n * Custom runtime for SvelteKit server-side helpers.\n *\n * This runtime is designed for SvelteKit server-side execution and provides:\n * - HttpClient for making HTTP requests\n * - FetchHttpClient using the platform's fetch implementation\n * - SvelteKitRequestEvent for accessing SvelteKit-specific request data\n *\n * @example\n * ```ts\n * import { SvelteKitRuntime } from '@thomasfosterau/effect-sveltekit/server';\n * import { Effect } from 'effect';\n * import * as HttpClient from 'effect/unstable/http/HttpClient';\n *\n * export const load = (event) => {\n * const runtime = SvelteKitRuntime.forRequest(event);\n * return runtime.runPromise(\n * Effect.gen(function* () {\n * // Access HttpClient from the runtime\n * const client = yield* HttpClient.HttpClient;\n * const response = yield* client.get(\"https://api.example.com/data\");\n * return { data: response };\n * })\n * );\n * };\n * ```\n */\nexport class SvelteKitRuntime {\n /**\n * Creates a layer with platform services for a specific request.\n * This includes FetchHttpClient and access to the RequestEvent.\n *\n * @param event - The SvelteKit RequestEvent\n * @returns A layer providing platform services\n */\n private static createRequestLayer(\n event: RequestEvent,\n ): Layer.Layer<HttpClient.HttpClient | SvelteKitRequestEvent> {\n // Provide HttpClient using SvelteKit's fetch\n const httpClientLayer = FetchHttpClient.layer.pipe(\n Layer.provide(Layer.succeed(FetchHttpClient.Fetch, event.fetch)),\n );\n\n // Provide access to the RequestEvent\n const requestEventLayer = Layer.succeed(SvelteKitRequestEvent, event);\n\n return Layer.merge(httpClientLayer, requestEventLayer);\n }\n\n /**\n * Creates a runtime for a specific SvelteKit request.\n * This runtime includes all platform services configured for the request.\n *\n * @param event - The SvelteKit RequestEvent\n * @returns A managed runtime with platform services\n */\n static forRequest(\n event: RequestEvent,\n ): ManagedRuntime.ManagedRuntime<HttpClient.HttpClient | SvelteKitRequestEvent, never> {\n return ManagedRuntime.make(this.createRequestLayer(event));\n }\n\n /**\n * Extends the request runtime with additional services.\n *\n * @param event - The SvelteKit RequestEvent\n * @param layer - Additional layer to merge\n * @returns A managed runtime with both platform and custom services\n *\n * @example\n * ```ts\n * import { SvelteKitRuntime } from '@thomasfosterau/effect-sveltekit/server';\n * import { Layer, Context } from 'effect';\n *\n * class Database extends Context.Service<Database, {\n * query: (sql: string) => Effect.Effect<unknown>\n * }>()(\"Database\") {}\n *\n * const dbLayer = Layer.succeed(Database, {\n * query: (sql) => Effect.succeed([])\n * });\n *\n * export const load = (event) => {\n * const runtime = SvelteKitRuntime.extend(event, dbLayer);\n * // Use runtime...\n * };\n * ```\n */\n static extend<R, E>(\n event: RequestEvent,\n layer: Layer.Layer<R, E>,\n ): ManagedRuntime.ManagedRuntime<R | HttpClient.HttpClient | SvelteKitRequestEvent, E> {\n return ManagedRuntime.make(Layer.merge(this.createRequestLayer(event), layer));\n }\n\n /**\n * Creates a runtime that provides `HttpClient` backed by the given fetch\n * implementation, without a `SvelteKitRequestEvent`.\n *\n * This is used for universal `load` functions running on the client, where\n * there is no `RequestEvent` but the load event still exposes `fetch`.\n *\n * @param fetchFn - The fetch implementation to back HttpClient with\n * @returns A managed runtime providing HttpClient\n */\n static forFetch(\n fetchFn: typeof globalThis.fetch,\n ): ManagedRuntime.ManagedRuntime<HttpClient.HttpClient, never> {\n return ManagedRuntime.make(\n FetchHttpClient.layer.pipe(Layer.provide(Layer.succeed(FetchHttpClient.Fetch, fetchFn))),\n );\n }\n\n /**\n * The base layer for SvelteKit without request-specific services.\n * Use this for effects that don't need access to the request.\n */\n static readonly baseLayer = Layer.empty;\n\n /**\n * Creates a runtime from a custom layer.\n *\n * @param layer - The layer to use for the runtime\n * @returns A managed runtime\n */\n static make<R, E>(layer: Layer.Layer<R, E>): ManagedRuntime.ManagedRuntime<R, E> {\n return ManagedRuntime.make(layer);\n }\n}\n\n/**\n * Helper to run an effect with the SvelteKit runtime for a specific request.\n * This automatically sets up and tears down the runtime.\n *\n * @param event - The SvelteKit RequestEvent\n * @param effect - The effect to run\n * @returns A promise with the result\n *\n * @example\n * ```ts\n * import { runWithSvelteKitRuntime } from '@thomasfosterau/effect-sveltekit/server';\n * import { Effect } from 'effect';\n *\n * export const load = async (event) => {\n * return await runWithSvelteKitRuntime(event,\n * Effect.succeed({ message: \"Hello!\" })\n * );\n * };\n * ```\n */\nexport function runWithSvelteKitRuntime<A, E>(\n event: RequestEvent,\n effect: Effect.Effect<A, E, HttpClient.HttpClient | SvelteKitRequestEvent>,\n): Promise<A> {\n const runtime = SvelteKitRuntime.forRequest(event);\n return runtime.runPromise(effect);\n}\n"],"mappings":";;;;;;;;AASA,IAAa,wBAAb,cAA2C,QAAQ,QAA6C,EAC9F,uBACF,EAAE,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6BH,IAAa,mBAAb,MAA8B;;;;;;;;CAQ5B,OAAe,mBACb,OAC4D;EAE5D,MAAM,kBAAkB,gBAAgB,MAAM,KAC5C,MAAM,QAAQ,MAAM,QAAQ,gBAAgB,OAAO,MAAM,KAAK,CAAC,CACjE;EAGA,MAAM,oBAAoB,MAAM,QAAQ,uBAAuB,KAAK;EAEpE,OAAO,MAAM,MAAM,iBAAiB,iBAAiB;CACvD;;;;;;;;CASA,OAAO,WACL,OACqF;EACrF,OAAO,eAAe,KAAK,KAAK,mBAAmB,KAAK,CAAC;CAC3D;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4BA,OAAO,OACL,OACA,OACqF;EACrF,OAAO,eAAe,KAAK,MAAM,MAAM,KAAK,mBAAmB,KAAK,GAAG,KAAK,CAAC;CAC/E;;;;;;;;;;;CAYA,OAAO,SACL,SAC6D;EAC7D,OAAO,eAAe,KACpB,gBAAgB,MAAM,KAAK,MAAM,QAAQ,MAAM,QAAQ,gBAAgB,OAAO,OAAO,CAAC,CAAC,CACzF;CACF;;;;;CAMA,OAAgB,YAAY,MAAM;;;;;;;CAQlC,OAAO,KAAW,OAA+D;EAC/E,OAAO,eAAe,KAAK,KAAK;CAClC;AACF;;;;;;;;;;;;;;;;;;;;;AAsBA,SAAgB,wBACd,OACA,QACY;CAEZ,OADgB,iBAAiB,WAAW,KAC/B,EAAE,WAAW,MAAM;AAClC"}
@@ -0,0 +1,101 @@
1
+ import { Effect, Layer, Scope } from "effect";
2
+ import { RequestHandler } from "@sveltejs/kit";
3
+ import * as HttpRouter from "effect/unstable/http/HttpRouter";
4
+ import * as HttpServerRequest from "effect/unstable/http/HttpServerRequest";
5
+ import * as HttpServerResponse from "effect/unstable/http/HttpServerResponse";
6
+ import * as HttpApi from "effect/unstable/httpapi/HttpApi";
7
+ import * as HttpApiGroup from "effect/unstable/httpapi/HttpApiGroup";
8
+
9
+ //#region src/server/Endpoint.d.ts
10
+ declare namespace Endpoint_d_exports {
11
+ export { EndpointHandler, EndpointOptions, fromApi, fromHttpEffect, fromRouter };
12
+ }
13
+ /**
14
+ * A SvelteKit endpoint handler — the built-in
15
+ * [`RequestHandler`](https://svelte.dev/docs/kit/@sveltejs-kit#RequestHandler) —
16
+ * backed by an Effect HTTP construct. Assign it to a `+server.ts` export
17
+ * (`fallback`, `GET`, ...). `dispose()` closes the scope of the layer behind it.
18
+ */
19
+ type EndpointHandler = RequestHandler & {
20
+ /** Close the scope of the layer backing the endpoint (runs its finalizers). */readonly dispose: () => Promise<void>;
21
+ };
22
+ /** Shared options for every `Endpoint.from*` helper. */
23
+ interface EndpointOptions {
24
+ /**
25
+ * A leading path segment to strip from each request before it reaches the
26
+ * Effect handler — the SvelteKit mount point. For an endpoint mounted at
27
+ * `src/routes/api/[...path]/+server.ts` whose routes are defined relative to
28
+ * the API root, pass `prefix: "/api"` so `/api/users` is dispatched as
29
+ * `/users`. The match respects path boundaries (`/api` does not strip
30
+ * `/apiary`). Defaults to no stripping.
31
+ */
32
+ readonly prefix?: string;
33
+ }
34
+ /**
35
+ * Create a SvelteKit endpoint that serves an Effect
36
+ * [`HttpApi`](https://effect.website).
37
+ *
38
+ * `layer` implements the API's groups (built with `HttpApiBuilder.group`), with
39
+ * any application services already provided. The platform services an `HttpApi`
40
+ * requires (`HttpPlatform`, `FileSystem`, `Path`, `Etag`) are supplied for you.
41
+ *
42
+ * @example
43
+ * ```ts
44
+ * // src/routes/api/[...path]/+server.ts
45
+ * import { Endpoint } from "@thomasfosterau/effect-sveltekit/server";
46
+ * import { api } from "$lib/server/api";
47
+ * import { ApiLive } from "$lib/server/handlers";
48
+ *
49
+ * export const fallback = Endpoint.fromApi(api, ApiLive, { prefix: "/api" });
50
+ * ```
51
+ */
52
+ declare const fromApi: <Id extends string, Groups extends HttpApiGroup.Any, E>(api: HttpApi.HttpApi<Id, Groups>, layer: Layer.Layer<HttpApiGroup.ToService<Id, Groups>, E>, options?: EndpointOptions & {
53
+ /** Serve the OpenAPI spec for the API at this path (e.g. `"/openapi.json"`). */readonly openapiPath?: `/${string}`; /** Add Effect's request logger middleware. Defaults to `false` (quiet). */
54
+ readonly logger?: boolean;
55
+ }) => EndpointHandler;
56
+ /**
57
+ * Create a SvelteKit endpoint that serves an Effect `HttpRouter` (provided by
58
+ * `layer`). The router's routes must be self-contained (any services they need
59
+ * are provided within `layer`).
60
+ *
61
+ * @example
62
+ * ```ts
63
+ * // src/routes/api/[...path]/+server.ts
64
+ * import { Endpoint } from "@thomasfosterau/effect-sveltekit/server";
65
+ * import { Effect } from "effect";
66
+ * import { HttpRouter, HttpServerResponse } from "effect/unstable/http";
67
+ *
68
+ * const RouterLive = HttpRouter.use((router) =>
69
+ * router.add("GET", "/hello", Effect.succeed(HttpServerResponse.text("hi"))),
70
+ * );
71
+ *
72
+ * export const fallback = Endpoint.fromRouter(RouterLive, { prefix: "/api" });
73
+ * ```
74
+ */
75
+ declare const fromRouter: <A, E, R extends HttpRouter.HttpRouter | HttpRouter.Request<"Requires", any> | HttpRouter.Request<"GlobalRequires", any> | HttpRouter.Request<"Error", any> | HttpRouter.Request<"GlobalError", any>>(layer: Layer.Layer<A, E, R>, options?: EndpointOptions & {
76
+ /** Add Effect's request logger middleware. Defaults to `false` (quiet). */readonly logger?: boolean;
77
+ }) => EndpointHandler;
78
+ /**
79
+ * Create a SvelteKit endpoint from a single Effect HTTP route — an effect
80
+ * producing an `HttpServerResponse` for the current `HttpServerRequest`. Pass
81
+ * `options.layer` to provide the route's services; the layer is built once and
82
+ * shared.
83
+ *
84
+ * @example
85
+ * ```ts
86
+ * // src/routes/health/+server.ts
87
+ * import { Endpoint } from "@thomasfosterau/effect-sveltekit/server";
88
+ * import { Effect } from "effect";
89
+ * import { HttpServerResponse } from "effect/unstable/http";
90
+ *
91
+ * export const GET = Endpoint.fromHttpEffect(
92
+ * Effect.succeed(HttpServerResponse.text("ok")),
93
+ * );
94
+ * ```
95
+ */
96
+ declare const fromHttpEffect: <E, R = never, ProvidedE = never>(effect: Effect.Effect<HttpServerResponse.HttpServerResponse, E, R | HttpServerRequest.HttpServerRequest | Scope.Scope>, options?: EndpointOptions & {
97
+ /** A layer providing the route's services (`R`), built once and shared. */readonly layer?: Layer.Layer<R, ProvidedE>;
98
+ }) => EndpointHandler;
99
+ //#endregion
100
+ export { Endpoint_d_exports };
101
+ //# sourceMappingURL=Endpoint.d.ts.map
@@ -0,0 +1,109 @@
1
+ import { __exportAll } from "../_virtual/_rolldown/runtime.js";
2
+ import { Layer } from "effect";
3
+ import * as FileSystem from "effect/FileSystem";
4
+ import * as Path from "effect/Path";
5
+ import * as Etag from "effect/unstable/http/Etag";
6
+ import * as HttpEffect from "effect/unstable/http/HttpEffect";
7
+ import * as HttpPlatform from "effect/unstable/http/HttpPlatform";
8
+ import * as HttpRouter from "effect/unstable/http/HttpRouter";
9
+ import * as HttpApiBuilder from "effect/unstable/httpapi/HttpApiBuilder";
10
+ //#region src/server/Endpoint.ts
11
+ var Endpoint_exports = /* @__PURE__ */ __exportAll({
12
+ fromApi: () => fromApi,
13
+ fromHttpEffect: () => fromHttpEffect,
14
+ fromRouter: () => fromRouter
15
+ });
16
+ const noopDispose = () => Promise.resolve();
17
+ /** Remove `prefix` from the request's path (respecting `/` boundaries). */
18
+ const stripPrefix = (request, prefix) => {
19
+ const normalized = prefix.endsWith("/") ? prefix.slice(0, -1) : prefix;
20
+ if (normalized === "") return request;
21
+ const url = new URL(request.url);
22
+ const path = url.pathname;
23
+ if (path === normalized) url.pathname = "/";
24
+ else if (path.startsWith(`${normalized}/`)) url.pathname = path.slice(normalized.length);
25
+ else return request;
26
+ return new Request(url, request);
27
+ };
28
+ /** Wrap a Web handler (and its dispose) as a SvelteKit endpoint handler. */
29
+ const make = (webHandler, dispose, prefix) => {
30
+ const handler = (event) => webHandler(prefix === void 0 ? event.request : stripPrefix(event.request, prefix));
31
+ return Object.assign(handler, { dispose });
32
+ };
33
+ /** The platform services an `HttpApi` needs, with a no-op file system. */
34
+ const apiPlatform = Layer.mergeAll(Path.layer, Etag.layerWeak, HttpPlatform.layer).pipe(Layer.provideMerge(FileSystem.layerNoop({})));
35
+ /**
36
+ * Create a SvelteKit endpoint that serves an Effect
37
+ * [`HttpApi`](https://effect.website).
38
+ *
39
+ * `layer` implements the API's groups (built with `HttpApiBuilder.group`), with
40
+ * any application services already provided. The platform services an `HttpApi`
41
+ * requires (`HttpPlatform`, `FileSystem`, `Path`, `Etag`) are supplied for you.
42
+ *
43
+ * @example
44
+ * ```ts
45
+ * // src/routes/api/[...path]/+server.ts
46
+ * import { Endpoint } from "@thomasfosterau/effect-sveltekit/server";
47
+ * import { api } from "$lib/server/api";
48
+ * import { ApiLive } from "$lib/server/handlers";
49
+ *
50
+ * export const fallback = Endpoint.fromApi(api, ApiLive, { prefix: "/api" });
51
+ * ```
52
+ */
53
+ const fromApi = (api, layer, options) => {
54
+ const appLayer = HttpApiBuilder.layer(api, options?.openapiPath ? { openapiPath: options.openapiPath } : void 0).pipe(Layer.provide(layer), Layer.provide(apiPlatform));
55
+ const { handler, dispose } = HttpRouter.toWebHandler(appLayer, { disableLogger: options?.logger !== true });
56
+ return make(handler, dispose, options?.prefix);
57
+ };
58
+ /**
59
+ * Create a SvelteKit endpoint that serves an Effect `HttpRouter` (provided by
60
+ * `layer`). The router's routes must be self-contained (any services they need
61
+ * are provided within `layer`).
62
+ *
63
+ * @example
64
+ * ```ts
65
+ * // src/routes/api/[...path]/+server.ts
66
+ * import { Endpoint } from "@thomasfosterau/effect-sveltekit/server";
67
+ * import { Effect } from "effect";
68
+ * import { HttpRouter, HttpServerResponse } from "effect/unstable/http";
69
+ *
70
+ * const RouterLive = HttpRouter.use((router) =>
71
+ * router.add("GET", "/hello", Effect.succeed(HttpServerResponse.text("hi"))),
72
+ * );
73
+ *
74
+ * export const fallback = Endpoint.fromRouter(RouterLive, { prefix: "/api" });
75
+ * ```
76
+ */
77
+ const fromRouter = (layer, options) => {
78
+ const { handler, dispose } = HttpRouter.toWebHandler(layer, { disableLogger: options?.logger !== true });
79
+ return make(handler, dispose, options?.prefix);
80
+ };
81
+ /**
82
+ * Create a SvelteKit endpoint from a single Effect HTTP route — an effect
83
+ * producing an `HttpServerResponse` for the current `HttpServerRequest`. Pass
84
+ * `options.layer` to provide the route's services; the layer is built once and
85
+ * shared.
86
+ *
87
+ * @example
88
+ * ```ts
89
+ * // src/routes/health/+server.ts
90
+ * import { Endpoint } from "@thomasfosterau/effect-sveltekit/server";
91
+ * import { Effect } from "effect";
92
+ * import { HttpServerResponse } from "effect/unstable/http";
93
+ *
94
+ * export const GET = Endpoint.fromHttpEffect(
95
+ * Effect.succeed(HttpServerResponse.text("ok")),
96
+ * );
97
+ * ```
98
+ */
99
+ const fromHttpEffect = (effect, options) => {
100
+ if (options?.layer) {
101
+ const { handler, dispose } = HttpEffect.toWebHandlerLayer(effect, options.layer);
102
+ return make(handler, dispose, options.prefix);
103
+ }
104
+ return make(HttpEffect.toWebHandler(effect), noopDispose, options?.prefix);
105
+ };
106
+ //#endregion
107
+ export { Endpoint_exports };
108
+
109
+ //# sourceMappingURL=Endpoint.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Endpoint.js","names":[],"sources":["../../src/server/Endpoint.ts"],"sourcesContent":["/**\n * Create SvelteKit server endpoints (`+server.ts`) backed by Effect — the\n * `Endpoint` namespace of `@thomasfosterau/effect-sveltekit/server`.\n *\n * A SvelteKit endpoint is a `RequestHandler` (`(event) => Response`). Effect can\n * turn an [`HttpApi`](https://effect.website), an `HttpRouter`, or a single\n * route effect into a Web `fetch` handler; these helpers wrap one as a SvelteKit\n * endpoint handler so a route can be served by Effect. Mount it on a catch-all\n * route (`[...path]`) and assign it to `fallback` so every method and sub-path\n * reaches it:\n *\n * @example\n * ```ts\n * // src/routes/api/[...path]/+server.ts\n * import { Endpoint } from \"@thomasfosterau/effect-sveltekit/server\";\n * import { api } from \"$lib/server/api\";\n * import { ApiLive } from \"$lib/server/handlers\"; // HttpApiBuilder.group(...) + your services\n *\n * // `prefix` strips the SvelteKit mount path so the API's own paths\n * // (e.g. \"/users\") match.\n * export const fallback = Endpoint.fromApi(api, ApiLive, { prefix: \"/api\" });\n * ```\n *\n * The layer backing an endpoint is built once, lazily, on the first request and\n * shared across subsequent requests (like `makeServerRuntime`). The returned\n * handler carries a `dispose()` that closes the layer's scope — call it on\n * shutdown if the endpoint holds resources.\n *\n * The Effect handlers receive an Effect-native `HttpServerRequest` (built from\n * `event.request`), not the SvelteKit `RequestEvent`.\n */\n\nimport type { RequestHandler } from \"@sveltejs/kit\";\nimport { Layer } from \"effect\";\nimport type { Effect, Scope } from \"effect\";\nimport * as FileSystem from \"effect/FileSystem\";\nimport * as Path from \"effect/Path\";\nimport * as Etag from \"effect/unstable/http/Etag\";\nimport * as HttpEffect from \"effect/unstable/http/HttpEffect\";\nimport * as HttpPlatform from \"effect/unstable/http/HttpPlatform\";\nimport * as HttpRouter from \"effect/unstable/http/HttpRouter\";\nimport type * as HttpServerRequest from \"effect/unstable/http/HttpServerRequest\";\nimport type * as HttpServerResponse from \"effect/unstable/http/HttpServerResponse\";\nimport type * as HttpApi from \"effect/unstable/httpapi/HttpApi\";\nimport * as HttpApiBuilder from \"effect/unstable/httpapi/HttpApiBuilder\";\nimport type * as HttpApiGroup from \"effect/unstable/httpapi/HttpApiGroup\";\n\n/** A Web `fetch`-style handler, as produced by Effect's `toWebHandler` family. */\ntype WebHandler = (request: Request) => Promise<Response>;\n\n/**\n * A SvelteKit endpoint handler — the built-in\n * [`RequestHandler`](https://svelte.dev/docs/kit/@sveltejs-kit#RequestHandler) —\n * backed by an Effect HTTP construct. Assign it to a `+server.ts` export\n * (`fallback`, `GET`, ...). `dispose()` closes the scope of the layer behind it.\n */\nexport type EndpointHandler = RequestHandler & {\n /** Close the scope of the layer backing the endpoint (runs its finalizers). */\n readonly dispose: () => Promise<void>;\n};\n\n/** Shared options for every `Endpoint.from*` helper. */\nexport interface EndpointOptions {\n /**\n * A leading path segment to strip from each request before it reaches the\n * Effect handler — the SvelteKit mount point. For an endpoint mounted at\n * `src/routes/api/[...path]/+server.ts` whose routes are defined relative to\n * the API root, pass `prefix: \"/api\"` so `/api/users` is dispatched as\n * `/users`. The match respects path boundaries (`/api` does not strip\n * `/apiary`). Defaults to no stripping.\n */\n readonly prefix?: string;\n}\n\nconst noopDispose = (): Promise<void> => Promise.resolve();\n\n/** Remove `prefix` from the request's path (respecting `/` boundaries). */\nconst stripPrefix = (request: Request, prefix: string): Request => {\n const normalized = prefix.endsWith(\"/\") ? prefix.slice(0, -1) : prefix;\n if (normalized === \"\") return request;\n\n const url = new URL(request.url);\n const path = url.pathname;\n if (path === normalized) {\n url.pathname = \"/\";\n } else if (path.startsWith(`${normalized}/`)) {\n url.pathname = path.slice(normalized.length);\n } else {\n return request;\n }\n return new Request(url, request);\n};\n\n/** Wrap a Web handler (and its dispose) as a SvelteKit endpoint handler. */\nconst make = (\n webHandler: WebHandler,\n dispose: () => Promise<void>,\n prefix: string | undefined,\n): EndpointHandler => {\n const handler: RequestHandler = (event) =>\n webHandler(prefix === undefined ? event.request : stripPrefix(event.request, prefix));\n return Object.assign(handler, { dispose });\n};\n\n/** The platform services an `HttpApi` needs, with a no-op file system. */\nconst apiPlatform = Layer.mergeAll(Path.layer, Etag.layerWeak, HttpPlatform.layer).pipe(\n Layer.provideMerge(FileSystem.layerNoop({})),\n);\n\n/**\n * Create a SvelteKit endpoint that serves an Effect\n * [`HttpApi`](https://effect.website).\n *\n * `layer` implements the API's groups (built with `HttpApiBuilder.group`), with\n * any application services already provided. The platform services an `HttpApi`\n * requires (`HttpPlatform`, `FileSystem`, `Path`, `Etag`) are supplied for you.\n *\n * @example\n * ```ts\n * // src/routes/api/[...path]/+server.ts\n * import { Endpoint } from \"@thomasfosterau/effect-sveltekit/server\";\n * import { api } from \"$lib/server/api\";\n * import { ApiLive } from \"$lib/server/handlers\";\n *\n * export const fallback = Endpoint.fromApi(api, ApiLive, { prefix: \"/api\" });\n * ```\n */\nexport const fromApi = <Id extends string, Groups extends HttpApiGroup.Any, E>(\n api: HttpApi.HttpApi<Id, Groups>,\n layer: Layer.Layer<HttpApiGroup.ToService<Id, Groups>, E>,\n options?: EndpointOptions & {\n /** Serve the OpenAPI spec for the API at this path (e.g. `\"/openapi.json\"`). */\n readonly openapiPath?: `/${string}`;\n /** Add Effect's request logger middleware. Defaults to `false` (quiet). */\n readonly logger?: boolean;\n },\n): EndpointHandler => {\n const appLayer = HttpApiBuilder.layer(\n api,\n options?.openapiPath ? { openapiPath: options.openapiPath } : undefined,\n ).pipe(Layer.provide(layer), Layer.provide(apiPlatform));\n\n const { handler, dispose } = HttpRouter.toWebHandler(\n appLayer as Layer.Layer<never, E, HttpRouter.HttpRouter>,\n { disableLogger: options?.logger !== true },\n );\n return make(handler, dispose, options?.prefix);\n};\n\n/**\n * Create a SvelteKit endpoint that serves an Effect `HttpRouter` (provided by\n * `layer`). The router's routes must be self-contained (any services they need\n * are provided within `layer`).\n *\n * @example\n * ```ts\n * // src/routes/api/[...path]/+server.ts\n * import { Endpoint } from \"@thomasfosterau/effect-sveltekit/server\";\n * import { Effect } from \"effect\";\n * import { HttpRouter, HttpServerResponse } from \"effect/unstable/http\";\n *\n * const RouterLive = HttpRouter.use((router) =>\n * router.add(\"GET\", \"/hello\", Effect.succeed(HttpServerResponse.text(\"hi\"))),\n * );\n *\n * export const fallback = Endpoint.fromRouter(RouterLive, { prefix: \"/api\" });\n * ```\n */\nexport const fromRouter = <\n A,\n E,\n R extends\n | HttpRouter.HttpRouter\n | HttpRouter.Request<\"Requires\", any>\n | HttpRouter.Request<\"GlobalRequires\", any>\n | HttpRouter.Request<\"Error\", any>\n | HttpRouter.Request<\"GlobalError\", any>,\n>(\n layer: Layer.Layer<A, E, R>,\n options?: EndpointOptions & {\n /** Add Effect's request logger middleware. Defaults to `false` (quiet). */\n readonly logger?: boolean;\n },\n): EndpointHandler => {\n const { handler, dispose } = HttpRouter.toWebHandler(layer, {\n disableLogger: options?.logger !== true,\n });\n return make(handler as WebHandler, dispose, options?.prefix);\n};\n\n/**\n * Create a SvelteKit endpoint from a single Effect HTTP route — an effect\n * producing an `HttpServerResponse` for the current `HttpServerRequest`. Pass\n * `options.layer` to provide the route's services; the layer is built once and\n * shared.\n *\n * @example\n * ```ts\n * // src/routes/health/+server.ts\n * import { Endpoint } from \"@thomasfosterau/effect-sveltekit/server\";\n * import { Effect } from \"effect\";\n * import { HttpServerResponse } from \"effect/unstable/http\";\n *\n * export const GET = Endpoint.fromHttpEffect(\n * Effect.succeed(HttpServerResponse.text(\"ok\")),\n * );\n * ```\n */\nexport const fromHttpEffect = <E, R = never, ProvidedE = never>(\n effect: Effect.Effect<\n HttpServerResponse.HttpServerResponse,\n E,\n R | HttpServerRequest.HttpServerRequest | Scope.Scope\n >,\n options?: EndpointOptions & {\n /** A layer providing the route's services (`R`), built once and shared. */\n readonly layer?: Layer.Layer<R, ProvidedE>;\n },\n): EndpointHandler => {\n if (options?.layer) {\n const { handler, dispose } = HttpEffect.toWebHandlerLayer(effect, options.layer);\n return make(handler as WebHandler, dispose, options.prefix);\n }\n const handler = HttpEffect.toWebHandler(\n effect as Effect.Effect<\n HttpServerResponse.HttpServerResponse,\n E,\n HttpServerRequest.HttpServerRequest | Scope.Scope\n >,\n );\n return make(handler, noopDispose, options?.prefix);\n};\n"],"mappings":";;;;;;;;;;;;;;;AA0EA,MAAM,oBAAmC,QAAQ,QAAQ;;AAGzD,MAAM,eAAe,SAAkB,WAA4B;CACjE,MAAM,aAAa,OAAO,SAAS,GAAG,IAAI,OAAO,MAAM,GAAG,EAAE,IAAI;CAChE,IAAI,eAAe,IAAI,OAAO;CAE9B,MAAM,MAAM,IAAI,IAAI,QAAQ,GAAG;CAC/B,MAAM,OAAO,IAAI;CACjB,IAAI,SAAS,YACX,IAAI,WAAW;MACV,IAAI,KAAK,WAAW,GAAG,WAAW,EAAE,GACzC,IAAI,WAAW,KAAK,MAAM,WAAW,MAAM;MAE3C,OAAO;CAET,OAAO,IAAI,QAAQ,KAAK,OAAO;AACjC;;AAGA,MAAM,QACJ,YACA,SACA,WACoB;CACpB,MAAM,WAA2B,UAC/B,WAAW,WAAW,KAAA,IAAY,MAAM,UAAU,YAAY,MAAM,SAAS,MAAM,CAAC;CACtF,OAAO,OAAO,OAAO,SAAS,EAAE,QAAQ,CAAC;AAC3C;;AAGA,MAAM,cAAc,MAAM,SAAS,KAAK,OAAO,KAAK,WAAW,aAAa,KAAK,EAAE,KACjF,MAAM,aAAa,WAAW,UAAU,CAAC,CAAC,CAAC,CAC7C;;;;;;;;;;;;;;;;;;;AAoBA,MAAa,WACX,KACA,OACA,YAMoB;CACpB,MAAM,WAAW,eAAe,MAC9B,KACA,SAAS,cAAc,EAAE,aAAa,QAAQ,YAAY,IAAI,KAAA,CAChE,EAAE,KAAK,MAAM,QAAQ,KAAK,GAAG,MAAM,QAAQ,WAAW,CAAC;CAEvD,MAAM,EAAE,SAAS,YAAY,WAAW,aACtC,UACA,EAAE,eAAe,SAAS,WAAW,KAAK,CAC5C;CACA,OAAO,KAAK,SAAS,SAAS,SAAS,MAAM;AAC/C;;;;;;;;;;;;;;;;;;;;AAqBA,MAAa,cAUX,OACA,YAIoB;CACpB,MAAM,EAAE,SAAS,YAAY,WAAW,aAAa,OAAO,EAC1D,eAAe,SAAS,WAAW,KACrC,CAAC;CACD,OAAO,KAAK,SAAuB,SAAS,SAAS,MAAM;AAC7D;;;;;;;;;;;;;;;;;;;AAoBA,MAAa,kBACX,QAKA,YAIoB;CACpB,IAAI,SAAS,OAAO;EAClB,MAAM,EAAE,SAAS,YAAY,WAAW,kBAAkB,QAAQ,QAAQ,KAAK;EAC/E,OAAO,KAAK,SAAuB,SAAS,QAAQ,MAAM;CAC5D;CAQA,OAAO,KAPS,WAAW,aACzB,MAMgB,GAAG,aAAa,SAAS,MAAM;AACnD"}