@rikalabs/effect-react 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (167) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +179 -0
  3. package/dist/actions/http.d.ts +18 -0
  4. package/dist/actions/index.d.ts +4 -0
  5. package/dist/actions/react.d.ts +7 -0
  6. package/dist/actions/service.d.ts +18 -0
  7. package/dist/actions/types.d.ts +33 -0
  8. package/dist/boundary/codecs.d.ts +40 -0
  9. package/dist/boundary/errors.d.ts +22 -0
  10. package/dist/boundary/index.d.ts +2 -0
  11. package/dist/chunk-2GIUCKL2.js +16 -0
  12. package/dist/chunk-2GIUCKL2.js.map +1 -0
  13. package/dist/chunk-2TG7YEVD.js +11 -0
  14. package/dist/chunk-2TG7YEVD.js.map +1 -0
  15. package/dist/chunk-6FI4ROTW.js +152 -0
  16. package/dist/chunk-6FI4ROTW.js.map +1 -0
  17. package/dist/chunk-C5JI7D7W.js +213 -0
  18. package/dist/chunk-C5JI7D7W.js.map +1 -0
  19. package/dist/chunk-EEYASTXR.js +99 -0
  20. package/dist/chunk-EEYASTXR.js.map +1 -0
  21. package/dist/chunk-H7MOLKTU.js +301 -0
  22. package/dist/chunk-H7MOLKTU.js.map +1 -0
  23. package/dist/chunk-IVIYY6S5.js +77 -0
  24. package/dist/chunk-IVIYY6S5.js.map +1 -0
  25. package/dist/chunk-JKN75OYC.js +87 -0
  26. package/dist/chunk-JKN75OYC.js.map +1 -0
  27. package/dist/chunk-M2CJG6T7.js +24 -0
  28. package/dist/chunk-M2CJG6T7.js.map +1 -0
  29. package/dist/chunk-MDGEGQZB.js +206 -0
  30. package/dist/chunk-MDGEGQZB.js.map +1 -0
  31. package/dist/chunk-NI2GNZ7S.js +78 -0
  32. package/dist/chunk-NI2GNZ7S.js.map +1 -0
  33. package/dist/chunk-O7XTA7H3.js +423 -0
  34. package/dist/chunk-O7XTA7H3.js.map +1 -0
  35. package/dist/chunk-S67FHWAR.js +88 -0
  36. package/dist/chunk-S67FHWAR.js.map +1 -0
  37. package/dist/chunk-SKC3HMF3.js +17 -0
  38. package/dist/chunk-SKC3HMF3.js.map +1 -0
  39. package/dist/chunk-TUJZ6XJY.js +127 -0
  40. package/dist/chunk-TUJZ6XJY.js.map +1 -0
  41. package/dist/chunk-WPV3WFMS.js +38 -0
  42. package/dist/chunk-WPV3WFMS.js.map +1 -0
  43. package/dist/chunk-XIBEKS5A.js +301 -0
  44. package/dist/chunk-XIBEKS5A.js.map +1 -0
  45. package/dist/chunk-YG22YP5K.js +68 -0
  46. package/dist/chunk-YG22YP5K.js.map +1 -0
  47. package/dist/chunk-ZMZQBREU.js +262 -0
  48. package/dist/chunk-ZMZQBREU.js.map +1 -0
  49. package/dist/client/index.cjs +191 -0
  50. package/dist/client/index.cjs.map +1 -0
  51. package/dist/client/index.d.ts +8 -0
  52. package/dist/client/index.js +14 -0
  53. package/dist/client/index.js.map +1 -0
  54. package/dist/config/index.cjs +63 -0
  55. package/dist/config/index.cjs.map +1 -0
  56. package/dist/config/index.d.ts +32 -0
  57. package/dist/config/index.js +9 -0
  58. package/dist/config/index.js.map +1 -0
  59. package/dist/data/index.d.ts +3 -0
  60. package/dist/data/react.d.ts +10 -0
  61. package/dist/data/service.d.ts +20 -0
  62. package/dist/data/types.d.ts +31 -0
  63. package/dist/devtools/events.d.ts +37 -0
  64. package/dist/devtools/index.cjs +149 -0
  65. package/dist/devtools/index.cjs.map +1 -0
  66. package/dist/devtools/index.d.ts +2 -0
  67. package/dist/devtools/index.js +18 -0
  68. package/dist/devtools/index.js.map +1 -0
  69. package/dist/devtools/react.d.ts +8 -0
  70. package/dist/form/index.cjs +301 -0
  71. package/dist/form/index.cjs.map +1 -0
  72. package/dist/form/index.d.ts +3 -0
  73. package/dist/form/index.js +14 -0
  74. package/dist/form/index.js.map +1 -0
  75. package/dist/form/react.d.ts +9 -0
  76. package/dist/form/service.d.ts +3 -0
  77. package/dist/form/types.d.ts +41 -0
  78. package/dist/framework/app.d.ts +21 -0
  79. package/dist/framework/cache.d.ts +10 -0
  80. package/dist/framework/contracts.d.ts +32 -0
  81. package/dist/framework/index.cjs +1006 -0
  82. package/dist/framework/index.cjs.map +1 -0
  83. package/dist/framework/index.d.ts +4 -0
  84. package/dist/framework/index.js +35 -0
  85. package/dist/framework/index.js.map +1 -0
  86. package/dist/framework/manifest.d.ts +12 -0
  87. package/dist/framework/vite.d.ts +13 -0
  88. package/dist/framework-vite/index.cjs +163 -0
  89. package/dist/framework-vite/index.cjs.map +1 -0
  90. package/dist/framework-vite/index.d.ts +1 -0
  91. package/dist/framework-vite/index.js +125 -0
  92. package/dist/framework-vite/index.js.map +1 -0
  93. package/dist/grid/grid.d.ts +8 -0
  94. package/dist/grid/index.cjs +238 -0
  95. package/dist/grid/index.cjs.map +1 -0
  96. package/dist/grid/index.d.ts +2 -0
  97. package/dist/grid/index.js +19 -0
  98. package/dist/grid/index.js.map +1 -0
  99. package/dist/grid/types.d.ts +35 -0
  100. package/dist/index.cjs +2512 -0
  101. package/dist/index.cjs.map +1 -0
  102. package/dist/index.d.ts +13 -0
  103. package/dist/index.js +207 -0
  104. package/dist/index.js.map +1 -0
  105. package/dist/kernel/app.d.ts +26 -0
  106. package/dist/kernel/index.d.ts +3 -0
  107. package/dist/kernel/runtime.d.ts +5 -0
  108. package/dist/kernel/telemetry.d.ts +37 -0
  109. package/dist/navigation/index.d.ts +4 -0
  110. package/dist/navigation/matcher.d.ts +13 -0
  111. package/dist/navigation/react.d.ts +12 -0
  112. package/dist/navigation/service.d.ts +23 -0
  113. package/dist/navigation/types.d.ts +65 -0
  114. package/dist/query/index.cjs +361 -0
  115. package/dist/query/index.cjs.map +1 -0
  116. package/dist/query/index.d.ts +3 -0
  117. package/dist/query/index.js +30 -0
  118. package/dist/query/index.js.map +1 -0
  119. package/dist/query/react.d.ts +27 -0
  120. package/dist/query/service.d.ts +10 -0
  121. package/dist/query/types.d.ts +5 -0
  122. package/dist/react/index.d.ts +1 -0
  123. package/dist/react/provider.d.ts +10 -0
  124. package/dist/realtime/channel.d.ts +15 -0
  125. package/dist/realtime/index.cjs +117 -0
  126. package/dist/realtime/index.cjs.map +1 -0
  127. package/dist/realtime/index.d.ts +2 -0
  128. package/dist/realtime/index.js +15 -0
  129. package/dist/realtime/index.js.map +1 -0
  130. package/dist/realtime/presence.d.ts +22 -0
  131. package/dist/render/hydration.d.ts +24 -0
  132. package/dist/render/index.d.ts +2 -0
  133. package/dist/render/ssr.d.ts +13 -0
  134. package/dist/router/helpers.d.ts +26 -0
  135. package/dist/router/index.cjs +236 -0
  136. package/dist/router/index.cjs.map +1 -0
  137. package/dist/router/index.d.ts +4 -0
  138. package/dist/router/index.js +40 -0
  139. package/dist/router/index.js.map +1 -0
  140. package/dist/router/react.d.ts +5 -0
  141. package/dist/router/service.d.ts +5 -0
  142. package/dist/router/types.d.ts +1 -0
  143. package/dist/server/index.cjs +174 -0
  144. package/dist/server/index.cjs.map +1 -0
  145. package/dist/server/index.d.ts +16 -0
  146. package/dist/server/index.js +12 -0
  147. package/dist/server/index.js.map +1 -0
  148. package/dist/state/index.cjs +128 -0
  149. package/dist/state/index.cjs.map +1 -0
  150. package/dist/state/index.d.ts +2 -0
  151. package/dist/state/index.js +36 -0
  152. package/dist/state/index.js.map +1 -0
  153. package/dist/state/react.d.ts +3 -0
  154. package/dist/state/service.d.ts +28 -0
  155. package/dist/testing/index.cjs +970 -0
  156. package/dist/testing/index.cjs.map +1 -0
  157. package/dist/testing/index.d.ts +2 -0
  158. package/dist/testing/index.js +13 -0
  159. package/dist/testing/index.js.map +1 -0
  160. package/dist/virtual/index.cjs +160 -0
  161. package/dist/virtual/index.cjs.map +1 -0
  162. package/dist/virtual/index.d.ts +2 -0
  163. package/dist/virtual/index.js +21 -0
  164. package/dist/virtual/index.js.map +1 -0
  165. package/dist/virtual/types.d.ts +25 -0
  166. package/dist/virtual/virtual.d.ts +9 -0
  167. package/package.json +156 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Rika Labs
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,179 @@
1
+ # @rikalabs/effect-react
2
+
3
+ Effect-native full-stack React framework.
4
+
5
+ React is the view layer. Effect is the execution layer.
6
+
7
+ ## Why This Exists
8
+
9
+ Modern React apps usually stitch together router, query, form, state, realtime, and SSR tooling with different semantics for retries, cancellation, caching, and errors.
10
+
11
+ `@rikalabs/effect-react` gives app teams one model across frontend and backend:
12
+
13
+ - `Effect` for async orchestration, cancellation, retries, streams, and failure values.
14
+ - `Schema` for boundary decoding/encoding.
15
+ - `Layer` for runtime composition.
16
+ - React for rendering.
17
+
18
+ ## What You Get
19
+
20
+ - SSR by default with hydration state handoff.
21
+ - Streaming-enabled runtime defaults.
22
+ - File-routing discovery via Vite plugin.
23
+ - Typed route loaders and typed actions.
24
+ - Built-in modules for state, query, router, form, grid, virtual lists, realtime, and devtools.
25
+ - Strict defaults for boundary schemas and typed errors.
26
+
27
+ ## Install
28
+
29
+ ```bash
30
+ bun add @rikalabs/effect-react effect react react-dom
31
+ ```
32
+
33
+ ## 5-File Quickstart
34
+
35
+ ```ts
36
+ // vite.config.ts
37
+ import react from "@vitejs/plugin-react";
38
+ import { defineConfig } from "vite";
39
+ import { effectReactVitePlugin } from "@rikalabs/effect-react/framework/vite";
40
+
41
+ export default defineConfig({
42
+ plugins: [react(), effectReactVitePlugin({ appDir: "app" })],
43
+ });
44
+ ```
45
+
46
+ ```tsx
47
+ // app/page.tsx
48
+ import { Effect } from "effect";
49
+ import { defineLoader, definePage, defineRoute } from "@rikalabs/effect-react/framework";
50
+
51
+ const route = defineRoute({
52
+ id: "home",
53
+ path: "/",
54
+ });
55
+
56
+ const loader = defineLoader({
57
+ name: "home.loader",
58
+ routeId: route.id,
59
+ run: () =>
60
+ Effect.succeed({
61
+ headline: "One runtime for the whole app lifecycle",
62
+ }),
63
+ });
64
+
65
+ const HomePage = () => <main>Hello from @rikalabs/effect-react</main>;
66
+
67
+ export default definePage({
68
+ id: "home.page",
69
+ route,
70
+ loader,
71
+ component: HomePage,
72
+ });
73
+ ```
74
+
75
+ ```ts
76
+ // app/actions/counter.increment.ts
77
+ import { Effect, Schema } from "effect";
78
+ import { defineAction } from "@rikalabs/effect-react/framework";
79
+
80
+ export const counterIncrement = defineAction({
81
+ name: "counter.increment",
82
+ input: Schema.Struct({ value: Schema.Number }),
83
+ output: Schema.Struct({ value: Schema.Number }),
84
+ error: Schema.Struct({ reason: Schema.String }),
85
+ handler: ({ value }) =>
86
+ value < 0
87
+ ? Effect.fail({ reason: "must be >= 0" })
88
+ : Effect.succeed({ value: value + 1 }),
89
+ });
90
+ ```
91
+
92
+ ```ts
93
+ // src/server.ts
94
+ import { createApp } from "@rikalabs/effect-react/framework";
95
+ import { createRequestHandler } from "@rikalabs/effect-react/server";
96
+ import manifest from "virtual:effect-react/manifest";
97
+
98
+ const app = createApp({ manifest });
99
+
100
+ export const handler = createRequestHandler({ app });
101
+ ```
102
+
103
+ ```ts
104
+ // src/client.tsx
105
+ import { hydrateApp } from "@rikalabs/effect-react/client";
106
+ import { createApp } from "@rikalabs/effect-react/framework";
107
+ import manifest from "virtual:effect-react/manifest";
108
+
109
+ const app = createApp({ manifest });
110
+
111
+ await hydrateApp({ app });
112
+ ```
113
+
114
+ ## Effect Model: `Effect<A, E, R>`
115
+
116
+ - `A`: success value
117
+ - `E`: typed error value
118
+ - `R`: required services/dependencies
119
+
120
+ How this maps to the framework:
121
+
122
+ - Request lifecycle runs in a managed app runtime with core services (`Boundary`, `Data`, `Actions`, `Navigation`, `Telemetry`).
123
+ - Loaders/actions/queries are transport-safe contracts with typed success/error channels.
124
+ - You can still use custom `R` dependencies at boundaries by providing a `Layer`.
125
+
126
+ ```ts
127
+ import { Context, Effect, Layer } from "effect";
128
+ import { createElement } from "react";
129
+ import { createApp } from "@rikalabs/effect-react/framework";
130
+ import { createRequestHandler } from "@rikalabs/effect-react/server";
131
+ import manifest from "virtual:effect-react/manifest";
132
+
133
+ class RequestLogger extends Context.Tag("app/RequestLogger")<
134
+ RequestLogger,
135
+ { readonly info: (message: string) => Effect.Effect<void> }
136
+ >() {}
137
+
138
+ const RequestLoggerLive = Layer.succeed(RequestLogger, {
139
+ info: (message: string) => Effect.sync(() => console.log(message)),
140
+ });
141
+
142
+ const app = createApp({ manifest });
143
+
144
+ export const handler = createRequestHandler({
145
+ app,
146
+ render: ({ page }) =>
147
+ Effect.gen(function* () {
148
+ const logger = yield* RequestLogger;
149
+ yield* logger.info(`rendering ${page.id}`);
150
+ return createElement(page.component);
151
+ }).pipe(Effect.provide(RequestLoggerLive)),
152
+ });
153
+ ```
154
+
155
+ ## Modules
156
+
157
+ - `@rikalabs/effect-react/framework`
158
+ - `@rikalabs/effect-react/framework/vite`
159
+ - `@rikalabs/effect-react/config`
160
+ - `@rikalabs/effect-react/server`
161
+ - `@rikalabs/effect-react/client`
162
+ - `@rikalabs/effect-react/testing`
163
+ - `@rikalabs/effect-react/state`
164
+ - `@rikalabs/effect-react/query`
165
+ - `@rikalabs/effect-react/router`
166
+ - `@rikalabs/effect-react/form`
167
+ - `@rikalabs/effect-react/grid`
168
+ - `@rikalabs/effect-react/virtual`
169
+ - `@rikalabs/effect-react/realtime`
170
+ - `@rikalabs/effect-react/devtools`
171
+
172
+ ## Docs
173
+
174
+ - Docs index: [`docs/README.md`](docs/README.md)
175
+ - Changelog: [`CHANGELOG.md`](CHANGELOG.md)
176
+
177
+ ## License
178
+
179
+ MIT
@@ -0,0 +1,18 @@
1
+ import { Effect } from "effect";
2
+ import { Boundary } from "../boundary";
3
+ import { Actions } from "./service";
4
+ import { type ActionDefinition, type ActionError } from "./types";
5
+ export declare class ActionTransportError extends Error {
6
+ readonly messageText: string;
7
+ readonly causeValue?: unknown | undefined;
8
+ readonly _tag: "ActionTransportError";
9
+ constructor(messageText: string, causeValue?: unknown | undefined);
10
+ }
11
+ export declare const createActionHttpHandlerEffect: () => ((request: Request) => Effect.Effect<Response, never, Boundary | Actions>);
12
+ export declare const createActionHttpHandler: () => (runtimeRun: <A>(effect: Effect.Effect<A, unknown, Boundary | Actions>) => Promise<A>) => (request: Request) => Promise<Response>;
13
+ export declare const callActionWire: <Name extends string, Input, Output, E>(definition: ActionDefinition<Name, Input, Output, E>, options: {
14
+ readonly endpoint: string;
15
+ readonly input: Input;
16
+ readonly fetcher?: (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;
17
+ readonly signal?: AbortSignal;
18
+ }) => Effect.Effect<Output, ActionError<E> | ActionTransportError, Boundary>;
@@ -0,0 +1,4 @@
1
+ export * from "./types";
2
+ export * from "./service";
3
+ export * from "./http";
4
+ export * from "./react";
@@ -0,0 +1,7 @@
1
+ import type { ActionDefinition, ActionError } from "./types";
2
+ export interface UseActionResult<Input, Output, E> {
3
+ readonly run: (input: Input) => Promise<Output>;
4
+ readonly pending: boolean;
5
+ readonly error: ActionError<E> | undefined;
6
+ }
7
+ export declare const useAction: <Name extends string, Input, Output, E>(definition: ActionDefinition<Name, Input, Output, E>) => UseActionResult<Input, Output, E>;
@@ -0,0 +1,18 @@
1
+ import { Context, Effect, Layer } from "effect";
2
+ import { Boundary } from "../boundary";
3
+ import { Telemetry } from "../kernel/telemetry";
4
+ import { type ActionDefinition, type ActionError, type ActionWireResult, type AnyActionDefinition } from "./types";
5
+ export interface ActionService {
6
+ readonly run: <Name extends string, Input, Output, E>(definition: ActionDefinition<Name, Input, Output, E>, input: unknown) => Effect.Effect<Output, ActionError<E>, never>;
7
+ readonly dispatch: (name: string, input: unknown) => Effect.Effect<ActionWireResult, never, never>;
8
+ }
9
+ declare const Actions_base: Context.TagClass<Actions, "EffectReact/Actions", ActionService>;
10
+ export declare class Actions extends Actions_base {
11
+ }
12
+ export interface MakeActionsLayerOptions {
13
+ readonly actions: readonly AnyActionDefinition[];
14
+ }
15
+ export declare const makeActionsLayer: (options: MakeActionsLayerOptions) => Layer.Layer<Actions, never, Boundary | Telemetry>;
16
+ export declare const runAction: <Name extends string, Input, Output, E>(definition: ActionDefinition<Name, Input, Output, E>, input: unknown) => Effect.Effect<Output, ActionError<E>, Actions>;
17
+ export declare const dispatchAction: (name: string, input: unknown) => Effect.Effect<ActionWireResult, never, Actions>;
18
+ export {};
@@ -0,0 +1,33 @@
1
+ import type { Effect, Schema } from "effect";
2
+ import type { BoundaryError } from "../boundary";
3
+ export interface ActionDefinition<Name extends string, Input, Output, E, InputEncoded = Input, OutputEncoded = Output, ErrorEncoded = E> {
4
+ readonly name: Name;
5
+ readonly input: Schema.Schema<Input, InputEncoded, never>;
6
+ readonly output: Schema.Schema<Output, OutputEncoded, never>;
7
+ readonly error: Schema.Schema<E, ErrorEncoded, never>;
8
+ readonly handler: (input: Input) => Effect.Effect<Output, E, never>;
9
+ }
10
+ export declare const defineAction: <Name extends string, Input, Output, E, InputEncoded = Input, OutputEncoded = Output, ErrorEncoded = E>(definition: ActionDefinition<Name, Input, Output, E, InputEncoded, OutputEncoded, ErrorEncoded>) => ActionDefinition<Name, Input, Output, E, InputEncoded, OutputEncoded, ErrorEncoded>;
11
+ export interface AnyActionDefinition {
12
+ readonly name: string;
13
+ readonly input: Schema.Schema.All;
14
+ readonly output: Schema.Schema.All;
15
+ readonly error: Schema.Schema.All;
16
+ readonly handler: (input: never) => Effect.Effect<unknown, unknown, never>;
17
+ }
18
+ export type ActionError<E> = E | BoundaryError | ActionRuntimeError;
19
+ export declare class ActionRuntimeError extends Error {
20
+ readonly messageText: string;
21
+ readonly _tag: "ActionRuntimeError";
22
+ constructor(messageText: string);
23
+ }
24
+ export type ActionWireResult = {
25
+ readonly _tag: "success";
26
+ readonly value: unknown;
27
+ } | {
28
+ readonly _tag: "failure";
29
+ readonly error: unknown;
30
+ } | {
31
+ readonly _tag: "defect";
32
+ readonly message: string;
33
+ };
@@ -0,0 +1,40 @@
1
+ import { Context, Effect, Layer, Schema } from "effect";
2
+ import { BoundaryDecodeError, type BoundaryError } from "./errors";
3
+ export interface BoundaryService {
4
+ readonly decodeUnknown: <A, I>(options: {
5
+ readonly source: string;
6
+ readonly schema: Schema.Schema<A, I, never>;
7
+ readonly value: unknown;
8
+ }) => Effect.Effect<A, BoundaryDecodeError, never>;
9
+ readonly decodeTextJson: <A, I>(options: {
10
+ readonly source: string;
11
+ readonly schema: Schema.Schema<A, I, never>;
12
+ readonly text: string;
13
+ }) => Effect.Effect<A, BoundaryError, never>;
14
+ readonly encode: <A, I>(options: {
15
+ readonly source: string;
16
+ readonly schema: Schema.Schema<A, I, never>;
17
+ readonly value: A;
18
+ }) => Effect.Effect<I, BoundaryError, never>;
19
+ }
20
+ declare const Boundary_base: Context.TagClass<Boundary, "EffectReact/Boundary", BoundaryService>;
21
+ export declare class Boundary extends Boundary_base {
22
+ }
23
+ export declare const makeBoundaryService: () => BoundaryService;
24
+ export declare const BoundaryLive: Layer.Layer<Boundary, never, never>;
25
+ export declare const decodeUnknown: <A, I>(options: {
26
+ readonly source: string;
27
+ readonly schema: Schema.Schema<A, I, never>;
28
+ readonly value: unknown;
29
+ }) => Effect.Effect<A, BoundaryDecodeError, Boundary>;
30
+ export declare const decodeTextJson: <A, I>(options: {
31
+ readonly source: string;
32
+ readonly schema: Schema.Schema<A, I, never>;
33
+ readonly text: string;
34
+ }) => Effect.Effect<A, BoundaryError, Boundary>;
35
+ export declare const encode: <A, I>(options: {
36
+ readonly source: string;
37
+ readonly schema: Schema.Schema<A, I, never>;
38
+ readonly value: A;
39
+ }) => Effect.Effect<I, BoundaryError, Boundary>;
40
+ export {};
@@ -0,0 +1,22 @@
1
+ import type { ParseResult } from "effect";
2
+ export declare class BoundaryDecodeError extends Error {
3
+ readonly source: string;
4
+ readonly messageText: string;
5
+ readonly causeValue?: ParseResult.ParseError | undefined;
6
+ readonly _tag: "BoundaryDecodeError";
7
+ constructor(source: string, messageText: string, causeValue?: ParseResult.ParseError | undefined);
8
+ }
9
+ export declare class BoundaryTransportError extends Error {
10
+ readonly source: string;
11
+ readonly messageText: string;
12
+ readonly causeValue?: unknown | undefined;
13
+ readonly _tag: "BoundaryTransportError";
14
+ constructor(source: string, messageText: string, causeValue?: unknown | undefined);
15
+ }
16
+ export declare class BoundaryProtocolError extends Error {
17
+ readonly source: string;
18
+ readonly messageText: string;
19
+ readonly _tag: "BoundaryProtocolError";
20
+ constructor(source: string, messageText: string);
21
+ }
22
+ export type BoundaryError = BoundaryDecodeError | BoundaryTransportError | BoundaryProtocolError;
@@ -0,0 +1,2 @@
1
+ export * from "./codecs";
2
+ export * from "./errors";
@@ -0,0 +1,16 @@
1
+ // src/react/provider.tsx
2
+ import { createContext, useContext, useEffect } from "react";
3
+ import { jsx } from "react/jsx-runtime";
4
+ var RuntimeContext = createContext(null);
5
+ var useEffectRuntime = () => {
6
+ const runtime = useContext(RuntimeContext);
7
+ if (runtime === null) {
8
+ throw new Error("Effect runtime is not available. Wrap your app with <EffectProvider>.");
9
+ }
10
+ return runtime;
11
+ };
12
+
13
+ export {
14
+ useEffectRuntime
15
+ };
16
+ //# sourceMappingURL=chunk-2GIUCKL2.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/react/provider.tsx"],"sourcesContent":["import type { ManagedRuntime } from \"effect\";\nimport { createContext, useContext, useEffect, type ReactNode } from \"react\";\nimport type { AppServices } from \"../kernel/app\";\n\nexport type EffectReactManagedRuntime<R = AppServices> = ManagedRuntime.ManagedRuntime<R, never>;\n\nconst RuntimeContext = createContext<EffectReactManagedRuntime | null>(null);\n\nexport interface EffectProviderProps {\n readonly runtime: EffectReactManagedRuntime;\n readonly children?: ReactNode;\n}\n\nexport const EffectProvider = ({ runtime, children }: EffectProviderProps) => {\n useEffect(\n () => () => {\n void runtime.dispose();\n },\n [runtime],\n );\n\n return <RuntimeContext.Provider value={runtime}>{children}</RuntimeContext.Provider>;\n};\n\nexport const useEffectRuntime = (): EffectReactManagedRuntime => {\n const runtime = useContext(RuntimeContext);\n if (runtime === null) {\n throw new Error(\"Effect runtime is not available. Wrap your app with <EffectProvider>.\");\n }\n return runtime;\n};\n"],"mappings":";AACA,SAAS,eAAe,YAAY,iBAAiC;AAoB5D;AAfT,IAAM,iBAAiB,cAAgD,IAAI;AAkBpE,IAAM,mBAAmB,MAAiC;AAC/D,QAAM,UAAU,WAAW,cAAc;AACzC,MAAI,YAAY,MAAM;AACpB,UAAM,IAAI,MAAM,uEAAuE;AAAA,EACzF;AACA,SAAO;AACT;","names":[]}
@@ -0,0 +1,11 @@
1
+ import {
2
+ createApp
3
+ } from "./chunk-XIBEKS5A.js";
4
+
5
+ // src/testing/index.ts
6
+ var createTestApp = (options) => createApp(options);
7
+
8
+ export {
9
+ createTestApp
10
+ };
11
+ //# sourceMappingURL=chunk-2TG7YEVD.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/testing/index.ts"],"sourcesContent":["import { createApp, type CreateAppOptions } from \"../framework\";\n\nexport const createTestApp = (options: CreateAppOptions) => createApp(options);\n"],"mappings":";;;;;AAEO,IAAM,gBAAgB,CAAC,YAA8B,UAAU,OAAO;","names":[]}
@@ -0,0 +1,152 @@
1
+ import {
2
+ useEffectRuntime
3
+ } from "./chunk-2GIUCKL2.js";
4
+ import {
5
+ Navigation,
6
+ buildHref,
7
+ navigateTo
8
+ } from "./chunk-O7XTA7H3.js";
9
+
10
+ // src/router/helpers.ts
11
+ var PARAM_PATTERN = /:([A-Za-z0-9_]+)/g;
12
+ var appendSearchValue = (params, key, value) => {
13
+ if (value === null || value === void 0) {
14
+ return;
15
+ }
16
+ if (Array.isArray(value)) {
17
+ for (const nestedValue of value) {
18
+ appendSearchValue(params, key, nestedValue);
19
+ }
20
+ return;
21
+ }
22
+ if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
23
+ params.append(key, String(value));
24
+ }
25
+ };
26
+ var defaultBase = () => {
27
+ if (typeof window === "undefined") {
28
+ return "http://localhost";
29
+ }
30
+ return window.location.origin;
31
+ };
32
+ var routeSearchText = (search) => {
33
+ if (search === void 0) {
34
+ return "";
35
+ }
36
+ const params = new URLSearchParams();
37
+ const keys = Object.keys(search).sort((a, b) => a.localeCompare(b));
38
+ for (const key of keys) {
39
+ appendSearchValue(params, key, search[key]);
40
+ }
41
+ const text = params.toString();
42
+ return text.length > 0 ? `?${text}` : "";
43
+ };
44
+ var routePath = (route, params) => route.path.replace(PARAM_PATTERN, (_match, name) => {
45
+ const value = params?.[name];
46
+ if (value === void 0) {
47
+ throw new Error(`Missing route param '${name}' for route '${route.id}'`);
48
+ }
49
+ return encodeURIComponent(String(value));
50
+ });
51
+ var routeHref = (route, options = {}) => buildHref(
52
+ routePath(route, options.params),
53
+ routeSearchText(options.search)
54
+ );
55
+ var routeUrl = (route, options = {}) => new URL(
56
+ routeHref(route, options),
57
+ options.base ?? defaultBase()
58
+ );
59
+
60
+ // src/router/service.ts
61
+ import { Effect as Effect2 } from "effect";
62
+
63
+ // src/navigation/react.tsx
64
+ import { Effect, Fiber, Stream } from "effect";
65
+ import {
66
+ useCallback,
67
+ useMemo,
68
+ useSyncExternalStore
69
+ } from "react";
70
+ import { Fragment, jsx } from "react/jsx-runtime";
71
+ var useNavigationService = () => {
72
+ const runtime = useEffectRuntime();
73
+ return useMemo(() => runtime.runSync(Navigation), [runtime]);
74
+ };
75
+ var useNavigationSnapshot = () => {
76
+ const runtime = useEffectRuntime();
77
+ const navigation = useNavigationService();
78
+ const subscribe = useCallback(
79
+ (listener) => {
80
+ const fiber = runtime.runFork(
81
+ Stream.runForEach(navigation.snapshots, () => Effect.sync(listener))
82
+ );
83
+ return () => {
84
+ runtime.runFork(Fiber.interrupt(fiber));
85
+ };
86
+ },
87
+ [navigation, runtime]
88
+ );
89
+ const getSnapshot = useCallback(
90
+ () => runtime.runSync(navigation.getSnapshot),
91
+ [navigation, runtime]
92
+ );
93
+ return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
94
+ };
95
+ var useNavigate = () => {
96
+ const runtime = useEffectRuntime();
97
+ const navigation = useNavigationService();
98
+ return useCallback(
99
+ (href) => runtime.runPromise(navigation.navigate(href)),
100
+ [navigation, runtime]
101
+ );
102
+ };
103
+ var Link = ({ to, onClick, children, ...rest }) => {
104
+ const navigate2 = useNavigate();
105
+ const handleClick = useCallback(
106
+ (event) => {
107
+ onClick?.(event);
108
+ if (event.defaultPrevented) {
109
+ return;
110
+ }
111
+ if (event.button !== 0 || event.metaKey || event.altKey || event.ctrlKey || event.shiftKey) {
112
+ return;
113
+ }
114
+ event.preventDefault();
115
+ void navigate2(to);
116
+ },
117
+ [navigate2, onClick, to]
118
+ );
119
+ return /* @__PURE__ */ jsx("a", { ...rest, href: to, onClick: handleClick, children });
120
+ };
121
+ var Outlet = ({ children }) => /* @__PURE__ */ jsx(Fragment, { children });
122
+
123
+ // src/router/service.ts
124
+ var navigate = (href) => navigateTo(href);
125
+ var revalidateNavigation = () => Effect2.flatMap(Navigation, (service) => service.revalidate());
126
+
127
+ // src/router/react.tsx
128
+ var useNavigate2 = () => useNavigate();
129
+ var useNavigationSnapshot2 = () => useNavigationSnapshot();
130
+ var useRouteMatch = (route) => {
131
+ const snapshot = useNavigationSnapshot2();
132
+ const match = snapshot.match;
133
+ if (match === null || match.route.id !== route.id) {
134
+ return null;
135
+ }
136
+ return match;
137
+ };
138
+
139
+ export {
140
+ Link,
141
+ Outlet,
142
+ routeSearchText,
143
+ routePath,
144
+ routeHref,
145
+ routeUrl,
146
+ navigate,
147
+ revalidateNavigation,
148
+ useNavigate2 as useNavigate,
149
+ useNavigationSnapshot2 as useNavigationSnapshot,
150
+ useRouteMatch
151
+ };
152
+ //# sourceMappingURL=chunk-6FI4ROTW.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/router/helpers.ts","../src/router/service.ts","../src/navigation/react.tsx","../src/router/react.tsx"],"sourcesContent":["import { buildHref } from \"../navigation/matcher\";\nimport type { AnyRouteDefinition, RouteDefinition } from \"./types\";\n\ntype ExtractSegmentParam<Segment extends string> =\n Segment extends `:${infer Param}` ? Param : never;\n\ntype ExtractPathParams<Path extends string> =\n Path extends `${infer Head}/${infer Tail}`\n ? ExtractSegmentParam<Head> | ExtractPathParams<Tail>\n : ExtractSegmentParam<Path>;\n\ntype SearchPrimitive = string | number | boolean;\ntype SearchFieldInput<Value> =\n Value extends readonly (infer Item)[]\n ? Item | readonly Item[] | null | undefined\n : Value | readonly Value[] | null | undefined;\n\ntype SearchFallback = Readonly<Record<string, SearchPrimitive | readonly SearchPrimitive[] | null | undefined>>;\n\nexport type RoutePathParams<Path extends string> =\n [ExtractPathParams<Path>] extends [never]\n ? Record<never, never>\n : {\n readonly [K in ExtractPathParams<Path>]: string | number | boolean;\n };\n\nexport type RouteSearchInput<TRoute extends AnyRouteDefinition> =\n TRoute extends RouteDefinition<string, infer Search, unknown>\n ? {\n readonly [K in keyof Search]?: SearchFieldInput<Search[K]>;\n }\n : SearchFallback;\n\nexport interface RouteHrefOptions<TRoute extends AnyRouteDefinition> {\n readonly params?: RoutePathParams<TRoute[\"path\"]>;\n readonly search?: RouteSearchInput<TRoute>;\n}\n\nexport interface RouteUrlOptions<TRoute extends AnyRouteDefinition>\n extends RouteHrefOptions<TRoute> {\n readonly base?: string | URL;\n}\n\nconst PARAM_PATTERN = /:([A-Za-z0-9_]+)/g;\n\nconst appendSearchValue = (\n params: URLSearchParams,\n key: string,\n value: unknown,\n): void => {\n if (value === null || value === undefined) {\n return;\n }\n if (Array.isArray(value)) {\n for (const nestedValue of value) {\n appendSearchValue(params, key, nestedValue);\n }\n return;\n }\n if (typeof value === \"string\" || typeof value === \"number\" || typeof value === \"boolean\") {\n params.append(key, String(value));\n }\n};\n\nconst defaultBase = (): string => {\n if (typeof window === \"undefined\") {\n return \"http://localhost\";\n }\n return window.location.origin;\n};\n\nexport const routeSearchText = (search?: SearchFallback): string => {\n if (search === undefined) {\n return \"\";\n }\n\n const params = new URLSearchParams();\n const keys = Object.keys(search).sort((a, b) => a.localeCompare(b));\n for (const key of keys) {\n appendSearchValue(params, key, search[key]);\n }\n\n const text = params.toString();\n return text.length > 0 ? `?${text}` : \"\";\n};\n\nexport const routePath = <TRoute extends AnyRouteDefinition>(\n route: TRoute,\n params?: RoutePathParams<TRoute[\"path\"]>,\n): string =>\n route.path.replace(PARAM_PATTERN, (_match, name: string) => {\n const value = (params as Readonly<Record<string, string | number | boolean>> | undefined)?.[name];\n if (value === undefined) {\n throw new Error(`Missing route param '${name}' for route '${route.id}'`);\n }\n return encodeURIComponent(String(value));\n });\n\nexport const routeHref = <TRoute extends AnyRouteDefinition>(\n route: TRoute,\n options: RouteHrefOptions<TRoute> = {},\n): string =>\n buildHref(\n routePath(route, options.params),\n routeSearchText(options.search as SearchFallback | undefined),\n );\n\nexport const routeUrl = <TRoute extends AnyRouteDefinition>(\n route: TRoute,\n options: RouteUrlOptions<TRoute> = {},\n): URL =>\n new URL(\n routeHref(route, options),\n options.base ?? defaultBase(),\n );\n","import { Effect } from \"effect\";\nimport { Navigation, navigateTo } from \"../navigation\";\nimport type { NavigationError, NavigationSnapshot } from \"./types\";\n\nexport const navigate = (\n href: string,\n): Effect.Effect<NavigationSnapshot, NavigationError, Navigation> =>\n navigateTo(href);\n\nexport const revalidateNavigation = (): Effect.Effect<NavigationSnapshot, NavigationError, Navigation> =>\n Effect.flatMap(Navigation, (service) => service.revalidate());\n","import { Effect, Fiber, Stream } from \"effect\";\nimport {\n type AnchorHTMLAttributes,\n type MouseEvent,\n type ReactNode,\n useCallback,\n useMemo,\n useSyncExternalStore,\n} from \"react\";\nimport { useEffectRuntime } from \"../react/provider\";\nimport { Navigation } from \"./service\";\nimport type { NavigationSnapshot } from \"./types\";\n\nconst useNavigationService = () => {\n const runtime = useEffectRuntime();\n return useMemo(() => runtime.runSync(Navigation), [runtime]);\n};\n\nexport const useNavigationSnapshot = (): NavigationSnapshot => {\n const runtime = useEffectRuntime();\n const navigation = useNavigationService();\n\n const subscribe = useCallback(\n (listener: () => void) => {\n const fiber = runtime.runFork(\n Stream.runForEach(navigation.snapshots, () => Effect.sync(listener)),\n );\n\n return () => {\n runtime.runFork(Fiber.interrupt(fiber));\n };\n },\n [navigation, runtime],\n );\n\n const getSnapshot = useCallback(\n () => runtime.runSync(navigation.getSnapshot),\n [navigation, runtime],\n );\n\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n};\n\nexport const useNavigate = (): ((href: string) => Promise<NavigationSnapshot>) => {\n const runtime = useEffectRuntime();\n const navigation = useNavigationService();\n\n return useCallback(\n (href: string) => runtime.runPromise(navigation.navigate(href)),\n [navigation, runtime],\n );\n};\n\nexport interface LinkProps extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, \"href\"> {\n readonly to: string;\n readonly children?: ReactNode;\n}\n\nexport const Link = ({ to, onClick, children, ...rest }: LinkProps) => {\n const navigate = useNavigate();\n\n const handleClick = useCallback(\n (event: MouseEvent<HTMLAnchorElement>) => {\n onClick?.(event);\n if (event.defaultPrevented) {\n return;\n }\n if (event.button !== 0 || event.metaKey || event.altKey || event.ctrlKey || event.shiftKey) {\n return;\n }\n event.preventDefault();\n void navigate(to);\n },\n [navigate, onClick, to],\n );\n\n return (\n <a {...rest} href={to} onClick={handleClick}>\n {children}\n </a>\n );\n};\n\nexport const Outlet = ({ children }: { readonly children?: ReactNode }) => <>{children}</>;\n","import {\n useNavigate as useNavigationNavigate,\n useNavigationSnapshot as useNavigationState,\n} from \"../navigation/react\";\nimport type { AnyRouteDefinition, NavigationSnapshot, RouteMatch } from \"./types\";\n\nexport {\n Link,\n Outlet,\n type LinkProps,\n} from \"../navigation/react\";\n\nexport const useNavigate = (): ((href: string) => Promise<NavigationSnapshot>) =>\n useNavigationNavigate();\n\nexport const useNavigationSnapshot = (): NavigationSnapshot =>\n useNavigationState();\n\nexport const useRouteMatch = <TRoute extends AnyRouteDefinition>(\n route: TRoute,\n): RouteMatch<TRoute> | null => {\n const snapshot = useNavigationSnapshot();\n const match = snapshot.match;\n if (match === null || match.route.id !== route.id) {\n return null;\n }\n return match as RouteMatch<TRoute>;\n};\n"],"mappings":"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","names":["Effect","navigate","Effect","useNavigate","useNavigationSnapshot"]}