@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.
- package/LICENSE +21 -0
- package/README.md +179 -0
- package/dist/actions/http.d.ts +18 -0
- package/dist/actions/index.d.ts +4 -0
- package/dist/actions/react.d.ts +7 -0
- package/dist/actions/service.d.ts +18 -0
- package/dist/actions/types.d.ts +33 -0
- package/dist/boundary/codecs.d.ts +40 -0
- package/dist/boundary/errors.d.ts +22 -0
- package/dist/boundary/index.d.ts +2 -0
- package/dist/chunk-2GIUCKL2.js +16 -0
- package/dist/chunk-2GIUCKL2.js.map +1 -0
- package/dist/chunk-2TG7YEVD.js +11 -0
- package/dist/chunk-2TG7YEVD.js.map +1 -0
- package/dist/chunk-6FI4ROTW.js +152 -0
- package/dist/chunk-6FI4ROTW.js.map +1 -0
- package/dist/chunk-C5JI7D7W.js +213 -0
- package/dist/chunk-C5JI7D7W.js.map +1 -0
- package/dist/chunk-EEYASTXR.js +99 -0
- package/dist/chunk-EEYASTXR.js.map +1 -0
- package/dist/chunk-H7MOLKTU.js +301 -0
- package/dist/chunk-H7MOLKTU.js.map +1 -0
- package/dist/chunk-IVIYY6S5.js +77 -0
- package/dist/chunk-IVIYY6S5.js.map +1 -0
- package/dist/chunk-JKN75OYC.js +87 -0
- package/dist/chunk-JKN75OYC.js.map +1 -0
- package/dist/chunk-M2CJG6T7.js +24 -0
- package/dist/chunk-M2CJG6T7.js.map +1 -0
- package/dist/chunk-MDGEGQZB.js +206 -0
- package/dist/chunk-MDGEGQZB.js.map +1 -0
- package/dist/chunk-NI2GNZ7S.js +78 -0
- package/dist/chunk-NI2GNZ7S.js.map +1 -0
- package/dist/chunk-O7XTA7H3.js +423 -0
- package/dist/chunk-O7XTA7H3.js.map +1 -0
- package/dist/chunk-S67FHWAR.js +88 -0
- package/dist/chunk-S67FHWAR.js.map +1 -0
- package/dist/chunk-SKC3HMF3.js +17 -0
- package/dist/chunk-SKC3HMF3.js.map +1 -0
- package/dist/chunk-TUJZ6XJY.js +127 -0
- package/dist/chunk-TUJZ6XJY.js.map +1 -0
- package/dist/chunk-WPV3WFMS.js +38 -0
- package/dist/chunk-WPV3WFMS.js.map +1 -0
- package/dist/chunk-XIBEKS5A.js +301 -0
- package/dist/chunk-XIBEKS5A.js.map +1 -0
- package/dist/chunk-YG22YP5K.js +68 -0
- package/dist/chunk-YG22YP5K.js.map +1 -0
- package/dist/chunk-ZMZQBREU.js +262 -0
- package/dist/chunk-ZMZQBREU.js.map +1 -0
- package/dist/client/index.cjs +191 -0
- package/dist/client/index.cjs.map +1 -0
- package/dist/client/index.d.ts +8 -0
- package/dist/client/index.js +14 -0
- package/dist/client/index.js.map +1 -0
- package/dist/config/index.cjs +63 -0
- package/dist/config/index.cjs.map +1 -0
- package/dist/config/index.d.ts +32 -0
- package/dist/config/index.js +9 -0
- package/dist/config/index.js.map +1 -0
- package/dist/data/index.d.ts +3 -0
- package/dist/data/react.d.ts +10 -0
- package/dist/data/service.d.ts +20 -0
- package/dist/data/types.d.ts +31 -0
- package/dist/devtools/events.d.ts +37 -0
- package/dist/devtools/index.cjs +149 -0
- package/dist/devtools/index.cjs.map +1 -0
- package/dist/devtools/index.d.ts +2 -0
- package/dist/devtools/index.js +18 -0
- package/dist/devtools/index.js.map +1 -0
- package/dist/devtools/react.d.ts +8 -0
- package/dist/form/index.cjs +301 -0
- package/dist/form/index.cjs.map +1 -0
- package/dist/form/index.d.ts +3 -0
- package/dist/form/index.js +14 -0
- package/dist/form/index.js.map +1 -0
- package/dist/form/react.d.ts +9 -0
- package/dist/form/service.d.ts +3 -0
- package/dist/form/types.d.ts +41 -0
- package/dist/framework/app.d.ts +21 -0
- package/dist/framework/cache.d.ts +10 -0
- package/dist/framework/contracts.d.ts +32 -0
- package/dist/framework/index.cjs +1006 -0
- package/dist/framework/index.cjs.map +1 -0
- package/dist/framework/index.d.ts +4 -0
- package/dist/framework/index.js +35 -0
- package/dist/framework/index.js.map +1 -0
- package/dist/framework/manifest.d.ts +12 -0
- package/dist/framework/vite.d.ts +13 -0
- package/dist/framework-vite/index.cjs +163 -0
- package/dist/framework-vite/index.cjs.map +1 -0
- package/dist/framework-vite/index.d.ts +1 -0
- package/dist/framework-vite/index.js +125 -0
- package/dist/framework-vite/index.js.map +1 -0
- package/dist/grid/grid.d.ts +8 -0
- package/dist/grid/index.cjs +238 -0
- package/dist/grid/index.cjs.map +1 -0
- package/dist/grid/index.d.ts +2 -0
- package/dist/grid/index.js +19 -0
- package/dist/grid/index.js.map +1 -0
- package/dist/grid/types.d.ts +35 -0
- package/dist/index.cjs +2512 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.js +207 -0
- package/dist/index.js.map +1 -0
- package/dist/kernel/app.d.ts +26 -0
- package/dist/kernel/index.d.ts +3 -0
- package/dist/kernel/runtime.d.ts +5 -0
- package/dist/kernel/telemetry.d.ts +37 -0
- package/dist/navigation/index.d.ts +4 -0
- package/dist/navigation/matcher.d.ts +13 -0
- package/dist/navigation/react.d.ts +12 -0
- package/dist/navigation/service.d.ts +23 -0
- package/dist/navigation/types.d.ts +65 -0
- package/dist/query/index.cjs +361 -0
- package/dist/query/index.cjs.map +1 -0
- package/dist/query/index.d.ts +3 -0
- package/dist/query/index.js +30 -0
- package/dist/query/index.js.map +1 -0
- package/dist/query/react.d.ts +27 -0
- package/dist/query/service.d.ts +10 -0
- package/dist/query/types.d.ts +5 -0
- package/dist/react/index.d.ts +1 -0
- package/dist/react/provider.d.ts +10 -0
- package/dist/realtime/channel.d.ts +15 -0
- package/dist/realtime/index.cjs +117 -0
- package/dist/realtime/index.cjs.map +1 -0
- package/dist/realtime/index.d.ts +2 -0
- package/dist/realtime/index.js +15 -0
- package/dist/realtime/index.js.map +1 -0
- package/dist/realtime/presence.d.ts +22 -0
- package/dist/render/hydration.d.ts +24 -0
- package/dist/render/index.d.ts +2 -0
- package/dist/render/ssr.d.ts +13 -0
- package/dist/router/helpers.d.ts +26 -0
- package/dist/router/index.cjs +236 -0
- package/dist/router/index.cjs.map +1 -0
- package/dist/router/index.d.ts +4 -0
- package/dist/router/index.js +40 -0
- package/dist/router/index.js.map +1 -0
- package/dist/router/react.d.ts +5 -0
- package/dist/router/service.d.ts +5 -0
- package/dist/router/types.d.ts +1 -0
- package/dist/server/index.cjs +174 -0
- package/dist/server/index.cjs.map +1 -0
- package/dist/server/index.d.ts +16 -0
- package/dist/server/index.js +12 -0
- package/dist/server/index.js.map +1 -0
- package/dist/state/index.cjs +128 -0
- package/dist/state/index.cjs.map +1 -0
- package/dist/state/index.d.ts +2 -0
- package/dist/state/index.js +36 -0
- package/dist/state/index.js.map +1 -0
- package/dist/state/react.d.ts +3 -0
- package/dist/state/service.d.ts +28 -0
- package/dist/testing/index.cjs +970 -0
- package/dist/testing/index.cjs.map +1 -0
- package/dist/testing/index.d.ts +2 -0
- package/dist/testing/index.js +13 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/virtual/index.cjs +160 -0
- package/dist/virtual/index.cjs.map +1 -0
- package/dist/virtual/index.d.ts +2 -0
- package/dist/virtual/index.js +21 -0
- package/dist/virtual/index.js.map +1 -0
- package/dist/virtual/types.d.ts +25 -0
- package/dist/virtual/virtual.d.ts +9 -0
- package/package.json +156 -0
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,2512 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/index.ts
|
|
31
|
+
var index_exports = {};
|
|
32
|
+
__export(index_exports, {
|
|
33
|
+
FormValidationError: () => FormValidationError,
|
|
34
|
+
Link: () => Link,
|
|
35
|
+
NavigationCancelledError: () => NavigationCancelledError,
|
|
36
|
+
NavigationRuntimeError: () => NavigationRuntimeError,
|
|
37
|
+
Outlet: () => Outlet,
|
|
38
|
+
QueryRuntimeError: () => QueryRuntimeError,
|
|
39
|
+
cachePolicy: () => cachePolicy,
|
|
40
|
+
calculateOffsetForIndex: () => calculateOffsetForIndex,
|
|
41
|
+
calculateOffsets: () => calculateOffsets,
|
|
42
|
+
calculateTotalSize: () => calculateTotalSize,
|
|
43
|
+
calculateVisibleRange: () => calculateVisibleRange,
|
|
44
|
+
changes: () => changes,
|
|
45
|
+
createApp: () => createApp,
|
|
46
|
+
createChannel: () => createChannel,
|
|
47
|
+
createDevtoolsEventStream: () => createDevtoolsEventStream,
|
|
48
|
+
createDevtoolsEventStreamFromTelemetry: () => createDevtoolsEventStreamFromTelemetry,
|
|
49
|
+
createPresence: () => createPresence,
|
|
50
|
+
createRequestHandler: () => createRequestHandler,
|
|
51
|
+
createRuntimeEventSource: () => createRuntimeEventSource,
|
|
52
|
+
createStore: () => createStore,
|
|
53
|
+
createStoreFromEffect: () => createStoreFromEffect,
|
|
54
|
+
createStoreTag: () => createStoreTag,
|
|
55
|
+
createTestApp: () => createTestApp,
|
|
56
|
+
defaultHydrationGlobalName: () => defaultHydrationGlobalName,
|
|
57
|
+
defineAction: () => defineAction,
|
|
58
|
+
defineColumns: () => defineColumns,
|
|
59
|
+
defineConfig: () => defineConfig,
|
|
60
|
+
defineForm: () => defineForm,
|
|
61
|
+
defineLayout: () => defineLayout,
|
|
62
|
+
defineLoader: () => defineLoader,
|
|
63
|
+
defineManifest: () => defineManifest,
|
|
64
|
+
defineMiddleware: () => defineMiddleware,
|
|
65
|
+
definePage: () => definePage,
|
|
66
|
+
defineQuery: () => defineQuery,
|
|
67
|
+
defineRoute: () => defineRoute,
|
|
68
|
+
derive: () => derive,
|
|
69
|
+
fetchQuery: () => fetchQuery2,
|
|
70
|
+
filterRows: () => filterRows,
|
|
71
|
+
get: () => get,
|
|
72
|
+
getOffsetForIndex: () => getOffsetForIndex,
|
|
73
|
+
getTotalSize: () => getTotalSize,
|
|
74
|
+
getVisibleRange: () => getVisibleRange,
|
|
75
|
+
hydrateApp: () => hydrateApp,
|
|
76
|
+
invalidate: () => invalidate,
|
|
77
|
+
invalidateQuery: () => invalidateQuery,
|
|
78
|
+
loadersFromManifest: () => loadersFromManifest,
|
|
79
|
+
makeForm: () => makeForm,
|
|
80
|
+
makeStoreLayer: () => makeStoreLayer,
|
|
81
|
+
makeStoreLayerFromEffect: () => makeStoreLayerFromEffect,
|
|
82
|
+
mapRows: () => mapRows,
|
|
83
|
+
measureVirtualItems: () => measureVirtualItems,
|
|
84
|
+
modify: () => modify,
|
|
85
|
+
navigate: () => navigate,
|
|
86
|
+
noStore: () => noStore,
|
|
87
|
+
paginateRows: () => paginateRows,
|
|
88
|
+
prefetch: () => prefetch,
|
|
89
|
+
prefetchQuery: () => prefetchQuery,
|
|
90
|
+
projectRow: () => projectRow,
|
|
91
|
+
projectRows: () => projectRows,
|
|
92
|
+
publish: () => publish,
|
|
93
|
+
publishAll: () => publishAll,
|
|
94
|
+
resolveConfig: () => resolveConfig,
|
|
95
|
+
revalidateNavigation: () => revalidateNavigation,
|
|
96
|
+
routeHref: () => routeHref,
|
|
97
|
+
routePath: () => routePath,
|
|
98
|
+
routeSearchText: () => routeSearchText,
|
|
99
|
+
routeUrl: () => routeUrl,
|
|
100
|
+
routesFromManifest: () => routesFromManifest,
|
|
101
|
+
select: () => select,
|
|
102
|
+
selectChanges: () => selectChanges,
|
|
103
|
+
set: () => set,
|
|
104
|
+
sortRows: () => sortRows,
|
|
105
|
+
subscribe: () => subscribe,
|
|
106
|
+
update: () => update,
|
|
107
|
+
useDevtoolsEvents: () => useDevtoolsEvents,
|
|
108
|
+
useEventStream: () => useEventStream,
|
|
109
|
+
useForm: () => useForm,
|
|
110
|
+
useInfiniteQuery: () => useInfiniteQuery,
|
|
111
|
+
useNavigate: () => useNavigate2,
|
|
112
|
+
useNavigationSnapshot: () => useNavigationSnapshot2,
|
|
113
|
+
useQuery: () => useQuery2,
|
|
114
|
+
useRouteMatch: () => useRouteMatch,
|
|
115
|
+
useStore: () => useStore,
|
|
116
|
+
useStoreSelector: () => useStoreSelector,
|
|
117
|
+
useSuspenseQuery: () => useSuspenseQuery2
|
|
118
|
+
});
|
|
119
|
+
module.exports = __toCommonJS(index_exports);
|
|
120
|
+
|
|
121
|
+
// src/actions/types.ts
|
|
122
|
+
var defineAction = (definition) => definition;
|
|
123
|
+
|
|
124
|
+
// src/actions/service.ts
|
|
125
|
+
var import_effect3 = require("effect");
|
|
126
|
+
|
|
127
|
+
// src/boundary/codecs.ts
|
|
128
|
+
var import_effect = require("effect");
|
|
129
|
+
|
|
130
|
+
// src/boundary/errors.ts
|
|
131
|
+
var BoundaryDecodeError = class extends Error {
|
|
132
|
+
constructor(source, messageText, causeValue) {
|
|
133
|
+
super(`Boundary decode failed at ${source}: ${messageText}`);
|
|
134
|
+
this.source = source;
|
|
135
|
+
this.messageText = messageText;
|
|
136
|
+
this.causeValue = causeValue;
|
|
137
|
+
this.name = "BoundaryDecodeError";
|
|
138
|
+
}
|
|
139
|
+
_tag = "BoundaryDecodeError";
|
|
140
|
+
};
|
|
141
|
+
var BoundaryTransportError = class extends Error {
|
|
142
|
+
constructor(source, messageText, causeValue) {
|
|
143
|
+
super(`Boundary transport failed at ${source}: ${messageText}`);
|
|
144
|
+
this.source = source;
|
|
145
|
+
this.messageText = messageText;
|
|
146
|
+
this.causeValue = causeValue;
|
|
147
|
+
this.name = "BoundaryTransportError";
|
|
148
|
+
}
|
|
149
|
+
_tag = "BoundaryTransportError";
|
|
150
|
+
};
|
|
151
|
+
var BoundaryProtocolError = class extends Error {
|
|
152
|
+
constructor(source, messageText) {
|
|
153
|
+
super(`Boundary protocol violation at ${source}: ${messageText}`);
|
|
154
|
+
this.source = source;
|
|
155
|
+
this.messageText = messageText;
|
|
156
|
+
this.name = "BoundaryProtocolError";
|
|
157
|
+
}
|
|
158
|
+
_tag = "BoundaryProtocolError";
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
// src/boundary/codecs.ts
|
|
162
|
+
var Boundary = class extends import_effect.Context.Tag("EffectReact/Boundary")() {
|
|
163
|
+
};
|
|
164
|
+
var parseErrorMessage = (error) => import_effect.Cause.pretty(import_effect.Cause.fail(error)).trim();
|
|
165
|
+
var makeBoundaryService = () => ({
|
|
166
|
+
decodeUnknown: ({ source, schema, value }) => import_effect.Schema.decodeUnknown(schema)(value).pipe(
|
|
167
|
+
import_effect.Effect.mapError(
|
|
168
|
+
(error) => new BoundaryDecodeError(source, parseErrorMessage(error), error)
|
|
169
|
+
)
|
|
170
|
+
),
|
|
171
|
+
decodeTextJson: ({ source, schema, text }) => import_effect.Effect.gen(function* () {
|
|
172
|
+
const payload = yield* import_effect.Effect.try({
|
|
173
|
+
try: () => JSON.parse(text),
|
|
174
|
+
catch: (cause) => new BoundaryTransportError(source, "failed to parse JSON payload", cause)
|
|
175
|
+
});
|
|
176
|
+
return yield* import_effect.Schema.decodeUnknown(schema)(payload).pipe(
|
|
177
|
+
import_effect.Effect.mapError(
|
|
178
|
+
(error) => new BoundaryDecodeError(source, parseErrorMessage(error), error)
|
|
179
|
+
)
|
|
180
|
+
);
|
|
181
|
+
}),
|
|
182
|
+
encode: ({ source, schema, value }) => import_effect.Schema.encode(schema)(value).pipe(
|
|
183
|
+
import_effect.Effect.mapError((error) => new BoundaryProtocolError(source, parseErrorMessage(error)))
|
|
184
|
+
)
|
|
185
|
+
});
|
|
186
|
+
var BoundaryLive = import_effect.Layer.succeed(Boundary, makeBoundaryService());
|
|
187
|
+
|
|
188
|
+
// src/kernel/telemetry.ts
|
|
189
|
+
var import_effect2 = require("effect");
|
|
190
|
+
var Telemetry = class extends import_effect2.Context.Tag("EffectReact/Telemetry")() {
|
|
191
|
+
};
|
|
192
|
+
var TelemetryLive = import_effect2.Layer.effect(
|
|
193
|
+
Telemetry,
|
|
194
|
+
import_effect2.Effect.map(import_effect2.PubSub.unbounded(), (pubsub) => ({
|
|
195
|
+
emit: (event) => import_effect2.PubSub.publish(pubsub, event).pipe(import_effect2.Effect.asVoid),
|
|
196
|
+
stream: import_effect2.Stream.fromPubSub(pubsub)
|
|
197
|
+
}))
|
|
198
|
+
);
|
|
199
|
+
|
|
200
|
+
// src/actions/service.ts
|
|
201
|
+
var toFailureDetail = (error) => {
|
|
202
|
+
if (error instanceof Error) {
|
|
203
|
+
return `${error.name}: ${error.message}`;
|
|
204
|
+
}
|
|
205
|
+
return String(error);
|
|
206
|
+
};
|
|
207
|
+
var Actions = class extends import_effect3.Context.Tag("EffectReact/Actions")() {
|
|
208
|
+
};
|
|
209
|
+
var makeActionsLayer = (options) => import_effect3.Layer.effect(
|
|
210
|
+
Actions,
|
|
211
|
+
import_effect3.Effect.gen(function* () {
|
|
212
|
+
const boundary = yield* Boundary;
|
|
213
|
+
const telemetry = yield* Telemetry;
|
|
214
|
+
const actionMap = new Map(
|
|
215
|
+
options.actions.map((action) => [action.name, action])
|
|
216
|
+
);
|
|
217
|
+
const run = (definition, input) => import_effect3.Effect.gen(function* () {
|
|
218
|
+
yield* telemetry.emit({
|
|
219
|
+
_tag: "action",
|
|
220
|
+
phase: "start",
|
|
221
|
+
name: definition.name,
|
|
222
|
+
timestamp: Date.now()
|
|
223
|
+
});
|
|
224
|
+
const decodedInput = yield* boundary.decodeUnknown({
|
|
225
|
+
source: `action:${definition.name}:input`,
|
|
226
|
+
schema: definition.input,
|
|
227
|
+
value: input
|
|
228
|
+
});
|
|
229
|
+
const value = yield* definition.handler(decodedInput);
|
|
230
|
+
const decodedOutput = yield* boundary.decodeUnknown({
|
|
231
|
+
source: `action:${definition.name}:output`,
|
|
232
|
+
schema: definition.output,
|
|
233
|
+
value
|
|
234
|
+
});
|
|
235
|
+
yield* telemetry.emit({
|
|
236
|
+
_tag: "action",
|
|
237
|
+
phase: "success",
|
|
238
|
+
name: definition.name,
|
|
239
|
+
timestamp: Date.now()
|
|
240
|
+
});
|
|
241
|
+
return decodedOutput;
|
|
242
|
+
}).pipe(
|
|
243
|
+
import_effect3.Effect.tapError(
|
|
244
|
+
(error) => telemetry.emit({
|
|
245
|
+
_tag: "action",
|
|
246
|
+
phase: "failure",
|
|
247
|
+
name: definition.name,
|
|
248
|
+
timestamp: Date.now(),
|
|
249
|
+
detail: error
|
|
250
|
+
})
|
|
251
|
+
)
|
|
252
|
+
);
|
|
253
|
+
const dispatch = (name, input) => import_effect3.Effect.gen(function* () {
|
|
254
|
+
const definition = actionMap.get(name);
|
|
255
|
+
if (definition === void 0) {
|
|
256
|
+
return {
|
|
257
|
+
_tag: "defect",
|
|
258
|
+
message: `Unknown action: ${name}`
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
const decodedInput = yield* boundary.decodeUnknown({
|
|
262
|
+
source: `action:${name}:dispatch-input`,
|
|
263
|
+
schema: definition.input,
|
|
264
|
+
value: input
|
|
265
|
+
});
|
|
266
|
+
const handler = definition.handler;
|
|
267
|
+
const result = yield* import_effect3.Effect.exit(handler(decodedInput));
|
|
268
|
+
if (result._tag === "Success") {
|
|
269
|
+
const encoded = yield* boundary.encode({
|
|
270
|
+
source: `action:${name}:wire-success`,
|
|
271
|
+
schema: definition.output,
|
|
272
|
+
value: result.value
|
|
273
|
+
});
|
|
274
|
+
return {
|
|
275
|
+
_tag: "success",
|
|
276
|
+
value: encoded
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
const failure = import_effect3.Cause.failureOption(result.cause);
|
|
280
|
+
if (failure._tag === "Some") {
|
|
281
|
+
const value = failure.value;
|
|
282
|
+
if (value instanceof BoundaryDecodeError || value instanceof BoundaryProtocolError) {
|
|
283
|
+
return {
|
|
284
|
+
_tag: "defect",
|
|
285
|
+
message: toFailureDetail(value)
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
const encodedError = yield* boundary.encode({
|
|
289
|
+
source: `action:${name}:wire-failure`,
|
|
290
|
+
schema: definition.error,
|
|
291
|
+
value
|
|
292
|
+
}).pipe(
|
|
293
|
+
import_effect3.Effect.catchAll(() => import_effect3.Effect.succeed(value))
|
|
294
|
+
);
|
|
295
|
+
return {
|
|
296
|
+
_tag: "failure",
|
|
297
|
+
error: encodedError
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
return {
|
|
301
|
+
_tag: "defect",
|
|
302
|
+
message: import_effect3.Cause.pretty(result.cause)
|
|
303
|
+
};
|
|
304
|
+
}).pipe(
|
|
305
|
+
import_effect3.Effect.catchAll(
|
|
306
|
+
(error) => import_effect3.Effect.succeed({
|
|
307
|
+
_tag: "defect",
|
|
308
|
+
message: toFailureDetail(error)
|
|
309
|
+
})
|
|
310
|
+
)
|
|
311
|
+
);
|
|
312
|
+
return {
|
|
313
|
+
run,
|
|
314
|
+
dispatch
|
|
315
|
+
};
|
|
316
|
+
})
|
|
317
|
+
);
|
|
318
|
+
|
|
319
|
+
// src/actions/http.ts
|
|
320
|
+
var import_effect4 = require("effect");
|
|
321
|
+
var ActionRequestSchema = import_effect4.Schema.Struct({
|
|
322
|
+
name: import_effect4.Schema.String,
|
|
323
|
+
input: import_effect4.Schema.Unknown
|
|
324
|
+
});
|
|
325
|
+
var ActionWireResultSchema = import_effect4.Schema.Union(
|
|
326
|
+
import_effect4.Schema.Struct({ _tag: import_effect4.Schema.Literal("success"), value: import_effect4.Schema.Unknown }),
|
|
327
|
+
import_effect4.Schema.Struct({ _tag: import_effect4.Schema.Literal("failure"), error: import_effect4.Schema.Unknown }),
|
|
328
|
+
import_effect4.Schema.Struct({ _tag: import_effect4.Schema.Literal("defect"), message: import_effect4.Schema.String })
|
|
329
|
+
);
|
|
330
|
+
var ActionTransportError = class extends Error {
|
|
331
|
+
constructor(messageText, causeValue) {
|
|
332
|
+
super(messageText);
|
|
333
|
+
this.messageText = messageText;
|
|
334
|
+
this.causeValue = causeValue;
|
|
335
|
+
this.name = "ActionTransportError";
|
|
336
|
+
}
|
|
337
|
+
_tag = "ActionTransportError";
|
|
338
|
+
};
|
|
339
|
+
var jsonResponse = (status, body) => new Response(JSON.stringify(body), {
|
|
340
|
+
status,
|
|
341
|
+
headers: {
|
|
342
|
+
"content-type": "application/json"
|
|
343
|
+
}
|
|
344
|
+
});
|
|
345
|
+
var createActionHttpHandlerEffect = () => (request) => import_effect4.Effect.gen(function* () {
|
|
346
|
+
if (request.method.toUpperCase() !== "POST") {
|
|
347
|
+
return jsonResponse(405, { error: "Method Not Allowed" });
|
|
348
|
+
}
|
|
349
|
+
const rawBody = yield* import_effect4.Effect.tryPromise({
|
|
350
|
+
try: () => request.text(),
|
|
351
|
+
catch: (cause) => new ActionTransportError("Failed to read request body", cause)
|
|
352
|
+
});
|
|
353
|
+
const boundary = yield* Boundary;
|
|
354
|
+
const payload = yield* boundary.decodeTextJson({
|
|
355
|
+
source: "action:http:request",
|
|
356
|
+
schema: ActionRequestSchema,
|
|
357
|
+
text: rawBody
|
|
358
|
+
});
|
|
359
|
+
const actions = yield* Actions;
|
|
360
|
+
const result = yield* actions.dispatch(payload.name, payload.input);
|
|
361
|
+
return jsonResponse(200, result);
|
|
362
|
+
}).pipe(
|
|
363
|
+
import_effect4.Effect.catchAll(
|
|
364
|
+
(error) => import_effect4.Effect.succeed(
|
|
365
|
+
jsonResponse(500, {
|
|
366
|
+
error: error instanceof Error ? error.message : String(error)
|
|
367
|
+
})
|
|
368
|
+
)
|
|
369
|
+
)
|
|
370
|
+
);
|
|
371
|
+
var createActionHttpHandler = () => {
|
|
372
|
+
const handleEffect = createActionHttpHandlerEffect();
|
|
373
|
+
return (runtimeRun) => (request) => runtimeRun(handleEffect(request));
|
|
374
|
+
};
|
|
375
|
+
|
|
376
|
+
// src/react/provider.tsx
|
|
377
|
+
var import_react = require("react");
|
|
378
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
379
|
+
var RuntimeContext = (0, import_react.createContext)(null);
|
|
380
|
+
var useEffectRuntime = () => {
|
|
381
|
+
const runtime = (0, import_react.useContext)(RuntimeContext);
|
|
382
|
+
if (runtime === null) {
|
|
383
|
+
throw new Error("Effect runtime is not available. Wrap your app with <EffectProvider>.");
|
|
384
|
+
}
|
|
385
|
+
return runtime;
|
|
386
|
+
};
|
|
387
|
+
|
|
388
|
+
// src/kernel/app.ts
|
|
389
|
+
var import_effect10 = require("effect");
|
|
390
|
+
|
|
391
|
+
// src/data/types.ts
|
|
392
|
+
var defineQuery = (definition) => definition;
|
|
393
|
+
var QueryRuntimeError = class extends Error {
|
|
394
|
+
constructor(messageText) {
|
|
395
|
+
super(messageText);
|
|
396
|
+
this.messageText = messageText;
|
|
397
|
+
this.name = "QueryRuntimeError";
|
|
398
|
+
}
|
|
399
|
+
_tag = "QueryRuntimeError";
|
|
400
|
+
};
|
|
401
|
+
|
|
402
|
+
// src/data/service.ts
|
|
403
|
+
var import_effect5 = require("effect");
|
|
404
|
+
var defaultRuntimeOptions = {
|
|
405
|
+
capacity: 2048,
|
|
406
|
+
timeToLive: "5 minutes"
|
|
407
|
+
};
|
|
408
|
+
var stableStringify = (value) => {
|
|
409
|
+
if (value === null || value === void 0) {
|
|
410
|
+
return String(value);
|
|
411
|
+
}
|
|
412
|
+
if (typeof value !== "object") {
|
|
413
|
+
return JSON.stringify(value);
|
|
414
|
+
}
|
|
415
|
+
if (Array.isArray(value)) {
|
|
416
|
+
return `[${value.map(stableStringify).join(",")}]`;
|
|
417
|
+
}
|
|
418
|
+
const entries = Object.entries(value).sort(
|
|
419
|
+
([a], [b]) => a.localeCompare(b)
|
|
420
|
+
);
|
|
421
|
+
return `{${entries.map(([key, nested]) => `${JSON.stringify(key)}:${stableStringify(nested)}`).join(",")}}`;
|
|
422
|
+
};
|
|
423
|
+
var initialSnapshot = (key) => ({
|
|
424
|
+
key,
|
|
425
|
+
phase: "initial",
|
|
426
|
+
data: void 0,
|
|
427
|
+
error: void 0,
|
|
428
|
+
updatedAt: null
|
|
429
|
+
});
|
|
430
|
+
var Data = class extends import_effect5.Context.Tag("EffectReact/Data")() {
|
|
431
|
+
};
|
|
432
|
+
var makeDataLayer = (options = {}) => {
|
|
433
|
+
const merged = {
|
|
434
|
+
...defaultRuntimeOptions,
|
|
435
|
+
...options
|
|
436
|
+
};
|
|
437
|
+
return import_effect5.Layer.effect(
|
|
438
|
+
Data,
|
|
439
|
+
import_effect5.Effect.gen(function* () {
|
|
440
|
+
const boundary = yield* Boundary;
|
|
441
|
+
const telemetry = yield* Telemetry;
|
|
442
|
+
const lookups = /* @__PURE__ */ new Map();
|
|
443
|
+
const snapshots = yield* import_effect5.SubscriptionRef.make(
|
|
444
|
+
/* @__PURE__ */ new Map()
|
|
445
|
+
);
|
|
446
|
+
const cache = yield* import_effect5.Cache.make({
|
|
447
|
+
capacity: merged.capacity,
|
|
448
|
+
timeToLive: merged.timeToLive,
|
|
449
|
+
lookup: (key) => import_effect5.Effect.suspend(() => {
|
|
450
|
+
const lookup = lookups.get(key);
|
|
451
|
+
if (lookup === void 0) {
|
|
452
|
+
return import_effect5.Effect.fail(new QueryRuntimeError(`No query executor registered for ${key}`));
|
|
453
|
+
}
|
|
454
|
+
return lookup;
|
|
455
|
+
})
|
|
456
|
+
});
|
|
457
|
+
const setSnapshot = (key, update2) => import_effect5.SubscriptionRef.update(snapshots, (current) => {
|
|
458
|
+
const next = new Map(current);
|
|
459
|
+
const previous = next.get(key) ?? initialSnapshot(key);
|
|
460
|
+
next.set(key, update2(previous));
|
|
461
|
+
return next;
|
|
462
|
+
}).pipe(import_effect5.Effect.asVoid);
|
|
463
|
+
const buildKey = (definition, input) => {
|
|
464
|
+
const base = definition.key ? definition.key(input) : input;
|
|
465
|
+
return `${definition.name}:${stableStringify(base)}`;
|
|
466
|
+
};
|
|
467
|
+
const fetch2 = (definition, input, runOptions) => import_effect5.Effect.gen(function* () {
|
|
468
|
+
const decodedInput = yield* boundary.decodeUnknown({
|
|
469
|
+
source: `query:${definition.name}:input`,
|
|
470
|
+
schema: definition.input,
|
|
471
|
+
value: input
|
|
472
|
+
});
|
|
473
|
+
const key = buildKey(definition, decodedInput);
|
|
474
|
+
yield* telemetry.emit({
|
|
475
|
+
_tag: "query",
|
|
476
|
+
phase: "start",
|
|
477
|
+
key,
|
|
478
|
+
timestamp: Date.now()
|
|
479
|
+
});
|
|
480
|
+
yield* setSnapshot(key, (previous) => ({
|
|
481
|
+
...previous,
|
|
482
|
+
phase: "loading",
|
|
483
|
+
error: void 0
|
|
484
|
+
}));
|
|
485
|
+
lookups.set(
|
|
486
|
+
key,
|
|
487
|
+
definition.run(decodedInput).pipe(
|
|
488
|
+
import_effect5.Effect.flatMap(
|
|
489
|
+
(output) => boundary.decodeUnknown({
|
|
490
|
+
source: `query:${definition.name}:output`,
|
|
491
|
+
schema: definition.output,
|
|
492
|
+
value: output
|
|
493
|
+
})
|
|
494
|
+
)
|
|
495
|
+
)
|
|
496
|
+
);
|
|
497
|
+
if (runOptions?.forceRefresh === true) {
|
|
498
|
+
yield* cache.refresh(key).pipe(import_effect5.Effect.ignore);
|
|
499
|
+
}
|
|
500
|
+
const value = yield* cache.get(key).pipe(
|
|
501
|
+
import_effect5.Effect.mapError(
|
|
502
|
+
(error) => error
|
|
503
|
+
)
|
|
504
|
+
);
|
|
505
|
+
yield* setSnapshot(key, () => ({
|
|
506
|
+
key,
|
|
507
|
+
phase: "success",
|
|
508
|
+
data: value,
|
|
509
|
+
error: void 0,
|
|
510
|
+
updatedAt: Date.now()
|
|
511
|
+
}));
|
|
512
|
+
yield* telemetry.emit({
|
|
513
|
+
_tag: "query",
|
|
514
|
+
phase: "success",
|
|
515
|
+
key,
|
|
516
|
+
timestamp: Date.now()
|
|
517
|
+
});
|
|
518
|
+
return value;
|
|
519
|
+
}).pipe(
|
|
520
|
+
import_effect5.Effect.tapError(
|
|
521
|
+
(error) => import_effect5.Effect.gen(function* () {
|
|
522
|
+
const decodedInput = yield* boundary.decodeUnknown({
|
|
523
|
+
source: `query:${definition.name}:input`,
|
|
524
|
+
schema: definition.input,
|
|
525
|
+
value: input
|
|
526
|
+
});
|
|
527
|
+
const key = buildKey(definition, decodedInput);
|
|
528
|
+
yield* setSnapshot(key, (previous) => ({
|
|
529
|
+
...previous,
|
|
530
|
+
phase: "failure",
|
|
531
|
+
error,
|
|
532
|
+
updatedAt: previous.updatedAt
|
|
533
|
+
}));
|
|
534
|
+
yield* telemetry.emit({
|
|
535
|
+
_tag: "query",
|
|
536
|
+
phase: "failure",
|
|
537
|
+
key,
|
|
538
|
+
timestamp: Date.now(),
|
|
539
|
+
detail: error
|
|
540
|
+
});
|
|
541
|
+
})
|
|
542
|
+
)
|
|
543
|
+
);
|
|
544
|
+
const prefetch2 = (definition, input) => fetch2(definition, input).pipe(import_effect5.Effect.asVoid);
|
|
545
|
+
const invalidate2 = (definition, input) => import_effect5.Effect.gen(function* () {
|
|
546
|
+
const key = `${definition.name}:${stableStringify(input)}`;
|
|
547
|
+
yield* cache.invalidate(key);
|
|
548
|
+
yield* import_effect5.SubscriptionRef.update(snapshots, (current) => {
|
|
549
|
+
const next = new Map(current);
|
|
550
|
+
next.delete(key);
|
|
551
|
+
return next;
|
|
552
|
+
}).pipe(import_effect5.Effect.asVoid);
|
|
553
|
+
yield* telemetry.emit({
|
|
554
|
+
_tag: "query",
|
|
555
|
+
phase: "invalidate",
|
|
556
|
+
key,
|
|
557
|
+
timestamp: Date.now()
|
|
558
|
+
});
|
|
559
|
+
});
|
|
560
|
+
const getSnapshot = (definition, input) => import_effect5.Effect.gen(function* () {
|
|
561
|
+
const key = `${definition.name}:${stableStringify(input)}`;
|
|
562
|
+
const current = yield* import_effect5.SubscriptionRef.get(snapshots);
|
|
563
|
+
const snapshot = current.get(key);
|
|
564
|
+
if (snapshot === void 0) {
|
|
565
|
+
return initialSnapshot(key);
|
|
566
|
+
}
|
|
567
|
+
return snapshot;
|
|
568
|
+
});
|
|
569
|
+
return {
|
|
570
|
+
fetch: fetch2,
|
|
571
|
+
prefetch: prefetch2,
|
|
572
|
+
invalidate: invalidate2,
|
|
573
|
+
getSnapshot,
|
|
574
|
+
getAllSnapshots: import_effect5.SubscriptionRef.get(snapshots),
|
|
575
|
+
hydrateSnapshots: (nextSnapshots) => import_effect5.SubscriptionRef.set(snapshots, new Map(nextSnapshots)),
|
|
576
|
+
snapshots: snapshots.changes
|
|
577
|
+
};
|
|
578
|
+
})
|
|
579
|
+
);
|
|
580
|
+
};
|
|
581
|
+
var fetchQuery = (definition, input, options) => import_effect5.Effect.flatMap(Data, (service) => service.fetch(definition, input, options));
|
|
582
|
+
|
|
583
|
+
// src/data/react.tsx
|
|
584
|
+
var import_effect6 = require("effect");
|
|
585
|
+
var import_react2 = require("react");
|
|
586
|
+
var useDataService = () => {
|
|
587
|
+
const runtime = useEffectRuntime();
|
|
588
|
+
return (0, import_react2.useMemo)(() => runtime.runSync(Data), [runtime]);
|
|
589
|
+
};
|
|
590
|
+
var useQuery = (definition, input, options = {}) => {
|
|
591
|
+
const runtime = useEffectRuntime();
|
|
592
|
+
const data = useDataService();
|
|
593
|
+
const subscribe2 = (0, import_react2.useCallback)(
|
|
594
|
+
(listener) => {
|
|
595
|
+
const fiber = runtime.runFork(
|
|
596
|
+
import_effect6.Stream.runForEach(data.snapshots, () => import_effect6.Effect.sync(listener))
|
|
597
|
+
);
|
|
598
|
+
return () => {
|
|
599
|
+
runtime.runFork(import_effect6.Fiber.interrupt(fiber));
|
|
600
|
+
};
|
|
601
|
+
},
|
|
602
|
+
[data, runtime]
|
|
603
|
+
);
|
|
604
|
+
const getSnapshot = (0, import_react2.useCallback)(
|
|
605
|
+
() => runtime.runSync(data.getSnapshot(definition, input)),
|
|
606
|
+
[data, definition, input, runtime]
|
|
607
|
+
);
|
|
608
|
+
const snapshot = (0, import_react2.useSyncExternalStore)(subscribe2, getSnapshot, getSnapshot);
|
|
609
|
+
(0, import_react2.useEffect)(() => {
|
|
610
|
+
if (options.enabled === false) {
|
|
611
|
+
return;
|
|
612
|
+
}
|
|
613
|
+
runtime.runFork(data.prefetch(definition, input));
|
|
614
|
+
}, [data, definition, input, options.enabled, runtime]);
|
|
615
|
+
const refetch = (0, import_react2.useCallback)(
|
|
616
|
+
() => runtime.runPromise(data.fetch(definition, input, { ...options.run, forceRefresh: true })),
|
|
617
|
+
[data, definition, input, options.run, runtime]
|
|
618
|
+
);
|
|
619
|
+
const invalidate2 = (0, import_react2.useCallback)(
|
|
620
|
+
() => runtime.runPromise(data.invalidate(definition, input)),
|
|
621
|
+
[data, definition, input, runtime]
|
|
622
|
+
);
|
|
623
|
+
return {
|
|
624
|
+
...snapshot,
|
|
625
|
+
refetch,
|
|
626
|
+
invalidate: invalidate2
|
|
627
|
+
};
|
|
628
|
+
};
|
|
629
|
+
var useSuspenseQuery = (definition, input) => {
|
|
630
|
+
const result = useQuery(definition, input);
|
|
631
|
+
if (result.phase === "failure") {
|
|
632
|
+
throw result.error;
|
|
633
|
+
}
|
|
634
|
+
if (result.phase === "success") {
|
|
635
|
+
return result.data;
|
|
636
|
+
}
|
|
637
|
+
throw result.refetch();
|
|
638
|
+
};
|
|
639
|
+
|
|
640
|
+
// src/navigation/types.ts
|
|
641
|
+
var defineRoute = (route) => route;
|
|
642
|
+
var defineLoader = (loader) => loader;
|
|
643
|
+
var NavigationRuntimeError = class extends Error {
|
|
644
|
+
constructor(messageText) {
|
|
645
|
+
super(messageText);
|
|
646
|
+
this.messageText = messageText;
|
|
647
|
+
this.name = "NavigationRuntimeError";
|
|
648
|
+
}
|
|
649
|
+
_tag = "NavigationRuntimeError";
|
|
650
|
+
};
|
|
651
|
+
var NavigationCancelledError = class extends Error {
|
|
652
|
+
constructor(pathname) {
|
|
653
|
+
super(`Navigation cancelled for ${pathname}`);
|
|
654
|
+
this.pathname = pathname;
|
|
655
|
+
this.name = "NavigationCancelledError";
|
|
656
|
+
}
|
|
657
|
+
_tag = "NavigationCancelledError";
|
|
658
|
+
};
|
|
659
|
+
|
|
660
|
+
// src/navigation/matcher.ts
|
|
661
|
+
var normalizePathname = (pathname) => {
|
|
662
|
+
if (pathname.length === 0) {
|
|
663
|
+
return "/";
|
|
664
|
+
}
|
|
665
|
+
const withSlash = pathname.startsWith("/") ? pathname : `/${pathname}`;
|
|
666
|
+
if (withSlash.length > 1 && withSlash.endsWith("/")) {
|
|
667
|
+
return withSlash.slice(0, -1);
|
|
668
|
+
}
|
|
669
|
+
return withSlash;
|
|
670
|
+
};
|
|
671
|
+
var scoreRoute = (path) => {
|
|
672
|
+
if (path === "/") {
|
|
673
|
+
return 10;
|
|
674
|
+
}
|
|
675
|
+
return path.split("/").filter((segment) => segment.length > 0).reduce((score, segment) => {
|
|
676
|
+
if (segment === "*") {
|
|
677
|
+
return score;
|
|
678
|
+
}
|
|
679
|
+
if (segment.startsWith(":")) {
|
|
680
|
+
return score + 2;
|
|
681
|
+
}
|
|
682
|
+
return score + 5;
|
|
683
|
+
}, 0);
|
|
684
|
+
};
|
|
685
|
+
var splitSegments = (path) => normalizePathname(path).split("/").filter((segment) => segment.length > 0);
|
|
686
|
+
var matchRoutePath = (routePath2, pathname) => {
|
|
687
|
+
const routeSegments = splitSegments(routePath2);
|
|
688
|
+
const pathSegments = splitSegments(pathname);
|
|
689
|
+
const params = {};
|
|
690
|
+
let i = 0;
|
|
691
|
+
let j = 0;
|
|
692
|
+
while (i < routeSegments.length && j < pathSegments.length) {
|
|
693
|
+
const routeSegment = routeSegments[i];
|
|
694
|
+
const pathSegment = pathSegments[j];
|
|
695
|
+
if (routeSegment === "*") {
|
|
696
|
+
return params;
|
|
697
|
+
}
|
|
698
|
+
if (routeSegment.startsWith(":")) {
|
|
699
|
+
params[routeSegment.slice(1)] = decodeURIComponent(pathSegment);
|
|
700
|
+
i += 1;
|
|
701
|
+
j += 1;
|
|
702
|
+
continue;
|
|
703
|
+
}
|
|
704
|
+
if (routeSegment !== pathSegment) {
|
|
705
|
+
return null;
|
|
706
|
+
}
|
|
707
|
+
i += 1;
|
|
708
|
+
j += 1;
|
|
709
|
+
}
|
|
710
|
+
if (i < routeSegments.length && routeSegments[i] === "*") {
|
|
711
|
+
return params;
|
|
712
|
+
}
|
|
713
|
+
if (i !== routeSegments.length || j !== pathSegments.length) {
|
|
714
|
+
return null;
|
|
715
|
+
}
|
|
716
|
+
return params;
|
|
717
|
+
};
|
|
718
|
+
var matchRoute = ({ routes, pathname, search }) => {
|
|
719
|
+
const normalized = normalizePathname(pathname);
|
|
720
|
+
const sorted = [...routes].sort((a, b) => scoreRoute(b.path) - scoreRoute(a.path));
|
|
721
|
+
for (const route of sorted) {
|
|
722
|
+
const params = matchRoutePath(route.path, normalized);
|
|
723
|
+
if (params !== null) {
|
|
724
|
+
return {
|
|
725
|
+
route,
|
|
726
|
+
pathname: normalized,
|
|
727
|
+
params,
|
|
728
|
+
search
|
|
729
|
+
};
|
|
730
|
+
}
|
|
731
|
+
}
|
|
732
|
+
return null;
|
|
733
|
+
};
|
|
734
|
+
var buildHref = (pathname, searchText) => searchText.length > 0 ? `${normalizePathname(pathname)}${searchText}` : normalizePathname(pathname);
|
|
735
|
+
var normalizeSearchText = (searchText) => {
|
|
736
|
+
if (searchText.length === 0 || searchText === "?") {
|
|
737
|
+
return "";
|
|
738
|
+
}
|
|
739
|
+
return searchText.startsWith("?") ? searchText : `?${searchText}`;
|
|
740
|
+
};
|
|
741
|
+
var parseHref = (href) => {
|
|
742
|
+
const [pathPart, ...searchParts] = href.split("?");
|
|
743
|
+
return {
|
|
744
|
+
pathname: normalizePathname(pathPart ?? "/"),
|
|
745
|
+
searchText: normalizeSearchText(searchParts.length === 0 ? "" : searchParts.join("?"))
|
|
746
|
+
};
|
|
747
|
+
};
|
|
748
|
+
|
|
749
|
+
// src/navigation/service.ts
|
|
750
|
+
var import_effect7 = require("effect");
|
|
751
|
+
var describeUnknown = (value) => {
|
|
752
|
+
if (value instanceof Error) {
|
|
753
|
+
return `${value.name}: ${value.message}`;
|
|
754
|
+
}
|
|
755
|
+
if (typeof value === "string") {
|
|
756
|
+
return value;
|
|
757
|
+
}
|
|
758
|
+
try {
|
|
759
|
+
return JSON.stringify(value);
|
|
760
|
+
} catch {
|
|
761
|
+
return String(value);
|
|
762
|
+
}
|
|
763
|
+
};
|
|
764
|
+
var initialSnapshot2 = {
|
|
765
|
+
pathname: "/",
|
|
766
|
+
searchText: "",
|
|
767
|
+
href: "/",
|
|
768
|
+
status: "idle",
|
|
769
|
+
match: null,
|
|
770
|
+
loaders: {},
|
|
771
|
+
error: void 0
|
|
772
|
+
};
|
|
773
|
+
var toLoadersByName = (loaders) => new Map(loaders.map((loader) => [loader.name, loader]));
|
|
774
|
+
var planLoaderBatches = (loaders) => {
|
|
775
|
+
const byName = toLoadersByName(loaders);
|
|
776
|
+
const depthByName = /* @__PURE__ */ new Map();
|
|
777
|
+
const visiting = /* @__PURE__ */ new Set();
|
|
778
|
+
const resolveDepth = (name) => {
|
|
779
|
+
const cached = depthByName.get(name);
|
|
780
|
+
if (cached !== void 0) {
|
|
781
|
+
return import_effect7.Effect.succeed(cached);
|
|
782
|
+
}
|
|
783
|
+
if (visiting.has(name)) {
|
|
784
|
+
return import_effect7.Effect.fail(new NavigationRuntimeError(`Cyclic loader dependency detected at ${name}`));
|
|
785
|
+
}
|
|
786
|
+
const loader = byName.get(name);
|
|
787
|
+
if (loader === void 0) {
|
|
788
|
+
return import_effect7.Effect.fail(new NavigationRuntimeError(`Loader dependency '${name}' is not registered`));
|
|
789
|
+
}
|
|
790
|
+
visiting.add(name);
|
|
791
|
+
const dependencies = loader.dependsOn ?? [];
|
|
792
|
+
return import_effect7.Effect.forEach(dependencies, resolveDepth).pipe(
|
|
793
|
+
import_effect7.Effect.map((depths) => {
|
|
794
|
+
const depth = depths.length === 0 ? 0 : Math.max(...depths) + 1;
|
|
795
|
+
depthByName.set(name, depth);
|
|
796
|
+
visiting.delete(name);
|
|
797
|
+
return depth;
|
|
798
|
+
}),
|
|
799
|
+
import_effect7.Effect.catchAll((error) => {
|
|
800
|
+
visiting.delete(name);
|
|
801
|
+
return import_effect7.Effect.fail(error);
|
|
802
|
+
})
|
|
803
|
+
);
|
|
804
|
+
};
|
|
805
|
+
return import_effect7.Effect.gen(function* () {
|
|
806
|
+
const entries = yield* import_effect7.Effect.forEach(
|
|
807
|
+
loaders,
|
|
808
|
+
(loader) => import_effect7.Effect.map(resolveDepth(loader.name), (depth) => [depth, loader])
|
|
809
|
+
);
|
|
810
|
+
const grouped = /* @__PURE__ */ new Map();
|
|
811
|
+
for (const [depth, loader] of entries) {
|
|
812
|
+
const existing = grouped.get(depth);
|
|
813
|
+
if (existing === void 0) {
|
|
814
|
+
grouped.set(depth, [loader]);
|
|
815
|
+
} else {
|
|
816
|
+
existing.push(loader);
|
|
817
|
+
}
|
|
818
|
+
}
|
|
819
|
+
const depths = Array.from(grouped.keys()).sort((a, b) => a - b);
|
|
820
|
+
return depths.map((depth) => grouped.get(depth) ?? []);
|
|
821
|
+
});
|
|
822
|
+
};
|
|
823
|
+
var Navigation = class extends import_effect7.Context.Tag("EffectReact/Navigation")() {
|
|
824
|
+
};
|
|
825
|
+
var makeNavigationLayer = (options) => {
|
|
826
|
+
const loaders = options.loaders ?? [];
|
|
827
|
+
const initial = parseHref(options.initialHref ?? "/");
|
|
828
|
+
return import_effect7.Layer.effect(
|
|
829
|
+
Navigation,
|
|
830
|
+
import_effect7.Effect.gen(function* () {
|
|
831
|
+
const boundary = yield* Boundary;
|
|
832
|
+
const telemetry = yield* Telemetry;
|
|
833
|
+
const snapshotsRef = yield* import_effect7.SubscriptionRef.make({
|
|
834
|
+
...initialSnapshot2,
|
|
835
|
+
pathname: initial.pathname,
|
|
836
|
+
searchText: initial.searchText,
|
|
837
|
+
href: buildHref(initial.pathname, initial.searchText)
|
|
838
|
+
});
|
|
839
|
+
const activeFiberRef = yield* import_effect7.Ref.make(import_effect7.Option.none());
|
|
840
|
+
const runLoaders = (snapshot) => import_effect7.Effect.gen(function* () {
|
|
841
|
+
if (snapshot.match === null) {
|
|
842
|
+
return {};
|
|
843
|
+
}
|
|
844
|
+
const routeLoaders = loaders.filter((loader) => loader.routeId === snapshot.match.route.id);
|
|
845
|
+
if (routeLoaders.length === 0) {
|
|
846
|
+
return {};
|
|
847
|
+
}
|
|
848
|
+
const batches = yield* planLoaderBatches(routeLoaders);
|
|
849
|
+
const results = {};
|
|
850
|
+
const states = {};
|
|
851
|
+
for (const loader of routeLoaders) {
|
|
852
|
+
states[loader.name] = { _tag: "pending" };
|
|
853
|
+
}
|
|
854
|
+
yield* import_effect7.SubscriptionRef.update(snapshotsRef, (current) => ({
|
|
855
|
+
...current,
|
|
856
|
+
loaders: {
|
|
857
|
+
...current.loaders,
|
|
858
|
+
...states
|
|
859
|
+
}
|
|
860
|
+
}));
|
|
861
|
+
for (const batch of batches) {
|
|
862
|
+
const exits = yield* import_effect7.Effect.all(
|
|
863
|
+
batch.map((loader) => {
|
|
864
|
+
const base = loader.run({
|
|
865
|
+
route: snapshot.match.route,
|
|
866
|
+
pathname: snapshot.pathname,
|
|
867
|
+
searchText: snapshot.searchText,
|
|
868
|
+
params: snapshot.match.params,
|
|
869
|
+
search: snapshot.match.search,
|
|
870
|
+
dependencyResults: results
|
|
871
|
+
});
|
|
872
|
+
const withRetry = loader.retry ? import_effect7.Effect.retry(base, loader.retry) : base;
|
|
873
|
+
return import_effect7.Effect.exit(withRetry).pipe(import_effect7.Effect.map((exit) => [loader, exit]));
|
|
874
|
+
}),
|
|
875
|
+
{
|
|
876
|
+
concurrency: "unbounded"
|
|
877
|
+
}
|
|
878
|
+
);
|
|
879
|
+
for (const [loader, exit] of exits) {
|
|
880
|
+
if (exit._tag === "Success") {
|
|
881
|
+
results[loader.name] = exit.value;
|
|
882
|
+
states[loader.name] = {
|
|
883
|
+
_tag: "success",
|
|
884
|
+
value: exit.value
|
|
885
|
+
};
|
|
886
|
+
continue;
|
|
887
|
+
}
|
|
888
|
+
const failure = import_effect7.Cause.failureOption(exit.cause);
|
|
889
|
+
states[loader.name] = {
|
|
890
|
+
_tag: "failure",
|
|
891
|
+
error: failure._tag === "Some" ? failure.value : import_effect7.Cause.pretty(exit.cause)
|
|
892
|
+
};
|
|
893
|
+
yield* import_effect7.SubscriptionRef.update(snapshotsRef, (current) => ({
|
|
894
|
+
...current,
|
|
895
|
+
status: "failure",
|
|
896
|
+
loaders: {
|
|
897
|
+
...current.loaders,
|
|
898
|
+
...states
|
|
899
|
+
},
|
|
900
|
+
error: states[loader.name]
|
|
901
|
+
}));
|
|
902
|
+
return yield* import_effect7.Effect.fail(
|
|
903
|
+
new NavigationRuntimeError(`Loader '${loader.name}' failed for route '${snapshot.match.route.id}'`)
|
|
904
|
+
);
|
|
905
|
+
}
|
|
906
|
+
yield* import_effect7.SubscriptionRef.update(snapshotsRef, (current) => ({
|
|
907
|
+
...current,
|
|
908
|
+
loaders: {
|
|
909
|
+
...current.loaders,
|
|
910
|
+
...states
|
|
911
|
+
}
|
|
912
|
+
}));
|
|
913
|
+
}
|
|
914
|
+
return states;
|
|
915
|
+
});
|
|
916
|
+
const performNavigation = (href) => import_effect7.Effect.gen(function* () {
|
|
917
|
+
const { pathname, searchText } = parseHref(href);
|
|
918
|
+
const searchParams = new URLSearchParams(searchText);
|
|
919
|
+
const candidate = options.routes.find((route) => matchRoute({
|
|
920
|
+
routes: [route],
|
|
921
|
+
pathname,
|
|
922
|
+
search: {}
|
|
923
|
+
}) !== null);
|
|
924
|
+
const decodedSearch = candidate?.search === void 0 ? import_effect7.Effect.succeed({}) : boundary.decodeUnknown({
|
|
925
|
+
source: `route:${candidate.id}:search`,
|
|
926
|
+
schema: candidate.search,
|
|
927
|
+
value: Object.fromEntries(searchParams.entries())
|
|
928
|
+
});
|
|
929
|
+
const search = yield* decodedSearch;
|
|
930
|
+
const matched = matchRoute({
|
|
931
|
+
routes: options.routes,
|
|
932
|
+
pathname,
|
|
933
|
+
search
|
|
934
|
+
});
|
|
935
|
+
if (matched === null) {
|
|
936
|
+
return yield* import_effect7.Effect.fail(
|
|
937
|
+
new NavigationRuntimeError(`No route matched pathname '${pathname}'`)
|
|
938
|
+
);
|
|
939
|
+
}
|
|
940
|
+
yield* telemetry.emit({
|
|
941
|
+
_tag: "navigation",
|
|
942
|
+
phase: "start",
|
|
943
|
+
pathname,
|
|
944
|
+
routeId: matched.route.id,
|
|
945
|
+
timestamp: Date.now()
|
|
946
|
+
});
|
|
947
|
+
const loadingSnapshot = {
|
|
948
|
+
pathname,
|
|
949
|
+
searchText: normalizeSearchText(searchText),
|
|
950
|
+
href: buildHref(pathname, normalizeSearchText(searchText)),
|
|
951
|
+
status: "loading",
|
|
952
|
+
match: matched,
|
|
953
|
+
loaders: {},
|
|
954
|
+
error: void 0
|
|
955
|
+
};
|
|
956
|
+
yield* import_effect7.SubscriptionRef.set(snapshotsRef, loadingSnapshot);
|
|
957
|
+
const loaderStates = yield* runLoaders(loadingSnapshot);
|
|
958
|
+
const completed = {
|
|
959
|
+
...loadingSnapshot,
|
|
960
|
+
status: "success",
|
|
961
|
+
loaders: loaderStates,
|
|
962
|
+
error: void 0
|
|
963
|
+
};
|
|
964
|
+
yield* import_effect7.SubscriptionRef.set(snapshotsRef, completed);
|
|
965
|
+
yield* telemetry.emit({
|
|
966
|
+
_tag: "navigation",
|
|
967
|
+
phase: "success",
|
|
968
|
+
pathname,
|
|
969
|
+
routeId: matched.route.id,
|
|
970
|
+
timestamp: Date.now()
|
|
971
|
+
});
|
|
972
|
+
return completed;
|
|
973
|
+
});
|
|
974
|
+
const navigate2 = (href) => import_effect7.Effect.gen(function* () {
|
|
975
|
+
const previous = yield* import_effect7.Ref.getAndSet(activeFiberRef, import_effect7.Option.none());
|
|
976
|
+
if (import_effect7.Option.isSome(previous)) {
|
|
977
|
+
yield* import_effect7.Fiber.interrupt(previous.value);
|
|
978
|
+
yield* telemetry.emit({
|
|
979
|
+
_tag: "navigation",
|
|
980
|
+
phase: "cancel",
|
|
981
|
+
pathname: href,
|
|
982
|
+
timestamp: Date.now()
|
|
983
|
+
});
|
|
984
|
+
}
|
|
985
|
+
const fiber = yield* import_effect7.Effect.fork(performNavigation(href));
|
|
986
|
+
yield* import_effect7.Ref.set(activeFiberRef, import_effect7.Option.some(fiber));
|
|
987
|
+
const exit = yield* import_effect7.Effect.exit(import_effect7.Fiber.join(fiber));
|
|
988
|
+
const current = yield* import_effect7.Ref.get(activeFiberRef);
|
|
989
|
+
if (import_effect7.Option.isSome(current) && current.value === fiber) {
|
|
990
|
+
yield* import_effect7.Ref.set(activeFiberRef, import_effect7.Option.none());
|
|
991
|
+
}
|
|
992
|
+
if (exit._tag === "Success") {
|
|
993
|
+
return exit.value;
|
|
994
|
+
}
|
|
995
|
+
if (import_effect7.Cause.isInterruptedOnly(exit.cause)) {
|
|
996
|
+
return yield* import_effect7.Effect.fail(new NavigationCancelledError(href));
|
|
997
|
+
}
|
|
998
|
+
const failure = import_effect7.Cause.failureOption(exit.cause);
|
|
999
|
+
if (failure._tag === "Some") {
|
|
1000
|
+
return yield* import_effect7.Effect.fail(
|
|
1001
|
+
failure.value instanceof NavigationRuntimeError ? failure.value : new NavigationRuntimeError(describeUnknown(failure.value))
|
|
1002
|
+
);
|
|
1003
|
+
}
|
|
1004
|
+
return yield* import_effect7.Effect.fail(new NavigationRuntimeError(import_effect7.Cause.pretty(exit.cause)));
|
|
1005
|
+
}).pipe(
|
|
1006
|
+
import_effect7.Effect.tapError(
|
|
1007
|
+
(error) => telemetry.emit({
|
|
1008
|
+
_tag: "navigation",
|
|
1009
|
+
phase: "failure",
|
|
1010
|
+
pathname: href,
|
|
1011
|
+
timestamp: Date.now(),
|
|
1012
|
+
detail: error
|
|
1013
|
+
})
|
|
1014
|
+
)
|
|
1015
|
+
);
|
|
1016
|
+
const revalidate = () => import_effect7.Effect.gen(function* () {
|
|
1017
|
+
const snapshot = yield* import_effect7.SubscriptionRef.get(snapshotsRef);
|
|
1018
|
+
return yield* navigate2(snapshot.href);
|
|
1019
|
+
});
|
|
1020
|
+
return {
|
|
1021
|
+
navigate: navigate2,
|
|
1022
|
+
revalidate,
|
|
1023
|
+
getSnapshot: import_effect7.SubscriptionRef.get(snapshotsRef),
|
|
1024
|
+
hydrateSnapshot: (snapshot) => import_effect7.SubscriptionRef.set(snapshotsRef, snapshot),
|
|
1025
|
+
snapshots: snapshotsRef.changes
|
|
1026
|
+
};
|
|
1027
|
+
})
|
|
1028
|
+
);
|
|
1029
|
+
};
|
|
1030
|
+
var navigateTo = (href) => import_effect7.Effect.flatMap(Navigation, (service) => service.navigate(href));
|
|
1031
|
+
|
|
1032
|
+
// src/navigation/react.tsx
|
|
1033
|
+
var import_effect8 = require("effect");
|
|
1034
|
+
var import_react3 = require("react");
|
|
1035
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
1036
|
+
var useNavigationService = () => {
|
|
1037
|
+
const runtime = useEffectRuntime();
|
|
1038
|
+
return (0, import_react3.useMemo)(() => runtime.runSync(Navigation), [runtime]);
|
|
1039
|
+
};
|
|
1040
|
+
var useNavigationSnapshot = () => {
|
|
1041
|
+
const runtime = useEffectRuntime();
|
|
1042
|
+
const navigation = useNavigationService();
|
|
1043
|
+
const subscribe2 = (0, import_react3.useCallback)(
|
|
1044
|
+
(listener) => {
|
|
1045
|
+
const fiber = runtime.runFork(
|
|
1046
|
+
import_effect8.Stream.runForEach(navigation.snapshots, () => import_effect8.Effect.sync(listener))
|
|
1047
|
+
);
|
|
1048
|
+
return () => {
|
|
1049
|
+
runtime.runFork(import_effect8.Fiber.interrupt(fiber));
|
|
1050
|
+
};
|
|
1051
|
+
},
|
|
1052
|
+
[navigation, runtime]
|
|
1053
|
+
);
|
|
1054
|
+
const getSnapshot = (0, import_react3.useCallback)(
|
|
1055
|
+
() => runtime.runSync(navigation.getSnapshot),
|
|
1056
|
+
[navigation, runtime]
|
|
1057
|
+
);
|
|
1058
|
+
return (0, import_react3.useSyncExternalStore)(subscribe2, getSnapshot, getSnapshot);
|
|
1059
|
+
};
|
|
1060
|
+
var useNavigate = () => {
|
|
1061
|
+
const runtime = useEffectRuntime();
|
|
1062
|
+
const navigation = useNavigationService();
|
|
1063
|
+
return (0, import_react3.useCallback)(
|
|
1064
|
+
(href) => runtime.runPromise(navigation.navigate(href)),
|
|
1065
|
+
[navigation, runtime]
|
|
1066
|
+
);
|
|
1067
|
+
};
|
|
1068
|
+
var Link = ({ to, onClick, children, ...rest }) => {
|
|
1069
|
+
const navigate2 = useNavigate();
|
|
1070
|
+
const handleClick = (0, import_react3.useCallback)(
|
|
1071
|
+
(event) => {
|
|
1072
|
+
onClick?.(event);
|
|
1073
|
+
if (event.defaultPrevented) {
|
|
1074
|
+
return;
|
|
1075
|
+
}
|
|
1076
|
+
if (event.button !== 0 || event.metaKey || event.altKey || event.ctrlKey || event.shiftKey) {
|
|
1077
|
+
return;
|
|
1078
|
+
}
|
|
1079
|
+
event.preventDefault();
|
|
1080
|
+
void navigate2(to);
|
|
1081
|
+
},
|
|
1082
|
+
[navigate2, onClick, to]
|
|
1083
|
+
);
|
|
1084
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("a", { ...rest, href: to, onClick: handleClick, children });
|
|
1085
|
+
};
|
|
1086
|
+
var Outlet = ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_jsx_runtime2.Fragment, { children });
|
|
1087
|
+
|
|
1088
|
+
// src/kernel/runtime.ts
|
|
1089
|
+
var import_effect9 = require("effect");
|
|
1090
|
+
var createManagedRuntime = (layer) => import_effect9.ManagedRuntime.make(layer);
|
|
1091
|
+
|
|
1092
|
+
// src/kernel/app.ts
|
|
1093
|
+
var createAppLayer = (options) => {
|
|
1094
|
+
const boundaryLayer = BoundaryLive;
|
|
1095
|
+
const telemetryLayer = TelemetryLive;
|
|
1096
|
+
const dataLayer = makeDataLayer(options.data).pipe(
|
|
1097
|
+
import_effect10.Layer.provide([boundaryLayer, telemetryLayer])
|
|
1098
|
+
);
|
|
1099
|
+
const actionsLayer = makeActionsLayer({
|
|
1100
|
+
actions: options.actions ?? []
|
|
1101
|
+
}).pipe(import_effect10.Layer.provide([boundaryLayer, telemetryLayer]));
|
|
1102
|
+
const navigationLayer = makeNavigationLayer({
|
|
1103
|
+
routes: options.routes,
|
|
1104
|
+
...options.loaders !== void 0 ? { loaders: options.loaders } : {},
|
|
1105
|
+
...options.initialHref !== void 0 ? { initialHref: options.initialHref } : {}
|
|
1106
|
+
}).pipe(import_effect10.Layer.provide([boundaryLayer, telemetryLayer]));
|
|
1107
|
+
return import_effect10.Layer.mergeAll(boundaryLayer, telemetryLayer, dataLayer, actionsLayer, navigationLayer);
|
|
1108
|
+
};
|
|
1109
|
+
var createAppRuntime = (options) => createManagedRuntime(createAppLayer(options));
|
|
1110
|
+
|
|
1111
|
+
// src/framework/manifest.ts
|
|
1112
|
+
var defineManifest = (manifest) => manifest;
|
|
1113
|
+
var routesFromManifest = (manifest) => manifest.pages.map((page) => page.route);
|
|
1114
|
+
var loadersFromManifest = (manifest) => {
|
|
1115
|
+
const pageLoaders = manifest.pages.map((page) => page.loader).filter((loader) => loader !== void 0);
|
|
1116
|
+
const layoutLoaders = (manifest.layouts ?? []).map((layout) => layout.loader).filter((loader) => loader !== void 0);
|
|
1117
|
+
return [...pageLoaders, ...layoutLoaders];
|
|
1118
|
+
};
|
|
1119
|
+
|
|
1120
|
+
// src/config/index.ts
|
|
1121
|
+
var defaultConfig = {
|
|
1122
|
+
appDir: "app",
|
|
1123
|
+
adapters: ["node", "bun"],
|
|
1124
|
+
ssr: {
|
|
1125
|
+
streaming: true
|
|
1126
|
+
},
|
|
1127
|
+
cache: {
|
|
1128
|
+
defaultPolicy: "no-store",
|
|
1129
|
+
routeSegmentDefaults: "explicit"
|
|
1130
|
+
},
|
|
1131
|
+
strict: {
|
|
1132
|
+
boundarySchemas: true,
|
|
1133
|
+
typedErrors: true
|
|
1134
|
+
}
|
|
1135
|
+
};
|
|
1136
|
+
var defineConfig = (config) => config;
|
|
1137
|
+
var resolveConfig = (config = {}) => ({
|
|
1138
|
+
appDir: config.appDir ?? defaultConfig.appDir,
|
|
1139
|
+
adapters: config.adapters ?? defaultConfig.adapters,
|
|
1140
|
+
ssr: {
|
|
1141
|
+
streaming: config.ssr?.streaming ?? defaultConfig.ssr.streaming
|
|
1142
|
+
},
|
|
1143
|
+
cache: {
|
|
1144
|
+
defaultPolicy: config.cache?.defaultPolicy ?? defaultConfig.cache.defaultPolicy,
|
|
1145
|
+
routeSegmentDefaults: config.cache?.routeSegmentDefaults ?? defaultConfig.cache.routeSegmentDefaults
|
|
1146
|
+
},
|
|
1147
|
+
strict: {
|
|
1148
|
+
boundarySchemas: config.strict?.boundarySchemas ?? defaultConfig.strict.boundarySchemas,
|
|
1149
|
+
typedErrors: config.strict?.typedErrors ?? defaultConfig.strict.typedErrors
|
|
1150
|
+
}
|
|
1151
|
+
});
|
|
1152
|
+
|
|
1153
|
+
// src/framework/app.ts
|
|
1154
|
+
var createPageMatcher = (pages) => {
|
|
1155
|
+
const routes = pages.map((page) => page.route);
|
|
1156
|
+
return (href) => {
|
|
1157
|
+
const parsed = parseHref(href);
|
|
1158
|
+
const matched = matchRoute({
|
|
1159
|
+
routes,
|
|
1160
|
+
pathname: parsed.pathname,
|
|
1161
|
+
search: {}
|
|
1162
|
+
});
|
|
1163
|
+
if (matched === null) {
|
|
1164
|
+
return void 0;
|
|
1165
|
+
}
|
|
1166
|
+
return pages.find((page) => page.route.id === matched.route.id);
|
|
1167
|
+
};
|
|
1168
|
+
};
|
|
1169
|
+
var createApp = (options) => {
|
|
1170
|
+
const manifest = options.manifest;
|
|
1171
|
+
const routes = routesFromManifest(manifest);
|
|
1172
|
+
const loaders = loadersFromManifest(manifest);
|
|
1173
|
+
const actions = manifest.actions ?? [];
|
|
1174
|
+
const runtime = createAppRuntime({
|
|
1175
|
+
routes,
|
|
1176
|
+
actions,
|
|
1177
|
+
loaders,
|
|
1178
|
+
...options.initialHref !== void 0 ? { initialHref: options.initialHref } : {}
|
|
1179
|
+
});
|
|
1180
|
+
const actionHandlerFactory = createActionHttpHandler();
|
|
1181
|
+
const handleActionRequest = actionHandlerFactory((effect) => runtime.runPromise(effect));
|
|
1182
|
+
return {
|
|
1183
|
+
manifest,
|
|
1184
|
+
config: resolveConfig(options.config),
|
|
1185
|
+
runtime,
|
|
1186
|
+
actions,
|
|
1187
|
+
matchPage: createPageMatcher(manifest.pages),
|
|
1188
|
+
handleActionRequest,
|
|
1189
|
+
dispose: () => runtime.dispose()
|
|
1190
|
+
};
|
|
1191
|
+
};
|
|
1192
|
+
|
|
1193
|
+
// src/framework/cache.ts
|
|
1194
|
+
var cachePolicy = (policy) => policy;
|
|
1195
|
+
var noStore = () => ({
|
|
1196
|
+
mode: "no-store"
|
|
1197
|
+
});
|
|
1198
|
+
|
|
1199
|
+
// src/framework/contracts.ts
|
|
1200
|
+
var definePage = (page) => page;
|
|
1201
|
+
var defineLayout = (layout) => layout;
|
|
1202
|
+
var defineMiddleware = (middleware) => middleware;
|
|
1203
|
+
|
|
1204
|
+
// src/server/index.ts
|
|
1205
|
+
var import_effect13 = require("effect");
|
|
1206
|
+
var import_react4 = require("react");
|
|
1207
|
+
|
|
1208
|
+
// src/render/hydration.ts
|
|
1209
|
+
var import_effect11 = require("effect");
|
|
1210
|
+
var QuerySnapshotSchema = import_effect11.Schema.Struct({
|
|
1211
|
+
key: import_effect11.Schema.String,
|
|
1212
|
+
phase: import_effect11.Schema.Union(
|
|
1213
|
+
import_effect11.Schema.Literal("initial"),
|
|
1214
|
+
import_effect11.Schema.Literal("loading"),
|
|
1215
|
+
import_effect11.Schema.Literal("success"),
|
|
1216
|
+
import_effect11.Schema.Literal("failure")
|
|
1217
|
+
),
|
|
1218
|
+
data: import_effect11.Schema.NullishOr(import_effect11.Schema.Unknown),
|
|
1219
|
+
error: import_effect11.Schema.NullishOr(import_effect11.Schema.Unknown),
|
|
1220
|
+
updatedAt: import_effect11.Schema.NullishOr(import_effect11.Schema.Number)
|
|
1221
|
+
});
|
|
1222
|
+
var HydrationStateSchema = import_effect11.Schema.Struct({
|
|
1223
|
+
version: import_effect11.Schema.Literal(1),
|
|
1224
|
+
data: import_effect11.Schema.Array(import_effect11.Schema.Tuple(import_effect11.Schema.String, QuerySnapshotSchema)),
|
|
1225
|
+
navigationHref: import_effect11.Schema.String
|
|
1226
|
+
});
|
|
1227
|
+
var escapeForScript = (value) => value.replace(/</g, "\\u003c").replace(/>/g, "\\u003e").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
|
|
1228
|
+
var dehydrateAppState = () => import_effect11.Effect.gen(function* () {
|
|
1229
|
+
const data = yield* Data;
|
|
1230
|
+
const navigation = yield* Navigation;
|
|
1231
|
+
const snapshots = yield* data.getAllSnapshots;
|
|
1232
|
+
const navigationSnapshot = yield* navigation.getSnapshot;
|
|
1233
|
+
return {
|
|
1234
|
+
version: 1,
|
|
1235
|
+
data: Array.from(snapshots.entries()),
|
|
1236
|
+
navigationHref: navigationSnapshot.href
|
|
1237
|
+
};
|
|
1238
|
+
});
|
|
1239
|
+
var createHydrationScript = (state, globalName = "__effectReactHydration") => {
|
|
1240
|
+
const serialized = JSON.stringify(state);
|
|
1241
|
+
return `window[${JSON.stringify(globalName)}]=JSON.parse(${JSON.stringify(escapeForScript(serialized))});`;
|
|
1242
|
+
};
|
|
1243
|
+
var hydrateAppState = (payload) => import_effect11.Effect.gen(function* () {
|
|
1244
|
+
const boundary = yield* Boundary;
|
|
1245
|
+
const data = yield* Data;
|
|
1246
|
+
const navigation = yield* Navigation;
|
|
1247
|
+
const decoded = yield* boundary.decodeUnknown({
|
|
1248
|
+
source: "hydration:payload",
|
|
1249
|
+
schema: HydrationStateSchema,
|
|
1250
|
+
value: payload
|
|
1251
|
+
});
|
|
1252
|
+
const mapped = new Map(decoded.data);
|
|
1253
|
+
yield* data.hydrateSnapshots(mapped);
|
|
1254
|
+
const current = yield* navigation.getSnapshot;
|
|
1255
|
+
const parsed = parseHref(decoded.navigationHref);
|
|
1256
|
+
yield* navigation.hydrateSnapshot({
|
|
1257
|
+
...current,
|
|
1258
|
+
pathname: parsed.pathname,
|
|
1259
|
+
searchText: parsed.searchText,
|
|
1260
|
+
href: decoded.navigationHref,
|
|
1261
|
+
status: "success",
|
|
1262
|
+
match: null,
|
|
1263
|
+
loaders: {},
|
|
1264
|
+
error: void 0
|
|
1265
|
+
});
|
|
1266
|
+
});
|
|
1267
|
+
|
|
1268
|
+
// src/render/ssr.ts
|
|
1269
|
+
var import_effect12 = require("effect");
|
|
1270
|
+
var ReactDOMServer = __toESM(require("react-dom/server"), 1);
|
|
1271
|
+
var htmlResponse = (options) => {
|
|
1272
|
+
const headers = new Headers(options.headers);
|
|
1273
|
+
if (!headers.has("content-type")) {
|
|
1274
|
+
headers.set("content-type", "text/html; charset=utf-8");
|
|
1275
|
+
}
|
|
1276
|
+
return new Response(options.html, {
|
|
1277
|
+
status: options.status,
|
|
1278
|
+
headers
|
|
1279
|
+
});
|
|
1280
|
+
};
|
|
1281
|
+
var injectScript = (html, script) => {
|
|
1282
|
+
const tag = `<script>${script}</script>`;
|
|
1283
|
+
const bodyClose = html.lastIndexOf("</body>");
|
|
1284
|
+
if (bodyClose === -1) {
|
|
1285
|
+
return `${html}${tag}`;
|
|
1286
|
+
}
|
|
1287
|
+
return `${html.slice(0, bodyClose)}${tag}${html.slice(bodyClose)}`;
|
|
1288
|
+
};
|
|
1289
|
+
var toError = (cause) => cause instanceof Error ? cause : new Error(String(cause));
|
|
1290
|
+
var createSsrHandler = (options) => (request) => {
|
|
1291
|
+
const program = import_effect12.Effect.gen(function* () {
|
|
1292
|
+
const element = yield* options.render(request);
|
|
1293
|
+
const html = ReactDOMServer.renderToString(element);
|
|
1294
|
+
const state = yield* dehydrateAppState();
|
|
1295
|
+
const script = createHydrationScript(state, options.hydrationGlobalName);
|
|
1296
|
+
return htmlResponse({
|
|
1297
|
+
html: injectScript(html, script),
|
|
1298
|
+
status: options.status ?? 200,
|
|
1299
|
+
...options.headers !== void 0 ? { headers: options.headers } : {}
|
|
1300
|
+
});
|
|
1301
|
+
});
|
|
1302
|
+
return options.runtime.runPromise(program).catch((cause) => {
|
|
1303
|
+
const squashed = toError(cause);
|
|
1304
|
+
if (options.onError !== void 0) {
|
|
1305
|
+
return options.onError(squashed);
|
|
1306
|
+
}
|
|
1307
|
+
return new Response(`SSR render failed: ${squashed.message}`, {
|
|
1308
|
+
status: 500,
|
|
1309
|
+
headers: {
|
|
1310
|
+
"content-type": "text/plain; charset=utf-8"
|
|
1311
|
+
}
|
|
1312
|
+
});
|
|
1313
|
+
});
|
|
1314
|
+
};
|
|
1315
|
+
|
|
1316
|
+
// src/server/index.ts
|
|
1317
|
+
var defaultNotFoundElement = () => (0, import_react4.createElement)("main", void 0, "Not Found");
|
|
1318
|
+
var createRequestHandler = (options) => {
|
|
1319
|
+
const actionPath = options.actionPath ?? "/_actions";
|
|
1320
|
+
const ssrHandler = createSsrHandler({
|
|
1321
|
+
runtime: options.app.runtime,
|
|
1322
|
+
...options.hydrationGlobalName !== void 0 ? { hydrationGlobalName: options.hydrationGlobalName } : {},
|
|
1323
|
+
...options.onError !== void 0 ? { onError: options.onError } : {},
|
|
1324
|
+
render: (request) => import_effect13.Effect.gen(function* () {
|
|
1325
|
+
const url = new URL(request.url);
|
|
1326
|
+
const href = `${url.pathname}${url.search}`;
|
|
1327
|
+
const page = options.app.matchPage(href);
|
|
1328
|
+
if (page === void 0) {
|
|
1329
|
+
return defaultNotFoundElement();
|
|
1330
|
+
}
|
|
1331
|
+
yield* navigateTo(href);
|
|
1332
|
+
if (options.render !== void 0) {
|
|
1333
|
+
return yield* options.render({ request, page });
|
|
1334
|
+
}
|
|
1335
|
+
return (0, import_react4.createElement)(page.component);
|
|
1336
|
+
}).pipe(
|
|
1337
|
+
import_effect13.Effect.mapError(
|
|
1338
|
+
(error) => error instanceof Error ? error : new Error(String(error))
|
|
1339
|
+
)
|
|
1340
|
+
)
|
|
1341
|
+
});
|
|
1342
|
+
return (request) => {
|
|
1343
|
+
const url = new URL(request.url);
|
|
1344
|
+
if (request.method.toUpperCase() === "POST" && url.pathname === actionPath) {
|
|
1345
|
+
return options.app.handleActionRequest(request);
|
|
1346
|
+
}
|
|
1347
|
+
return ssrHandler(request);
|
|
1348
|
+
};
|
|
1349
|
+
};
|
|
1350
|
+
|
|
1351
|
+
// src/client/index.ts
|
|
1352
|
+
var import_effect14 = require("effect");
|
|
1353
|
+
var defaultHydrationGlobalName = "__effectReactHydration";
|
|
1354
|
+
var readGlobalHydrationPayload = (globalName) => {
|
|
1355
|
+
const globalScope = globalThis;
|
|
1356
|
+
return globalScope[globalName];
|
|
1357
|
+
};
|
|
1358
|
+
var hydrateApp = (options) => {
|
|
1359
|
+
const payload = options.payload ?? readGlobalHydrationPayload(options.globalName ?? defaultHydrationGlobalName);
|
|
1360
|
+
if (payload === void 0) {
|
|
1361
|
+
return options.app.runtime.runPromise(import_effect14.Effect.void);
|
|
1362
|
+
}
|
|
1363
|
+
return options.app.runtime.runPromise(hydrateAppState(payload));
|
|
1364
|
+
};
|
|
1365
|
+
|
|
1366
|
+
// src/testing/index.ts
|
|
1367
|
+
var createTestApp = (options) => createApp(options);
|
|
1368
|
+
|
|
1369
|
+
// src/state/service.ts
|
|
1370
|
+
var import_effect15 = require("effect");
|
|
1371
|
+
var defaultEquality = (left, right) => Object.is(left, right);
|
|
1372
|
+
var createStore = (initial) => import_effect15.Effect.map(import_effect15.SubscriptionRef.make(initial), (ref) => ({ ref }));
|
|
1373
|
+
var createStoreFromEffect = (initial) => import_effect15.Effect.flatMap(initial, createStore);
|
|
1374
|
+
var createStoreTag = (key) => import_effect15.Context.GenericTag(key);
|
|
1375
|
+
var makeStoreLayer = (tag, initial) => import_effect15.Layer.effect(tag, createStore(initial));
|
|
1376
|
+
var makeStoreLayerFromEffect = (tag, initial) => import_effect15.Layer.effect(tag, createStoreFromEffect(initial));
|
|
1377
|
+
var get = (store) => import_effect15.SubscriptionRef.get(store.ref);
|
|
1378
|
+
var set = (store, value) => import_effect15.SubscriptionRef.set(store.ref, value);
|
|
1379
|
+
var update = (store, mutate) => import_effect15.SubscriptionRef.update(store.ref, mutate);
|
|
1380
|
+
var modify = (store, mutate) => import_effect15.SubscriptionRef.modify(store.ref, mutate);
|
|
1381
|
+
var select = (store, selector) => import_effect15.Effect.map(get(store), selector);
|
|
1382
|
+
var changes = (store) => store.ref.changes;
|
|
1383
|
+
var selectChanges = (store, selector, options = {}) => {
|
|
1384
|
+
const selected = changes(store).pipe(import_effect15.Stream.map(selector));
|
|
1385
|
+
if (options.distinct === false) {
|
|
1386
|
+
return selected;
|
|
1387
|
+
}
|
|
1388
|
+
return selected.pipe(import_effect15.Stream.changesWith(options.equals ?? defaultEquality));
|
|
1389
|
+
};
|
|
1390
|
+
var derive = (store, selector, options = {}) => ({
|
|
1391
|
+
get: select(store, selector),
|
|
1392
|
+
changes: selectChanges(store, selector, options)
|
|
1393
|
+
});
|
|
1394
|
+
|
|
1395
|
+
// src/state/react.tsx
|
|
1396
|
+
var import_effect16 = require("effect");
|
|
1397
|
+
var import_react5 = require("react");
|
|
1398
|
+
var defaultEquality2 = (left, right) => Object.is(left, right);
|
|
1399
|
+
var useStore = (store) => useStoreSelector(store, (state) => state);
|
|
1400
|
+
var useStoreSelector = (store, selector, equals = defaultEquality2) => {
|
|
1401
|
+
const runtime = useEffectRuntime();
|
|
1402
|
+
const subscribe2 = (0, import_react5.useCallback)(
|
|
1403
|
+
(listener) => {
|
|
1404
|
+
const fiber = runtime.runFork(
|
|
1405
|
+
import_effect16.Stream.runForEach(
|
|
1406
|
+
selectChanges(store, selector, {
|
|
1407
|
+
equals
|
|
1408
|
+
}),
|
|
1409
|
+
() => import_effect16.Effect.sync(listener)
|
|
1410
|
+
)
|
|
1411
|
+
);
|
|
1412
|
+
return () => {
|
|
1413
|
+
runtime.runFork(import_effect16.Fiber.interrupt(fiber));
|
|
1414
|
+
};
|
|
1415
|
+
},
|
|
1416
|
+
[equals, runtime, selector, store]
|
|
1417
|
+
);
|
|
1418
|
+
const getSnapshot = (0, import_react5.useCallback)(
|
|
1419
|
+
() => runtime.runSync(select(store, selector)),
|
|
1420
|
+
[runtime, selector, store]
|
|
1421
|
+
);
|
|
1422
|
+
return (0, import_react5.useSyncExternalStore)(subscribe2, getSnapshot, getSnapshot);
|
|
1423
|
+
};
|
|
1424
|
+
|
|
1425
|
+
// src/query/service.ts
|
|
1426
|
+
var import_effect17 = require("effect");
|
|
1427
|
+
var fetchQuery2 = fetchQuery;
|
|
1428
|
+
var prefetchQuery = (definition, input) => import_effect17.Effect.flatMap(Data, (service) => service.prefetch(definition, input));
|
|
1429
|
+
var invalidateQuery = (definition, input) => import_effect17.Effect.flatMap(Data, (service) => service.invalidate(definition, input));
|
|
1430
|
+
var prefetch = prefetchQuery;
|
|
1431
|
+
var invalidate = invalidateQuery;
|
|
1432
|
+
|
|
1433
|
+
// src/query/react.tsx
|
|
1434
|
+
var import_effect18 = require("effect");
|
|
1435
|
+
var import_react6 = require("react");
|
|
1436
|
+
var upsertInfiniteEntry = (entries, nextEntry) => {
|
|
1437
|
+
const index = entries.findIndex((entry) => entry.key === nextEntry.key);
|
|
1438
|
+
if (index < 0) {
|
|
1439
|
+
return [...entries, nextEntry];
|
|
1440
|
+
}
|
|
1441
|
+
const next = [...entries];
|
|
1442
|
+
next[index] = nextEntry;
|
|
1443
|
+
return next;
|
|
1444
|
+
};
|
|
1445
|
+
var useDataService2 = () => {
|
|
1446
|
+
const runtime = useEffectRuntime();
|
|
1447
|
+
return (0, import_react6.useMemo)(() => runtime.runSync(Data), [runtime]);
|
|
1448
|
+
};
|
|
1449
|
+
var useQuery2 = (definition, input, options = {}) => useQuery(definition, input, options);
|
|
1450
|
+
var useSuspenseQuery2 = (definition, input) => useSuspenseQuery(definition, input);
|
|
1451
|
+
var useInfiniteQuery = (definition, options) => {
|
|
1452
|
+
const optionsRef = (0, import_react6.useRef)(options);
|
|
1453
|
+
optionsRef.current = options;
|
|
1454
|
+
const initialPageParam = options.initialPageParam;
|
|
1455
|
+
const enabled = options.enabled;
|
|
1456
|
+
const run = options.run;
|
|
1457
|
+
const getInput = (0, import_react6.useCallback)(
|
|
1458
|
+
(pageParam) => optionsRef.current.getInput(pageParam),
|
|
1459
|
+
[]
|
|
1460
|
+
);
|
|
1461
|
+
const getNextPageParam = (0, import_react6.useCallback)(
|
|
1462
|
+
(lastPage, allPages, lastPageParam, allPageParams) => optionsRef.current.getNextPageParam(lastPage, allPages, lastPageParam, allPageParams),
|
|
1463
|
+
[]
|
|
1464
|
+
);
|
|
1465
|
+
const runtime = useEffectRuntime();
|
|
1466
|
+
const data = useDataService2();
|
|
1467
|
+
const [initialInput, setInitialInput] = (0, import_react6.useState)(
|
|
1468
|
+
() => getInput(initialPageParam)
|
|
1469
|
+
);
|
|
1470
|
+
const [entries, setEntries] = (0, import_react6.useState)([]);
|
|
1471
|
+
const [error, setError] = (0, import_react6.useState)(void 0);
|
|
1472
|
+
const [isFetchingNextPage, setIsFetchingNextPage] = (0, import_react6.useState)(false);
|
|
1473
|
+
const initialQuery = useQuery2(
|
|
1474
|
+
definition,
|
|
1475
|
+
initialInput,
|
|
1476
|
+
{
|
|
1477
|
+
...enabled !== void 0 ? { enabled } : {},
|
|
1478
|
+
...run !== void 0 ? { run } : {}
|
|
1479
|
+
}
|
|
1480
|
+
);
|
|
1481
|
+
(0, import_react6.useEffect)(() => {
|
|
1482
|
+
setInitialInput(getInput(initialPageParam));
|
|
1483
|
+
setEntries([]);
|
|
1484
|
+
setError(void 0);
|
|
1485
|
+
setIsFetchingNextPage(false);
|
|
1486
|
+
}, [definition, getInput, initialPageParam]);
|
|
1487
|
+
(0, import_react6.useEffect)(() => {
|
|
1488
|
+
if (initialQuery.phase === "success") {
|
|
1489
|
+
setEntries(
|
|
1490
|
+
(current) => upsertInfiniteEntry(current, {
|
|
1491
|
+
key: initialQuery.key,
|
|
1492
|
+
pageParam: initialPageParam,
|
|
1493
|
+
data: initialQuery.data
|
|
1494
|
+
})
|
|
1495
|
+
);
|
|
1496
|
+
setError(void 0);
|
|
1497
|
+
return;
|
|
1498
|
+
}
|
|
1499
|
+
if (initialQuery.phase === "failure") {
|
|
1500
|
+
setError(initialQuery.error);
|
|
1501
|
+
}
|
|
1502
|
+
}, [
|
|
1503
|
+
initialQuery.data,
|
|
1504
|
+
initialQuery.error,
|
|
1505
|
+
initialQuery.key,
|
|
1506
|
+
initialQuery.phase,
|
|
1507
|
+
initialPageParam
|
|
1508
|
+
]);
|
|
1509
|
+
const pages = (0, import_react6.useMemo)(() => entries.map((entry) => entry.data), [entries]);
|
|
1510
|
+
const pageParams = (0, import_react6.useMemo)(() => entries.map((entry) => entry.pageParam), [entries]);
|
|
1511
|
+
const resolveNextPageParam = (0, import_react6.useCallback)(() => {
|
|
1512
|
+
const lastEntry = entries[entries.length - 1];
|
|
1513
|
+
if (lastEntry !== void 0) {
|
|
1514
|
+
return getNextPageParam(lastEntry.data, pages, lastEntry.pageParam, pageParams);
|
|
1515
|
+
}
|
|
1516
|
+
if (initialQuery.phase !== "success") {
|
|
1517
|
+
return void 0;
|
|
1518
|
+
}
|
|
1519
|
+
const initialPage = initialQuery.data;
|
|
1520
|
+
return getNextPageParam(
|
|
1521
|
+
initialPage,
|
|
1522
|
+
[initialPage],
|
|
1523
|
+
initialPageParam,
|
|
1524
|
+
[initialPageParam]
|
|
1525
|
+
);
|
|
1526
|
+
}, [
|
|
1527
|
+
entries,
|
|
1528
|
+
getNextPageParam,
|
|
1529
|
+
initialPageParam,
|
|
1530
|
+
initialQuery.data,
|
|
1531
|
+
initialQuery.phase,
|
|
1532
|
+
pageParams,
|
|
1533
|
+
pages
|
|
1534
|
+
]);
|
|
1535
|
+
const fetchNextPage = (0, import_react6.useCallback)(() => {
|
|
1536
|
+
const nextPageParam = resolveNextPageParam();
|
|
1537
|
+
if (nextPageParam === void 0) {
|
|
1538
|
+
return runtime.runPromise(import_effect18.Effect.succeed(void 0));
|
|
1539
|
+
}
|
|
1540
|
+
setIsFetchingNextPage(true);
|
|
1541
|
+
setError(void 0);
|
|
1542
|
+
const input = getInput(nextPageParam);
|
|
1543
|
+
const program = import_effect18.Effect.gen(function* () {
|
|
1544
|
+
const value = yield* data.fetch(definition, input, run);
|
|
1545
|
+
const snapshot = yield* data.getSnapshot(definition, input);
|
|
1546
|
+
return {
|
|
1547
|
+
key: snapshot.key,
|
|
1548
|
+
pageParam: nextPageParam,
|
|
1549
|
+
value
|
|
1550
|
+
};
|
|
1551
|
+
});
|
|
1552
|
+
return runtime.runPromise(program).then(
|
|
1553
|
+
({ key, pageParam, value }) => {
|
|
1554
|
+
setEntries(
|
|
1555
|
+
(current) => upsertInfiniteEntry(current, {
|
|
1556
|
+
key,
|
|
1557
|
+
pageParam,
|
|
1558
|
+
data: value
|
|
1559
|
+
})
|
|
1560
|
+
);
|
|
1561
|
+
setIsFetchingNextPage(false);
|
|
1562
|
+
return value;
|
|
1563
|
+
},
|
|
1564
|
+
(cause) => {
|
|
1565
|
+
setIsFetchingNextPage(false);
|
|
1566
|
+
const resolved = cause;
|
|
1567
|
+
setError(resolved);
|
|
1568
|
+
return runtime.runPromise(import_effect18.Effect.fail(resolved));
|
|
1569
|
+
}
|
|
1570
|
+
);
|
|
1571
|
+
}, [data, definition, getInput, resolveNextPageParam, run, runtime]);
|
|
1572
|
+
const refetch = (0, import_react6.useCallback)(() => {
|
|
1573
|
+
const targets = pageParams.length === 0 ? [initialPageParam] : pageParams;
|
|
1574
|
+
setError(void 0);
|
|
1575
|
+
const program = import_effect18.Effect.forEach(
|
|
1576
|
+
targets,
|
|
1577
|
+
(pageParam) => {
|
|
1578
|
+
const input = getInput(pageParam);
|
|
1579
|
+
return import_effect18.Effect.gen(function* () {
|
|
1580
|
+
const value = yield* data.fetch(definition, input, {
|
|
1581
|
+
...run,
|
|
1582
|
+
forceRefresh: true
|
|
1583
|
+
});
|
|
1584
|
+
const snapshot = yield* data.getSnapshot(definition, input);
|
|
1585
|
+
return {
|
|
1586
|
+
key: snapshot.key,
|
|
1587
|
+
pageParam,
|
|
1588
|
+
data: value
|
|
1589
|
+
};
|
|
1590
|
+
});
|
|
1591
|
+
},
|
|
1592
|
+
{
|
|
1593
|
+
concurrency: 1,
|
|
1594
|
+
discard: false
|
|
1595
|
+
}
|
|
1596
|
+
);
|
|
1597
|
+
return runtime.runPromise(program).then(
|
|
1598
|
+
(fetchedEntries) => {
|
|
1599
|
+
setEntries(fetchedEntries);
|
|
1600
|
+
return fetchedEntries.map((entry) => entry.data);
|
|
1601
|
+
},
|
|
1602
|
+
(cause) => {
|
|
1603
|
+
const resolved = cause;
|
|
1604
|
+
setError(resolved);
|
|
1605
|
+
return runtime.runPromise(import_effect18.Effect.fail(resolved));
|
|
1606
|
+
}
|
|
1607
|
+
);
|
|
1608
|
+
}, [data, definition, getInput, initialPageParam, pageParams, run, runtime]);
|
|
1609
|
+
const invalidate2 = (0, import_react6.useCallback)(() => {
|
|
1610
|
+
const targets = pageParams.length === 0 ? [initialPageParam] : pageParams;
|
|
1611
|
+
const program = import_effect18.Effect.forEach(
|
|
1612
|
+
targets,
|
|
1613
|
+
(pageParam) => data.invalidate(definition, getInput(pageParam)),
|
|
1614
|
+
{
|
|
1615
|
+
concurrency: 1,
|
|
1616
|
+
discard: true
|
|
1617
|
+
}
|
|
1618
|
+
);
|
|
1619
|
+
return runtime.runPromise(program).then(
|
|
1620
|
+
() => {
|
|
1621
|
+
setEntries([]);
|
|
1622
|
+
setError(void 0);
|
|
1623
|
+
setIsFetchingNextPage(false);
|
|
1624
|
+
return void 0;
|
|
1625
|
+
},
|
|
1626
|
+
(cause) => {
|
|
1627
|
+
const resolved = cause;
|
|
1628
|
+
setError(resolved);
|
|
1629
|
+
return runtime.runPromise(import_effect18.Effect.fail(resolved));
|
|
1630
|
+
}
|
|
1631
|
+
);
|
|
1632
|
+
}, [data, definition, getInput, initialPageParam, pageParams, runtime]);
|
|
1633
|
+
const resolvedError = error ?? (initialQuery.phase === "failure" ? initialQuery.error : void 0);
|
|
1634
|
+
const phase = resolvedError !== void 0 ? "failure" : entries.length > 0 ? "success" : initialQuery.phase;
|
|
1635
|
+
return {
|
|
1636
|
+
phase,
|
|
1637
|
+
pages,
|
|
1638
|
+
pageParams,
|
|
1639
|
+
error: resolvedError,
|
|
1640
|
+
hasNextPage: resolveNextPageParam() !== void 0,
|
|
1641
|
+
isFetchingNextPage,
|
|
1642
|
+
fetchNextPage,
|
|
1643
|
+
refetch,
|
|
1644
|
+
invalidate: invalidate2
|
|
1645
|
+
};
|
|
1646
|
+
};
|
|
1647
|
+
|
|
1648
|
+
// src/router/helpers.ts
|
|
1649
|
+
var PARAM_PATTERN = /:([A-Za-z0-9_]+)/g;
|
|
1650
|
+
var appendSearchValue = (params, key, value) => {
|
|
1651
|
+
if (value === null || value === void 0) {
|
|
1652
|
+
return;
|
|
1653
|
+
}
|
|
1654
|
+
if (Array.isArray(value)) {
|
|
1655
|
+
for (const nestedValue of value) {
|
|
1656
|
+
appendSearchValue(params, key, nestedValue);
|
|
1657
|
+
}
|
|
1658
|
+
return;
|
|
1659
|
+
}
|
|
1660
|
+
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
1661
|
+
params.append(key, String(value));
|
|
1662
|
+
}
|
|
1663
|
+
};
|
|
1664
|
+
var defaultBase = () => {
|
|
1665
|
+
if (typeof window === "undefined") {
|
|
1666
|
+
return "http://localhost";
|
|
1667
|
+
}
|
|
1668
|
+
return window.location.origin;
|
|
1669
|
+
};
|
|
1670
|
+
var routeSearchText = (search) => {
|
|
1671
|
+
if (search === void 0) {
|
|
1672
|
+
return "";
|
|
1673
|
+
}
|
|
1674
|
+
const params = new URLSearchParams();
|
|
1675
|
+
const keys = Object.keys(search).sort((a, b) => a.localeCompare(b));
|
|
1676
|
+
for (const key of keys) {
|
|
1677
|
+
appendSearchValue(params, key, search[key]);
|
|
1678
|
+
}
|
|
1679
|
+
const text = params.toString();
|
|
1680
|
+
return text.length > 0 ? `?${text}` : "";
|
|
1681
|
+
};
|
|
1682
|
+
var routePath = (route, params) => route.path.replace(PARAM_PATTERN, (_match, name) => {
|
|
1683
|
+
const value = params?.[name];
|
|
1684
|
+
if (value === void 0) {
|
|
1685
|
+
throw new Error(`Missing route param '${name}' for route '${route.id}'`);
|
|
1686
|
+
}
|
|
1687
|
+
return encodeURIComponent(String(value));
|
|
1688
|
+
});
|
|
1689
|
+
var routeHref = (route, options = {}) => buildHref(
|
|
1690
|
+
routePath(route, options.params),
|
|
1691
|
+
routeSearchText(options.search)
|
|
1692
|
+
);
|
|
1693
|
+
var routeUrl = (route, options = {}) => new URL(
|
|
1694
|
+
routeHref(route, options),
|
|
1695
|
+
options.base ?? defaultBase()
|
|
1696
|
+
);
|
|
1697
|
+
|
|
1698
|
+
// src/router/service.ts
|
|
1699
|
+
var import_effect19 = require("effect");
|
|
1700
|
+
var navigate = (href) => navigateTo(href);
|
|
1701
|
+
var revalidateNavigation = () => import_effect19.Effect.flatMap(Navigation, (service) => service.revalidate());
|
|
1702
|
+
|
|
1703
|
+
// src/router/react.tsx
|
|
1704
|
+
var useNavigate2 = () => useNavigate();
|
|
1705
|
+
var useNavigationSnapshot2 = () => useNavigationSnapshot();
|
|
1706
|
+
var useRouteMatch = (route) => {
|
|
1707
|
+
const snapshot = useNavigationSnapshot2();
|
|
1708
|
+
const match = snapshot.match;
|
|
1709
|
+
if (match === null || match.route.id !== route.id) {
|
|
1710
|
+
return null;
|
|
1711
|
+
}
|
|
1712
|
+
return match;
|
|
1713
|
+
};
|
|
1714
|
+
|
|
1715
|
+
// src/form/types.ts
|
|
1716
|
+
var defineForm = (contract) => contract;
|
|
1717
|
+
var FormValidationError = class extends Error {
|
|
1718
|
+
constructor(errors) {
|
|
1719
|
+
super("Form validation failed");
|
|
1720
|
+
this.errors = errors;
|
|
1721
|
+
this.name = "FormValidationError";
|
|
1722
|
+
}
|
|
1723
|
+
_tag = "FormValidationError";
|
|
1724
|
+
};
|
|
1725
|
+
|
|
1726
|
+
// src/form/service.ts
|
|
1727
|
+
var import_effect20 = require("effect");
|
|
1728
|
+
var isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1729
|
+
var cloneUnknown = (value) => {
|
|
1730
|
+
if (Array.isArray(value)) {
|
|
1731
|
+
return value.map((entry) => cloneUnknown(entry));
|
|
1732
|
+
}
|
|
1733
|
+
if (isRecord(value)) {
|
|
1734
|
+
const clone = {};
|
|
1735
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
1736
|
+
clone[key] = cloneUnknown(entry);
|
|
1737
|
+
}
|
|
1738
|
+
return clone;
|
|
1739
|
+
}
|
|
1740
|
+
return value;
|
|
1741
|
+
};
|
|
1742
|
+
var cloneValue = (value) => {
|
|
1743
|
+
return cloneUnknown(value);
|
|
1744
|
+
};
|
|
1745
|
+
var deepEqual = (left, right) => {
|
|
1746
|
+
if (Object.is(left, right)) {
|
|
1747
|
+
return true;
|
|
1748
|
+
}
|
|
1749
|
+
if (Array.isArray(left) && Array.isArray(right)) {
|
|
1750
|
+
if (left.length !== right.length) {
|
|
1751
|
+
return false;
|
|
1752
|
+
}
|
|
1753
|
+
for (let index = 0; index < left.length; index += 1) {
|
|
1754
|
+
if (!deepEqual(left[index], right[index])) {
|
|
1755
|
+
return false;
|
|
1756
|
+
}
|
|
1757
|
+
}
|
|
1758
|
+
return true;
|
|
1759
|
+
}
|
|
1760
|
+
if (isRecord(left) && isRecord(right)) {
|
|
1761
|
+
const leftKeys = Object.keys(left);
|
|
1762
|
+
const rightKeys = Object.keys(right);
|
|
1763
|
+
if (leftKeys.length !== rightKeys.length) {
|
|
1764
|
+
return false;
|
|
1765
|
+
}
|
|
1766
|
+
for (const key of leftKeys) {
|
|
1767
|
+
if (!(key in right)) {
|
|
1768
|
+
return false;
|
|
1769
|
+
}
|
|
1770
|
+
if (!deepEqual(left[key], right[key])) {
|
|
1771
|
+
return false;
|
|
1772
|
+
}
|
|
1773
|
+
}
|
|
1774
|
+
return true;
|
|
1775
|
+
}
|
|
1776
|
+
return false;
|
|
1777
|
+
};
|
|
1778
|
+
var toFormErrors = (error, fieldNames) => {
|
|
1779
|
+
const formatted = import_effect20.ParseResult.ArrayFormatter.formatErrorSync(error);
|
|
1780
|
+
const errors = {};
|
|
1781
|
+
for (const entry of formatted) {
|
|
1782
|
+
const root = entry.path[0];
|
|
1783
|
+
if (typeof root === "string" && fieldNames.has(root)) {
|
|
1784
|
+
const key = root;
|
|
1785
|
+
errors[key] ??= entry.message;
|
|
1786
|
+
continue;
|
|
1787
|
+
}
|
|
1788
|
+
errors._form ??= entry.message;
|
|
1789
|
+
}
|
|
1790
|
+
if (formatted.length === 0 && errors._form === void 0) {
|
|
1791
|
+
errors._form = "Invalid form values.";
|
|
1792
|
+
}
|
|
1793
|
+
return errors;
|
|
1794
|
+
};
|
|
1795
|
+
var createInitialState = (defaults) => ({
|
|
1796
|
+
values: cloneValue(defaults),
|
|
1797
|
+
errors: {},
|
|
1798
|
+
touched: {},
|
|
1799
|
+
dirty: false,
|
|
1800
|
+
submitting: false,
|
|
1801
|
+
submitted: false
|
|
1802
|
+
});
|
|
1803
|
+
var makeForm = (contract) => import_effect20.Effect.gen(function* () {
|
|
1804
|
+
const decode = import_effect20.Schema.decodeUnknown(contract.schema, { errors: "all" });
|
|
1805
|
+
const defaults = cloneValue(contract.defaults);
|
|
1806
|
+
const fieldNames = new Set(Object.keys(defaults));
|
|
1807
|
+
const snapshots = yield* import_effect20.SubscriptionRef.make(createInitialState(defaults));
|
|
1808
|
+
const validateCurrent = (current) => decode(current.values).pipe(
|
|
1809
|
+
import_effect20.Effect.match({
|
|
1810
|
+
onFailure: (issue) => ({
|
|
1811
|
+
_tag: "invalid",
|
|
1812
|
+
errors: toFormErrors(issue, fieldNames),
|
|
1813
|
+
issue
|
|
1814
|
+
}),
|
|
1815
|
+
onSuccess: (values) => ({
|
|
1816
|
+
_tag: "valid",
|
|
1817
|
+
values: cloneValue(values)
|
|
1818
|
+
})
|
|
1819
|
+
})
|
|
1820
|
+
);
|
|
1821
|
+
const setField = (field, value) => import_effect20.SubscriptionRef.update(snapshots, (current) => {
|
|
1822
|
+
const nextValues = {
|
|
1823
|
+
...current.values,
|
|
1824
|
+
[field]: value
|
|
1825
|
+
};
|
|
1826
|
+
const nextErrors = {
|
|
1827
|
+
...current.errors
|
|
1828
|
+
};
|
|
1829
|
+
delete nextErrors[field];
|
|
1830
|
+
return {
|
|
1831
|
+
...current,
|
|
1832
|
+
values: nextValues,
|
|
1833
|
+
errors: nextErrors,
|
|
1834
|
+
touched: {
|
|
1835
|
+
...current.touched,
|
|
1836
|
+
[field]: true
|
|
1837
|
+
},
|
|
1838
|
+
dirty: !deepEqual(nextValues, defaults),
|
|
1839
|
+
submitted: false
|
|
1840
|
+
};
|
|
1841
|
+
}).pipe(import_effect20.Effect.asVoid);
|
|
1842
|
+
const reset = import_effect20.SubscriptionRef.set(
|
|
1843
|
+
snapshots,
|
|
1844
|
+
createInitialState(defaults)
|
|
1845
|
+
).pipe(import_effect20.Effect.asVoid);
|
|
1846
|
+
const validate = import_effect20.Effect.gen(function* () {
|
|
1847
|
+
const current = yield* import_effect20.SubscriptionRef.get(snapshots);
|
|
1848
|
+
const result = yield* validateCurrent(current);
|
|
1849
|
+
if (result._tag === "valid") {
|
|
1850
|
+
yield* import_effect20.SubscriptionRef.update(snapshots, (snapshot) => ({
|
|
1851
|
+
...snapshot,
|
|
1852
|
+
values: result.values,
|
|
1853
|
+
errors: {},
|
|
1854
|
+
dirty: !deepEqual(result.values, defaults)
|
|
1855
|
+
}));
|
|
1856
|
+
} else {
|
|
1857
|
+
yield* import_effect20.SubscriptionRef.update(snapshots, (snapshot) => ({
|
|
1858
|
+
...snapshot,
|
|
1859
|
+
errors: result.errors
|
|
1860
|
+
}));
|
|
1861
|
+
}
|
|
1862
|
+
return result;
|
|
1863
|
+
});
|
|
1864
|
+
const submit = (handler) => import_effect20.Effect.gen(function* () {
|
|
1865
|
+
yield* import_effect20.SubscriptionRef.update(snapshots, (current2) => ({
|
|
1866
|
+
...current2,
|
|
1867
|
+
submitting: true,
|
|
1868
|
+
submitted: false
|
|
1869
|
+
}));
|
|
1870
|
+
const current = yield* import_effect20.SubscriptionRef.get(snapshots);
|
|
1871
|
+
const validation = yield* validateCurrent(current);
|
|
1872
|
+
if (validation._tag === "invalid") {
|
|
1873
|
+
yield* import_effect20.SubscriptionRef.update(snapshots, (snapshot) => ({
|
|
1874
|
+
...snapshot,
|
|
1875
|
+
submitting: false,
|
|
1876
|
+
submitted: false,
|
|
1877
|
+
errors: validation.errors
|
|
1878
|
+
}));
|
|
1879
|
+
return yield* import_effect20.Effect.fail(new FormValidationError(validation.errors));
|
|
1880
|
+
}
|
|
1881
|
+
yield* import_effect20.SubscriptionRef.update(snapshots, (snapshot) => ({
|
|
1882
|
+
...snapshot,
|
|
1883
|
+
values: validation.values,
|
|
1884
|
+
errors: {},
|
|
1885
|
+
dirty: !deepEqual(validation.values, defaults)
|
|
1886
|
+
}));
|
|
1887
|
+
return yield* handler(validation.values).pipe(
|
|
1888
|
+
import_effect20.Effect.tap(
|
|
1889
|
+
() => import_effect20.SubscriptionRef.update(snapshots, (snapshot) => ({
|
|
1890
|
+
...snapshot,
|
|
1891
|
+
submitting: false,
|
|
1892
|
+
submitted: true
|
|
1893
|
+
})).pipe(import_effect20.Effect.asVoid)
|
|
1894
|
+
),
|
|
1895
|
+
import_effect20.Effect.tapError(
|
|
1896
|
+
() => import_effect20.SubscriptionRef.update(snapshots, (snapshot) => ({
|
|
1897
|
+
...snapshot,
|
|
1898
|
+
submitting: false,
|
|
1899
|
+
submitted: false
|
|
1900
|
+
})).pipe(import_effect20.Effect.asVoid)
|
|
1901
|
+
)
|
|
1902
|
+
);
|
|
1903
|
+
});
|
|
1904
|
+
return {
|
|
1905
|
+
getSnapshot: import_effect20.SubscriptionRef.get(snapshots),
|
|
1906
|
+
snapshots: snapshots.changes,
|
|
1907
|
+
setField,
|
|
1908
|
+
reset,
|
|
1909
|
+
validate,
|
|
1910
|
+
submit
|
|
1911
|
+
};
|
|
1912
|
+
});
|
|
1913
|
+
|
|
1914
|
+
// src/form/react.tsx
|
|
1915
|
+
var import_effect21 = require("effect");
|
|
1916
|
+
var import_react9 = require("react");
|
|
1917
|
+
var useFormStore = (contract) => {
|
|
1918
|
+
const runtime = useEffectRuntime();
|
|
1919
|
+
return (0, import_react9.useMemo)(() => runtime.runSync(makeForm(contract)), [contract, runtime]);
|
|
1920
|
+
};
|
|
1921
|
+
var useForm = (contract) => {
|
|
1922
|
+
const runtime = useEffectRuntime();
|
|
1923
|
+
const form = useFormStore(contract);
|
|
1924
|
+
const subscribe2 = (0, import_react9.useCallback)(
|
|
1925
|
+
(listener) => {
|
|
1926
|
+
const fiber = runtime.runFork(import_effect21.Stream.runForEach(form.snapshots, () => import_effect21.Effect.sync(listener)));
|
|
1927
|
+
return () => {
|
|
1928
|
+
runtime.runFork(import_effect21.Fiber.interrupt(fiber));
|
|
1929
|
+
};
|
|
1930
|
+
},
|
|
1931
|
+
[form, runtime]
|
|
1932
|
+
);
|
|
1933
|
+
const getSnapshot = (0, import_react9.useCallback)(() => runtime.runSync(form.getSnapshot), [form, runtime]);
|
|
1934
|
+
const snapshot = (0, import_react9.useSyncExternalStore)(subscribe2, getSnapshot, getSnapshot);
|
|
1935
|
+
const setField = (0, import_react9.useCallback)(
|
|
1936
|
+
(field, value) => runtime.runPromise(form.setField(field, value)),
|
|
1937
|
+
[form, runtime]
|
|
1938
|
+
);
|
|
1939
|
+
const reset = (0, import_react9.useCallback)(
|
|
1940
|
+
() => runtime.runPromise(form.reset),
|
|
1941
|
+
[form, runtime]
|
|
1942
|
+
);
|
|
1943
|
+
const validate = (0, import_react9.useCallback)(
|
|
1944
|
+
() => runtime.runPromise(form.validate),
|
|
1945
|
+
[form, runtime]
|
|
1946
|
+
);
|
|
1947
|
+
const submit = (0, import_react9.useCallback)(
|
|
1948
|
+
(handler) => runtime.runPromise(form.submit(handler)),
|
|
1949
|
+
[form, runtime]
|
|
1950
|
+
);
|
|
1951
|
+
return {
|
|
1952
|
+
...snapshot,
|
|
1953
|
+
commands: {
|
|
1954
|
+
setField: form.setField,
|
|
1955
|
+
reset: form.reset,
|
|
1956
|
+
validate: form.validate,
|
|
1957
|
+
submit: form.submit
|
|
1958
|
+
},
|
|
1959
|
+
setField,
|
|
1960
|
+
reset,
|
|
1961
|
+
validate,
|
|
1962
|
+
submit
|
|
1963
|
+
};
|
|
1964
|
+
};
|
|
1965
|
+
|
|
1966
|
+
// src/grid/grid.ts
|
|
1967
|
+
var import_effect22 = require("effect");
|
|
1968
|
+
var normalizeInteger = (value, minimum) => {
|
|
1969
|
+
if (!Number.isFinite(value)) {
|
|
1970
|
+
return minimum;
|
|
1971
|
+
}
|
|
1972
|
+
return Math.max(minimum, Math.floor(value));
|
|
1973
|
+
};
|
|
1974
|
+
var toComparable = (value) => {
|
|
1975
|
+
if (value === null || value === void 0 || value instanceof Date) {
|
|
1976
|
+
return value;
|
|
1977
|
+
}
|
|
1978
|
+
switch (typeof value) {
|
|
1979
|
+
case "string":
|
|
1980
|
+
case "number":
|
|
1981
|
+
case "bigint":
|
|
1982
|
+
case "boolean":
|
|
1983
|
+
return value;
|
|
1984
|
+
case "symbol":
|
|
1985
|
+
return value.description ?? "symbol";
|
|
1986
|
+
case "function":
|
|
1987
|
+
return value.name.length > 0 ? `[function ${value.name}]` : "[function]";
|
|
1988
|
+
default:
|
|
1989
|
+
try {
|
|
1990
|
+
const encoded = JSON.stringify(value);
|
|
1991
|
+
return encoded ?? "";
|
|
1992
|
+
} catch {
|
|
1993
|
+
return "";
|
|
1994
|
+
}
|
|
1995
|
+
}
|
|
1996
|
+
};
|
|
1997
|
+
var compareComparable = (left, right) => {
|
|
1998
|
+
if (left === right) {
|
|
1999
|
+
return 0;
|
|
2000
|
+
}
|
|
2001
|
+
if (left === null || left === void 0) {
|
|
2002
|
+
return right === null || right === void 0 ? 0 : -1;
|
|
2003
|
+
}
|
|
2004
|
+
if (right === null || right === void 0) {
|
|
2005
|
+
return 1;
|
|
2006
|
+
}
|
|
2007
|
+
if (left instanceof Date && right instanceof Date) {
|
|
2008
|
+
return import_effect22.Order.Date(left, right);
|
|
2009
|
+
}
|
|
2010
|
+
if (typeof left === "number" && typeof right === "number") {
|
|
2011
|
+
return import_effect22.Order.number(left, right);
|
|
2012
|
+
}
|
|
2013
|
+
if (typeof left === "bigint" && typeof right === "bigint") {
|
|
2014
|
+
return import_effect22.Order.bigint(left, right);
|
|
2015
|
+
}
|
|
2016
|
+
if (typeof left === "boolean" && typeof right === "boolean") {
|
|
2017
|
+
return import_effect22.Order.boolean(left, right);
|
|
2018
|
+
}
|
|
2019
|
+
return import_effect22.Order.string(toSearchText(left), toSearchText(right));
|
|
2020
|
+
};
|
|
2021
|
+
var comparableOrder = import_effect22.Order.make(compareComparable);
|
|
2022
|
+
var toSearchText = (value) => {
|
|
2023
|
+
if (value === null || value === void 0) {
|
|
2024
|
+
return "";
|
|
2025
|
+
}
|
|
2026
|
+
if (value instanceof Date) {
|
|
2027
|
+
return value.toISOString();
|
|
2028
|
+
}
|
|
2029
|
+
switch (typeof value) {
|
|
2030
|
+
case "string":
|
|
2031
|
+
return value;
|
|
2032
|
+
case "number":
|
|
2033
|
+
case "bigint":
|
|
2034
|
+
case "boolean":
|
|
2035
|
+
return value.toString();
|
|
2036
|
+
case "symbol":
|
|
2037
|
+
return value.description ?? "symbol";
|
|
2038
|
+
case "function":
|
|
2039
|
+
return value.name.length > 0 ? value.name : "function";
|
|
2040
|
+
default:
|
|
2041
|
+
try {
|
|
2042
|
+
const encoded = JSON.stringify(value);
|
|
2043
|
+
return encoded ?? "";
|
|
2044
|
+
} catch {
|
|
2045
|
+
return "";
|
|
2046
|
+
}
|
|
2047
|
+
}
|
|
2048
|
+
};
|
|
2049
|
+
var defaultFilterMatch = (value, filterValue) => {
|
|
2050
|
+
if (filterValue === null || filterValue === void 0) {
|
|
2051
|
+
return true;
|
|
2052
|
+
}
|
|
2053
|
+
if (typeof filterValue === "string") {
|
|
2054
|
+
const normalizedFilter = filterValue.trim().toLowerCase();
|
|
2055
|
+
if (normalizedFilter.length === 0) {
|
|
2056
|
+
return true;
|
|
2057
|
+
}
|
|
2058
|
+
return toSearchText(value).toLowerCase().includes(normalizedFilter);
|
|
2059
|
+
}
|
|
2060
|
+
if (Array.isArray(filterValue)) {
|
|
2061
|
+
return filterValue.some((candidate) => Object.is(candidate, value));
|
|
2062
|
+
}
|
|
2063
|
+
if (filterValue instanceof Date && value instanceof Date) {
|
|
2064
|
+
return filterValue.getTime() === value.getTime();
|
|
2065
|
+
}
|
|
2066
|
+
return Object.is(value, filterValue);
|
|
2067
|
+
};
|
|
2068
|
+
var toSortDirection = (direction) => direction === "desc" ? "desc" : "asc";
|
|
2069
|
+
var defineColumns = (columns) => columns;
|
|
2070
|
+
var projectRow = (row, columns) => {
|
|
2071
|
+
const projection = {};
|
|
2072
|
+
for (const column of columns) {
|
|
2073
|
+
projection[column.id] = column.accessor(row);
|
|
2074
|
+
}
|
|
2075
|
+
return projection;
|
|
2076
|
+
};
|
|
2077
|
+
var projectRows = (rows, columns) => (0, import_effect22.pipe)(
|
|
2078
|
+
rows,
|
|
2079
|
+
import_effect22.Array.fromIterable,
|
|
2080
|
+
import_effect22.Array.map((row) => projectRow(row, columns))
|
|
2081
|
+
);
|
|
2082
|
+
var mapRows = projectRows;
|
|
2083
|
+
var sortRows = (rows, columns, sorts) => {
|
|
2084
|
+
const input = import_effect22.Array.fromIterable(rows);
|
|
2085
|
+
if (input.length < 2 || sorts.length === 0) {
|
|
2086
|
+
return input;
|
|
2087
|
+
}
|
|
2088
|
+
const columnLookup = /* @__PURE__ */ new Map();
|
|
2089
|
+
for (const column of columns) {
|
|
2090
|
+
columnLookup.set(column.id, column);
|
|
2091
|
+
}
|
|
2092
|
+
const orders = [];
|
|
2093
|
+
for (const sort of sorts) {
|
|
2094
|
+
const column = columnLookup.get(sort.id);
|
|
2095
|
+
if (column === void 0) {
|
|
2096
|
+
continue;
|
|
2097
|
+
}
|
|
2098
|
+
const orderForColumn = import_effect22.Order.mapInput(
|
|
2099
|
+
comparableOrder,
|
|
2100
|
+
(row) => toComparable(column.accessor(row))
|
|
2101
|
+
);
|
|
2102
|
+
orders.push(toSortDirection(sort.direction) === "desc" ? import_effect22.Order.reverse(orderForColumn) : orderForColumn);
|
|
2103
|
+
}
|
|
2104
|
+
if (orders.length === 0) {
|
|
2105
|
+
return input;
|
|
2106
|
+
}
|
|
2107
|
+
const combinedOrder = import_effect22.Order.combineAll(orders);
|
|
2108
|
+
const indexedOrder = import_effect22.Order.combine(
|
|
2109
|
+
import_effect22.Order.mapInput(combinedOrder, (entry) => entry.row),
|
|
2110
|
+
import_effect22.Order.mapInput(import_effect22.Order.number, (entry) => entry.index)
|
|
2111
|
+
);
|
|
2112
|
+
return (0, import_effect22.pipe)(
|
|
2113
|
+
input,
|
|
2114
|
+
import_effect22.Array.map((row, index) => ({ row, index })),
|
|
2115
|
+
import_effect22.Array.sort(indexedOrder),
|
|
2116
|
+
import_effect22.Array.map((entry) => entry.row)
|
|
2117
|
+
);
|
|
2118
|
+
};
|
|
2119
|
+
var filterRows = (rows, columns, filters) => {
|
|
2120
|
+
const input = import_effect22.Array.fromIterable(rows);
|
|
2121
|
+
if (filters.length === 0) {
|
|
2122
|
+
return input;
|
|
2123
|
+
}
|
|
2124
|
+
const columnLookup = /* @__PURE__ */ new Map();
|
|
2125
|
+
for (const column of columns) {
|
|
2126
|
+
columnLookup.set(column.id, column);
|
|
2127
|
+
}
|
|
2128
|
+
return (0, import_effect22.pipe)(
|
|
2129
|
+
input,
|
|
2130
|
+
import_effect22.Array.filter(
|
|
2131
|
+
(row) => filters.every((filter) => {
|
|
2132
|
+
const column = columnLookup.get(filter.id);
|
|
2133
|
+
if (column === void 0) {
|
|
2134
|
+
return true;
|
|
2135
|
+
}
|
|
2136
|
+
return defaultFilterMatch(column.accessor(row), filter.value);
|
|
2137
|
+
})
|
|
2138
|
+
)
|
|
2139
|
+
);
|
|
2140
|
+
};
|
|
2141
|
+
var paginateRows = (rows, pagination) => {
|
|
2142
|
+
const input = import_effect22.Array.fromIterable(rows);
|
|
2143
|
+
const pageSize = normalizeInteger(pagination.pageSize, 1);
|
|
2144
|
+
const pageCount = input.length === 0 ? 0 : Math.ceil(input.length / pageSize);
|
|
2145
|
+
const requestedPageIndex = normalizeInteger(pagination.pageIndex, 0);
|
|
2146
|
+
const pageIndex = pageCount === 0 ? 0 : Math.min(requestedPageIndex, pageCount - 1);
|
|
2147
|
+
const pageOffset = pageIndex * pageSize;
|
|
2148
|
+
const pageRows = (0, import_effect22.pipe)(
|
|
2149
|
+
input,
|
|
2150
|
+
import_effect22.Array.drop(pageOffset),
|
|
2151
|
+
import_effect22.Array.take(pageSize)
|
|
2152
|
+
);
|
|
2153
|
+
return {
|
|
2154
|
+
rows: pageRows,
|
|
2155
|
+
pageIndex,
|
|
2156
|
+
pageSize,
|
|
2157
|
+
pageCount,
|
|
2158
|
+
totalRows: input.length
|
|
2159
|
+
};
|
|
2160
|
+
};
|
|
2161
|
+
|
|
2162
|
+
// src/virtual/virtual.ts
|
|
2163
|
+
var import_effect23 = require("effect");
|
|
2164
|
+
var normalizeNonNegativeInteger = (value) => {
|
|
2165
|
+
if (!Number.isFinite(value)) {
|
|
2166
|
+
return 0;
|
|
2167
|
+
}
|
|
2168
|
+
return Math.max(0, Math.floor(value));
|
|
2169
|
+
};
|
|
2170
|
+
var normalizeNonNegativeNumber = (value) => {
|
|
2171
|
+
if (!Number.isFinite(value)) {
|
|
2172
|
+
return 0;
|
|
2173
|
+
}
|
|
2174
|
+
return Math.max(0, value);
|
|
2175
|
+
};
|
|
2176
|
+
var normalizePositiveNumber = (value, fallback) => {
|
|
2177
|
+
if (!Number.isFinite(value) || value <= 0) {
|
|
2178
|
+
return fallback;
|
|
2179
|
+
}
|
|
2180
|
+
return value;
|
|
2181
|
+
};
|
|
2182
|
+
var normalizeCount = (count) => normalizeNonNegativeInteger(count);
|
|
2183
|
+
var normalizeEstimateSize = (estimateSize) => normalizePositiveNumber(estimateSize, 1);
|
|
2184
|
+
var resolveItemSize = (sizes, index, estimateSize) => normalizePositiveNumber(sizes?.[index] ?? estimateSize, estimateSize);
|
|
2185
|
+
var measureVirtualItems = (input) => {
|
|
2186
|
+
const count = normalizeCount(input.count);
|
|
2187
|
+
const estimateSize = normalizeEstimateSize(input.estimateSize);
|
|
2188
|
+
const items = [];
|
|
2189
|
+
let offset = 0;
|
|
2190
|
+
for (let index = 0; index < count; index += 1) {
|
|
2191
|
+
const size = resolveItemSize(input.sizes, index, estimateSize);
|
|
2192
|
+
const start = offset;
|
|
2193
|
+
const end = start + size;
|
|
2194
|
+
items[index] = {
|
|
2195
|
+
index,
|
|
2196
|
+
size,
|
|
2197
|
+
start,
|
|
2198
|
+
end
|
|
2199
|
+
};
|
|
2200
|
+
offset = end;
|
|
2201
|
+
}
|
|
2202
|
+
return items;
|
|
2203
|
+
};
|
|
2204
|
+
var calculateOffsets = (input) => (0, import_effect23.pipe)(
|
|
2205
|
+
measureVirtualItems(input),
|
|
2206
|
+
import_effect23.Array.map((item) => item.start)
|
|
2207
|
+
);
|
|
2208
|
+
var calculateTotalSize = (input) => {
|
|
2209
|
+
const items = measureVirtualItems(input);
|
|
2210
|
+
if (items.length === 0) {
|
|
2211
|
+
return 0;
|
|
2212
|
+
}
|
|
2213
|
+
return items[items.length - 1].end;
|
|
2214
|
+
};
|
|
2215
|
+
var calculateOffsetForIndex = (input) => {
|
|
2216
|
+
const count = normalizeCount(input.count);
|
|
2217
|
+
const index = normalizeNonNegativeInteger(input.index);
|
|
2218
|
+
if (count === 0 || index === 0) {
|
|
2219
|
+
return 0;
|
|
2220
|
+
}
|
|
2221
|
+
if (index >= count) {
|
|
2222
|
+
return calculateTotalSize(input);
|
|
2223
|
+
}
|
|
2224
|
+
const estimateSize = normalizeEstimateSize(input.estimateSize);
|
|
2225
|
+
let offset = 0;
|
|
2226
|
+
for (let currentIndex = 0; currentIndex < index; currentIndex += 1) {
|
|
2227
|
+
offset += resolveItemSize(input.sizes, currentIndex, estimateSize);
|
|
2228
|
+
}
|
|
2229
|
+
return offset;
|
|
2230
|
+
};
|
|
2231
|
+
var calculateVisibleRange = (input) => {
|
|
2232
|
+
const count = normalizeCount(input.count);
|
|
2233
|
+
if (count === 0) {
|
|
2234
|
+
return {
|
|
2235
|
+
startIndex: 0,
|
|
2236
|
+
endIndex: -1,
|
|
2237
|
+
overscanStartIndex: 0,
|
|
2238
|
+
overscanEndIndex: -1
|
|
2239
|
+
};
|
|
2240
|
+
}
|
|
2241
|
+
const viewportSize = normalizeNonNegativeNumber(input.viewportSize);
|
|
2242
|
+
const scrollOffset = normalizeNonNegativeNumber(input.scrollOffset);
|
|
2243
|
+
const overscan = normalizeNonNegativeInteger(input.overscan ?? 0);
|
|
2244
|
+
const viewportEnd = scrollOffset + viewportSize;
|
|
2245
|
+
const measurements = measureVirtualItems(input);
|
|
2246
|
+
let startIndex = count - 1;
|
|
2247
|
+
let endIndex = count - 1;
|
|
2248
|
+
let foundStart = false;
|
|
2249
|
+
for (const item of measurements) {
|
|
2250
|
+
if (!foundStart && item.end > scrollOffset) {
|
|
2251
|
+
startIndex = item.index;
|
|
2252
|
+
foundStart = true;
|
|
2253
|
+
}
|
|
2254
|
+
if (item.start < viewportEnd) {
|
|
2255
|
+
endIndex = item.index;
|
|
2256
|
+
}
|
|
2257
|
+
if (foundStart && item.start >= viewportEnd) {
|
|
2258
|
+
break;
|
|
2259
|
+
}
|
|
2260
|
+
}
|
|
2261
|
+
if (!foundStart) {
|
|
2262
|
+
startIndex = count - 1;
|
|
2263
|
+
endIndex = count - 1;
|
|
2264
|
+
} else if (viewportSize <= 0) {
|
|
2265
|
+
endIndex = startIndex;
|
|
2266
|
+
}
|
|
2267
|
+
return {
|
|
2268
|
+
startIndex,
|
|
2269
|
+
endIndex,
|
|
2270
|
+
overscanStartIndex: Math.max(0, startIndex - overscan),
|
|
2271
|
+
overscanEndIndex: Math.min(count - 1, endIndex + overscan)
|
|
2272
|
+
};
|
|
2273
|
+
};
|
|
2274
|
+
var getOffsetForIndex = calculateOffsetForIndex;
|
|
2275
|
+
var getTotalSize = calculateTotalSize;
|
|
2276
|
+
var getVisibleRange = calculateVisibleRange;
|
|
2277
|
+
|
|
2278
|
+
// src/realtime/channel.ts
|
|
2279
|
+
var import_effect24 = require("effect");
|
|
2280
|
+
var createChannel = (options = {}) => import_effect24.Effect.map(import_effect24.PubSub.unbounded(options), (pubsub) => {
|
|
2281
|
+
const subscribe2 = () => import_effect24.Stream.fromPubSub(pubsub);
|
|
2282
|
+
return {
|
|
2283
|
+
publish: (message) => import_effect24.PubSub.publish(pubsub, message).pipe(import_effect24.Effect.asVoid),
|
|
2284
|
+
publishAll: (messages) => import_effect24.PubSub.publishAll(pubsub, messages).pipe(import_effect24.Effect.asVoid),
|
|
2285
|
+
subscribe: subscribe2,
|
|
2286
|
+
stream: subscribe2(),
|
|
2287
|
+
shutdown: import_effect24.PubSub.shutdown(pubsub)
|
|
2288
|
+
};
|
|
2289
|
+
});
|
|
2290
|
+
var publish = (channel, message) => channel.publish(message);
|
|
2291
|
+
var publishAll = (channel, messages) => channel.publishAll(messages);
|
|
2292
|
+
var subscribe = (channel) => channel.subscribe();
|
|
2293
|
+
|
|
2294
|
+
// src/realtime/presence.ts
|
|
2295
|
+
var import_effect25 = require("effect");
|
|
2296
|
+
var cloneMembers = (members) => new Map(members);
|
|
2297
|
+
var applyPresenceEvent = (members, event) => {
|
|
2298
|
+
const next = new Map(members);
|
|
2299
|
+
if (event._tag === "join") {
|
|
2300
|
+
next.set(event.memberId, event.member);
|
|
2301
|
+
} else {
|
|
2302
|
+
next.delete(event.memberId);
|
|
2303
|
+
}
|
|
2304
|
+
return next;
|
|
2305
|
+
};
|
|
2306
|
+
var createPresence = (options) => import_effect25.Effect.gen(function* () {
|
|
2307
|
+
const channel = yield* createChannel();
|
|
2308
|
+
const membersRef = yield* import_effect25.Ref.make(/* @__PURE__ */ new Map());
|
|
2309
|
+
const getMembers = import_effect25.Ref.get(membersRef).pipe(
|
|
2310
|
+
import_effect25.Effect.map((members2) => cloneMembers(members2))
|
|
2311
|
+
);
|
|
2312
|
+
const events = subscribe(channel);
|
|
2313
|
+
const members = import_effect25.Stream.flatMap(
|
|
2314
|
+
import_effect25.Stream.fromEffect(getMembers),
|
|
2315
|
+
(initialMembers) => events.pipe(
|
|
2316
|
+
import_effect25.Stream.scan(
|
|
2317
|
+
initialMembers,
|
|
2318
|
+
(current, event) => applyPresenceEvent(current, event)
|
|
2319
|
+
)
|
|
2320
|
+
)
|
|
2321
|
+
);
|
|
2322
|
+
const join = (member) => {
|
|
2323
|
+
const memberId = options.identify(member);
|
|
2324
|
+
const event = {
|
|
2325
|
+
_tag: "join",
|
|
2326
|
+
memberId,
|
|
2327
|
+
member,
|
|
2328
|
+
timestamp: Date.now()
|
|
2329
|
+
};
|
|
2330
|
+
return import_effect25.Ref.update(membersRef, (current) => {
|
|
2331
|
+
const next = new Map(current);
|
|
2332
|
+
next.set(memberId, member);
|
|
2333
|
+
return next;
|
|
2334
|
+
}).pipe(import_effect25.Effect.zipRight(publish(channel, event)));
|
|
2335
|
+
};
|
|
2336
|
+
const leave = (memberId) => {
|
|
2337
|
+
const event = {
|
|
2338
|
+
_tag: "leave",
|
|
2339
|
+
memberId,
|
|
2340
|
+
timestamp: Date.now()
|
|
2341
|
+
};
|
|
2342
|
+
return import_effect25.Ref.update(membersRef, (current) => {
|
|
2343
|
+
const next = new Map(current);
|
|
2344
|
+
next.delete(memberId);
|
|
2345
|
+
return next;
|
|
2346
|
+
}).pipe(import_effect25.Effect.zipRight(publish(channel, event)));
|
|
2347
|
+
};
|
|
2348
|
+
return {
|
|
2349
|
+
events,
|
|
2350
|
+
members,
|
|
2351
|
+
getMembers,
|
|
2352
|
+
join,
|
|
2353
|
+
leave
|
|
2354
|
+
};
|
|
2355
|
+
});
|
|
2356
|
+
|
|
2357
|
+
// src/devtools/events.ts
|
|
2358
|
+
var import_effect26 = require("effect");
|
|
2359
|
+
var emptyRuntimeStream = () => import_effect26.Stream.fromIterable([]);
|
|
2360
|
+
var wrapTelemetryEvent = (event) => ({
|
|
2361
|
+
_tag: "telemetry",
|
|
2362
|
+
timestamp: event.timestamp,
|
|
2363
|
+
event
|
|
2364
|
+
});
|
|
2365
|
+
var wrapRuntimeEvent = (event) => ({
|
|
2366
|
+
_tag: "runtime",
|
|
2367
|
+
timestamp: event.timestamp,
|
|
2368
|
+
event
|
|
2369
|
+
});
|
|
2370
|
+
var createRuntimeEventSource = () => import_effect26.Effect.map(createChannel(), (channel) => ({
|
|
2371
|
+
emit: (event) => publish(channel, event),
|
|
2372
|
+
stream: subscribe(channel)
|
|
2373
|
+
}));
|
|
2374
|
+
var createDevtoolsEventStream = (options) => {
|
|
2375
|
+
const telemetry = options.telemetry.pipe(import_effect26.Stream.map(wrapTelemetryEvent));
|
|
2376
|
+
const runtime = (options.runtime ?? emptyRuntimeStream()).pipe(import_effect26.Stream.map(wrapRuntimeEvent));
|
|
2377
|
+
return {
|
|
2378
|
+
stream: import_effect26.Stream.merge(telemetry, runtime)
|
|
2379
|
+
};
|
|
2380
|
+
};
|
|
2381
|
+
var createDevtoolsEventStreamFromTelemetry = (options = {}) => import_effect26.Effect.map(
|
|
2382
|
+
Telemetry,
|
|
2383
|
+
(telemetry) => createDevtoolsEventStream({
|
|
2384
|
+
telemetry: telemetry.stream,
|
|
2385
|
+
...options.runtime !== void 0 ? { runtime: options.runtime } : {}
|
|
2386
|
+
})
|
|
2387
|
+
);
|
|
2388
|
+
|
|
2389
|
+
// src/devtools/react.tsx
|
|
2390
|
+
var import_effect27 = require("effect");
|
|
2391
|
+
var import_react10 = require("react");
|
|
2392
|
+
var appendEvent = (current, event, limit) => {
|
|
2393
|
+
if (limit <= 0) {
|
|
2394
|
+
return current;
|
|
2395
|
+
}
|
|
2396
|
+
if (current.length < limit) {
|
|
2397
|
+
return [...current, event];
|
|
2398
|
+
}
|
|
2399
|
+
return [...current.slice(current.length - limit + 1), event];
|
|
2400
|
+
};
|
|
2401
|
+
var useEventStream = (stream, options = {}) => {
|
|
2402
|
+
const runtime = useEffectRuntime();
|
|
2403
|
+
const limit = options.limit ?? 128;
|
|
2404
|
+
const [events, setEvents] = (0, import_react10.useState)([]);
|
|
2405
|
+
(0, import_react10.useEffect)(() => {
|
|
2406
|
+
if (options.enabled === false || limit <= 0) {
|
|
2407
|
+
return;
|
|
2408
|
+
}
|
|
2409
|
+
const fiber = runtime.runFork(
|
|
2410
|
+
import_effect27.Stream.runForEach(
|
|
2411
|
+
stream,
|
|
2412
|
+
(event) => import_effect27.Effect.sync(() => {
|
|
2413
|
+
setEvents((current) => appendEvent(current, event, limit));
|
|
2414
|
+
})
|
|
2415
|
+
)
|
|
2416
|
+
);
|
|
2417
|
+
return () => {
|
|
2418
|
+
runtime.runFork(import_effect27.Fiber.interrupt(fiber));
|
|
2419
|
+
};
|
|
2420
|
+
}, [runtime, stream, options.enabled, limit]);
|
|
2421
|
+
return events;
|
|
2422
|
+
};
|
|
2423
|
+
var useDevtoolsEvents = (source, options = {}) => useEventStream(source.stream, options);
|
|
2424
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
2425
|
+
0 && (module.exports = {
|
|
2426
|
+
FormValidationError,
|
|
2427
|
+
Link,
|
|
2428
|
+
NavigationCancelledError,
|
|
2429
|
+
NavigationRuntimeError,
|
|
2430
|
+
Outlet,
|
|
2431
|
+
QueryRuntimeError,
|
|
2432
|
+
cachePolicy,
|
|
2433
|
+
calculateOffsetForIndex,
|
|
2434
|
+
calculateOffsets,
|
|
2435
|
+
calculateTotalSize,
|
|
2436
|
+
calculateVisibleRange,
|
|
2437
|
+
changes,
|
|
2438
|
+
createApp,
|
|
2439
|
+
createChannel,
|
|
2440
|
+
createDevtoolsEventStream,
|
|
2441
|
+
createDevtoolsEventStreamFromTelemetry,
|
|
2442
|
+
createPresence,
|
|
2443
|
+
createRequestHandler,
|
|
2444
|
+
createRuntimeEventSource,
|
|
2445
|
+
createStore,
|
|
2446
|
+
createStoreFromEffect,
|
|
2447
|
+
createStoreTag,
|
|
2448
|
+
createTestApp,
|
|
2449
|
+
defaultHydrationGlobalName,
|
|
2450
|
+
defineAction,
|
|
2451
|
+
defineColumns,
|
|
2452
|
+
defineConfig,
|
|
2453
|
+
defineForm,
|
|
2454
|
+
defineLayout,
|
|
2455
|
+
defineLoader,
|
|
2456
|
+
defineManifest,
|
|
2457
|
+
defineMiddleware,
|
|
2458
|
+
definePage,
|
|
2459
|
+
defineQuery,
|
|
2460
|
+
defineRoute,
|
|
2461
|
+
derive,
|
|
2462
|
+
fetchQuery,
|
|
2463
|
+
filterRows,
|
|
2464
|
+
get,
|
|
2465
|
+
getOffsetForIndex,
|
|
2466
|
+
getTotalSize,
|
|
2467
|
+
getVisibleRange,
|
|
2468
|
+
hydrateApp,
|
|
2469
|
+
invalidate,
|
|
2470
|
+
invalidateQuery,
|
|
2471
|
+
loadersFromManifest,
|
|
2472
|
+
makeForm,
|
|
2473
|
+
makeStoreLayer,
|
|
2474
|
+
makeStoreLayerFromEffect,
|
|
2475
|
+
mapRows,
|
|
2476
|
+
measureVirtualItems,
|
|
2477
|
+
modify,
|
|
2478
|
+
navigate,
|
|
2479
|
+
noStore,
|
|
2480
|
+
paginateRows,
|
|
2481
|
+
prefetch,
|
|
2482
|
+
prefetchQuery,
|
|
2483
|
+
projectRow,
|
|
2484
|
+
projectRows,
|
|
2485
|
+
publish,
|
|
2486
|
+
publishAll,
|
|
2487
|
+
resolveConfig,
|
|
2488
|
+
revalidateNavigation,
|
|
2489
|
+
routeHref,
|
|
2490
|
+
routePath,
|
|
2491
|
+
routeSearchText,
|
|
2492
|
+
routeUrl,
|
|
2493
|
+
routesFromManifest,
|
|
2494
|
+
select,
|
|
2495
|
+
selectChanges,
|
|
2496
|
+
set,
|
|
2497
|
+
sortRows,
|
|
2498
|
+
subscribe,
|
|
2499
|
+
update,
|
|
2500
|
+
useDevtoolsEvents,
|
|
2501
|
+
useEventStream,
|
|
2502
|
+
useForm,
|
|
2503
|
+
useInfiniteQuery,
|
|
2504
|
+
useNavigate,
|
|
2505
|
+
useNavigationSnapshot,
|
|
2506
|
+
useQuery,
|
|
2507
|
+
useRouteMatch,
|
|
2508
|
+
useStore,
|
|
2509
|
+
useStoreSelector,
|
|
2510
|
+
useSuspenseQuery
|
|
2511
|
+
});
|
|
2512
|
+
//# sourceMappingURL=index.cjs.map
|