ignotum 0.0.2 → 0.0.4
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/README.md +23 -7
- package/dist/cli/bin.mjs +32313 -751
- package/dist/cli/bin.mjs.map +1 -1
- package/dist/runtime/{api-Cpx57mk3.d.ts → api-D2bsAz4T.d.ts} +3 -2
- package/dist/runtime/{api-BXXIZc_Q.js → api-DtX8qPrq.js} +58 -27
- package/dist/runtime/api-DtX8qPrq.js.map +1 -0
- package/dist/runtime/client.d.ts +11 -4
- package/dist/runtime/client.js +343 -79
- package/dist/runtime/client.js.map +1 -1
- package/dist/runtime/{result-B2W-z2wG.js → descriptor-t6BOEGw9-BTHR-ZMv.js} +119 -4
- package/dist/runtime/descriptor-t6BOEGw9-BTHR-ZMv.js.map +1 -0
- package/dist/runtime/id-Btwac71X-B9OeBzvq.d.ts +9 -0
- package/dist/runtime/id-D570vudg.js +26 -0
- package/dist/runtime/id-D570vudg.js.map +1 -0
- package/dist/runtime/{index-BgWROoyk.d.ts → index-Dl_VQGmA.d.ts} +114 -31
- package/dist/runtime/internal/api.d.ts +1 -1
- package/dist/runtime/internal/api.js +1 -1
- package/dist/runtime/internal/host.d.ts +44 -0
- package/dist/runtime/internal/host.js +213 -0
- package/dist/runtime/internal/host.js.map +1 -0
- package/dist/runtime/internal/server.d.ts +1 -1
- package/dist/runtime/internal/server.js +1 -1
- package/dist/runtime/internal/types.d.ts +1 -1
- package/dist/runtime/internal/types.js +1 -1
- package/dist/runtime/{result-C1ZdsM6Y.d.ts → result-BgcHn25t.d.ts} +21 -6
- package/dist/runtime/schema-B-jMZEbs.js +227 -0
- package/dist/runtime/schema-B-jMZEbs.js.map +1 -0
- package/dist/runtime/server.d.ts +2 -2
- package/dist/runtime/server.js +2 -2
- package/package.json +15 -5
- package/src/cli/agent-files.ts +6 -2
- package/src/cli/app-configuration.ts +135 -0
- package/src/cli/bin.ts +24 -1
- package/src/cli/build/artifact.ts +95 -0
- package/src/cli/build/client.ts +103 -0
- package/src/cli/build/server.ts +526 -0
- package/src/cli/client-config.ts +141 -0
- package/src/cli/client-entry.ts +152 -0
- package/src/cli/client-plugin.ts +86 -16
- package/src/cli/codegen.ts +5 -5
- package/src/cli/command.ts +41 -9
- package/src/cli/control-client.ts +343 -0
- package/src/cli/deploy.ts +217 -0
- package/src/cli/dev.ts +43 -108
- package/src/cli/module-boundaries.ts +183 -0
- package/src/cli/{new-project.ts → new-app.ts} +86 -86
- package/src/cli/package-manager.ts +9 -9
- package/src/client/app.ts +15 -0
- package/src/client/errors.ts +1 -17
- package/src/client/index.ts +2 -0
- package/src/client/sync.ts +172 -120
- package/src/dev-runtime/database.ts +253 -96
- package/src/dev-runtime/dev-database.ts +14 -14
- package/src/dev-runtime/functions.ts +57 -88
- package/src/dev-runtime/id.ts +2 -10
- package/src/dev-runtime/migrations.ts +68 -0
- package/src/dev-runtime/sync.ts +266 -83
- package/src/internal/function-definition.ts +77 -0
- package/src/internal/host.ts +1 -0
- package/src/internal/http-paths.ts +3 -1
- package/dist/runtime/api-BXXIZc_Q.js.map +0 -1
- package/dist/runtime/result-B2W-z2wG.js.map +0 -1
- package/dist/runtime/schema-CNEVLF7D.js +0 -116
- package/dist/runtime/schema-CNEVLF7D.js.map +0 -1
package/src/dev-runtime/sync.ts
CHANGED
|
@@ -3,6 +3,16 @@ import type { IncomingMessage, ServerResponse } from "node:http";
|
|
|
3
3
|
|
|
4
4
|
import { NodeHttpServer, NodeServices, NodeSocket } from "@effect/platform-node";
|
|
5
5
|
import { SqliteClient } from "@effect/sql-sqlite-node";
|
|
6
|
+
import {
|
|
7
|
+
AppId,
|
|
8
|
+
AppStateRevision,
|
|
9
|
+
DeploymentGeneration,
|
|
10
|
+
DeploymentId,
|
|
11
|
+
InvocationId,
|
|
12
|
+
RuntimeMutationResult,
|
|
13
|
+
canonicalInvocationInput,
|
|
14
|
+
canonicalQueryKey,
|
|
15
|
+
} from "@ignotum/contracts/runtime/hosted";
|
|
6
16
|
import {
|
|
7
17
|
ClientMessageJson,
|
|
8
18
|
ServerMessageJson,
|
|
@@ -12,7 +22,6 @@ import {
|
|
|
12
22
|
type ProtocolErrorCode,
|
|
13
23
|
type ServerMessage,
|
|
14
24
|
type SubscriptionId,
|
|
15
|
-
type WireResult,
|
|
16
25
|
} from "@ignotum/contracts/runtime/sync";
|
|
17
26
|
import {
|
|
18
27
|
Effect,
|
|
@@ -25,44 +34,140 @@ import {
|
|
|
25
34
|
ManagedRuntime,
|
|
26
35
|
Option,
|
|
27
36
|
Path,
|
|
28
|
-
PartitionedSemaphore,
|
|
29
37
|
PubSub,
|
|
30
38
|
Ref,
|
|
31
39
|
Schema,
|
|
32
40
|
Semaphore,
|
|
33
41
|
} from "effect";
|
|
34
42
|
import { HttpServerRequest, HttpServerResponse } from "effect/unstable/http";
|
|
43
|
+
import { SqlClient, SqlError, SqlSchema } from "effect/unstable/sql";
|
|
35
44
|
import type * as Socket from "effect/unstable/socket/Socket";
|
|
36
45
|
import type { Plugin, ViteDevServer } from "vite";
|
|
37
46
|
import { FunctionRuntime, type PreparedFunction } from "@ignotum/runtime/functions";
|
|
38
|
-
import {
|
|
47
|
+
import {
|
|
48
|
+
makeDependencyIndex,
|
|
49
|
+
QueryInvalidation,
|
|
50
|
+
type QueryInvalidationEvent,
|
|
51
|
+
} from "@ignotum/runtime/sync";
|
|
39
52
|
|
|
40
53
|
import { generate } from "../cli/codegen.js";
|
|
41
54
|
import { isIgnotumPath, syncPath } from "../internal/http-paths.js";
|
|
42
55
|
import { LocalDatabase } from "./database.js";
|
|
43
56
|
import { idGeneratorLayer } from "./id.js";
|
|
57
|
+
import { DevelopmentDatabase } from "./migrations.js";
|
|
44
58
|
import { FunctionExecutor, FunctionRegistry, functionRuntimeLayer } from "./functions.js";
|
|
45
59
|
|
|
46
60
|
interface QuerySubscription {
|
|
47
61
|
readonly args: Schema.Json;
|
|
48
62
|
readonly function: FunctionAddress;
|
|
63
|
+
readonly queryKey: ReturnType<typeof canonicalQueryKey>;
|
|
64
|
+
refreshGeneration: number;
|
|
49
65
|
}
|
|
50
66
|
|
|
67
|
+
export const localSyncIdentity = {
|
|
68
|
+
appId: AppId.make("app_000000000000000000000001"),
|
|
69
|
+
deploymentId: DeploymentId.make("dep_000000000000000000000001"),
|
|
70
|
+
generation: DeploymentGeneration.make(0),
|
|
71
|
+
} as const;
|
|
72
|
+
|
|
51
73
|
export { QueryInvalidation };
|
|
52
74
|
|
|
53
75
|
export const queryInvalidationLayer = Layer.effect(
|
|
54
76
|
QueryInvalidation,
|
|
55
77
|
Effect.gen(function* () {
|
|
56
|
-
const pubsub = yield* PubSub.unbounded<
|
|
78
|
+
const pubsub = yield* PubSub.unbounded<QueryInvalidationEvent>();
|
|
79
|
+
const latestRevision = yield* Ref.make(AppStateRevision.make(0));
|
|
57
80
|
return QueryInvalidation.of({
|
|
58
|
-
|
|
81
|
+
latestRevision: Ref.get(latestRevision),
|
|
82
|
+
publish: (event) =>
|
|
83
|
+
Effect.gen(function* () {
|
|
84
|
+
if (event.type === "Dependencies") {
|
|
85
|
+
yield* Ref.update(latestRevision, (current) =>
|
|
86
|
+
AppStateRevision.make(Math.max(current, event.committedRevision)),
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
yield* PubSub.publish(pubsub, event);
|
|
90
|
+
}).pipe(Effect.asVoid),
|
|
59
91
|
subscribe: PubSub.subscribe(pubsub),
|
|
60
92
|
});
|
|
61
93
|
}),
|
|
62
94
|
);
|
|
63
95
|
|
|
64
|
-
|
|
65
|
-
|
|
96
|
+
class InvocationIdConflict extends Schema.TaggedError<InvocationIdConflict>()(
|
|
97
|
+
"InvocationIdConflict",
|
|
98
|
+
{
|
|
99
|
+
id: Schema.String,
|
|
100
|
+
},
|
|
101
|
+
) {}
|
|
102
|
+
|
|
103
|
+
const MutationReplayRow = Schema.Struct({ input: Schema.String, result: Schema.String });
|
|
104
|
+
|
|
105
|
+
class MutationReplay extends Context.Service<
|
|
106
|
+
MutationReplay,
|
|
107
|
+
{
|
|
108
|
+
readonly execute: (
|
|
109
|
+
id: InvocationId,
|
|
110
|
+
input: string,
|
|
111
|
+
execute: Effect.Effect<RuntimeMutationResult>,
|
|
112
|
+
) => Effect.Effect<RuntimeMutationResult, InvocationIdConflict | SqlError.SqlError>;
|
|
113
|
+
}
|
|
114
|
+
>()("ignotum/dev-runtime/sync/MutationReplay") {
|
|
115
|
+
static readonly layer = Layer.effect(
|
|
116
|
+
MutationReplay,
|
|
117
|
+
Effect.gen(function* () {
|
|
118
|
+
yield* DevelopmentDatabase;
|
|
119
|
+
const sql = yield* SqlClient.SqlClient;
|
|
120
|
+
const findReplay = SqlSchema.findOneOption({
|
|
121
|
+
Request: Schema.Struct({ id: InvocationId }),
|
|
122
|
+
Result: MutationReplayRow,
|
|
123
|
+
execute: ({ id }) => sql`
|
|
124
|
+
SELECT input, result
|
|
125
|
+
FROM invocation_replays
|
|
126
|
+
WHERE id = ${id}
|
|
127
|
+
LIMIT 1
|
|
128
|
+
`,
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
return MutationReplay.of({
|
|
132
|
+
execute: Effect.fn("MutationReplay.execute")(
|
|
133
|
+
function* (
|
|
134
|
+
id,
|
|
135
|
+
input,
|
|
136
|
+
execute,
|
|
137
|
+
): Effect.fn.Return<RuntimeMutationResult, InvocationIdConflict | SqlError.SqlError> {
|
|
138
|
+
return yield* sql.withTransaction(
|
|
139
|
+
Effect.gen(function* () {
|
|
140
|
+
const replay = yield* findReplay({ id }).pipe(
|
|
141
|
+
Effect.catchTags({ SchemaError: Effect.die }),
|
|
142
|
+
);
|
|
143
|
+
if (Option.isSome(replay)) {
|
|
144
|
+
if (replay.value.input !== input) return yield* InvocationIdConflict.make({ id });
|
|
145
|
+
return yield* Schema.decodeEffect(Schema.fromJsonString(RuntimeMutationResult))(
|
|
146
|
+
replay.value.result,
|
|
147
|
+
).pipe(Effect.orDie);
|
|
148
|
+
}
|
|
149
|
+
const result = yield* execute;
|
|
150
|
+
const encoded = yield* Schema.encodeEffect(
|
|
151
|
+
Schema.fromJsonString(RuntimeMutationResult),
|
|
152
|
+
)(result).pipe(Effect.orDie);
|
|
153
|
+
yield* sql`
|
|
154
|
+
INSERT INTO invocation_replays (id, input, result)
|
|
155
|
+
VALUES (${id}, ${input}, ${encoded})
|
|
156
|
+
`;
|
|
157
|
+
return result;
|
|
158
|
+
}),
|
|
159
|
+
);
|
|
160
|
+
},
|
|
161
|
+
),
|
|
162
|
+
});
|
|
163
|
+
}),
|
|
164
|
+
);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
export const mutationReplayLayer = MutationReplay.layer;
|
|
168
|
+
|
|
169
|
+
const operationForSubscription = (subscriptionId: SubscriptionId): Operation => ({
|
|
170
|
+
type: "Subscription",
|
|
66
171
|
id: subscriptionId,
|
|
67
172
|
});
|
|
68
173
|
|
|
@@ -80,9 +185,10 @@ const protocolError = (
|
|
|
80
185
|
export const runSession = Effect.fn("SyncServer.runSession")(function* (socket: Socket.Socket) {
|
|
81
186
|
const runtime = yield* FunctionRuntime;
|
|
82
187
|
const invalidation = yield* QueryInvalidation;
|
|
188
|
+
const mutationReplay = yield* MutationReplay;
|
|
83
189
|
const subscriptions = yield* Ref.make(HashMap.empty<SubscriptionId, QuerySubscription>());
|
|
190
|
+
const dependencyIndex = makeDependencyIndex<SubscriptionId>();
|
|
84
191
|
const invocationFibers = yield* FiberSet.make();
|
|
85
|
-
const querySemaphore = yield* PartitionedSemaphore.make<SubscriptionId>({ permits: 1 });
|
|
86
192
|
const messageSemaphore = yield* Semaphore.make(1);
|
|
87
193
|
const writeSemaphore = yield* Semaphore.make(1);
|
|
88
194
|
const write = yield* socket.writer;
|
|
@@ -128,62 +234,89 @@ export const runSession = Effect.fn("SyncServer.runSession")(function* (socket:
|
|
|
128
234
|
const executeQuery = Effect.fn("SyncServer.executeQuery")(function* (
|
|
129
235
|
subscriptionId: SubscriptionId,
|
|
130
236
|
subscription: QuerySubscription,
|
|
237
|
+
refreshGeneration: number,
|
|
131
238
|
previouslyPrepared?: PreparedFunction,
|
|
132
239
|
) {
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
const operation = operationForQuery(subscriptionId);
|
|
240
|
+
const operation = operationForSubscription(subscriptionId);
|
|
136
241
|
const deliver = (message: ServerMessage) => sendIfActive(subscriptionId, subscription, message);
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
242
|
+
let prepared = previouslyPrepared;
|
|
243
|
+
|
|
244
|
+
while (yield* isActive(subscriptionId, subscription)) {
|
|
245
|
+
if (prepared === undefined) {
|
|
246
|
+
const resolved = yield* runtime
|
|
247
|
+
.prepare(subscription.function, "Query", subscription.args)
|
|
248
|
+
.pipe(
|
|
249
|
+
Effect.catchTags({
|
|
250
|
+
FunctionUnavailable: (error) => sendResolutionError(operation, error, deliver),
|
|
251
|
+
InvalidArguments: (error) => sendResolutionError(operation, error, deliver),
|
|
252
|
+
UnknownFunction: (error) => sendResolutionError(operation, error, deliver),
|
|
253
|
+
WrongFunctionKind: (error) => sendResolutionError(operation, error, deliver),
|
|
254
|
+
}),
|
|
255
|
+
);
|
|
256
|
+
if (resolved === undefined) return;
|
|
257
|
+
prepared = resolved;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
const result = yield* prepared.execute;
|
|
261
|
+
prepared = undefined;
|
|
262
|
+
if (result.type !== "Query") return;
|
|
263
|
+
if (
|
|
264
|
+
!(yield* isActive(subscriptionId, subscription)) ||
|
|
265
|
+
subscription.refreshGeneration !== refreshGeneration
|
|
266
|
+
) {
|
|
267
|
+
return;
|
|
268
|
+
}
|
|
269
|
+
dependencyIndex.record(subscriptionId, result.dependencies);
|
|
270
|
+
if ((yield* invalidation.latestRevision) > result.observedRevision) continue;
|
|
271
|
+
yield* deliver({
|
|
272
|
+
type: "Snapshot",
|
|
273
|
+
id: subscriptionId,
|
|
274
|
+
result: result.result,
|
|
275
|
+
revision: result.observedRevision,
|
|
276
|
+
});
|
|
277
|
+
return;
|
|
278
|
+
}
|
|
155
279
|
});
|
|
156
280
|
|
|
157
281
|
const scheduleQuery = (
|
|
158
282
|
subscriptionId: SubscriptionId,
|
|
159
283
|
subscription: QuerySubscription,
|
|
160
284
|
previouslyPrepared?: PreparedFunction,
|
|
161
|
-
) =>
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
.pipe(
|
|
168
|
-
Effect.catchCause((cause) =>
|
|
169
|
-
Effect.logError("A query refresh fiber failed.").pipe(
|
|
170
|
-
Effect.annotateLogs({ cause, function: subscription.function, subscriptionId }),
|
|
171
|
-
),
|
|
285
|
+
) => {
|
|
286
|
+
const refreshGeneration = ++subscription.refreshGeneration;
|
|
287
|
+
return executeQuery(subscriptionId, subscription, refreshGeneration, previouslyPrepared).pipe(
|
|
288
|
+
Effect.catchCause((cause) =>
|
|
289
|
+
Effect.logError("A query refresh fiber failed.").pipe(
|
|
290
|
+
Effect.annotateLogs({ cause, function: subscription.function, subscriptionId }),
|
|
172
291
|
),
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
292
|
+
),
|
|
293
|
+
FiberSet.run(invocationFibers),
|
|
294
|
+
Effect.asVoid,
|
|
295
|
+
);
|
|
296
|
+
};
|
|
176
297
|
|
|
177
|
-
const
|
|
298
|
+
const refreshAll = Effect.fn("SyncServer.refreshAll")(function* () {
|
|
178
299
|
const current = yield* Ref.get(subscriptions);
|
|
179
300
|
yield* Effect.forEach(HashMap.toEntries(current), ([subscriptionId, subscription]) =>
|
|
180
301
|
scheduleQuery(subscriptionId, subscription),
|
|
181
302
|
);
|
|
182
303
|
});
|
|
183
304
|
|
|
305
|
+
const refreshAffected = Effect.fn("SyncServer.refreshAffected")(function* (
|
|
306
|
+
invalidations: Parameters<typeof dependencyIndex.affected>[0],
|
|
307
|
+
) {
|
|
308
|
+
const current = yield* Ref.get(subscriptions);
|
|
309
|
+
yield* Effect.forEach(dependencyIndex.affected(invalidations), (subscriptionId) => {
|
|
310
|
+
const subscription = Option.getOrUndefined(HashMap.get(current, subscriptionId));
|
|
311
|
+
return subscription === undefined ? Effect.void : scheduleQuery(subscriptionId, subscription);
|
|
312
|
+
});
|
|
313
|
+
});
|
|
314
|
+
|
|
184
315
|
const invalidations = yield* invalidation.subscribe;
|
|
185
316
|
yield* PubSub.take(invalidations).pipe(
|
|
186
|
-
Effect.flatMap(
|
|
317
|
+
Effect.flatMap((event) =>
|
|
318
|
+
event.type === "All" ? refreshAll() : refreshAffected(event.invalidations),
|
|
319
|
+
),
|
|
187
320
|
Effect.forever,
|
|
188
321
|
Effect.forkScoped,
|
|
189
322
|
);
|
|
@@ -191,7 +324,7 @@ export const runSession = Effect.fn("SyncServer.runSession")(function* (socket:
|
|
|
191
324
|
const handleSubscribe = Effect.fn("SyncServer.handleSubscribe")(function* (
|
|
192
325
|
message: Extract<ClientMessage, { readonly type: "Subscribe" }>,
|
|
193
326
|
) {
|
|
194
|
-
const operation =
|
|
327
|
+
const operation = operationForSubscription(message.id);
|
|
195
328
|
const current = yield* Ref.get(subscriptions);
|
|
196
329
|
|
|
197
330
|
if (HashMap.has(current, message.id)) {
|
|
@@ -218,15 +351,20 @@ export const runSession = Effect.fn("SyncServer.runSession")(function* (socket:
|
|
|
218
351
|
return;
|
|
219
352
|
}
|
|
220
353
|
|
|
221
|
-
const subscription = {
|
|
354
|
+
const subscription = {
|
|
355
|
+
args: message.args,
|
|
356
|
+
function: message.function,
|
|
357
|
+
queryKey: canonicalQueryKey(localSyncIdentity.deploymentId, message.function, message.args),
|
|
358
|
+
refreshGeneration: 0,
|
|
359
|
+
};
|
|
222
360
|
yield* Ref.update(subscriptions, HashMap.set(message.id, subscription));
|
|
223
361
|
yield* scheduleQuery(message.id, subscription, prepared);
|
|
224
362
|
});
|
|
225
363
|
|
|
226
|
-
const
|
|
227
|
-
message: Extract<ClientMessage, { readonly type: "
|
|
364
|
+
const handleInvoke = Effect.fn("SyncServer.handleInvoke")(function* (
|
|
365
|
+
message: Extract<ClientMessage, { readonly type: "Invoke" }>,
|
|
228
366
|
) {
|
|
229
|
-
const operation: Operation = { type: "
|
|
367
|
+
const operation: Operation = { type: "Invocation", id: message.id };
|
|
230
368
|
const prepared = yield* runtime.prepare(message.function, "Mutation", message.args).pipe(
|
|
231
369
|
Effect.catchTags({
|
|
232
370
|
FunctionUnavailable: (error) => sendResolutionError(operation, error),
|
|
@@ -240,21 +378,61 @@ export const runSession = Effect.fn("SyncServer.runSession")(function* (socket:
|
|
|
240
378
|
return;
|
|
241
379
|
}
|
|
242
380
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
: response;
|
|
249
|
-
}),
|
|
250
|
-
Effect.catchCause((cause) =>
|
|
251
|
-
Effect.logError("A mutation invocation fiber failed.").pipe(
|
|
252
|
-
Effect.annotateLogs({ cause, function: message.function, requestId: message.id }),
|
|
253
|
-
),
|
|
254
|
-
),
|
|
255
|
-
FiberSet.run(invocationFibers),
|
|
256
|
-
Effect.asVoid,
|
|
381
|
+
const input = canonicalInvocationInput(
|
|
382
|
+
localSyncIdentity.deploymentId,
|
|
383
|
+
"Mutation",
|
|
384
|
+
message.function,
|
|
385
|
+
message.args,
|
|
257
386
|
);
|
|
387
|
+
yield* mutationReplay
|
|
388
|
+
.execute(
|
|
389
|
+
message.id,
|
|
390
|
+
input,
|
|
391
|
+
prepared.execute.pipe(
|
|
392
|
+
Effect.flatMap((result) =>
|
|
393
|
+
result.type === "Mutation" ? Effect.succeed(result) : Effect.die("Expected mutation"),
|
|
394
|
+
),
|
|
395
|
+
),
|
|
396
|
+
)
|
|
397
|
+
.pipe(
|
|
398
|
+
Effect.flatMap((result) => {
|
|
399
|
+
if (!("committedRevision" in result)) {
|
|
400
|
+
return send({ type: "Result", id: message.id, result: result.result });
|
|
401
|
+
}
|
|
402
|
+
const response = send({
|
|
403
|
+
type: "Result",
|
|
404
|
+
id: message.id,
|
|
405
|
+
result: result.result,
|
|
406
|
+
committedRevision: result.committedRevision,
|
|
407
|
+
});
|
|
408
|
+
return response.pipe(
|
|
409
|
+
Effect.ensuring(
|
|
410
|
+
invalidation.publish({
|
|
411
|
+
type: "Dependencies",
|
|
412
|
+
invalidations: result.invalidations,
|
|
413
|
+
committedRevision: result.committedRevision,
|
|
414
|
+
}),
|
|
415
|
+
),
|
|
416
|
+
);
|
|
417
|
+
}),
|
|
418
|
+
Effect.catchTags({
|
|
419
|
+
InvocationIdConflict: () =>
|
|
420
|
+
send(
|
|
421
|
+
protocolError(
|
|
422
|
+
"InvocationIdConflict",
|
|
423
|
+
`Invocation ${message.id} was already used with different inputs.`,
|
|
424
|
+
operation,
|
|
425
|
+
),
|
|
426
|
+
),
|
|
427
|
+
}),
|
|
428
|
+
Effect.catchCause((cause) =>
|
|
429
|
+
Effect.logError("A mutation invocation fiber failed.").pipe(
|
|
430
|
+
Effect.annotateLogs({ cause, function: message.function, requestId: message.id }),
|
|
431
|
+
),
|
|
432
|
+
),
|
|
433
|
+
FiberSet.run(invocationFibers),
|
|
434
|
+
Effect.asVoid,
|
|
435
|
+
);
|
|
258
436
|
});
|
|
259
437
|
|
|
260
438
|
const handleMessage = Effect.fn("SyncServer.handleMessage")(function* (text: string) {
|
|
@@ -273,15 +451,18 @@ export const runSession = Effect.fn("SyncServer.runSession")(function* (socket:
|
|
|
273
451
|
yield* handleSubscribe(message);
|
|
274
452
|
return;
|
|
275
453
|
case "Unsubscribe":
|
|
454
|
+
dependencyIndex.remove(message.id);
|
|
276
455
|
yield* Ref.update(subscriptions, HashMap.remove(message.id));
|
|
277
456
|
return;
|
|
278
|
-
case "
|
|
279
|
-
yield*
|
|
457
|
+
case "Invoke":
|
|
458
|
+
yield* handleInvoke(message);
|
|
280
459
|
return;
|
|
281
460
|
}
|
|
282
461
|
});
|
|
283
462
|
|
|
284
|
-
yield* socket.runString((text) => messageSemaphore.withPermits(1)(handleMessage(text))
|
|
463
|
+
yield* socket.runString((text) => messageSemaphore.withPermits(1)(handleMessage(text)), {
|
|
464
|
+
onOpen: send({ type: "Handshake", ...localSyncIdentity }).pipe(Effect.orDie),
|
|
465
|
+
});
|
|
285
466
|
});
|
|
286
467
|
|
|
287
468
|
interface SyncHandlersService {
|
|
@@ -296,19 +477,20 @@ class SyncHandlers extends Context.Service<SyncHandlers, SyncHandlersService>()(
|
|
|
296
477
|
"ignotum/dev-runtime/sync/SyncHandlers",
|
|
297
478
|
) {}
|
|
298
479
|
|
|
299
|
-
const makeHandlersLayer = (
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
)
|
|
304
|
-
|
|
305
|
-
|
|
480
|
+
const makeHandlersLayer = (server: ViteDevServer, appDirectory: string, databasePath: string) => {
|
|
481
|
+
const sqliteLayer = SqliteClient.layer({ filename: databasePath });
|
|
482
|
+
const persistenceLayer = Layer.merge(LocalDatabase.layer, mutationReplayLayer).pipe(
|
|
483
|
+
Layer.provideMerge(DevelopmentDatabase.layer),
|
|
484
|
+
Layer.provide(Layer.merge(idGeneratorLayer, sqliteLayer)),
|
|
485
|
+
);
|
|
486
|
+
const executorLayer = FunctionExecutor.layer.pipe(
|
|
487
|
+
Layer.provide(persistenceLayer),
|
|
488
|
+
Layer.provide(idGeneratorLayer),
|
|
306
489
|
);
|
|
307
|
-
const executorLayer = FunctionExecutor.layer.pipe(Layer.provide(databaseLayer));
|
|
308
490
|
const devFunctionRuntimeLayer = functionRuntimeLayer.pipe(
|
|
309
491
|
Layer.provide(
|
|
310
492
|
Layer.merge(
|
|
311
|
-
FunctionRegistry.layer(server,
|
|
493
|
+
FunctionRegistry.layer(server, appDirectory).pipe(Layer.provide(NodeServices.layer)),
|
|
312
494
|
executorLayer,
|
|
313
495
|
),
|
|
314
496
|
),
|
|
@@ -316,6 +498,7 @@ const makeHandlersLayer = (
|
|
|
316
498
|
const dependencies = Layer.mergeAll(
|
|
317
499
|
devFunctionRuntimeLayer,
|
|
318
500
|
queryInvalidationLayer,
|
|
501
|
+
persistenceLayer,
|
|
319
502
|
NodeServices.layer,
|
|
320
503
|
);
|
|
321
504
|
|
|
@@ -358,7 +541,7 @@ const makeHandlersLayer = (
|
|
|
358
541
|
socketApp,
|
|
359
542
|
{ scope },
|
|
360
543
|
);
|
|
361
|
-
const serverDirectory = path.join(
|
|
544
|
+
const serverDirectory = path.join(appDirectory, "server");
|
|
362
545
|
const reloadUnsafe = Effect.fn("SyncServer.reload")(function* (
|
|
363
546
|
file: string,
|
|
364
547
|
event: "add" | "change" | "unlink",
|
|
@@ -369,12 +552,12 @@ const makeHandlersLayer = (
|
|
|
369
552
|
}
|
|
370
553
|
|
|
371
554
|
if (event !== "change") {
|
|
372
|
-
yield* generate(
|
|
555
|
+
yield* generate(appDirectory).pipe(
|
|
373
556
|
Effect.provideService(FileSystem.FileSystem, fileSystem),
|
|
374
557
|
Effect.provideService(Path.Path, path),
|
|
375
558
|
);
|
|
376
559
|
}
|
|
377
|
-
yield* invalidation.publish;
|
|
560
|
+
yield* invalidation.publish({ type: "All" });
|
|
378
561
|
});
|
|
379
562
|
const reload = (file: string, event: "add" | "change" | "unlink") =>
|
|
380
563
|
reloadSemaphore
|
|
@@ -415,16 +598,16 @@ const rejectUpgrade = (socket: import("node:stream").Duplex): void => {
|
|
|
415
598
|
export const syncPluginInternals = { isAppOrigin };
|
|
416
599
|
|
|
417
600
|
export const ignotumSyncPlugin: {
|
|
418
|
-
(databasePath: string): (
|
|
419
|
-
(
|
|
420
|
-
} = Function.dual(2, (
|
|
601
|
+
(databasePath: string): (appDirectory: string) => Plugin;
|
|
602
|
+
(appDirectory: string, databasePath: string): Plugin;
|
|
603
|
+
} = Function.dual(2, (appDirectory: string, databasePath: string): Plugin => ({
|
|
421
604
|
name: "ignotum:sync",
|
|
422
605
|
configureServer: (server) => {
|
|
423
606
|
if (server.httpServer === null) {
|
|
424
607
|
throw new Error("Ignotum sync requires Vite's Node HTTP server.");
|
|
425
608
|
}
|
|
426
609
|
|
|
427
|
-
const runtime = ManagedRuntime.make(makeHandlersLayer(server,
|
|
610
|
+
const runtime = ManagedRuntime.make(makeHandlersLayer(server, appDirectory, databasePath));
|
|
428
611
|
const httpServer = server.httpServer;
|
|
429
612
|
return runtime.runPromise(SyncHandlers).then(
|
|
430
613
|
(handlers) => {
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getFunctionSchema,
|
|
3
|
+
type FunctionSchemaCarrier,
|
|
4
|
+
type RuntimeSchemaDefinition,
|
|
5
|
+
} from "@ignotum/contracts/runtime/schema";
|
|
6
|
+
import type { ErrorValue } from "@ignotum/contracts/runtime/result";
|
|
7
|
+
import type { FunctionKind } from "@ignotum/contracts/runtime/functions";
|
|
8
|
+
import type { TransportValue } from "@ignotum/contracts/runtime/sync";
|
|
9
|
+
import { Predicate, Schema } from "effect";
|
|
10
|
+
import type { Effect } from "effect";
|
|
11
|
+
|
|
12
|
+
type RuntimeFields = Readonly<Record<string, Schema.ConstraintDecoder<unknown>>>;
|
|
13
|
+
|
|
14
|
+
declare const FunctionArgumentsTypeId: unique symbol;
|
|
15
|
+
export interface FunctionArguments {
|
|
16
|
+
readonly [FunctionArgumentsTypeId]?: never;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface RuntimeFunctionDefinition<Context = unknown> {
|
|
20
|
+
readonly _tag: FunctionKind;
|
|
21
|
+
readonly args?: RuntimeFields;
|
|
22
|
+
readonly returns?: Schema.Codec<unknown, unknown>;
|
|
23
|
+
readonly errors?: Schema.Codec<unknown, unknown>;
|
|
24
|
+
readonly handler: (
|
|
25
|
+
context: Context,
|
|
26
|
+
args: FunctionArguments,
|
|
27
|
+
) => Generator<Effect.Effect<unknown, ErrorValue, never>, TransportValue | void, never>;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface InspectedRuntimeFunctionDefinition<Context = unknown> {
|
|
31
|
+
readonly definition: RuntimeFunctionDefinition<Context>;
|
|
32
|
+
readonly schema: RuntimeSchemaDefinition;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
interface RuntimeFunctionCandidate extends FunctionSchemaCarrier {
|
|
36
|
+
readonly _tag?: unknown;
|
|
37
|
+
readonly args?: unknown;
|
|
38
|
+
readonly returns?: unknown;
|
|
39
|
+
readonly errors?: unknown;
|
|
40
|
+
readonly handler?: unknown;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export const inspectRuntimeFunctionDefinition = <Context = unknown>(
|
|
44
|
+
value: RuntimeFunctionCandidate,
|
|
45
|
+
): InspectedRuntimeFunctionDefinition<Context> | undefined => {
|
|
46
|
+
const schema = getFunctionSchema(value);
|
|
47
|
+
if (
|
|
48
|
+
schema === undefined ||
|
|
49
|
+
!Predicate.hasProperty(value, "_tag") ||
|
|
50
|
+
(value._tag !== "Mutation" && value._tag !== "Query") ||
|
|
51
|
+
(Predicate.hasProperty(value, "args") &&
|
|
52
|
+
value.args !== undefined &&
|
|
53
|
+
!Predicate.isObject(value.args)) ||
|
|
54
|
+
(Predicate.hasProperty(value, "returns") &&
|
|
55
|
+
value.returns !== undefined &&
|
|
56
|
+
!Schema.isSchema(value.returns)) ||
|
|
57
|
+
(Predicate.hasProperty(value, "errors") &&
|
|
58
|
+
value.errors !== undefined &&
|
|
59
|
+
!Schema.isSchema(value.errors)) ||
|
|
60
|
+
!Predicate.hasProperty(value, "handler") ||
|
|
61
|
+
!Predicate.isFunction(value.handler)
|
|
62
|
+
) {
|
|
63
|
+
return undefined;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (
|
|
67
|
+
Predicate.hasProperty(value, "args") &&
|
|
68
|
+
Predicate.isObject(value.args) &&
|
|
69
|
+
!Object.values(value.args).every(Schema.isSchema)
|
|
70
|
+
) {
|
|
71
|
+
return undefined;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// SAFETY: every RuntimeFunctionDefinition property and argument Schema was
|
|
75
|
+
// checked above. Predicate.hasProperty does not retain the literal tag type.
|
|
76
|
+
return { definition: value as RuntimeFunctionDefinition<Context>, schema };
|
|
77
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { invoke } from "@ignotum/runtime/guest";
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
import { appSyncPath } from "@ignotum/contracts/runtime/transport";
|
|
2
|
+
|
|
1
3
|
export const ignotumPathPrefix = "/_ignotum";
|
|
2
|
-
export const syncPath =
|
|
4
|
+
export const syncPath = appSyncPath;
|
|
3
5
|
|
|
4
6
|
export const isIgnotumPath = (pathname: string): boolean =>
|
|
5
7
|
pathname === ignotumPathPrefix || pathname.startsWith(`${ignotumPathPrefix}/`);
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"api-BXXIZc_Q.js","names":[],"sources":["../../../contracts/dist/runtime/sync.js","../../src/internal/api.ts"],"sourcesContent":["import { a as decodeTransportValue, i as decodeTransportObject, n as datePathsOf, o as encodeTransportObject, r as datePathsOfObject, s as encodeTransportValue, t as TransportValueSchema } from \"../value-Briqf-Ua.js\";\nimport { Schema } from \"effect\";\n//#region src/runtime/sync.ts\nconst FunctionNamePart = Schema.String.check(Schema.isPattern(/^[A-Za-z_$][A-Za-z0-9_$]*$/));\nconst ApiFunctionAddressParts = Schema.TemplateLiteralParser([\n\t\"api.\",\n\tFunctionNamePart,\n\t\".\",\n\tFunctionNamePart\n]);\nconst FunctionAddress = Schema.TemplateLiteral([\n\t\"api.\",\n\tFunctionNamePart,\n\t\".\",\n\tFunctionNamePart\n]);\nconst apiFunctionParts = (address) => {\n\tconst [, moduleName, , functionName] = Schema.decodeSync(ApiFunctionAddressParts)(address);\n\treturn {\n\t\tfunctionName,\n\t\tmoduleName\n\t};\n};\nconst SubscriptionId = Schema.Natural.pipe(Schema.brand(\"ignotum/sync/SubscriptionId\"));\nconst RequestId = Schema.Natural.pipe(Schema.brand(\"ignotum/sync/RequestId\"));\nconst Subscribe = Schema.Struct({\n\ttype: Schema.Literal(\"Subscribe\"),\n\tid: SubscriptionId,\n\tfunction: FunctionAddress,\n\targs: Schema.Json\n});\nconst Unsubscribe = Schema.Struct({\n\ttype: Schema.Literal(\"Unsubscribe\"),\n\tid: SubscriptionId\n});\nconst Mutate = Schema.Struct({\n\ttype: Schema.Literal(\"Mutate\"),\n\tid: RequestId,\n\tfunction: FunctionAddress,\n\targs: Schema.Json\n});\nconst ClientMessage = Schema.Union([\n\tSubscribe,\n\tUnsubscribe,\n\tMutate\n]);\nconst QueryOperation = Schema.Struct({\n\ttype: Schema.Literal(\"Query\"),\n\tid: SubscriptionId\n});\nconst MutateOperation = Schema.Struct({\n\ttype: Schema.Literal(\"Mutate\"),\n\tid: RequestId\n});\nconst Operation = Schema.Union([QueryOperation, MutateOperation]);\nconst DatePath = Schema.Array(Schema.Union([Schema.String, Schema.Natural]));\nconst DatePaths = Schema.Array(DatePath);\nconst WireResult = Schema.Union([Schema.Struct({\n\ttype: Schema.Literal(\"Success\"),\n\tvalue: Schema.optional(Schema.Json),\n\tdates: Schema.optional(DatePaths)\n}), Schema.Struct({\n\ttype: Schema.Literal(\"Failure\"),\n\terror: Schema.Json,\n\tdates: Schema.optional(DatePaths)\n})]);\nconst QuerySnapshot = Schema.Struct({\n\ttype: Schema.Literal(\"QuerySnapshot\"),\n\tid: SubscriptionId,\n\tresult: WireResult\n});\nconst MutationResult = Schema.Struct({\n\ttype: Schema.Literal(\"MutationResult\"),\n\tid: RequestId,\n\tresult: WireResult\n});\nconst ProtocolErrorCode = Schema.Literals([\n\t\"DuplicateOperationId\",\n\t\"FunctionUnavailable\",\n\t\"InvalidArguments\",\n\t\"InvalidMessage\",\n\t\"UnknownFunction\",\n\t\"WrongFunctionKind\"\n]);\nconst ProtocolError = Schema.Struct({\n\ttype: Schema.Literal(\"ProtocolError\"),\n\toperation: Schema.optional(Operation),\n\tcode: ProtocolErrorCode,\n\tmessage: Schema.String\n});\nconst ServerMessage = Schema.Union([\n\tQuerySnapshot,\n\tMutationResult,\n\tProtocolError\n]);\nconst ClientMessageJson = Schema.fromJsonString(ClientMessage);\nconst ServerMessageJson = Schema.fromJsonString(ServerMessage);\n//#endregion\nexport { ClientMessage, ClientMessageJson, DatePath, FunctionAddress, FunctionNamePart, Operation, ProtocolErrorCode, RequestId, ServerMessage, ServerMessageJson, SubscriptionId, TransportValueSchema, WireResult, apiFunctionParts, datePathsOf, datePathsOfObject, decodeTransportObject, decodeTransportValue, encodeTransportObject, encodeTransportValue };\n\n//# sourceMappingURL=sync.js.map","import { Predicate } from \"effect\";\nimport type { Effect } from \"effect\";\n\nimport type { ErrorValue, InternalServerError } from \"@ignotum/contracts/runtime/result\";\nimport { FunctionAddress } from \"@ignotum/contracts/runtime/sync\";\n\nconst FunctionReferenceTypeId: unique symbol = Symbol.for(\"ignotum/internal/api/FunctionReference\");\ndeclare const FunctionReferenceTypesTypeId: unique symbol;\n\ntype FunctionKind = \"Mutation\" | \"Query\";\n\nexport interface FunctionReference<\n Kind extends FunctionKind,\n Args,\n Success,\n Failure extends ErrorValue,\n> {\n readonly [FunctionReferenceTypeId]: FunctionAddress;\n readonly [FunctionReferenceTypesTypeId]?: {\n readonly kind: Kind;\n readonly args: Args;\n readonly value: Success;\n readonly error: Failure;\n };\n}\n\ntype ReferenceTypes<Reference> = Reference extends {\n readonly [FunctionReferenceTypesTypeId]?: infer Types;\n}\n ? Exclude<Types, undefined>\n : never;\n\nexport declare namespace FunctionReference {\n type Args<Reference> =\n ReferenceTypes<Reference> extends { readonly args: infer Args } ? Args : never;\n type Failure<Reference> =\n ReferenceTypes<Reference> extends {\n readonly error: infer Failure;\n }\n ? Failure\n : never;\n type Kind<Reference> =\n ReferenceTypes<Reference> extends { readonly kind: infer Kind } ? Kind : never;\n type Success<Reference> =\n ReferenceTypes<Reference> extends {\n readonly value: infer Success;\n }\n ? Success\n : never;\n}\n\ntype ReferenceOf<Definition> = Definition extends {\n readonly _tag: infer Kind extends FunctionKind;\n readonly handler: (\n ...arguments_: infer HandlerArguments\n ) => Generator<infer Yielded, infer Success, never>;\n}\n ? HandlerArguments extends readonly [infer _Context, ...infer Rest]\n ? FunctionReference<\n Kind,\n Rest extends readonly [infer Args, ...ReadonlyArray<unknown>] ? Args : void,\n Success,\n | (Yielded extends Effect.Effect<unknown, infer Failure extends ErrorValue, never>\n ? Failure\n : never)\n | InternalServerError\n >\n : never\n : never;\n\ntype ApiModule<Module> = {\n readonly [FunctionName in keyof Module as FunctionName extends string\n ? ReferenceOf<Module[FunctionName]> extends never\n ? never\n : FunctionName\n : never]: ReferenceOf<Module[FunctionName]>;\n};\n\nexport type Api<Modules> = {\n readonly [ModuleName in keyof Modules]: ApiModule<Modules[ModuleName]>;\n};\n\nexport const functionPathOf = <\n Kind extends FunctionKind,\n Args,\n Success,\n Failure extends ErrorValue,\n>(\n reference: FunctionReference<Kind, Args, Success, Failure>,\n) => reference[FunctionReferenceTypeId];\n\nconst makeModuleReference = (moduleName: string) => {\n const references = new Map<string, object>();\n\n return new Proxy(\n {},\n {\n get: (_target, functionName) => {\n if (!Predicate.isString(functionName)) {\n return undefined;\n }\n\n const existing = references.get(functionName);\n if (existing !== undefined) {\n return existing;\n }\n\n const reference = {\n [FunctionReferenceTypeId]: FunctionAddress.make(`api.${moduleName}.${functionName}`),\n };\n references.set(functionName, reference);\n return reference;\n },\n },\n );\n};\n\nexport function createApi<Modules>(): Api<Modules>;\nexport function createApi() {\n const modules = new Map<string, object>();\n\n return new Proxy(\n {},\n {\n get: (_target, moduleName) => {\n if (!Predicate.isString(moduleName)) {\n return undefined;\n }\n\n const existing = modules.get(moduleName);\n if (existing !== undefined) {\n return existing;\n }\n\n const moduleReference = makeModuleReference(moduleName);\n modules.set(moduleName, moduleReference);\n return moduleReference;\n },\n },\n );\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"result-B2W-z2wG.js","names":[],"sources":["../../../contracts/dist/value-Briqf-Ua.js","../../../contracts/dist/runtime/result.js"],"sourcesContent":["import { Predicate, Schema } from \"effect\";\n//#region src/runtime/value.ts\nconst TransportValueSchema = Schema.suspend(() => Schema.Union([\n\tSchema.Null,\n\tSchema.Boolean,\n\tSchema.Finite,\n\tSchema.String,\n\tSchema.Date,\n\tSchema.Array(TransportValueSchema),\n\tSchema.Record(Schema.String, Schema.UndefinedOr(TransportValueSchema))\n]));\nconst encodeTransportValue = (value) => {\n\tif (Predicate.isDate(value)) return Schema.encodeSync(Schema.DateFromMillis)(value);\n\tif (globalThis.Array.isArray(value)) return value.map(encodeTransportValue);\n\tif (Predicate.isNumber(value)) return Schema.decodeSync(Schema.Finite)(value);\n\tif (Predicate.isNull(value) || Predicate.isString(value) || Predicate.isBoolean(value)) return value;\n\treturn Object.fromEntries(Object.entries(value).flatMap(([key, child]) => child === void 0 ? [] : [[key, encodeTransportValue(child)]]));\n};\nconst encodeTransportObject = (value) => Schema.decodeUnknownSync(Schema.JsonObject)(encodeTransportValue(Schema.decodeUnknownSync(TransportValueSchema)(value)));\nconst collectDatePaths = (value, path, paths) => {\n\tif (Predicate.isDate(value)) {\n\t\tSchema.decodeSync(Schema.Date)(value);\n\t\tpaths.push(path);\n\t\treturn;\n\t}\n\tif (globalThis.Array.isArray(value)) {\n\t\tfor (const [index, child] of value.entries()) collectDatePaths(child, [...path, index], paths);\n\t\treturn;\n\t}\n\tif (value === void 0 || Predicate.isNull(value) || Predicate.isString(value) || Predicate.isNumber(value) || Predicate.isBoolean(value)) return;\n\tfor (const [key, child] of Object.entries(value)) collectDatePaths(child, [...path, key], paths);\n};\nconst datePathsOf = (value) => {\n\tconst paths = [];\n\tcollectDatePaths(value, [], paths);\n\treturn paths;\n};\nconst datePathsOfObject = (value) => datePathsOf(Schema.decodeUnknownSync(TransportValueSchema)(value));\nconst pathKey = (path) => JSON.stringify(path);\nconst decodeTransportValueAt = (value, path, encodedDatePaths) => {\n\tif (encodedDatePaths.has(pathKey(path))) return Schema.decodeUnknownSync(Schema.DateFromMillis)(value);\n\tif (globalThis.Array.isArray(value)) return value.map((item, index) => decodeTransportValueAt(item, [...path, index], encodedDatePaths));\n\tif (Predicate.isNull(value) || Predicate.isString(value) || Predicate.isNumber(value) || Predicate.isBoolean(value)) return value;\n\treturn Object.fromEntries(Object.entries(value).map(([key, item]) => [key, decodeTransportValueAt(item, [...path, key], encodedDatePaths)]));\n};\nconst decodeTransportValue = (value, datePaths) => decodeTransportValueAt(value, [], new Set(datePaths.map(pathKey)));\nconst decodeTransportObject = (value, datePaths) => {\n\tconst encodedDatePaths = new Set(datePaths.map(pathKey));\n\treturn Object.fromEntries(Object.entries(value).map(([key, child]) => [key, decodeTransportValueAt(child, [key], encodedDatePaths)]));\n};\n//#endregion\nexport { decodeTransportValue as a, decodeTransportObject as i, datePathsOf as n, encodeTransportObject as o, datePathsOfObject as r, encodeTransportValue as s, TransportValueSchema as t };\n\n//# sourceMappingURL=value-Briqf-Ua.js.map","import { i as decodeTransportObject } from \"../value-Briqf-Ua.js\";\nimport { Brand, Effect, Effectable, Function, Option, Predicate, Schema } from \"effect\";\n//#region src/runtime/result.ts\nconst ResultTypeId = Symbol.for(\"ignotum/runtime/result/Result\");\nconst CompletedResultTypeId = Symbol.for(\"ignotum/runtime/result/Completed\");\nconst PendingResultTypeId = Symbol.for(\"ignotum/runtime/result/Pending\");\nconst ErrorBrand = \"ignotum/error\";\nconst makeErrorValue = Brand.nominal();\nconst ErrorValueSchema = Schema.StructWithRest(Schema.Struct({ _tag: Schema.String }), [Schema.Record(Schema.String, Schema.Json)]).pipe(Schema.brand(ErrorBrand));\nvar InternalServerErrorCause = class extends Schema.TaggedError()(\"InternalServerError\", { requestId: Schema.String }) {};\nconst InternalServerError = InternalServerErrorCause;\nconst InternalServerErrorSchema = InternalServerErrorCause.pipe(Schema.brand(ErrorBrand));\nconst effectOf = (value) => Predicate.hasProperty(value, ResultTypeId) ? value[ResultTypeId] : Effect.succeed(value);\nfunction makeResultEffectBase() {\n\tconst Base = function() {};\n\tBase.prototype = Effectable.Prototype({\n\t\tlabel: \"IgnotumResult\",\n\t\tevaluate() {\n\t\t\treturn this[ResultTypeId];\n\t\t}\n\t});\n\treturn Base;\n}\nconst ResultEffectBase = makeResultEffectBase();\nvar ResultOperation = class ResultOperation extends ResultEffectBase {\n\t[ResultTypeId];\n\tconstructor(effect, completed) {\n\t\tsuper();\n\t\tthis[ResultTypeId] = effect;\n\t\tif (completed !== void 0) Object.defineProperty(this, CompletedResultTypeId, { value: completed });\n\t}\n\tcatch(cases) {\n\t\tconst effectCases = {};\n\t\tfor (const [tag, handler] of Object.entries(cases)) if (Predicate.isFunction(handler)) effectCases[tag] = (failure) => effectOf(handler(failure));\n\t\tconst runtimeEffect = this[ResultTypeId];\n\t\tconst caught = Effect.catchTags(runtimeEffect, effectCases);\n\t\treturn new ResultOperation(caught);\n\t}\n};\nvar PendingQueryResult = class {\n\t[PendingResultTypeId] = PendingResultTypeId;\n};\nconst inspectResult = (value) => {\n\tif (!Predicate.hasProperty(value, CompletedResultTypeId)) return void 0;\n\treturn value[CompletedResultTypeId];\n};\nconst effectFromResult = (result) => result[ResultTypeId];\nconst resultFromEffect = (effect) => new ResultOperation(effect);\nconst isFailureResult = (result) => Predicate.hasProperty(result, CompletedResultTypeId) && Predicate.isObject(result[CompletedResultTypeId]) && Predicate.hasProperty(result[CompletedResultTypeId], \"type\") && result[CompletedResultTypeId].type === \"Failure\";\nconst succeed = (value) => new ResultOperation(Effect.succeed(value), {\n\ttype: \"Success\",\n\tvalue\n});\nconst fail = (error) => new ResultOperation(Effect.fail(error), {\n\ttype: \"Failure\",\n\terror\n});\nconst tryResult = (body) => {\n\treturn new ResultOperation(Effect.gen(body));\n};\nconst match = Function.dual(2, (result, matchers) => {\n\tif (result instanceof PendingQueryResult) {\n\t\tif (matchers.pending === void 0) throw new Error(\"A pending Result requires a pending matcher.\");\n\t\treturn matchers.pending();\n\t}\n\tif (!Predicate.hasProperty(result, ResultTypeId)) throw new Error(\"Unknown Result implementation.\");\n\tconst inspected = inspectResult(result);\n\tif (inspected?.type === \"Success\") {\n\t\tconst value = inspected.value;\n\t\treturn matchers.value(value);\n\t}\n\tif (!isFailureResult(result)) throw new Error(\"Unknown or incomplete Result operation.\");\n\tconst error = result[CompletedResultTypeId].error;\n\tif (error._tag === \"InternalServerError\") {\n\t\tconst internalError = Schema.decodeUnknownSync(InternalServerErrorSchema)(error);\n\t\tconst handler = matchers.internalError;\n\t\tif (handler === void 0) throw internalError;\n\t\treturn handler(internalError);\n\t}\n\tconst errorMatcher = matchers.error;\n\tif (errorMatcher === void 0) throw new Error(`No matcher was provided for ${error._tag}.`);\n\tif (Predicate.isFunction(errorMatcher)) return errorMatcher(error);\n\tconst handlers = errorMatcher;\n\tconst handler = Object.hasOwn(handlers, error._tag) ? handlers[error._tag] : void 0;\n\tif (handler === void 0) throw new Error(`No matcher was provided for ${error._tag}.`);\n\treturn handler(error);\n});\nconst pending = () => new PendingQueryResult();\nconst failureFromWire = (error, datePaths = []) => {\n\tconst internalError = Schema.decodeUnknownOption(InternalServerErrorSchema)(error);\n\tif (Option.isSome(internalError)) return fail(internalError.value);\n\tconst decoded = Schema.decodeUnknownOption(ErrorValueSchema)(error);\n\tif (Option.isNone(decoded)) throw new Error(\"The server returned an invalid application error.\");\n\tconst restored = decodeTransportObject(decoded.value, datePaths);\n\treturn fail(makeErrorValue({\n\t\t...restored,\n\t\t_tag: decoded.value._tag\n\t}));\n};\nconst documentNotFound = (table, id) => Brand.nominal()({\n\t_tag: \"DocumentNotFound\",\n\ttable,\n\tid\n});\nconst Result = {\n\tfail,\n\tmatch,\n\tsucceed,\n\ttry: tryResult\n};\n//#endregion\nexport { ErrorBrand, ErrorValueSchema, InternalServerError, InternalServerErrorSchema, Result, documentNotFound, effectFromResult, failureFromWire, inspectResult, match, pending, resultFromEffect };\n\n//# sourceMappingURL=result.js.map"],"mappings":"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"}
|