@thomasfosterau/effect-sveltekit 0.6.0 → 0.8.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 (119) hide show
  1. package/README.md +37 -21
  2. package/dist/Hooks.d.ts +3 -3
  3. package/dist/Hooks.js +1 -1
  4. package/dist/Hooks.js.map +1 -1
  5. package/dist/Navigation.d.ts +11 -11
  6. package/dist/Navigation.js +15 -2
  7. package/dist/Navigation.js.map +1 -1
  8. package/dist/Remote.d.ts +18 -17
  9. package/dist/Remote.js +2 -4
  10. package/dist/Remote.js.map +1 -1
  11. package/dist/State.d.ts +10 -6
  12. package/dist/State.js +2 -1
  13. package/dist/State.js.map +1 -1
  14. package/dist/adapter/assets.d.ts +24 -7
  15. package/dist/adapter/assets.js +58 -37
  16. package/dist/adapter/assets.js.map +1 -1
  17. package/dist/adapter/handler.d.ts +27 -12
  18. package/dist/adapter/handler.js +53 -26
  19. package/dist/adapter/handler.js.map +1 -1
  20. package/dist/adapter/index.d.ts +3 -3
  21. package/dist/adapter/index.js +1 -1
  22. package/dist/adapter/index.js.map +1 -1
  23. package/dist/adapter/serve.d.ts +6 -5
  24. package/dist/adapter/serve.js +3 -1
  25. package/dist/adapter/serve.js.map +1 -1
  26. package/dist/api-client.d.ts +3 -4
  27. package/dist/api-client.js +2 -1
  28. package/dist/api-client.js.map +1 -1
  29. package/dist/app-runtime.d.ts +12 -9
  30. package/dist/app-runtime.js +23 -14
  31. package/dist/app-runtime.js.map +1 -1
  32. package/dist/client/Hooks.d.ts +4 -4
  33. package/dist/client/Hooks.js +2 -1
  34. package/dist/client/Hooks.js.map +1 -1
  35. package/dist/client.d.ts +2 -2
  36. package/dist/config.d.ts +7 -5
  37. package/dist/config.js +5 -34
  38. package/dist/config.js.map +1 -1
  39. package/dist/errors.d.ts +14 -16
  40. package/dist/errors.js +20 -12
  41. package/dist/errors.js.map +1 -1
  42. package/dist/forms.d.ts +9 -10
  43. package/dist/forms.js +5 -2
  44. package/dist/forms.js.map +1 -1
  45. package/dist/index.d.ts +5 -4
  46. package/dist/index.js +5 -4
  47. package/dist/internal/app-state.d.ts +16 -14
  48. package/dist/internal/app-state.js +9 -3
  49. package/dist/internal/app-state.js.map +1 -1
  50. package/dist/internal/auto.d.ts +23 -14
  51. package/dist/internal/auto.js +50 -40
  52. package/dist/internal/auto.js.map +1 -1
  53. package/dist/internal/enhance.d.ts +20 -18
  54. package/dist/internal/enhance.js +3 -1
  55. package/dist/internal/enhance.js.map +1 -1
  56. package/dist/internal/error.d.ts +13 -0
  57. package/dist/internal/error.js +4 -3
  58. package/dist/internal/error.js.map +1 -1
  59. package/dist/internal/navigation-events.js +3 -1
  60. package/dist/internal/navigation-events.js.map +1 -1
  61. package/dist/internal/remote-run.d.ts +6 -6
  62. package/dist/internal/remote-run.js +13 -16
  63. package/dist/internal/remote-run.js.map +1 -1
  64. package/dist/internal/remote-validators.js +4 -3
  65. package/dist/internal/remote-validators.js.map +1 -1
  66. package/dist/internal/route-params.d.ts +1 -2
  67. package/dist/internal/sse.js +2 -1
  68. package/dist/internal/sse.js.map +1 -1
  69. package/dist/kit.d.ts +12 -11
  70. package/dist/kit.js +6 -2
  71. package/dist/kit.js.map +1 -1
  72. package/dist/realtime.d.ts +29 -31
  73. package/dist/realtime.js +23 -4
  74. package/dist/realtime.js.map +1 -1
  75. package/dist/remote-functions.d.ts +34 -18
  76. package/dist/remote-functions.js +78 -46
  77. package/dist/remote-functions.js.map +1 -1
  78. package/dist/remote-reactive.d.ts +8 -4
  79. package/dist/remote-reactive.js.map +1 -1
  80. package/dist/request-parse.d.ts +13 -13
  81. package/dist/request-parse.js +29 -15
  82. package/dist/request-parse.js.map +1 -1
  83. package/dist/request-runtime.d.ts +16 -11
  84. package/dist/request-runtime.js +28 -29
  85. package/dist/request-runtime.js.map +1 -1
  86. package/dist/request-services.d.ts +10 -8
  87. package/dist/request-services.js +3 -1
  88. package/dist/request-services.js.map +1 -1
  89. package/dist/response-headers.d.ts +2 -3
  90. package/dist/response-headers.js +2 -1
  91. package/dist/response-headers.js.map +1 -1
  92. package/dist/runtime.d.ts +8 -5
  93. package/dist/runtime.js +4 -1
  94. package/dist/runtime.js.map +1 -1
  95. package/dist/server/Endpoint.d.ts +17 -11
  96. package/dist/server/Endpoint.js +18 -4
  97. package/dist/server/Endpoint.js.map +1 -1
  98. package/dist/server/Hooks.d.ts +6 -6
  99. package/dist/server/Hooks.js +1 -1
  100. package/dist/server/Hooks.js.map +1 -1
  101. package/dist/server.d.ts +8 -7
  102. package/dist/server.js +8 -8
  103. package/dist/server.js.map +1 -1
  104. package/dist/streamed-load.d.ts +2 -3
  105. package/dist/streamed-load.js +1 -1
  106. package/dist/streamed-load.js.map +1 -1
  107. package/dist/testing.d.ts +15 -14
  108. package/dist/testing.js +27 -7
  109. package/dist/testing.js.map +1 -1
  110. package/dist/transport.d.ts +6 -7
  111. package/dist/transport.js +3 -6
  112. package/dist/transport.js.map +1 -1
  113. package/dist/universal.d.ts +3 -3
  114. package/dist/universal.js +1 -1
  115. package/dist/universal.js.map +1 -1
  116. package/dist/vite.d.ts +4 -4
  117. package/dist/vite.js +102 -103
  118. package/dist/vite.js.map +1 -1
  119. package/package.json +12 -9
@@ -1,6 +1,10 @@
1
1
  import { causeToThrowable } from "./error.js";
2
2
  import { makeServerRuntime, makeUniversalRuntime } from "../app-runtime.js";
3
- import { Effect, Exit } from "effect";
3
+ import * as Effect from "effect/Effect";
4
+ import * as Exit from "effect/Exit";
5
+ import * as Predicate from "effect/Predicate";
6
+ import * as Rec from "effect/Record";
7
+ import * as Result from "effect/Result";
4
8
  //#region src/internal/auto.ts
5
9
  let defaultServerRuntime;
6
10
  let defaultUniversalRuntime;
@@ -30,27 +34,33 @@ async function runBare(effect, runtime) {
30
34
  onSuccess: (value) => value
31
35
  });
32
36
  }
33
- function isEffectValue(value) {
34
- return Effect.isEffect(value);
35
- }
37
+ /**
38
+ * Detect an Effect returned by (or exported as) a user hook. Its requirements
39
+ * are typed `never`: the user's export may only need what the runtime provides,
40
+ * and anything else surfaces as a missing-service defect when it runs.
41
+ */
42
+ const isUserEffect = (value) => Effect.isEffect(value);
43
+ /** A user export's Effect form as is, or the result of calling its function form with `arg`. */
44
+ const resolveExport = (value, arg) => Effect.isEffect(value) ? value : value(arg);
36
45
  /**
37
46
  * Wraps a value intended to be a SvelteKit universal `load` export.
38
47
  * Used by the Vite plugin for `+page.ts` / `+layout.ts`.
39
48
  */
40
49
  function wrapLoad(value, runtimeMod) {
41
- if (value === void 0) return void 0;
42
- return (async (event) => {
43
- const result = isEffectValue(value) ? value : value(event);
44
- if (!isEffectValue(result)) return result;
50
+ if (value === void 0) return;
51
+ const load = async (event) => {
52
+ const result = resolveExport(value, event);
53
+ if (!Effect.isEffect(result)) return result;
45
54
  return universalRuntimeOf(runtimeMod).load(() => result)(event);
46
- });
55
+ };
56
+ return load;
47
57
  }
48
58
  /** Shared implementation for server-side, event-based wrappers. */
49
59
  function wrapServerEvent(value, runtimeMod) {
50
60
  if (value === void 0) return void 0;
51
61
  return async (event) => {
52
- const result = isEffectValue(value) ? value : value(event);
53
- if (!isEffectValue(result)) return result;
62
+ const result = resolveExport(value, event);
63
+ if (!Effect.isEffect(result)) return result;
54
64
  return serverRuntimeOf(runtimeMod).runPromise(event, result);
55
65
  };
56
66
  }
@@ -71,23 +81,20 @@ function wrapAction(value, runtimeMod) {
71
81
  * Wraps a SvelteKit `actions` object, individually wrapping each entry.
72
82
  */
73
83
  function wrapActions(value, runtimeMod) {
74
- if (value === void 0) return void 0;
75
- if (typeof value !== "object" || value === null) return value;
76
- const wrapped = {};
77
- for (const [key, fn] of Object.entries(value)) {
78
- const wrappedAction = wrapAction(fn, runtimeMod);
79
- if (wrappedAction !== void 0) wrapped[key] = wrappedAction;
80
- }
81
- return wrapped;
84
+ if (value === void 0 || !Predicate.isObjectOrArray(value)) return value;
85
+ return Rec.filterMap(value, (fn) => {
86
+ const wrappedAction = wrapServerEvent(fn, runtimeMod);
87
+ return wrappedAction === void 0 ? Result.fail(void 0) : Result.succeed(wrappedAction);
88
+ });
82
89
  }
83
90
  /**
84
91
  * Wraps a SvelteKit `handle` hook export.
85
92
  */
86
93
  function wrapHandle(value, runtimeMod) {
87
- if (value === void 0) return void 0;
94
+ if (value === void 0) return;
88
95
  const handle = (input) => {
89
- const result = isEffectValue(value) ? value : value(input);
90
- if (!isEffectValue(result)) return result;
96
+ const result = resolveExport(value, input);
97
+ if (!Effect.isEffect(result)) return result;
91
98
  return serverRuntimeOf(runtimeMod).handle(() => result)(input);
92
99
  };
93
100
  return handle;
@@ -96,10 +103,10 @@ function wrapHandle(value, runtimeMod) {
96
103
  * Wraps a SvelteKit `handleFetch` hook export.
97
104
  */
98
105
  function wrapHandleFetch(value, runtimeMod) {
99
- if (value === void 0) return void 0;
106
+ if (value === void 0) return;
100
107
  const handleFetch = async (args) => {
101
- const result = isEffectValue(value) ? value : value(args);
102
- if (!isEffectValue(result)) return result;
108
+ const result = resolveExport(value, args);
109
+ if (!Effect.isEffect(result)) return result;
103
110
  return serverRuntimeOf(runtimeMod).runPromise(args.event, result);
104
111
  };
105
112
  return handleFetch;
@@ -108,14 +115,15 @@ function wrapHandleFetch(value, runtimeMod) {
108
115
  * Wraps a SvelteKit `handleError` hook export.
109
116
  */
110
117
  function wrapHandleError(value, runtimeMod) {
111
- if (value === void 0) return void 0;
112
- return (async (args) => {
113
- const result = isEffectValue(value) ? value : value(args);
114
- if (!isEffectValue(result)) return result;
118
+ if (value === void 0) return;
119
+ const handleError = async (args) => {
120
+ const result = resolveExport(value, args);
121
+ if (!isUserEffect(result)) return result;
115
122
  const event = args.event;
116
123
  if (event !== void 0 && "request" in event) return serverRuntimeOf(runtimeMod).runPromise(event, result);
117
124
  return runBare(result, runtimeOfModule(runtimeMod));
118
- });
125
+ };
126
+ return handleError;
119
127
  }
120
128
  /**
121
129
  * Wraps a SvelteKit HTTP endpoint export (`GET`, `POST`, etc.).
@@ -132,12 +140,13 @@ function wrapEndpoint(value, runtimeMod) {
132
140
  * the server and the client.
133
141
  */
134
142
  function wrapReroute(value, runtimeMod) {
135
- if (value === void 0) return void 0;
136
- return ((event) => {
137
- const result = isEffectValue(value) ? value : value(event);
138
- if (!isEffectValue(result)) return result;
143
+ if (value === void 0) return;
144
+ const reroute = (event) => {
145
+ const result = resolveExport(value, event);
146
+ if (!Effect.isEffect(result)) return result;
139
147
  return universalRuntimeOf(runtimeMod).runPromise(event.fetch, result);
140
- });
148
+ };
149
+ return reroute;
141
150
  }
142
151
  /**
143
152
  * Wraps a SvelteKit `init` hook export (server or client).
@@ -145,15 +154,16 @@ function wrapReroute(value, runtimeMod) {
145
154
  * application runtime's services (if configured) are.
146
155
  */
147
156
  function wrapInit(value, runtimeMod) {
148
- if (value === void 0) return void 0;
149
- return (async () => {
150
- const result = isEffectValue(value) ? value : value();
151
- if (!isEffectValue(result)) {
157
+ if (value === void 0) return;
158
+ const init = async () => {
159
+ const result = Effect.isEffect(value) ? value : value();
160
+ if (!isUserEffect(result)) {
152
161
  await result;
153
162
  return;
154
163
  }
155
164
  await runBare(result, runtimeOfModule(runtimeMod));
156
- });
165
+ };
166
+ return init;
157
167
  }
158
168
  //#endregion
159
169
  export { wrapAction, wrapActions, wrapEndpoint, wrapHandle, wrapHandleError, wrapHandleFetch, wrapInit, wrapLoad, wrapReroute, wrapServerLoad };
@@ -1 +1 @@
1
- {"version":3,"file":"auto.js","names":[],"sources":["../../src/internal/auto.ts"],"sourcesContent":["/**\n * Runtime auto-wrappers used by the SvelteKit Vite plugin.\n *\n * The plugin replaces user-declared SvelteKit exports (`load`, `actions`,\n * `handle`, HTTP method handlers, etc.) with calls into the helpers in this\n * module. At runtime each helper detects whether the underlying value is an\n * Effect, a function returning an Effect, or a plain SvelteKit-compatible\n * function/value, and routes accordingly.\n *\n * When the plugin is configured with a `serverRuntime` / `clientRuntime`\n * module, that module's app-wide runtime (created with `makeServerRuntime` /\n * `makeUniversalRuntime`) is passed as the second argument to these helpers,\n * so plain-Effect exports get access to the application's services.\n *\n * This module is internal — the public Vite plugin generates references to it.\n */\n\nimport type { Action, Actions, Load, RequestEvent, ServerLoad } from \"@sveltejs/kit\";\nimport type {\n Handle,\n HandleClientError,\n HandleFetch,\n HandleServerError,\n Reroute,\n} from \"@sveltejs/kit/hooks\";\nimport { Effect, Exit } from \"effect\";\nimport {\n makeServerRuntime,\n makeUniversalRuntime,\n type ServerRuntime,\n type UniversalRuntime,\n} from \"../app-runtime.js\";\nimport { causeToThrowable } from \"./error.js\";\n\ntype AnyEffect = Effect.Effect<unknown, unknown, never>;\n\ntype AnyRuntime = ServerRuntime<any, any> | UniversalRuntime<any, any>;\n\n/**\n * Module shape accepted for the plugin's `serverRuntime` / `clientRuntime`\n * options: the runtime can be the default export or a named `runtime` export.\n */\nexport interface RuntimeModule {\n readonly runtime?: AnyRuntime;\n readonly default?: AnyRuntime;\n}\n\n// Default runtimes (no application layer), created lazily and shared across\n// all requests in the process.\nlet defaultServerRuntime: ServerRuntime<any, any> | undefined;\nlet defaultUniversalRuntime: UniversalRuntime<any, any> | undefined;\n\n/** Extract the runtime from a runtime module, if any. */\nconst runtimeOfModule = (mod?: RuntimeModule): AnyRuntime | undefined =>\n mod?.runtime ?? mod?.default;\n\n/** Distinguish a ServerRuntime from a UniversalRuntime structurally. */\nconst isServerRuntime = (runtime: AnyRuntime): runtime is ServerRuntime<any, any> =>\n \"serverLoad\" in runtime;\n\n/** The server runtime for a module, falling back to the shared default. */\nconst serverRuntimeOf = (mod?: RuntimeModule): ServerRuntime<any, any> => {\n const runtime = runtimeOfModule(mod);\n if (runtime !== undefined && isServerRuntime(runtime)) return runtime;\n return (defaultServerRuntime ??= makeServerRuntime<any, any>());\n};\n\n/** The universal runtime for a module, falling back to the shared default. */\nconst universalRuntimeOf = (mod?: RuntimeModule): UniversalRuntime<any, any> => {\n const runtime = runtimeOfModule(mod);\n if (runtime !== undefined && !isServerRuntime(runtime)) return runtime;\n return (defaultUniversalRuntime ??= makeUniversalRuntime<any, any>());\n};\n\n/** Run an effect without any request context (e.g. `init` hooks). */\nasync function runBare(effect: AnyEffect, runtime?: AnyRuntime): Promise<unknown> {\n const exit = runtime\n ? ((await runtime.runtime.runPromiseExit(effect)) as Exit.Exit<unknown, unknown>)\n : await Effect.runPromiseExit(effect);\n\n return Exit.match(exit, {\n onFailure: (cause) => {\n throw causeToThrowable(cause);\n },\n onSuccess: (value) => value,\n });\n}\n\nfunction isEffectValue(value: unknown): value is AnyEffect {\n return Effect.isEffect(value as never);\n}\n\ntype LoadLikeInput = undefined | AnyEffect | ((event: any) => unknown);\n\n/**\n * Wraps a value intended to be a SvelteKit universal `load` export.\n * Used by the Vite plugin for `+page.ts` / `+layout.ts`.\n */\nexport function wrapLoad<T extends LoadLikeInput>(\n value: T,\n runtimeMod?: RuntimeModule,\n): T extends undefined ? undefined : Load {\n if (value === undefined) return undefined as never;\n\n return (async (event: Parameters<Load>[0]) => {\n const result = isEffectValue(value) ? value : (value as (event: unknown) => unknown)(event);\n if (!isEffectValue(result)) return result;\n\n // Reuse the universal runtime's load wrapper so client/server detection\n // and per-request services stay in one place.\n return universalRuntimeOf(runtimeMod).load(\n () => result as Effect.Effect<Record<string, unknown>, unknown, never>,\n )(event);\n }) as never;\n}\n\n/** Shared implementation for server-side, event-based wrappers. */\nfunction wrapServerEvent<T extends LoadLikeInput>(\n value: T,\n runtimeMod?: RuntimeModule,\n): undefined | ((event: RequestEvent) => Promise<unknown>) {\n if (value === undefined) return undefined;\n\n return async (event: RequestEvent) => {\n const result = isEffectValue(value)\n ? value\n : (value as (event: RequestEvent) => unknown)(event);\n if (!isEffectValue(result)) return result;\n\n return serverRuntimeOf(runtimeMod).runPromise(event, result);\n };\n}\n\n/**\n * Wraps a value intended to be a SvelteKit server `load` export.\n * Used by the Vite plugin for `+page.server.ts` / `+layout.server.ts`.\n */\nexport function wrapServerLoad<T extends LoadLikeInput>(\n value: T,\n runtimeMod?: RuntimeModule,\n): T extends undefined ? undefined : ServerLoad {\n return wrapServerEvent(value, runtimeMod) as never;\n}\n\n/**\n * Wraps a single SvelteKit action handler.\n */\nexport function wrapAction<T extends LoadLikeInput>(\n value: T,\n runtimeMod?: RuntimeModule,\n): T extends undefined ? undefined : Action {\n return wrapServerEvent(value, runtimeMod) as never;\n}\n\n/**\n * Wraps a SvelteKit `actions` object, individually wrapping each entry.\n */\nexport function wrapActions<T extends Record<string, LoadLikeInput> | undefined>(\n value: T,\n runtimeMod?: RuntimeModule,\n): T extends undefined ? undefined : Actions {\n if (value === undefined) return undefined as never;\n if (typeof value !== \"object\" || value === null) return value as never;\n\n const wrapped: Actions = {};\n for (const [key, fn] of Object.entries(value)) {\n const wrappedAction = wrapAction(fn as LoadLikeInput, runtimeMod);\n if (wrappedAction !== undefined) {\n wrapped[key] = wrappedAction;\n }\n }\n return wrapped as never;\n}\n\n/**\n * Wraps a SvelteKit `handle` hook export.\n */\nexport function wrapHandle<\n T extends undefined | AnyEffect | ((args: Parameters<Handle>[0]) => unknown),\n>(value: T, runtimeMod?: RuntimeModule): T extends undefined ? undefined : Handle {\n if (value === undefined) return undefined as never;\n\n const handle: Handle = (input) => {\n const result = isEffectValue(value)\n ? value\n : (value as (args: Parameters<Handle>[0]) => unknown)(input);\n if (!isEffectValue(result)) return result as Response | Promise<Response>;\n\n // Route through `handle` so the per-request runtime is installed on\n // `event.locals` for the rest of the request, like the explicit wrapper.\n return serverRuntimeOf(runtimeMod).handle(\n () => result as Effect.Effect<Response, unknown, never>,\n )(input) as Promise<Response>;\n };\n return handle as never;\n}\n\n/**\n * Wraps a SvelteKit `handleFetch` hook export.\n */\nexport function wrapHandleFetch<\n T extends undefined | AnyEffect | ((args: Parameters<HandleFetch>[0]) => unknown),\n>(value: T, runtimeMod?: RuntimeModule): T extends undefined ? undefined : HandleFetch {\n if (value === undefined) return undefined as never;\n\n const handleFetch: HandleFetch = async (args) => {\n const result = isEffectValue(value)\n ? value\n : (value as (args: Parameters<HandleFetch>[0]) => unknown)(args);\n if (!isEffectValue(result)) return result as Response | Promise<Response>;\n\n return serverRuntimeOf(runtimeMod).runPromise(args.event, result) as Promise<Response>;\n };\n return handleFetch as never;\n}\n\ntype AnyHandleError = HandleServerError | HandleClientError;\n\n/**\n * Wraps a SvelteKit `handleError` hook export.\n */\nexport function wrapHandleError<\n T extends undefined | AnyEffect | ((args: Parameters<AnyHandleError>[0]) => unknown),\n>(value: T, runtimeMod?: RuntimeModule): T extends undefined ? undefined : AnyHandleError {\n if (value === undefined) return undefined as never;\n\n return (async (args: Parameters<AnyHandleError>[0]) => {\n const result = isEffectValue(value)\n ? value\n : (value as (args: Parameters<AnyHandleError>[0]) => unknown)(args);\n if (!isEffectValue(result)) return result as ReturnType<AnyHandleError>;\n\n // Server errors carry a RequestEvent; client errors carry a NavigationEvent.\n const event = (args as { event?: RequestEvent }).event;\n const isServerEvent = event !== undefined && \"request\" in event;\n\n if (isServerEvent) {\n return serverRuntimeOf(runtimeMod).runPromise(event, result) as ReturnType<AnyHandleError>;\n }\n\n // Client-side: run on the bare app runtime (no request services).\n return runBare(result, runtimeOfModule(runtimeMod)) as ReturnType<AnyHandleError>;\n }) as never;\n}\n\n/**\n * Wraps a SvelteKit HTTP endpoint export (`GET`, `POST`, etc.).\n * Errors thrown by the underlying Effect propagate to SvelteKit's normal\n * error-handling pipeline (i.e. they are not silently swallowed). Use the\n * explicit `endpoint()` helper if you need the `exposeErrors` toggle.\n */\nexport function wrapEndpoint<T extends undefined | AnyEffect | ((event: RequestEvent) => unknown)>(\n value: T,\n runtimeMod?: RuntimeModule,\n): T extends undefined ? undefined : (event: RequestEvent) => Response | Promise<Response> {\n return wrapServerEvent(value as LoadLikeInput, runtimeMod) as never;\n}\n\ntype RerouteEvent = Parameters<Reroute>[0];\n\n/**\n * Wraps a SvelteKit universal `reroute` hook export. The effect runs on the\n * universal runtime with an `HttpClient` backed by the event's `fetch`, on both\n * the server and the client.\n */\nexport function wrapReroute<T extends undefined | AnyEffect | ((event: RerouteEvent) => unknown)>(\n value: T,\n runtimeMod?: RuntimeModule,\n): T extends undefined ? undefined : Reroute {\n if (value === undefined) return undefined as never;\n\n return ((event: RerouteEvent) => {\n const result = isEffectValue(value)\n ? value\n : (value as (event: RerouteEvent) => unknown)(event);\n if (!isEffectValue(result)) return result as ReturnType<Reroute>;\n\n return universalRuntimeOf(runtimeMod).runPromise(event.fetch, result) as ReturnType<Reroute>;\n }) as never;\n}\n\n/**\n * Wraps a SvelteKit `init` hook export (server or client).\n * `init` runs once at startup; there is no request event available, but the\n * application runtime's services (if configured) are.\n */\nexport function wrapInit<T extends undefined | AnyEffect | (() => unknown)>(\n value: T,\n runtimeMod?: RuntimeModule,\n): T extends undefined ? undefined : () => Promise<void> {\n if (value === undefined) return undefined as never;\n\n return (async () => {\n const result = isEffectValue(value) ? value : (value as () => unknown)();\n if (!isEffectValue(result)) {\n await result;\n return;\n }\n await runBare(result, runtimeOfModule(runtimeMod));\n }) as never;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"auto.js","names":[],"sources":["../../src/internal/auto.ts"],"sourcesContent":["/**\n * Runtime auto-wrappers used by the SvelteKit Vite plugin.\n *\n * The plugin replaces user-declared SvelteKit exports (`load`, `actions`,\n * `handle`, HTTP method handlers, etc.) with calls into the helpers in this\n * module. At runtime each helper detects whether the underlying value is an\n * Effect, a function returning an Effect, or a plain SvelteKit-compatible\n * function/value, and routes accordingly.\n *\n * When the plugin is configured with a `serverRuntime` / `clientRuntime`\n * module, that module's app-wide runtime (created with `makeServerRuntime` /\n * `makeUniversalRuntime`) is passed as the second argument to these helpers,\n * so plain-Effect exports get access to the application's services.\n *\n * This module is internal — the public Vite plugin generates references to it.\n */\n\nimport type { Action, Actions, Load, RequestEvent, ServerLoad } from \"@sveltejs/kit\";\nimport type {\n Handle,\n HandleClientError,\n HandleFetch,\n HandleServerError,\n Reroute,\n} from \"@sveltejs/kit/hooks\";\nimport * as Effect from \"effect/Effect\";\nimport * as Exit from \"effect/Exit\";\nimport * as Predicate from \"effect/Predicate\";\nimport * as Rec from \"effect/Record\";\nimport * as Result from \"effect/Result\";\nimport {\n makeServerRuntime,\n makeUniversalRuntime,\n type ServerRuntime,\n type UniversalRuntime,\n} from \"../app-runtime.js\";\nimport { causeToThrowable } from \"./error.js\";\n\ntype AnyEffect = Effect.Effect<unknown, unknown, never>;\n\n/**\n * The function form of a user export: called with the hook / load argument, it\n * returns an Effect to run or a plain SvelteKit value to pass through. Its\n * result is only known at runtime (`Effect.isEffect` tells the two apart).\n */\ntype UserFn<Arg> = (arg: Arg) => unknown;\n\n/** The argument-less function form of a user `init` export (see {@link UserFn}). */\ntype UserThunk = () => unknown;\n\ntype AnyRuntime = ServerRuntime<any, any> | UniversalRuntime<any, any>;\n\n/**\n * Module shape accepted for the plugin's `serverRuntime` / `clientRuntime`\n * options: the runtime can be the default export or a named `runtime` export.\n */\nexport interface RuntimeModule {\n readonly runtime?: AnyRuntime;\n readonly default?: AnyRuntime;\n}\n\n// Default runtimes (no application layer), created lazily and shared across\n// all requests in the process.\nlet defaultServerRuntime: ServerRuntime<any, any> | undefined;\nlet defaultUniversalRuntime: UniversalRuntime<any, any> | undefined;\n\n/** Extract the runtime from a runtime module, if any. */\nconst runtimeOfModule = (mod?: RuntimeModule): AnyRuntime | undefined =>\n mod?.runtime ?? mod?.default;\n\n/** Distinguish a ServerRuntime from a UniversalRuntime structurally. */\nconst isServerRuntime = (runtime: AnyRuntime): runtime is ServerRuntime<any, any> =>\n \"serverLoad\" in runtime;\n\n/** The server runtime for a module, falling back to the shared default. */\nconst serverRuntimeOf = (mod?: RuntimeModule): ServerRuntime<any, any> => {\n const runtime = runtimeOfModule(mod);\n if (runtime !== undefined && isServerRuntime(runtime)) return runtime;\n return (defaultServerRuntime ??= makeServerRuntime<any, any>());\n};\n\n/** The universal runtime for a module, falling back to the shared default. */\nconst universalRuntimeOf = (mod?: RuntimeModule): UniversalRuntime<any, any> => {\n const runtime = runtimeOfModule(mod);\n if (runtime !== undefined && !isServerRuntime(runtime)) return runtime;\n return (defaultUniversalRuntime ??= makeUniversalRuntime<any, any>());\n};\n\n/** Run an effect without any request context (e.g. `init` hooks). */\nasync function runBare<A, E>(effect: Effect.Effect<A, E>, runtime?: AnyRuntime): Promise<A> {\n const exit = runtime\n ? await runtime.runtime.runPromiseExit(effect)\n : await Effect.runPromiseExit(effect);\n\n return Exit.match(exit, {\n onFailure: (cause) => {\n throw causeToThrowable(cause);\n },\n onSuccess: (value) => value,\n });\n}\n\n/**\n * Detect an Effect returned by (or exported as) a user hook. Its requirements\n * are typed `never`: the user's export may only need what the runtime provides,\n * and anything else surfaces as a missing-service defect when it runs.\n */\nconst isUserEffect = (value: unknown): value is AnyEffect => Effect.isEffect(value);\n\n/** A user export's Effect form as is, or the result of calling its function form with `arg`. */\nconst resolveExport = <Arg>(value: AnyEffect | UserFn<Arg>, arg: Arg) =>\n Effect.isEffect(value) ? value : value(arg);\n\ntype LoadLikeInput = undefined | AnyEffect | UserFn<any>;\n\n/** The page data a universal `load` resolves to. */\ntype LoadData = Awaited<ReturnType<Load>>;\n\n/**\n * Wraps a value intended to be a SvelteKit universal `load` export.\n * Used by the Vite plugin for `+page.ts` / `+layout.ts`.\n */\nexport function wrapLoad<T extends LoadLikeInput>(\n value: T,\n runtimeMod?: RuntimeModule,\n): T extends undefined ? undefined : Load {\n if (value === undefined) {\n // SAFETY: `undefined` in, `undefined` out; anything else becomes a `Load`\n // (an async function of the load event), matching the conditional return.\n return undefined as never;\n }\n\n const load = async (event: Parameters<Load>[0]) => {\n const result = resolveExport(value, event);\n if (!Effect.isEffect(result)) return result;\n\n // Reuse the universal runtime's load wrapper so client/server detection\n // and per-request services stay in one place.\n // SAFETY: the effect is the user's `load`; its value is the page data,\n // which SvelteKit itself validates when the load resolves.\n return universalRuntimeOf(runtimeMod).load(\n () => result as Effect.Effect<LoadData, unknown, never>,\n )(event);\n };\n // SAFETY: see the `undefined` case above; a non-Effect result is the user's\n // own `load` return value, passed through unchanged.\n return load as never;\n}\n\n/** Shared implementation for server-side, event-based wrappers. */\nfunction wrapServerEvent<T extends LoadLikeInput>(value: T, runtimeMod?: RuntimeModule) {\n if (value === undefined) return undefined;\n\n return async (event: RequestEvent) => {\n const result = resolveExport(value, event);\n if (!Effect.isEffect(result)) return result;\n\n return serverRuntimeOf(runtimeMod).runPromise(event, result);\n };\n}\n\n/**\n * Wraps a value intended to be a SvelteKit server `load` export.\n * Used by the Vite plugin for `+page.server.ts` / `+layout.server.ts`.\n */\nexport function wrapServerLoad<T extends LoadLikeInput>(\n value: T,\n runtimeMod?: RuntimeModule,\n): T extends undefined ? undefined : ServerLoad {\n // SAFETY: `wrapServerEvent` returns `undefined` for `undefined` and otherwise\n // an async function of the request event that runs the effect or passes the\n // user's plain return value through — a `ServerLoad`.\n return wrapServerEvent(value, runtimeMod) as never;\n}\n\n/**\n * Wraps a single SvelteKit action handler.\n */\nexport function wrapAction<T extends LoadLikeInput>(\n value: T,\n runtimeMod?: RuntimeModule,\n): T extends undefined ? undefined : Action {\n // SAFETY: `wrapServerEvent` returns `undefined` for `undefined` and otherwise\n // an async function of the request event that runs the effect or passes the\n // user's plain return value through — an `Action`.\n return wrapServerEvent(value, runtimeMod) as never;\n}\n\n/**\n * Wraps a SvelteKit `actions` object, individually wrapping each entry.\n */\nexport function wrapActions<T extends Record<string, LoadLikeInput> | undefined>(\n value: T,\n runtimeMod?: RuntimeModule,\n): T extends undefined ? undefined : Actions {\n if (value === undefined || !Predicate.isObjectOrArray(value)) {\n // SAFETY: `undefined` and non-objects pass through untouched, as before;\n // an object becomes a record of wrapped actions (entries that are\n // `undefined` are dropped), which is an `Actions`.\n return value as never;\n }\n\n const wrapped = Rec.filterMap(value, (fn) => {\n const wrappedAction = wrapServerEvent(fn, runtimeMod);\n return wrappedAction === undefined ? Result.fail(undefined) : Result.succeed(wrappedAction);\n });\n // SAFETY: see above.\n return wrapped as never;\n}\n\n/**\n * Wraps a SvelteKit `handle` hook export.\n */\nexport function wrapHandle<T extends undefined | AnyEffect | UserFn<Parameters<Handle>[0]>>(\n value: T,\n runtimeMod?: RuntimeModule,\n): T extends undefined ? undefined : Handle {\n if (value === undefined) {\n // SAFETY: `undefined` in, `undefined` out; anything else becomes the\n // `Handle` below, matching the conditional return.\n return undefined as never;\n }\n\n const handle: Handle = (input) => {\n const result = resolveExport(value, input);\n if (!Effect.isEffect(result)) {\n // SAFETY: a non-Effect result is the user's own `handle` return value\n // (a `Response` or a promise of one), passed through unchanged.\n return result as Response | Promise<Response>;\n }\n\n // Route through `handle` so the per-request runtime is installed on\n // `event.locals` for the rest of the request, like the explicit wrapper.\n // SAFETY: the effect is the user's `handle`, which resolves to the\n // `Response`; the runtime's `Handle` is async, so it returns a promise.\n return serverRuntimeOf(runtimeMod).handle(\n () => result as Effect.Effect<Response, unknown, never>,\n )(input) as Promise<Response>;\n };\n // SAFETY: see the `undefined` case above.\n return handle as never;\n}\n\n/**\n * Wraps a SvelteKit `handleFetch` hook export.\n */\nexport function wrapHandleFetch<\n T extends undefined | AnyEffect | UserFn<Parameters<HandleFetch>[0]>,\n>(value: T, runtimeMod?: RuntimeModule): T extends undefined ? undefined : HandleFetch {\n if (value === undefined) {\n // SAFETY: `undefined` in, `undefined` out; anything else becomes the\n // `HandleFetch` below, matching the conditional return.\n return undefined as never;\n }\n\n const handleFetch: HandleFetch = async (args) => {\n const result = resolveExport(value, args);\n if (!Effect.isEffect(result)) {\n // SAFETY: a non-Effect result is the user's own `handleFetch` return value\n // (a `Response` or a promise of one), passed through unchanged.\n return result as Response | Promise<Response>;\n }\n\n // SAFETY: the effect is the user's `handleFetch`, which resolves to the\n // `Response`.\n return serverRuntimeOf(runtimeMod).runPromise(args.event, result) as Promise<Response>;\n };\n // SAFETY: see the `undefined` case above.\n return handleFetch as never;\n}\n\ntype AnyHandleError = HandleServerError | HandleClientError;\ntype HandleErrorInput = Parameters<AnyHandleError>[0];\ntype HandleErrorOutput = ReturnType<AnyHandleError>;\n\n/**\n * Wraps a SvelteKit `handleError` hook export.\n */\nexport function wrapHandleError<T extends undefined | AnyEffect | UserFn<HandleErrorInput>>(\n value: T,\n runtimeMod?: RuntimeModule,\n): T extends undefined ? undefined : AnyHandleError {\n if (value === undefined) {\n // SAFETY: `undefined` in, `undefined` out; anything else becomes the\n // async `handleError` below, matching the conditional return.\n return undefined as never;\n }\n\n const handleError = async (args: HandleErrorInput) => {\n const result = resolveExport(value, args);\n if (!isUserEffect(result)) {\n // SAFETY: a non-Effect result is the user's own `handleError` return\n // value, passed through unchanged.\n return result as HandleErrorOutput;\n }\n\n // Server errors carry a RequestEvent; client errors carry a NavigationEvent.\n const event = args.event;\n if (event !== undefined && \"request\" in event) {\n // SAFETY: the effect is the user's `handleError`, which resolves to\n // its `App.Error` (or nothing).\n return serverRuntimeOf(runtimeMod).runPromise(event, result) as HandleErrorOutput;\n }\n\n // Client-side: run on the bare app runtime (no request services).\n // SAFETY: as above.\n return runBare(result, runtimeOfModule(runtimeMod)) as HandleErrorOutput;\n };\n // SAFETY: see the `undefined` case above.\n return handleError as never;\n}\n\n/**\n * Wraps a SvelteKit HTTP endpoint export (`GET`, `POST`, etc.).\n * Errors thrown by the underlying Effect propagate to SvelteKit's normal\n * error-handling pipeline (i.e. they are not silently swallowed). Use the\n * explicit `endpoint()` helper if you need the `exposeErrors` toggle.\n */\nexport function wrapEndpoint<T extends undefined | AnyEffect | UserFn<RequestEvent>>(\n value: T,\n runtimeMod?: RuntimeModule,\n): T extends undefined ? undefined : (event: RequestEvent) => Response | Promise<Response> {\n // SAFETY: `wrapServerEvent` returns `undefined` for `undefined` and otherwise\n // an async function of the request event that runs the effect or passes the\n // user's plain return value (a `Response`) through.\n return wrapServerEvent(value, runtimeMod) as never;\n}\n\ntype RerouteEvent = Parameters<Reroute>[0];\n\n/**\n * Wraps a SvelteKit universal `reroute` hook export. The effect runs on the\n * universal runtime with an `HttpClient` backed by the event's `fetch`, on both\n * the server and the client.\n */\nexport function wrapReroute<T extends undefined | AnyEffect | UserFn<RerouteEvent>>(\n value: T,\n runtimeMod?: RuntimeModule,\n): T extends undefined ? undefined : Reroute {\n if (value === undefined) {\n // SAFETY: `undefined` in, `undefined` out; anything else becomes the\n // `reroute` below, matching the conditional return.\n return undefined as never;\n }\n\n const reroute = (event: RerouteEvent) => {\n const result = resolveExport(value, event);\n if (!Effect.isEffect(result)) {\n // SAFETY: a non-Effect result is the user's own `reroute` return value\n // (a pathname, a promise of one, or nothing), passed through unchanged.\n return result as ReturnType<Reroute>;\n }\n\n // SAFETY: the effect is the user's `reroute`, which resolves to the\n // pathname (or nothing).\n return universalRuntimeOf(runtimeMod).runPromise(event.fetch, result) as ReturnType<Reroute>;\n };\n // SAFETY: see the `undefined` case above.\n return reroute as never;\n}\n\n/**\n * Wraps a SvelteKit `init` hook export (server or client).\n * `init` runs once at startup; there is no request event available, but the\n * application runtime's services (if configured) are.\n */\nexport function wrapInit<T extends undefined | AnyEffect | UserThunk>(\n value: T,\n runtimeMod?: RuntimeModule,\n): T extends undefined ? undefined : () => Promise<void> {\n if (value === undefined) {\n // SAFETY: `undefined` in, `undefined` out; anything else becomes the async\n // `init` below, matching the conditional return.\n return undefined as never;\n }\n\n const init = async () => {\n const result = Effect.isEffect(value) ? value : value();\n if (!isUserEffect(result)) {\n await result;\n return;\n }\n await runBare(result, runtimeOfModule(runtimeMod));\n };\n // SAFETY: see the `undefined` case above.\n return init as never;\n}\n"],"mappings":"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"}
@@ -1,14 +1,16 @@
1
- import { Context, Effect, ManagedRuntime } from "effect";
1
+ import * as Effect from "effect/Effect";
2
+ import * as Context from "effect/Context";
3
+ import * as ManagedRuntime from "effect/ManagedRuntime";
2
4
  import { SubmitFunction } from "$app/forms";
3
5
  //#region src/internal/enhance.d.ts
4
6
  /** The input SvelteKit passes to a `SubmitFunction` before the request is sent. */
5
- type SubmitInput = Parameters<SubmitFunction>[0];
7
+ export type SubmitInput = Parameters<SubmitFunction>[0];
6
8
  /** The result callback a `SubmitFunction` may return, run once the action responds. */
7
- type ResultCallback = Extract<Awaited<ReturnType<SubmitFunction>>, (...args: never) => unknown>;
9
+ type ResultCallback = Extract<Awaited<ReturnType<SubmitFunction>>, (...args: never) => void>;
8
10
  /** The options passed to the result callback (`result`, `update`, ...). */
9
- type ResultOptions = Parameters<ResultCallback>[0];
11
+ export type ResultOptions = Parameters<ResultCallback>[0];
10
12
  /** A runtime the handler effects can run against (a `Context` or `ManagedRuntime`). */
11
- type EnhanceRuntime<R> = Context.Context<R> | ManagedRuntime.ManagedRuntime<R, never>;
13
+ export type EnhanceRuntime<R> = Context.Context<R> | ManagedRuntime.ManagedRuntime<R, never>;
12
14
  /**
13
15
  * Effect-based handlers for the two phases of an enhanced form submission,
14
16
  * plus `onError` for the errors they fail with. `ESubmit` / `EResult` are the
@@ -17,7 +19,7 @@ type EnhanceRuntime<R> = Context.Context<R> | ManagedRuntime.ManagedRuntime<R, n
17
19
  * the handlers object, so `this` in a handler written as a method is that
18
20
  * object.
19
21
  */
20
- interface EnhanceHandlers<R = never, ESubmit = never, EResult = never, E = ESubmit | EResult> {
22
+ export interface EnhanceHandlers<R = never, ESubmit = never, EResult = never, E = ESubmit | EResult> {
21
23
  /**
22
24
  * Runs before the request is sent. Call `input.cancel()` to abort the
23
25
  * submission (the result phase then never runs). Use for optimistic UI or
@@ -62,7 +64,7 @@ interface EnhanceHandlers<R = never, ESubmit = never, EResult = never, E = ESubm
62
64
  readonly onError?: ((error: E) => Effect.Effect<void, never, R>) | undefined;
63
65
  }
64
66
  /** Options for {@link makeSubmitFunction}. */
65
- interface EnhanceOptions<R = never> {
67
+ export interface EnhanceOptions<R = never> {
66
68
  /**
67
69
  * The runtime to run the handler effects against, providing every service
68
70
  * `R` they require. Required when the handlers (or `onError`) require
@@ -80,18 +82,18 @@ interface EnhanceOptions<R = never> {
80
82
  * `R` takes its options as `...options: EnhanceOptionsArgs<R>` and forwards
81
83
  * them unchanged.
82
84
  */
83
- type EnhanceOptionsArgs<R> = [R] extends [never] ? [options?: EnhanceOptions<never> | undefined] : [options: EnhanceOptions<R> & {
85
+ export type EnhanceOptionsArgs<R> = [R] extends [never] ? [options?: EnhanceOptions<never> | undefined] : [options: EnhanceOptions<R> & {
84
86
  readonly runtime: EnhanceRuntime<R>;
85
87
  }];
86
88
  /** The handler names {@link makeSubmitFunction} accepts. */
87
- type EnhanceHandlerKey = keyof EnhanceHandlers;
89
+ export type EnhanceHandlerKey = keyof EnhanceHandlers;
88
90
  /**
89
91
  * Records which handlers a handlers object names: `Keys` is inferred from the
90
92
  * object's keys, which TypeScript knows before it types any handler.
91
93
  */
92
- type HandlerKeys<Keys extends EnhanceHandlerKey> = { readonly [Key in Keys]?: unknown; };
94
+ export type HandlerKeys<Keys extends EnhanceHandlerKey> = { readonly [Key in Keys]?: unknown; };
93
95
  /** Whether `Errors` includes a handler error not inferred yet ({@link ErrorNotInferred}). */
94
- type IsErrorNotInferred<Errors> = 0 extends 1 & Errors ? true : false;
96
+ export type IsErrorNotInferred<Errors> = 0 extends 1 & Errors ? true : false;
95
97
  /**
96
98
  * The services a handler requires: `R`, or none while it is not inferred
97
99
  * ({@link ServicesNotInferred}), as for an absent handler.
@@ -104,23 +106,23 @@ type IsErrorNotInferred<Errors> = 0 extends 1 & Errors ? true : false;
104
106
  * be checked against, and only a top type fits every handler in TypeScript's
105
107
  * first inference pass.
106
108
  */
107
- type RequiredServices<R> = unknown extends R ? never : R;
109
+ export type RequiredServices<R> = unknown extends R ? never : R;
108
110
  /** The errors of the handlers named in `Keys`. */
109
- type HandlerErrors<Keys extends EnhanceHandlerKey, ESubmit, EResult> = ("onSubmit" extends Keys ? ESubmit : never) | ("onResult" extends Keys ? EResult : never);
111
+ export type HandlerErrors<Keys extends EnhanceHandlerKey, ESubmit, EResult> = ("onSubmit" extends Keys ? ESubmit : never) | ("onResult" extends Keys ? EResult : never);
110
112
  /**
111
113
  * The error an unannotated `onError` receives: the handlers' errors, or
112
114
  * `unknown` while one of them is not inferred yet (`onError` written before a
113
115
  * handler whose parameters are not annotated).
114
116
  */
115
- type OnErrorInput<Errors> = IsErrorNotInferred<Errors> extends true ? unknown : Errors;
117
+ export type OnErrorInput<Errors> = IsErrorNotInferred<Errors> extends true ? unknown : Errors;
116
118
  /**
117
119
  * Requires `onError` to accept every error in `Errors` when its parameter is
118
120
  * annotated (`E` is then inferred from the annotation). The check waits while
119
121
  * a handler's error is not inferred yet, and applies once it is.
120
122
  */
121
- type OnErrorAccepts<R, Errors, E> = IsErrorNotInferred<Errors> extends true ? unknown : [Errors] extends [E] ? unknown : OnErrorMustAccept<R, Errors>;
123
+ export type OnErrorAccepts<R, Errors, E> = IsErrorNotInferred<Errors> extends true ? unknown : [Errors] extends [E] ? unknown : OnErrorMustAccept<R, Errors>;
122
124
  /** The `onError` that {@link OnErrorAccepts} requires. */
123
- interface OnErrorMustAccept<R, Errors> {
125
+ export interface OnErrorMustAccept<R, Errors> {
124
126
  readonly onError?: ((error: Errors) => Effect.Effect<void, never, R>) | undefined;
125
127
  }
126
128
  /**
@@ -130,7 +132,7 @@ interface OnErrorMustAccept<R, Errors> {
130
132
  * not union them, so a single requirements parameter would reject handlers
131
133
  * that require different services even when the runtime provides them all.
132
134
  */
133
- type EnhanceHandlersBy<RSubmit, RResult, RError, ESubmit, EResult, E> = Pick<EnhanceHandlers<RSubmit, ESubmit, EResult, E>, "onSubmit"> & Pick<EnhanceHandlers<RResult, ESubmit, EResult, E>, "onResult"> & Pick<EnhanceHandlers<RError, ESubmit, EResult, E>, "onError">;
135
+ export type EnhanceHandlersBy<RSubmit, RResult, RError, ESubmit, EResult, E> = Pick<EnhanceHandlers<RSubmit, ESubmit, EResult, E>, "onSubmit"> & Pick<EnhanceHandlers<RResult, ESubmit, EResult, E>, "onResult"> & Pick<EnhanceHandlers<RError, ESubmit, EResult, E>, "onError">;
134
136
  //#endregion
135
- export { EnhanceHandlerKey, EnhanceHandlers, EnhanceHandlersBy, EnhanceOptions, EnhanceOptionsArgs, EnhanceRuntime, HandlerErrors, HandlerKeys, IsErrorNotInferred, OnErrorAccepts, OnErrorInput, OnErrorMustAccept, RequiredServices, ResultOptions, SubmitInput };
137
+ export {};
136
138
  //# sourceMappingURL=enhance.d.ts.map
@@ -1,4 +1,6 @@
1
- import { Context, Effect } from "effect";
1
+ import * as Effect from "effect/Effect";
2
+ import * as Context from "effect/Context";
3
+ import "effect/ManagedRuntime";
2
4
  //#region src/internal/enhance.ts
3
5
  /** Run an `Effect<A, E, R>` on the given runtime (or the default when none). */
4
6
  const runPromiseWith = (runtime) => (effect) => {
@@ -1 +1 @@
1
- {"version":3,"file":"enhance.js","names":[],"sources":["../../src/internal/enhance.ts"],"sourcesContent":["/**\n * The runtime-agnostic core of the `use:enhance` bridge, kept free of any\n * `$app/*` import so it can be unit-tested outside a SvelteKit app build.\n */\n\nimport type { SubmitFunction } from \"$app/forms\";\nimport { Context, Effect, ManagedRuntime } from \"effect\";\n\n/** The input SvelteKit passes to a `SubmitFunction` before the request is sent. */\nexport type SubmitInput = Parameters<SubmitFunction>[0];\n\n/** The result callback a `SubmitFunction` may return, run once the action responds. */\ntype ResultCallback = Extract<Awaited<ReturnType<SubmitFunction>>, (...args: never) => unknown>;\n\n/** The options passed to the result callback (`result`, `update`, ...). */\nexport type ResultOptions = Parameters<ResultCallback>[0];\n\n/** A runtime the handler effects can run against (a `Context` or `ManagedRuntime`). */\nexport type EnhanceRuntime<R> = Context.Context<R> | ManagedRuntime.ManagedRuntime<R, never>;\n\n/**\n * Effect-based handlers for the two phases of an enhanced form submission,\n * plus `onError` for the errors they fail with. `ESubmit` / `EResult` are the\n * errors `onSubmit` / `onResult` may fail with, and `E` (their union by\n * default) the error `onError` receives. Each handler is called as a method of\n * the handlers object, so `this` in a handler written as a method is that\n * object.\n */\nexport interface EnhanceHandlers<\n R = never,\n ESubmit = never,\n EResult = never,\n E = ESubmit | EResult,\n> {\n /**\n * Runs before the request is sent. Call `input.cancel()` to abort the\n * submission (the result phase then never runs). Use for optimistic UI or\n * validation.\n *\n * If it fails with `ESubmit`, the submission is cancelled and the error goes\n * to {@link EnhanceHandlers.onError | onError}.\n */\n readonly onSubmit?: ((input: SubmitInput) => Effect.Effect<void, ESubmit, R>) | undefined;\n /**\n * Runs once the action responds, with the `ActionResult` and SvelteKit's\n * `update()` (which applies the default behaviour — updating `page.form`,\n * resetting the form, invalidating). If omitted, SvelteKit's default\n * behaviour applies automatically.\n *\n * If it fails with `EResult`, the error goes to\n * {@link EnhanceHandlers.onError | onError}; SvelteKit's default behaviour\n * is not applied in its place.\n */\n readonly onResult?: ((options: ResultOptions) => Effect.Effect<void, EResult, R>) | undefined;\n /**\n * Handles an error `onSubmit` or `onResult` failed with (`E`, the union of\n * their error types), as `Effect.catch` would. It runs on the same runtime\n * and must not fail itself.\n *\n * Write it after `onSubmit` / `onResult` for `error` to be inferred\n * precisely. Written before a handler whose parameters are not annotated\n * (such as `onResult: ({ result }) => ...`), it still type-checks, but\n * `error` is `unknown`: TypeScript types `onError`'s parameter before it has\n * seen that handler's error type. An annotated parameter (or a function\n * passed by name) must accept every error the handlers fail with, in either\n * order.\n *\n * Only failures reach it: a defect or interruption (in a handler or in\n * `onError`) still rejects the promise SvelteKit awaits, as does a failure\n * when `onError` is omitted (rejecting with the error itself, as if the\n * handler ended in `Effect.orDie`). SvelteKit does not catch that rejection:\n * it sends no request after a rejected `onSubmit`, applies no default result\n * after a rejected `onResult`, and the browser reports an unhandled\n * rejection.\n */\n readonly onError?: ((error: E) => Effect.Effect<void, never, R>) | undefined;\n}\n\n/** Options for {@link makeSubmitFunction}. */\nexport interface EnhanceOptions<R = never> {\n /**\n * The runtime to run the handler effects against, providing every service\n * `R` they require. Required when the handlers (or `onError`) require\n * services; omit it when they require none (`R = never`), and they run on\n * the default runtime.\n */\n readonly runtime?: EnhanceRuntime<R> | undefined;\n}\n\n/**\n * The options argument of `Forms.enhance`, as a rest tuple: optional when the\n * handlers require no services (`R = never`), and otherwise required, with a\n * `runtime` that provides `R`. There is no ambient runtime to fall back on, so\n * handlers that require services and run without one would die with a\n * missing-service defect. A function that wraps `Forms.enhance` for a generic\n * `R` takes its options as `...options: EnhanceOptionsArgs<R>` and forwards\n * them unchanged.\n */\nexport type EnhanceOptionsArgs<R> = [R] extends [never]\n ? [options?: EnhanceOptions<never> | undefined]\n : [options: EnhanceOptions<R> & { readonly runtime: EnhanceRuntime<R> }];\n\n/** The handler names {@link makeSubmitFunction} accepts. */\nexport type EnhanceHandlerKey = keyof EnhanceHandlers;\n\n/**\n * Records which handlers a handlers object names: `Keys` is inferred from the\n * object's keys, which TypeScript knows before it types any handler.\n */\nexport type HandlerKeys<Keys extends EnhanceHandlerKey> = { readonly [Key in Keys]?: unknown };\n\n/**\n * The default of a handler's error (`ESubmit` / `EResult`) while TypeScript\n * has not inferred it: for a handler it types after `onError`, for one it\n * skips in its first inference pass (a handler whose parameters are not\n * annotated), or for one that is absent (and left out by `Keys`).\n *\n * It is `any` so that every handler type-checks against it, whatever it fails\n * with: when a call does not type-check, TypeScript may report the errors\n * against its first-pass inference, and a handler that did not fit this\n * default would then be blamed for a missing or wrong runtime. Detected with\n * {@link IsErrorNotInferred}, never left in `onError`'s parameter type.\n */\nexport type ErrorNotInferred = any;\n\n/** Whether `Errors` includes a handler error not inferred yet ({@link ErrorNotInferred}). */\nexport type IsErrorNotInferred<Errors> = 0 extends 1 & Errors ? true : false;\n\n/**\n * The default of a handler's requirements (`RSubmit` / `RResult` / `RError`)\n * while TypeScript has not inferred them: `unknown`, which every handler's\n * requirements are assignable to (see {@link ErrorNotInferred} for why), and\n * which {@link RequiredServices} counts as none.\n */\nexport type ServicesNotInferred = unknown;\n\n/**\n * The services a handler requires: `R`, or none while it is not inferred\n * ({@link ServicesNotInferred}), as for an absent handler.\n *\n * Since `unknown` must count as none, so does every requirements type that\n * `unknown` is assignable to: an effect typed as requiring `any` or `unknown`\n * (to which a union with `unknown` collapses), such as one annotated\n * `Effect.Effect<void, never, any>`, is treated as requiring no services, so\n * no runtime is demanded for it. Such a type names no service a runtime could\n * be checked against, and only a top type fits every handler in TypeScript's\n * first inference pass.\n */\nexport type RequiredServices<R> = unknown extends R ? never : R;\n\n/** The errors of the handlers named in `Keys`. */\nexport type HandlerErrors<Keys extends EnhanceHandlerKey, ESubmit, EResult> =\n | (\"onSubmit\" extends Keys ? ESubmit : never)\n | (\"onResult\" extends Keys ? EResult : never);\n\n/**\n * The error an unannotated `onError` receives: the handlers' errors, or\n * `unknown` while one of them is not inferred yet (`onError` written before a\n * handler whose parameters are not annotated).\n */\nexport type OnErrorInput<Errors> = IsErrorNotInferred<Errors> extends true ? unknown : Errors;\n\n/**\n * Requires `onError` to accept every error in `Errors` when its parameter is\n * annotated (`E` is then inferred from the annotation). The check waits while\n * a handler's error is not inferred yet, and applies once it is.\n */\nexport type OnErrorAccepts<R, Errors, E> =\n IsErrorNotInferred<Errors> extends true\n ? unknown\n : [Errors] extends [E]\n ? unknown\n : OnErrorMustAccept<R, Errors>;\n\n/** The `onError` that {@link OnErrorAccepts} requires. */\nexport interface OnErrorMustAccept<R, Errors> {\n readonly onError?: ((error: Errors) => Effect.Effect<void, never, R>) | undefined;\n}\n\n/** Run an `Effect<A, E, R>` on the given runtime (or the default when none). */\nconst runPromiseWith =\n <R>(runtime: EnhanceRuntime<R> | undefined) =>\n <A, E>(effect: Effect.Effect<A, E, R>): Promise<A> => {\n if (runtime === undefined) return Effect.runPromise(effect as Effect.Effect<A, E, never>);\n return Context.isContext(runtime)\n ? Effect.runPromiseWith(runtime)(effect)\n : runtime.runPromise(effect);\n };\n\n/**\n * The handlers {@link makeSubmitFunction} accepts: {@link EnhanceHandlers},\n * with each handler's requirements in a parameter of its own (`RSubmit`,\n * `RResult`, `RError`). TypeScript infers one candidate per handler and does\n * not union them, so a single requirements parameter would reject handlers\n * that require different services even when the runtime provides them all.\n */\nexport type EnhanceHandlersBy<RSubmit, RResult, RError, ESubmit, EResult, E> = Pick<\n EnhanceHandlers<RSubmit, ESubmit, EResult, E>,\n \"onSubmit\"\n> &\n Pick<EnhanceHandlers<RResult, ESubmit, EResult, E>, \"onResult\"> &\n Pick<EnhanceHandlers<RError, ESubmit, EResult, E>, \"onError\">;\n\n/**\n * Build a SvelteKit `SubmitFunction` from Effect-based handlers. See\n * `Forms.enhance` for the public entry point and documentation.\n *\n * The type parameters are inferred, never written. `RSubmit`, `RResult` and\n * `RError` are the services each handler requires (see\n * {@link EnhanceHandlersBy}). `Keys` names the handlers present, and `E` (the\n * error `onError` receives) is computed from their errors, or inferred from\n * `onError`'s parameter annotation and then checked against them, so a\n * handlers object type-checks whatever its property order (see\n * {@link EnhanceHandlers.onError}). The options argument, and its `runtime`,\n * are required when the handlers require any service, and the runtime must\n * provide all of them (see {@link EnhanceOptionsArgs}).\n *\n * When a call does not type-check, TypeScript may report it against its first\n * inference pass, which skips handlers whose parameters are not annotated. The\n * defaults of the handler parameters ({@link ErrorNotInferred},\n * {@link ServicesNotInferred}) accept any handler, so a missing or wrong\n * runtime is reported on the call or on the runtime, never on a handler.\n */\nexport const makeSubmitFunction = <\n RSubmit = ServicesNotInferred,\n RResult = ServicesNotInferred,\n RError = ServicesNotInferred,\n ESubmit = ErrorNotInferred,\n EResult = ErrorNotInferred,\n Keys extends EnhanceHandlerKey = never,\n E = OnErrorInput<HandlerErrors<Keys, ESubmit, EResult>>,\n>(\n handlers: EnhanceHandlersBy<RSubmit, RResult, RError, ESubmit, EResult, E> &\n HandlerKeys<Keys> &\n NoInfer<OnErrorAccepts<RError, HandlerErrors<Keys, ESubmit, EResult>, E>>,\n // The requirements are inferred from the handlers alone; the runtime is\n // then checked against their union.\n ...rest: NoInfer<\n EnhanceOptionsArgs<\n RequiredServices<RSubmit> | RequiredServices<RResult> | RequiredServices<RError>\n >\n >\n): SubmitFunction => {\n type R = RequiredServices<RSubmit> | RequiredServices<RResult> | RequiredServices<RError>;\n // Either branch of `EnhanceOptionsArgs<R>`: the `never` one only when `R`\n // is `never`, where the two coincide.\n const options = rest[0] as EnhanceOptions<R> | undefined;\n const run = runPromiseWith(options?.runtime);\n // Each handler requires a part of `R`, which the runtime provides in full.\n const phases = handlers as EnhanceHandlers<R, ESubmit, EResult, E>;\n // `E` is the union of the errors of the handlers present, so `onError`\n // accepts whatever either handler fails with.\n const onError = handlers.onError as\n | ((error: ESubmit | EResult) => Effect.Effect<void, never, R>)\n | undefined;\n // Each handler is called as a method of the handlers object (`this` is\n // `handlers`), as 0.5.0 called `onSubmit`.\n const handleError =\n onError === undefined ? undefined : (error: ESubmit | EResult) => onError.call(handlers, error);\n return async (input) => {\n // `onSubmit` and `onResult` are read on each submission, so a handler\n // replaced on the handlers object after `enhance()` is the one that runs.\n // `onResult` is read once `onSubmit` has run, so `onSubmit` may set it.\n const submit = phases.onSubmit?.(input);\n if (submit !== undefined) {\n await run(\n handleError === undefined\n ? submit\n : submit.pipe(\n Effect.catch((error) =>\n Effect.sync(() => input.cancel()).pipe(Effect.andThen(handleError(error))),\n ),\n ),\n );\n }\n const { onResult } = phases;\n // Returning `undefined` lets SvelteKit apply its default result behaviour.\n if (!onResult) return undefined;\n return (resultOptions) => {\n const result = onResult.call(handlers, resultOptions);\n return run(handleError === undefined ? result : result.pipe(Effect.catch(handleError)));\n };\n };\n};\n"],"mappings":";;;AAoLA,MAAM,kBACA,aACG,WAA+C;CACpD,IAAI,YAAY,KAAA,GAAW,OAAO,OAAO,WAAW,MAAoC;CACxF,OAAO,QAAQ,UAAU,OAAO,IAC5B,OAAO,eAAe,OAAO,CAAC,CAAC,MAAM,IACrC,QAAQ,WAAW,MAAM;AAC/B;;;;;;;;;;;;;;;;;;;;;AAoCF,MAAa,sBASX,UAKA,GAAG,SAKgB;CAInB,MAAM,UAAU,KAAK;CACrB,MAAM,MAAM,eAAe,SAAS,OAAO;CAE3C,MAAM,SAAS;CAGf,MAAM,UAAU,SAAS;CAKzB,MAAM,cACJ,YAAY,KAAA,IAAY,KAAA,KAAa,UAA6B,QAAQ,KAAK,UAAU,KAAK;CAChG,OAAO,OAAO,UAAU;EAItB,MAAM,SAAS,OAAO,WAAW,KAAK;EACtC,IAAI,WAAW,KAAA,GACb,MAAM,IACJ,gBAAgB,KAAA,IACZ,SACA,OAAO,KACL,OAAO,OAAO,UACZ,OAAO,WAAW,MAAM,OAAO,CAAC,CAAC,CAAC,KAAK,OAAO,QAAQ,YAAY,KAAK,CAAC,CAAC,CAC3E,CACF,CACN;EAEF,MAAM,EAAE,aAAa;EAErB,IAAI,CAAC,UAAU,OAAO,KAAA;EACtB,QAAQ,kBAAkB;GACxB,MAAM,SAAS,SAAS,KAAK,UAAU,aAAa;GACpD,OAAO,IAAI,gBAAgB,KAAA,IAAY,SAAS,OAAO,KAAK,OAAO,MAAM,WAAW,CAAC,CAAC;EACxF;CACF;AACF"}
1
+ {"version":3,"file":"enhance.js","names":[],"sources":["../../src/internal/enhance.ts"],"sourcesContent":["/**\n * The runtime-agnostic core of the `use:enhance` bridge, kept free of any\n * `$app/*` import so it can be unit-tested outside a SvelteKit app build.\n */\n\nimport type { SubmitFunction } from \"$app/forms\";\nimport * as Context from \"effect/Context\";\nimport * as Effect from \"effect/Effect\";\nimport * as ManagedRuntime from \"effect/ManagedRuntime\";\n\n/** The input SvelteKit passes to a `SubmitFunction` before the request is sent. */\nexport type SubmitInput = Parameters<SubmitFunction>[0];\n\n/** The result callback a `SubmitFunction` may return, run once the action responds. */\ntype ResultCallback = Extract<Awaited<ReturnType<SubmitFunction>>, (...args: never) => void>;\n\n/** The options passed to the result callback (`result`, `update`, ...). */\nexport type ResultOptions = Parameters<ResultCallback>[0];\n\n/** A runtime the handler effects can run against (a `Context` or `ManagedRuntime`). */\nexport type EnhanceRuntime<R> = Context.Context<R> | ManagedRuntime.ManagedRuntime<R, never>;\n\n/**\n * Effect-based handlers for the two phases of an enhanced form submission,\n * plus `onError` for the errors they fail with. `ESubmit` / `EResult` are the\n * errors `onSubmit` / `onResult` may fail with, and `E` (their union by\n * default) the error `onError` receives. Each handler is called as a method of\n * the handlers object, so `this` in a handler written as a method is that\n * object.\n */\nexport interface EnhanceHandlers<\n R = never,\n ESubmit = never,\n EResult = never,\n E = ESubmit | EResult,\n> {\n /**\n * Runs before the request is sent. Call `input.cancel()` to abort the\n * submission (the result phase then never runs). Use for optimistic UI or\n * validation.\n *\n * If it fails with `ESubmit`, the submission is cancelled and the error goes\n * to {@link EnhanceHandlers.onError | onError}.\n */\n readonly onSubmit?: ((input: SubmitInput) => Effect.Effect<void, ESubmit, R>) | undefined;\n /**\n * Runs once the action responds, with the `ActionResult` and SvelteKit's\n * `update()` (which applies the default behaviour — updating `page.form`,\n * resetting the form, invalidating). If omitted, SvelteKit's default\n * behaviour applies automatically.\n *\n * If it fails with `EResult`, the error goes to\n * {@link EnhanceHandlers.onError | onError}; SvelteKit's default behaviour\n * is not applied in its place.\n */\n readonly onResult?: ((options: ResultOptions) => Effect.Effect<void, EResult, R>) | undefined;\n /**\n * Handles an error `onSubmit` or `onResult` failed with (`E`, the union of\n * their error types), as `Effect.catch` would. It runs on the same runtime\n * and must not fail itself.\n *\n * Write it after `onSubmit` / `onResult` for `error` to be inferred\n * precisely. Written before a handler whose parameters are not annotated\n * (such as `onResult: ({ result }) => ...`), it still type-checks, but\n * `error` is `unknown`: TypeScript types `onError`'s parameter before it has\n * seen that handler's error type. An annotated parameter (or a function\n * passed by name) must accept every error the handlers fail with, in either\n * order.\n *\n * Only failures reach it: a defect or interruption (in a handler or in\n * `onError`) still rejects the promise SvelteKit awaits, as does a failure\n * when `onError` is omitted (rejecting with the error itself, as if the\n * handler ended in `Effect.orDie`). SvelteKit does not catch that rejection:\n * it sends no request after a rejected `onSubmit`, applies no default result\n * after a rejected `onResult`, and the browser reports an unhandled\n * rejection.\n */\n readonly onError?: ((error: E) => Effect.Effect<void, never, R>) | undefined;\n}\n\n/** Options for {@link makeSubmitFunction}. */\nexport interface EnhanceOptions<R = never> {\n /**\n * The runtime to run the handler effects against, providing every service\n * `R` they require. Required when the handlers (or `onError`) require\n * services; omit it when they require none (`R = never`), and they run on\n * the default runtime.\n */\n readonly runtime?: EnhanceRuntime<R> | undefined;\n}\n\n/**\n * The options argument of `Forms.enhance`, as a rest tuple: optional when the\n * handlers require no services (`R = never`), and otherwise required, with a\n * `runtime` that provides `R`. There is no ambient runtime to fall back on, so\n * handlers that require services and run without one would die with a\n * missing-service defect. A function that wraps `Forms.enhance` for a generic\n * `R` takes its options as `...options: EnhanceOptionsArgs<R>` and forwards\n * them unchanged.\n */\nexport type EnhanceOptionsArgs<R> = [R] extends [never]\n ? [options?: EnhanceOptions<never> | undefined]\n : [options: EnhanceOptions<R> & { readonly runtime: EnhanceRuntime<R> }];\n\n/** The handler names {@link makeSubmitFunction} accepts. */\nexport type EnhanceHandlerKey = keyof EnhanceHandlers;\n\n/**\n * Records which handlers a handlers object names: `Keys` is inferred from the\n * object's keys, which TypeScript knows before it types any handler.\n */\nexport type HandlerKeys<Keys extends EnhanceHandlerKey> = { readonly [Key in Keys]?: unknown };\n\n/**\n * The default of a handler's error (`ESubmit` / `EResult`) while TypeScript\n * has not inferred it: for a handler it types after `onError`, for one it\n * skips in its first inference pass (a handler whose parameters are not\n * annotated), or for one that is absent (and left out by `Keys`).\n *\n * It is `any` so that every handler type-checks against it, whatever it fails\n * with: when a call does not type-check, TypeScript may report the errors\n * against its first-pass inference, and a handler that did not fit this\n * default would then be blamed for a missing or wrong runtime. Detected with\n * {@link IsErrorNotInferred}, never left in `onError`'s parameter type.\n */\nexport type ErrorNotInferred = any;\n\n/** Whether `Errors` includes a handler error not inferred yet ({@link ErrorNotInferred}). */\nexport type IsErrorNotInferred<Errors> = 0 extends 1 & Errors ? true : false;\n\n/**\n * The default of a handler's requirements (`RSubmit` / `RResult` / `RError`)\n * while TypeScript has not inferred them: `unknown`, which every handler's\n * requirements are assignable to (see {@link ErrorNotInferred} for why), and\n * which {@link RequiredServices} counts as none.\n */\nexport type ServicesNotInferred = unknown;\n\n/**\n * The services a handler requires: `R`, or none while it is not inferred\n * ({@link ServicesNotInferred}), as for an absent handler.\n *\n * Since `unknown` must count as none, so does every requirements type that\n * `unknown` is assignable to: an effect typed as requiring `any` or `unknown`\n * (to which a union with `unknown` collapses), such as one annotated\n * `Effect.Effect<void, never, any>`, is treated as requiring no services, so\n * no runtime is demanded for it. Such a type names no service a runtime could\n * be checked against, and only a top type fits every handler in TypeScript's\n * first inference pass.\n */\nexport type RequiredServices<R> = unknown extends R ? never : R;\n\n/** The errors of the handlers named in `Keys`. */\nexport type HandlerErrors<Keys extends EnhanceHandlerKey, ESubmit, EResult> =\n | (\"onSubmit\" extends Keys ? ESubmit : never)\n | (\"onResult\" extends Keys ? EResult : never);\n\n/**\n * The error an unannotated `onError` receives: the handlers' errors, or\n * `unknown` while one of them is not inferred yet (`onError` written before a\n * handler whose parameters are not annotated).\n */\nexport type OnErrorInput<Errors> = IsErrorNotInferred<Errors> extends true ? unknown : Errors;\n\n/**\n * Requires `onError` to accept every error in `Errors` when its parameter is\n * annotated (`E` is then inferred from the annotation). The check waits while\n * a handler's error is not inferred yet, and applies once it is.\n */\nexport type OnErrorAccepts<R, Errors, E> =\n IsErrorNotInferred<Errors> extends true\n ? unknown\n : [Errors] extends [E]\n ? unknown\n : OnErrorMustAccept<R, Errors>;\n\n/** The `onError` that {@link OnErrorAccepts} requires. */\nexport interface OnErrorMustAccept<R, Errors> {\n readonly onError?: ((error: Errors) => Effect.Effect<void, never, R>) | undefined;\n}\n\n/** Run an `Effect<A, E, R>` on the given runtime (or the default when none). */\nconst runPromiseWith =\n <R>(runtime: EnhanceRuntime<R> | undefined) =>\n <A, E>(effect: Effect.Effect<A, E, R>): Promise<A> => {\n if (runtime === undefined) {\n // SAFETY: `EnhanceOptionsArgs` makes the runtime optional only when the\n // handlers require no services, so without one `R` is `never`.\n return Effect.runPromise(effect as Effect.Effect<A, E, never>);\n }\n return Context.isContext(runtime)\n ? Effect.runPromiseWith(runtime)(effect)\n : runtime.runPromise(effect);\n };\n\n/**\n * The handlers {@link makeSubmitFunction} accepts: {@link EnhanceHandlers},\n * with each handler's requirements in a parameter of its own (`RSubmit`,\n * `RResult`, `RError`). TypeScript infers one candidate per handler and does\n * not union them, so a single requirements parameter would reject handlers\n * that require different services even when the runtime provides them all.\n */\nexport type EnhanceHandlersBy<RSubmit, RResult, RError, ESubmit, EResult, E> = Pick<\n EnhanceHandlers<RSubmit, ESubmit, EResult, E>,\n \"onSubmit\"\n> &\n Pick<EnhanceHandlers<RResult, ESubmit, EResult, E>, \"onResult\"> &\n Pick<EnhanceHandlers<RError, ESubmit, EResult, E>, \"onError\">;\n\n/**\n * Build a SvelteKit `SubmitFunction` from Effect-based handlers. See\n * `Forms.enhance` for the public entry point and documentation.\n *\n * The type parameters are inferred, never written. `RSubmit`, `RResult` and\n * `RError` are the services each handler requires (see\n * {@link EnhanceHandlersBy}). `Keys` names the handlers present, and `E` (the\n * error `onError` receives) is computed from their errors, or inferred from\n * `onError`'s parameter annotation and then checked against them, so a\n * handlers object type-checks whatever its property order (see\n * {@link EnhanceHandlers.onError}). The options argument, and its `runtime`,\n * are required when the handlers require any service, and the runtime must\n * provide all of them (see {@link EnhanceOptionsArgs}).\n *\n * When a call does not type-check, TypeScript may report it against its first\n * inference pass, which skips handlers whose parameters are not annotated. The\n * defaults of the handler parameters ({@link ErrorNotInferred},\n * {@link ServicesNotInferred}) accept any handler, so a missing or wrong\n * runtime is reported on the call or on the runtime, never on a handler.\n */\nexport const makeSubmitFunction = <\n RSubmit = ServicesNotInferred,\n RResult = ServicesNotInferred,\n RError = ServicesNotInferred,\n ESubmit = ErrorNotInferred,\n EResult = ErrorNotInferred,\n Keys extends EnhanceHandlerKey = never,\n E = OnErrorInput<HandlerErrors<Keys, ESubmit, EResult>>,\n>(\n handlers: EnhanceHandlersBy<RSubmit, RResult, RError, ESubmit, EResult, E> &\n HandlerKeys<Keys> &\n NoInfer<OnErrorAccepts<RError, HandlerErrors<Keys, ESubmit, EResult>, E>>,\n // The requirements are inferred from the handlers alone; the runtime is\n // then checked against their union.\n ...rest: NoInfer<\n EnhanceOptionsArgs<\n RequiredServices<RSubmit> | RequiredServices<RResult> | RequiredServices<RError>\n >\n >\n): SubmitFunction => {\n type R = RequiredServices<RSubmit> | RequiredServices<RResult> | RequiredServices<RError>;\n // SAFETY: `rest` is either branch of `EnhanceOptionsArgs<R>`: the `never`\n // one only when `R` is `never`, where the two coincide.\n const options = rest[0] as EnhanceOptions<R> | undefined;\n const run = runPromiseWith(options?.runtime);\n // SAFETY: each handler requires a part of `R`, which the runtime provides in full.\n const phases = handlers as EnhanceHandlers<R, ESubmit, EResult, E>;\n // SAFETY: `E` is the union of the errors of the handlers present, so\n // `onError` accepts whatever either handler fails with.\n const onError = handlers.onError as\n | ((error: ESubmit | EResult) => Effect.Effect<void, never, R>)\n | undefined;\n // Each handler is called as a method of the handlers object (`this` is\n // `handlers`), as 0.5.0 called `onSubmit`.\n const handleError =\n onError === undefined ? undefined : (error: ESubmit | EResult) => onError.call(handlers, error);\n return async (input) => {\n // `onSubmit` and `onResult` are read on each submission, so a handler\n // replaced on the handlers object after `enhance()` is the one that runs.\n // `onResult` is read once `onSubmit` has run, so `onSubmit` may set it.\n const submit = phases.onSubmit?.(input);\n if (submit !== undefined) {\n await run(\n handleError === undefined\n ? submit\n : submit.pipe(\n Effect.catch((error) =>\n Effect.sync(() => input.cancel()).pipe(Effect.andThen(handleError(error))),\n ),\n ),\n );\n }\n const { onResult } = phases;\n // Returning `undefined` lets SvelteKit apply its default result behaviour.\n if (!onResult) return undefined;\n return (resultOptions) => {\n const result = onResult.call(handlers, resultOptions);\n return run(handleError === undefined ? result : result.pipe(Effect.catch(handleError)));\n };\n };\n};\n"],"mappings":";;;;;AAsLA,MAAM,kBACA,aACG,WAA+C;CACpD,IAAI,YAAY,KAAA,GAGd,OAAO,OAAO,WAAW,MAAoC;CAE/D,OAAO,QAAQ,UAAU,OAAO,IAC5B,OAAO,eAAe,OAAO,CAAC,CAAC,MAAM,IACrC,QAAQ,WAAW,MAAM;AAC/B;;;;;;;;;;;;;;;;;;;;;AAoCF,MAAa,sBASX,UAKA,GAAG,SAKgB;CAInB,MAAM,UAAU,KAAK;CACrB,MAAM,MAAM,eAAe,SAAS,OAAO;CAE3C,MAAM,SAAS;CAGf,MAAM,UAAU,SAAS;CAKzB,MAAM,cACJ,YAAY,KAAA,IAAY,KAAA,KAAa,UAA6B,QAAQ,KAAK,UAAU,KAAK;CAChG,OAAO,OAAO,UAAU;EAItB,MAAM,SAAS,OAAO,WAAW,KAAK;EACtC,IAAI,WAAW,KAAA,GACb,MAAM,IACJ,gBAAgB,KAAA,IACZ,SACA,OAAO,KACL,OAAO,OAAO,UACZ,OAAO,WAAW,MAAM,OAAO,CAAC,CAAC,CAAC,KAAK,OAAO,QAAQ,YAAY,KAAK,CAAC,CAAC,CAC3E,CACF,CACN;EAEF,MAAM,EAAE,aAAa;EAErB,IAAI,CAAC,UAAU,OAAO,KAAA;EACtB,QAAQ,kBAAkB;GACxB,MAAM,SAAS,SAAS,KAAK,UAAU,aAAa;GACpD,OAAO,IAAI,gBAAgB,KAAA,IAAY,SAAS,OAAO,KAAK,OAAO,MAAM,WAAW,CAAC,CAAC;EACxF;CACF;AACF"}
@@ -0,0 +1,13 @@
1
+ import "@sveltejs/kit";
2
+ import "effect/Cause";
3
+ //#region src/internal/error.d.ts
4
+ /**
5
+ * The body of a SvelteKit HTTP error: a message, or your app's `App.Error`
6
+ * (with `status` optional — the error's status wins over it), exactly the body
7
+ * SvelteKit's own `error(status, body)` accepts.
8
+ */
9
+ export type KitErrorBody = string | (Omit<App.Error, "status"> & {
10
+ readonly status?: number;
11
+ });
12
+ //#endregion
13
+ //# sourceMappingURL=error.d.ts.map
@@ -1,5 +1,6 @@
1
- import { Cause } from "effect";
1
+ import * as Predicate from "effect/Predicate";
2
2
  import { error, isHttpError, isRedirect } from "@sveltejs/kit";
3
+ import * as Cause from "effect/Cause";
3
4
  //#region src/internal/error.ts
4
5
  /**
5
6
  * Custom error type that preserves the original Effect Cause.
@@ -42,9 +43,9 @@ const kitErrorWith = error;
42
43
  * `App.Error` type) is dropped in favour of that default.
43
44
  */
44
45
  const throwKitError = (status, body) => {
45
- if (body === void 0 || typeof body === "string") return kitErrorWith(status, body);
46
+ if (body === void 0 || Predicate.isString(body)) return kitErrorWith(status, body);
46
47
  const { message, ...properties } = body;
47
- return kitErrorWith(status, typeof message === "string" ? message : void 0, properties);
48
+ return kitErrorWith(status, Predicate.isString(message) ? message : void 0, properties);
48
49
  };
49
50
  //#endregion
50
51
  export { EffectCauseError, causeToThrowable, throwKitError };
@@ -1 +1 @@
1
- {"version":3,"file":"error.js","names":["kitError"],"sources":["../../src/internal/error.ts"],"sourcesContent":["import { error as kitError, isHttpError, isRedirect } from \"@sveltejs/kit\";\nimport { Cause } from \"effect\";\n\n/**\n * Custom error type that preserves the original Effect Cause.\n */\nexport class EffectCauseError extends Error {\n declare cause: Cause.Cause<unknown>;\n\n constructor(message: string, cause: Cause.Cause<unknown>) {\n super(message);\n this.name = \"EffectCauseError\";\n this.cause = cause;\n }\n}\n\n/**\n * Converts a failed Effect Cause into the value to `throw`.\n *\n * SvelteKit uses thrown `redirect()` and `error()` objects for control flow.\n * When one of those is raised inside an Effect (either thrown, surfacing as a\n * defect, or used as a typed failure) the original object is rethrown so\n * SvelteKit can handle it as intended. Anything else is wrapped in an\n * `EffectCauseError` that preserves the full Cause for debugging.\n */\nexport const causeToThrowable = (cause: Cause.Cause<unknown>): unknown => {\n const squashed = Cause.squash(cause);\n if (isRedirect(squashed) || isHttpError(squashed)) {\n return squashed;\n }\n return new EffectCauseError(Cause.pretty(cause), cause);\n};\n\n/**\n * `error()` with the message and the extra `App.Error` properties as separate\n * arguments. Kit's typed overloads only admit a third argument once the app\n * augments `App.Error`, which this library cannot see.\n */\nconst kitErrorWith = kitError as (\n status: number,\n message?: string,\n properties?: Readonly<Record<string, unknown>>,\n) => never;\n\n/**\n * Throw SvelteKit's `error()` for a string or `App.Error`-shaped body, without\n * the `error(status, body)` overload Kit 3 deprecates (kit#16540): an object\n * body is split into `error(status, message, properties)`.\n *\n * The resulting `HttpError` is the one the deprecated overload built: `status`\n * always wins over a `status` field in the body, and a missing message becomes\n * Kit's default `Error: <status>`. A non-string `message` field (outside the\n * `App.Error` type) is dropped in favour of that default.\n */\nexport const throwKitError = (\n status: number,\n body?: string | Readonly<Record<string, unknown>>,\n): never => {\n if (body === undefined || typeof body === \"string\") return kitErrorWith(status, body);\n const { message, ...properties } = body;\n return kitErrorWith(status, typeof message === \"string\" ? message : undefined, properties);\n};\n"],"mappings":";;;;;;AAMA,IAAa,mBAAb,cAAsC,MAAM;CAG1C,YAAY,SAAiB,OAA6B;EACxD,MAAM,OAAO;EACb,KAAK,OAAO;EACZ,KAAK,QAAQ;CACf;AACF;;;;;;;;;;AAWA,MAAa,oBAAoB,UAAyC;CACxE,MAAM,WAAW,MAAM,OAAO,KAAK;CACnC,IAAI,WAAW,QAAQ,KAAK,YAAY,QAAQ,GAC9C,OAAO;CAET,OAAO,IAAI,iBAAiB,MAAM,OAAO,KAAK,GAAG,KAAK;AACxD;;;;;;AAOA,MAAM,eAAeA;;;;;;;;;;;AAgBrB,MAAa,iBACX,QACA,SACU;CACV,IAAI,SAAS,KAAA,KAAa,OAAO,SAAS,UAAU,OAAO,aAAa,QAAQ,IAAI;CACpF,MAAM,EAAE,SAAS,GAAG,eAAe;CACnC,OAAO,aAAa,QAAQ,OAAO,YAAY,WAAW,UAAU,KAAA,GAAW,UAAU;AAC3F"}
1
+ {"version":3,"file":"error.js","names":["kitError"],"sources":["../../src/internal/error.ts"],"sourcesContent":["import {\n error as kitError,\n isHttpError,\n isRedirect,\n type HttpError,\n type Redirect,\n} from \"@sveltejs/kit\";\nimport * as Cause from \"effect/Cause\";\nimport * as Predicate from \"effect/Predicate\";\n\n/**\n * Custom error type that preserves the original Effect Cause.\n */\nexport class EffectCauseError extends Error {\n declare cause: Cause.Cause<unknown>;\n\n constructor(message: string, cause: Cause.Cause<unknown>) {\n super(message);\n this.name = \"EffectCauseError\";\n this.cause = cause;\n }\n}\n\n/**\n * Converts a failed Effect Cause into the value to `throw`.\n *\n * SvelteKit uses thrown `redirect()` and `error()` objects for control flow.\n * When one of those is raised inside an Effect (either thrown, surfacing as a\n * defect, or used as a typed failure) the original object is rethrown so\n * SvelteKit can handle it as intended. Anything else is wrapped in an\n * `EffectCauseError` that preserves the full Cause for debugging.\n */\nexport const causeToThrowable = (\n cause: Cause.Cause<unknown>,\n): Redirect | HttpError | EffectCauseError => {\n const squashed = Cause.squash(cause);\n if (isRedirect(squashed) || isHttpError(squashed)) {\n return squashed;\n }\n return new EffectCauseError(Cause.pretty(cause), cause);\n};\n\n/**\n * The body of a SvelteKit HTTP error: a message, or your app's `App.Error`\n * (with `status` optional — the error's status wins over it), exactly the body\n * SvelteKit's own `error(status, body)` accepts.\n */\nexport type KitErrorBody = string | (Omit<App.Error, \"status\"> & { readonly status?: number });\n\n/**\n * `error()` with the message and the extra `App.Error` properties as separate\n * arguments. Kit's typed overloads only admit a third argument once the app\n * augments `App.Error`, which this library cannot see.\n */\n// SAFETY: at runtime `error(status, message, properties)` accepts any\n// properties object (it spreads it into the `HttpError` body); only its typed\n// overload withholds the third argument until the app augments `App.Error`.\nconst kitErrorWith = kitError as (\n status: number,\n message?: string,\n properties?: Omit<Exclude<KitErrorBody, string>, \"message\">,\n) => never;\n\n/**\n * Throw SvelteKit's `error()` for a string or `App.Error`-shaped body, without\n * the `error(status, body)` overload Kit 3 deprecates (kit#16540): an object\n * body is split into `error(status, message, properties)`.\n *\n * The resulting `HttpError` is the one the deprecated overload built: `status`\n * always wins over a `status` field in the body, and a missing message becomes\n * Kit's default `Error: <status>`. A non-string `message` field (outside the\n * `App.Error` type) is dropped in favour of that default.\n */\nexport const throwKitError = (status: number, body?: KitErrorBody): never => {\n if (body === undefined || Predicate.isString(body)) return kitErrorWith(status, body);\n const { message, ...properties } = body;\n return kitErrorWith(status, Predicate.isString(message) ? message : undefined, properties);\n};\n"],"mappings":";;;;;;;AAaA,IAAa,mBAAb,cAAsC,MAAM;CAG1C,YAAY,SAAiB,OAA6B;EACxD,MAAM,OAAO;EACb,KAAK,OAAO;EACZ,KAAK,QAAQ;CACf;AACF;;;;;;;;;;AAWA,MAAa,oBACX,UAC4C;CAC5C,MAAM,WAAW,MAAM,OAAO,KAAK;CACnC,IAAI,WAAW,QAAQ,KAAK,YAAY,QAAQ,GAC9C,OAAO;CAET,OAAO,IAAI,iBAAiB,MAAM,OAAO,KAAK,GAAG,KAAK;AACxD;;;;;;AAiBA,MAAM,eAAeA;;;;;;;;;;;AAgBrB,MAAa,iBAAiB,QAAgB,SAA+B;CAC3E,IAAI,SAAS,KAAA,KAAa,UAAU,SAAS,IAAI,GAAG,OAAO,aAAa,QAAQ,IAAI;CACpF,MAAM,EAAE,SAAS,GAAG,eAAe;CACnC,OAAO,aAAa,QAAQ,UAAU,SAAS,OAAO,IAAI,UAAU,KAAA,GAAW,UAAU;AAC3F"}
@@ -1,4 +1,6 @@
1
- import { Effect, Queue, Stream } from "effect";
1
+ import * as Effect from "effect/Effect";
2
+ import * as Stream from "effect/Stream";
3
+ import * as Queue from "effect/Queue";
2
4
  //#region src/internal/navigation-events.ts
3
5
  /**
4
6
  * Pure, `$app/navigation`-free core for the navigation-event bridge in
@@ -1 +1 @@
1
- {"version":3,"file":"navigation-events.js","names":[],"sources":["../../src/internal/navigation-events.ts"],"sourcesContent":["/**\n * Pure, `$app/navigation`-free core for the navigation-event bridge in\n * `../Navigation.ts`.\n *\n * The public helpers can't be unit-tested directly because importing them pulls\n * in `$app/navigation` (a SvelteKit virtual module that only exists inside a\n * build). The queue → stream plumbing and the run-per-navigation + cleanup\n * forwarding live here instead, parameterised over the callback registrar, so\n * they can be driven with a stand-in registrar in tests while the public\n * wrappers stay a thin pass-through of SvelteKit's real functions.\n *\n * @internal\n */\n\nimport { Effect, Queue, Stream } from \"effect\";\n\n/**\n * Registers `register`'s callback against a fresh unbounded queue and exposes\n * that queue as a `Stream`. The callback is wired synchronously (so the public\n * wrappers register during component init, where `$app/navigation` requires);\n * each value offered through it is later yielded by the stream.\n */\nexport function registeredStream<A>(\n register: (callback: (value: A) => void) => void,\n): Stream.Stream<A> {\n const queue = Effect.runSync(Queue.unbounded<A>());\n register((value) => {\n Queue.offerUnsafe(queue, value);\n });\n return Stream.fromQueue(queue);\n}\n\n/**\n * Registers `register`'s callback so that each navigation runs `fn` via\n * `runEffect`, forwarding any cleanup function the resolved Effect produces back\n * to the registrar (SvelteKit awaits it before completing the navigation and\n * runs the returned cleanup once the DOM has updated).\n */\nexport function onNavigateWith<A>(\n register: (callback: (value: A) => Promise<(() => void) | void> | (() => void) | void) => void,\n fn: (navigation: A) => Effect.Effect<(() => void) | void>,\n runEffect: <X>(effect: Effect.Effect<X>) => Promise<X>,\n): void {\n register((navigation) => runEffect(fn(navigation)));\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAsBA,SAAgB,iBACd,UACkB;CAClB,MAAM,QAAQ,OAAO,QAAQ,MAAM,UAAa,CAAC;CACjD,UAAU,UAAU;EAClB,MAAM,YAAY,OAAO,KAAK;CAChC,CAAC;CACD,OAAO,OAAO,UAAU,KAAK;AAC/B;;;;;;;AAQA,SAAgB,eACd,UACA,IACA,WACM;CACN,UAAU,eAAe,UAAU,GAAG,UAAU,CAAC,CAAC;AACpD"}
1
+ {"version":3,"file":"navigation-events.js","names":[],"sources":["../../src/internal/navigation-events.ts"],"sourcesContent":["/**\n * Pure, `$app/navigation`-free core for the navigation-event bridge in\n * `../Navigation.ts`.\n *\n * The public helpers can't be unit-tested directly because importing them pulls\n * in `$app/navigation` (a SvelteKit virtual module that only exists inside a\n * build). The queue → stream plumbing and the run-per-navigation + cleanup\n * forwarding live here instead, parameterised over the callback registrar, so\n * they can be driven with a stand-in registrar in tests while the public\n * wrappers stay a thin pass-through of SvelteKit's real functions.\n *\n * @internal\n */\n\nimport * as Effect from \"effect/Effect\";\nimport * as Queue from \"effect/Queue\";\nimport * as Stream from \"effect/Stream\";\n\n/**\n * Registers `register`'s callback against a fresh unbounded queue and exposes\n * that queue as a `Stream`. The callback is wired synchronously (so the public\n * wrappers register during component init, where `$app/navigation` requires);\n * each value offered through it is later yielded by the stream.\n */\nexport function registeredStream<A>(\n register: (callback: (value: A) => void) => void,\n): Stream.Stream<A> {\n const queue = Effect.runSync(Queue.unbounded<A>());\n register((value) => {\n Queue.offerUnsafe(queue, value);\n });\n return Stream.fromQueue(queue);\n}\n\n/**\n * Registers `register`'s callback so that each navigation runs `fn` via\n * `runEffect`, forwarding any cleanup function the resolved Effect produces back\n * to the registrar (SvelteKit awaits it before completing the navigation and\n * runs the returned cleanup once the DOM has updated).\n */\nexport function onNavigateWith<A>(\n register: (callback: (value: A) => Promise<(() => void) | void> | (() => void) | void) => void,\n fn: (navigation: A) => Effect.Effect<(() => void) | void>,\n runEffect: <X>(effect: Effect.Effect<X>) => Promise<X>,\n): void {\n register((navigation) => runEffect(fn(navigation)));\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAwBA,SAAgB,iBACd,UACkB;CAClB,MAAM,QAAQ,OAAO,QAAQ,MAAM,UAAa,CAAC;CACjD,UAAU,UAAU;EAClB,MAAM,YAAY,OAAO,KAAK;CAChC,CAAC;CACD,OAAO,OAAO,UAAU,KAAK;AAC/B;;;;;;;AAQA,SAAgB,eACd,UACA,IACA,WACM;CACN,UAAU,eAAe,UAAU,GAAG,UAAU,CAAC,CAAC;AACpD"}
@@ -1,5 +1,6 @@
1
1
  import "../request-runtime.js";
2
- import { Effect, Exit } from "effect";
2
+ import * as Effect from "effect/Effect";
3
+ import "effect/Exit";
3
4
  import { RemoteFormInvalidField } from "$app/server";
4
5
  //#region src/internal/remote-run.d.ts
5
6
  /**
@@ -8,22 +9,21 @@ import { RemoteFormInvalidField } from "$app/server";
8
9
  * structured/nested validation error drives field-level invalidation instead of
9
10
  * a generic failure. Receives the squashed handler failure.
10
11
  */
11
- type FormErrorMapper = (error: unknown, ctx: {
12
+ export type FormErrorMapper = (error: unknown, ctx: {
12
13
  readonly issue: RemoteFormInvalidField<any>;
13
14
  readonly data: unknown;
14
15
  }) => never;
15
16
  /** Runs a remote handler's effect and settles it (value or thrown via translator). */
16
- type Runner = <A>(effect: Effect.Effect<A, unknown, any>) => Promise<A>;
17
+ export type Runner = <A>(effect: Effect.Effect<A, unknown, any>) => Promise<A>;
17
18
  /** Like {@link Runner}, but with the form's `issue` / `data` for error interop. */
18
- type FormRunner = <A>(effect: Effect.Effect<A, unknown, any>, ctx: {
19
+ export type FormRunner = <A>(effect: Effect.Effect<A, unknown, any>, ctx: {
19
20
  readonly issue: RemoteFormInvalidField<any>;
20
21
  readonly data: unknown;
21
22
  }) => Promise<A>;
22
23
  /** Runners that execute a remote-function handler's Effect on a request runtime, as `runRemote` returns them. */
23
- interface RunHelpers {
24
+ export interface RunHelpers {
24
25
  readonly run: Runner;
25
26
  readonly runForm: FormRunner;
26
27
  }
27
28
  //#endregion
28
- export { FormErrorMapper, FormRunner, RunHelpers, Runner };
29
29
  //# sourceMappingURL=remote-run.d.ts.map
@@ -1,30 +1,27 @@
1
1
  import { SvelteKit } from "../kit.js";
2
- import { Cause, Exit } from "effect";
2
+ import * as Exit from "effect/Exit";
3
+ import * as Cause from "effect/Cause";
3
4
  //#region src/internal/remote-run.ts
4
5
  /** The default translator: Kit control-flow errors through, anything else a 500. */
5
6
  const defaultTranslate = SvelteKit.translate;
7
+ /**
8
+ * Settle an exit (return its value, or throw via the translator) and then run
9
+ * the optional teardown, whether settling returned or threw; a throw becomes
10
+ * the returned promise's rejection.
11
+ */
12
+ const settleThenDispose = (settle, dispose) => new Promise((resolve) => resolve(settle())).finally(() => dispose?.());
6
13
  /** Build the `run` / `runForm` helpers from an exit resolver and a translator. */
7
14
  const makeRunHelpers = (resolve, translate, formError) => {
8
15
  const run = (effect) => {
9
16
  const { runExit, dispose } = resolve();
10
- return runExit(effect).then((exit) => {
11
- try {
12
- return Exit.isSuccess(exit) ? exit.value : translate(exit.cause);
13
- } finally {
14
- dispose?.();
15
- }
16
- });
17
+ return runExit(effect).then((exit) => settleThenDispose(() => Exit.isSuccess(exit) ? exit.value : translate(exit.cause), dispose));
17
18
  };
18
19
  const runForm = (effect, ctx) => {
19
20
  const { runExit, dispose } = resolve();
20
- return runExit(effect).then((exit) => {
21
- try {
22
- if (Exit.isSuccess(exit)) return exit.value;
23
- return formError ? formError(Cause.squash(exit.cause), ctx) : translate(exit.cause);
24
- } finally {
25
- dispose?.();
26
- }
27
- });
21
+ return runExit(effect).then((exit) => settleThenDispose(() => {
22
+ if (Exit.isSuccess(exit)) return exit.value;
23
+ return formError ? formError(Cause.squash(exit.cause), ctx) : translate(exit.cause);
24
+ }, dispose));
28
25
  };
29
26
  return {
30
27
  run,
@@ -1 +1 @@
1
- {"version":3,"file":"remote-run.js","names":[],"sources":["../../src/internal/remote-run.ts"],"sourcesContent":["/**\n * Run/settle helpers for the remote-function wrappers, factored out so they can\n * be unit-tested without importing `$app/server` (a SvelteKit virtual module\n * unavailable outside an app build). The `$app/server`-dependent resolvers live\n * in `remote-functions.ts`; this module only deals in `Exit`s.\n */\n\nimport type { RemoteFormInvalidField as InvalidField } from \"$app/server\";\nimport { Cause, type Effect, Exit } from \"effect\";\nimport type { ErrorTranslator } from \"../request-runtime.js\";\nimport { SvelteKit } from \"../kit.js\";\n\n/** The default translator: Kit control-flow errors through, anything else a 500. */\nexport const defaultTranslate: ErrorTranslator = SvelteKit.translate;\n\n/**\n * Maps a remote *form* handler's failure into SvelteKit's field issues, given\n * the form's parsed `data` and the `issue` helper. It may call `invalid()` so a\n * structured/nested validation error drives field-level invalidation instead of\n * a generic failure. Receives the squashed handler failure.\n */\nexport type FormErrorMapper = (\n error: unknown,\n ctx: { readonly issue: InvalidField<any>; readonly data: unknown },\n) => never;\n\n/** Runs a remote handler's effect and settles it (value or thrown via translator). */\nexport type Runner = <A>(effect: Effect.Effect<A, unknown, any>) => Promise<A>;\n\n/** Like {@link Runner}, but with the form's `issue` / `data` for error interop. */\nexport type FormRunner = <A>(\n effect: Effect.Effect<A, unknown, any>,\n ctx: { readonly issue: InvalidField<any>; readonly data: unknown },\n) => Promise<A>;\n\n/** Runners that execute a remote-function handler's Effect on a request runtime, as `runRemote` returns them. */\nexport interface RunHelpers {\n readonly run: Runner;\n readonly runForm: FormRunner;\n}\n\n/** How to obtain an `Exit` for the current request, plus optional teardown. */\nexport type ExitResolver = () => {\n readonly runExit: <A>(effect: Effect.Effect<A, unknown, any>) => Promise<Exit.Exit<A, unknown>>;\n readonly dispose?: () => void;\n};\n\n/** Build the `run` / `runForm` helpers from an exit resolver and a translator. */\nexport const makeRunHelpers = (\n resolve: ExitResolver,\n translate: ErrorTranslator,\n formError?: FormErrorMapper,\n): RunHelpers => {\n const run: Runner = (effect) => {\n const { runExit, dispose } = resolve();\n return runExit(effect).then((exit) => {\n try {\n return Exit.isSuccess(exit) ? exit.value : translate(exit.cause);\n } finally {\n dispose?.();\n }\n });\n };\n const runForm: FormRunner = (effect, ctx) => {\n const { runExit, dispose } = resolve();\n return runExit(effect).then((exit) => {\n try {\n if (Exit.isSuccess(exit)) return exit.value;\n return formError ? formError(Cause.squash(exit.cause), ctx) : translate(exit.cause);\n } finally {\n dispose?.();\n }\n });\n };\n return { run, runForm };\n};\n"],"mappings":";;;;AAaA,MAAa,mBAAoC,UAAU;;AAmC3D,MAAa,kBACX,SACA,WACA,cACe;CACf,MAAM,OAAe,WAAW;EAC9B,MAAM,EAAE,SAAS,YAAY,QAAQ;EACrC,OAAO,QAAQ,MAAM,CAAC,CAAC,MAAM,SAAS;GACpC,IAAI;IACF,OAAO,KAAK,UAAU,IAAI,IAAI,KAAK,QAAQ,UAAU,KAAK,KAAK;GACjE,UAAU;IACR,UAAU;GACZ;EACF,CAAC;CACH;CACA,MAAM,WAAuB,QAAQ,QAAQ;EAC3C,MAAM,EAAE,SAAS,YAAY,QAAQ;EACrC,OAAO,QAAQ,MAAM,CAAC,CAAC,MAAM,SAAS;GACpC,IAAI;IACF,IAAI,KAAK,UAAU,IAAI,GAAG,OAAO,KAAK;IACtC,OAAO,YAAY,UAAU,MAAM,OAAO,KAAK,KAAK,GAAG,GAAG,IAAI,UAAU,KAAK,KAAK;GACpF,UAAU;IACR,UAAU;GACZ;EACF,CAAC;CACH;CACA,OAAO;EAAE;EAAK;CAAQ;AACxB"}
1
+ {"version":3,"file":"remote-run.js","names":[],"sources":["../../src/internal/remote-run.ts"],"sourcesContent":["/**\n * Run/settle helpers for the remote-function wrappers, factored out so they can\n * be unit-tested without importing `$app/server` (a SvelteKit virtual module\n * unavailable outside an app build). The `$app/server`-dependent resolvers live\n * in `remote-functions.ts`; this module only deals in `Exit`s.\n */\n\nimport type { RemoteFormInvalidField as InvalidField } from \"$app/server\";\nimport * as Cause from \"effect/Cause\";\nimport type * as Effect from \"effect/Effect\";\nimport * as Exit from \"effect/Exit\";\nimport type { ErrorTranslator } from \"../request-runtime.js\";\nimport { SvelteKit } from \"../kit.js\";\n\n/** The default translator: Kit control-flow errors through, anything else a 500. */\nexport const defaultTranslate: ErrorTranslator = SvelteKit.translate;\n\n/**\n * Maps a remote *form* handler's failure into SvelteKit's field issues, given\n * the form's parsed `data` and the `issue` helper. It may call `invalid()` so a\n * structured/nested validation error drives field-level invalidation instead of\n * a generic failure. Receives the squashed handler failure.\n */\nexport type FormErrorMapper = (\n error: unknown,\n ctx: { readonly issue: InvalidField<any>; readonly data: unknown },\n) => never;\n\n/** Runs a remote handler's effect and settles it (value or thrown via translator). */\nexport type Runner = <A>(effect: Effect.Effect<A, unknown, any>) => Promise<A>;\n\n/** Like {@link Runner}, but with the form's `issue` / `data` for error interop. */\nexport type FormRunner = <A>(\n effect: Effect.Effect<A, unknown, any>,\n ctx: { readonly issue: InvalidField<any>; readonly data: unknown },\n) => Promise<A>;\n\n/** Runners that execute a remote-function handler's Effect on a request runtime, as `runRemote` returns them. */\nexport interface RunHelpers {\n readonly run: Runner;\n readonly runForm: FormRunner;\n}\n\n/** How to obtain an `Exit` for the current request, plus optional teardown. */\nexport type ExitResolver = () => {\n readonly runExit: <A>(effect: Effect.Effect<A, unknown, any>) => Promise<Exit.Exit<A, unknown>>;\n readonly dispose?: () => void;\n};\n\n/**\n * Settle an exit (return its value, or throw via the translator) and then run\n * the optional teardown, whether settling returned or threw; a throw becomes\n * the returned promise's rejection.\n */\nconst settleThenDispose = <A>(settle: () => A, dispose: (() => void) | undefined): Promise<A> =>\n new Promise<A>((resolve) => resolve(settle())).finally(() => dispose?.());\n\n/** Build the `run` / `runForm` helpers from an exit resolver and a translator. */\nexport const makeRunHelpers = (\n resolve: ExitResolver,\n translate: ErrorTranslator,\n formError?: FormErrorMapper,\n): RunHelpers => {\n const run: Runner = (effect) => {\n const { runExit, dispose } = resolve();\n return runExit(effect).then((exit) =>\n settleThenDispose(() => (Exit.isSuccess(exit) ? exit.value : translate(exit.cause)), dispose),\n );\n };\n const runForm: FormRunner = (effect, ctx) => {\n const { runExit, dispose } = resolve();\n return runExit(effect).then((exit) =>\n settleThenDispose(() => {\n if (Exit.isSuccess(exit)) return exit.value;\n return formError ? formError(Cause.squash(exit.cause), ctx) : translate(exit.cause);\n }, dispose),\n );\n };\n return { run, runForm };\n};\n"],"mappings":";;;;;AAeA,MAAa,mBAAoC,UAAU;;;;;;AAuC3D,MAAM,qBAAwB,QAAiB,YAC7C,IAAI,SAAY,YAAY,QAAQ,OAAO,CAAC,CAAC,CAAC,CAAC,cAAc,UAAU,CAAC;;AAG1E,MAAa,kBACX,SACA,WACA,cACe;CACf,MAAM,OAAe,WAAW;EAC9B,MAAM,EAAE,SAAS,YAAY,QAAQ;EACrC,OAAO,QAAQ,MAAM,CAAC,CAAC,MAAM,SAC3B,wBAAyB,KAAK,UAAU,IAAI,IAAI,KAAK,QAAQ,UAAU,KAAK,KAAK,GAAI,OAAO,CAC9F;CACF;CACA,MAAM,WAAuB,QAAQ,QAAQ;EAC3C,MAAM,EAAE,SAAS,YAAY,QAAQ;EACrC,OAAO,QAAQ,MAAM,CAAC,CAAC,MAAM,SAC3B,wBAAwB;GACtB,IAAI,KAAK,UAAU,IAAI,GAAG,OAAO,KAAK;GACtC,OAAO,YAAY,UAAU,MAAM,OAAO,KAAK,KAAK,GAAG,GAAG,IAAI,UAAU,KAAK,KAAK;EACpF,GAAG,OAAO,CACZ;CACF;CACA,OAAO;EAAE;EAAK;CAAQ;AACxB"}