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.
Files changed (64) hide show
  1. package/README.md +23 -7
  2. package/dist/cli/bin.mjs +32313 -751
  3. package/dist/cli/bin.mjs.map +1 -1
  4. package/dist/runtime/{api-Cpx57mk3.d.ts → api-D2bsAz4T.d.ts} +3 -2
  5. package/dist/runtime/{api-BXXIZc_Q.js → api-DtX8qPrq.js} +58 -27
  6. package/dist/runtime/api-DtX8qPrq.js.map +1 -0
  7. package/dist/runtime/client.d.ts +11 -4
  8. package/dist/runtime/client.js +343 -79
  9. package/dist/runtime/client.js.map +1 -1
  10. package/dist/runtime/{result-B2W-z2wG.js → descriptor-t6BOEGw9-BTHR-ZMv.js} +119 -4
  11. package/dist/runtime/descriptor-t6BOEGw9-BTHR-ZMv.js.map +1 -0
  12. package/dist/runtime/id-Btwac71X-B9OeBzvq.d.ts +9 -0
  13. package/dist/runtime/id-D570vudg.js +26 -0
  14. package/dist/runtime/id-D570vudg.js.map +1 -0
  15. package/dist/runtime/{index-BgWROoyk.d.ts → index-Dl_VQGmA.d.ts} +114 -31
  16. package/dist/runtime/internal/api.d.ts +1 -1
  17. package/dist/runtime/internal/api.js +1 -1
  18. package/dist/runtime/internal/host.d.ts +44 -0
  19. package/dist/runtime/internal/host.js +213 -0
  20. package/dist/runtime/internal/host.js.map +1 -0
  21. package/dist/runtime/internal/server.d.ts +1 -1
  22. package/dist/runtime/internal/server.js +1 -1
  23. package/dist/runtime/internal/types.d.ts +1 -1
  24. package/dist/runtime/internal/types.js +1 -1
  25. package/dist/runtime/{result-C1ZdsM6Y.d.ts → result-BgcHn25t.d.ts} +21 -6
  26. package/dist/runtime/schema-B-jMZEbs.js +227 -0
  27. package/dist/runtime/schema-B-jMZEbs.js.map +1 -0
  28. package/dist/runtime/server.d.ts +2 -2
  29. package/dist/runtime/server.js +2 -2
  30. package/package.json +15 -5
  31. package/src/cli/agent-files.ts +6 -2
  32. package/src/cli/app-configuration.ts +135 -0
  33. package/src/cli/bin.ts +24 -1
  34. package/src/cli/build/artifact.ts +95 -0
  35. package/src/cli/build/client.ts +103 -0
  36. package/src/cli/build/server.ts +526 -0
  37. package/src/cli/client-config.ts +141 -0
  38. package/src/cli/client-entry.ts +152 -0
  39. package/src/cli/client-plugin.ts +86 -16
  40. package/src/cli/codegen.ts +5 -5
  41. package/src/cli/command.ts +41 -9
  42. package/src/cli/control-client.ts +343 -0
  43. package/src/cli/deploy.ts +217 -0
  44. package/src/cli/dev.ts +43 -108
  45. package/src/cli/module-boundaries.ts +183 -0
  46. package/src/cli/{new-project.ts → new-app.ts} +86 -86
  47. package/src/cli/package-manager.ts +9 -9
  48. package/src/client/app.ts +15 -0
  49. package/src/client/errors.ts +1 -17
  50. package/src/client/index.ts +2 -0
  51. package/src/client/sync.ts +172 -120
  52. package/src/dev-runtime/database.ts +253 -96
  53. package/src/dev-runtime/dev-database.ts +14 -14
  54. package/src/dev-runtime/functions.ts +57 -88
  55. package/src/dev-runtime/id.ts +2 -10
  56. package/src/dev-runtime/migrations.ts +68 -0
  57. package/src/dev-runtime/sync.ts +266 -83
  58. package/src/internal/function-definition.ts +77 -0
  59. package/src/internal/host.ts +1 -0
  60. package/src/internal/http-paths.ts +3 -1
  61. package/dist/runtime/api-BXXIZc_Q.js.map +0 -1
  62. package/dist/runtime/result-B2W-z2wG.js.map +0 -1
  63. package/dist/runtime/schema-CNEVLF7D.js +0 -116
  64. package/dist/runtime/schema-CNEVLF7D.js.map +0 -1
@@ -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 { QueryInvalidation } from "@ignotum/runtime/sync";
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<void>();
78
+ const pubsub = yield* PubSub.unbounded<QueryInvalidationEvent>();
79
+ const latestRevision = yield* Ref.make(AppStateRevision.make(0));
57
80
  return QueryInvalidation.of({
58
- publish: PubSub.publish(pubsub, undefined),
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
- const operationForQuery = (subscriptionId: SubscriptionId): Operation => ({
65
- type: "Query",
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
- if (!(yield* isActive(subscriptionId, subscription))) return;
134
-
135
- const operation = operationForQuery(subscriptionId);
240
+ const operation = operationForSubscription(subscriptionId);
136
241
  const deliver = (message: ServerMessage) => sendIfActive(subscriptionId, subscription, message);
137
- const prepared =
138
- previouslyPrepared ??
139
- (yield* runtime.prepare(subscription.function, "Query", subscription.args).pipe(
140
- Effect.catchTags({
141
- FunctionUnavailable: (error) => sendResolutionError(operation, error, deliver),
142
- InvalidArguments: (error) => sendResolutionError(operation, error, deliver),
143
- UnknownFunction: (error) => sendResolutionError(operation, error, deliver),
144
- WrongFunctionKind: (error) => sendResolutionError(operation, error, deliver),
145
- }),
146
- ));
147
- if (prepared === undefined) return;
148
-
149
- const result = yield* prepared.execute;
150
- yield* deliver({
151
- type: "QuerySnapshot",
152
- id: subscriptionId,
153
- result,
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
- querySemaphore
163
- .withPermits(
164
- subscriptionId,
165
- 1,
166
- )(executeQuery(subscriptionId, subscription, previouslyPrepared))
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
- FiberSet.run(invocationFibers),
174
- Effect.asVoid,
175
- );
292
+ ),
293
+ FiberSet.run(invocationFibers),
294
+ Effect.asVoid,
295
+ );
296
+ };
176
297
 
177
- const refresh = Effect.fn("SyncServer.refresh")(function* () {
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(refresh),
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 = operationForQuery(message.id);
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 = { args: message.args, function: message.function };
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 handleMutate = Effect.fn("SyncServer.handleMutate")(function* (
227
- message: Extract<ClientMessage, { readonly type: "Mutate" }>,
364
+ const handleInvoke = Effect.fn("SyncServer.handleInvoke")(function* (
365
+ message: Extract<ClientMessage, { readonly type: "Invoke" }>,
228
366
  ) {
229
- const operation: Operation = { type: "Mutate", id: message.id };
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
- yield* prepared.execute.pipe(
244
- Effect.flatMap((result: WireResult) => {
245
- const response = send({ type: "MutationResult", id: message.id, result });
246
- return result.type === "Success"
247
- ? response.pipe(Effect.ensuring(invalidation.publish))
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 "Mutate":
279
- yield* handleMutate(message);
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
- server: ViteDevServer,
301
- projectDirectory: string,
302
- databasePath: string,
303
- ) => {
304
- const databaseLayer = LocalDatabase.layer.pipe(
305
- Layer.provide(Layer.merge(idGeneratorLayer, SqliteClient.layer({ filename: databasePath }))),
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, projectDirectory).pipe(Layer.provide(NodeServices.layer)),
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(projectDirectory, "server");
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(projectDirectory).pipe(
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): (projectDirectory: string) => Plugin;
419
- (projectDirectory: string, databasePath: string): Plugin;
420
- } = Function.dual(2, (projectDirectory: string, databasePath: string): Plugin => ({
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, projectDirectory, databasePath));
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 = `${ignotumPathPrefix}/sync`;
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":";;AAEA,MAAM,uBAAuB,OAAO,cAAc,OAAO,MAAM;CAC9D,OAAO;CACP,OAAO;CACP,OAAO;CACP,OAAO;CACP,OAAO;CACP,OAAO,MAAM,oBAAoB;CACjC,OAAO,OAAO,OAAO,QAAQ,OAAO,YAAY,oBAAoB,CAAC;AACtE,CAAC,CAAC;AACF,MAAM,wBAAwB,UAAU;CACvC,IAAI,UAAU,OAAO,KAAK,GAAG,OAAO,OAAO,WAAW,OAAO,cAAc,CAAC,CAAC,KAAK;CAClF,IAAI,WAAW,MAAM,QAAQ,KAAK,GAAG,OAAO,MAAM,IAAI,oBAAoB;CAC1E,IAAI,UAAU,SAAS,KAAK,GAAG,OAAO,OAAO,WAAW,OAAO,MAAM,CAAC,CAAC,KAAK;CAC5E,IAAI,UAAU,OAAO,KAAK,KAAK,UAAU,SAAS,KAAK,KAAK,UAAU,UAAU,KAAK,GAAG,OAAO;CAC/F,OAAO,OAAO,YAAY,OAAO,QAAQ,KAAK,CAAC,CAAC,SAAS,CAAC,KAAK,WAAW,UAAU,KAAK,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,qBAAqB,KAAK,CAAC,CAAC,CAAC,CAAC;AACxI;AACA,MAAM,yBAAyB,UAAU,OAAO,kBAAkB,OAAO,UAAU,CAAC,CAAC,qBAAqB,OAAO,kBAAkB,oBAAoB,CAAC,CAAC,KAAK,CAAC,CAAC;AAoBhK,MAAM,WAAW,SAAS,KAAK,UAAU,IAAI;AAC7C,MAAM,0BAA0B,OAAO,MAAM,qBAAqB;CACjE,IAAI,iBAAiB,IAAI,QAAQ,IAAI,CAAC,GAAG,OAAO,OAAO,kBAAkB,OAAO,cAAc,CAAC,CAAC,KAAK;CACrG,IAAI,WAAW,MAAM,QAAQ,KAAK,GAAG,OAAO,MAAM,KAAK,MAAM,UAAU,uBAAuB,MAAM,CAAC,GAAG,MAAM,KAAK,GAAG,gBAAgB,CAAC;CACvI,IAAI,UAAU,OAAO,KAAK,KAAK,UAAU,SAAS,KAAK,KAAK,UAAU,SAAS,KAAK,KAAK,UAAU,UAAU,KAAK,GAAG,OAAO;CAC5H,OAAO,OAAO,YAAY,OAAO,QAAQ,KAAK,CAAC,CAAC,KAAK,CAAC,KAAK,UAAU,CAAC,KAAK,uBAAuB,MAAM,CAAC,GAAG,MAAM,GAAG,GAAG,gBAAgB,CAAC,CAAC,CAAC;AAC5I;AACA,MAAM,wBAAwB,OAAO,cAAc,uBAAuB,OAAO,CAAC,GAAG,IAAI,IAAI,UAAU,IAAI,OAAO,CAAC,CAAC;AACpH,MAAM,yBAAyB,OAAO,cAAc;CACnD,MAAM,mBAAmB,IAAI,IAAI,UAAU,IAAI,OAAO,CAAC;CACvD,OAAO,OAAO,YAAY,OAAO,QAAQ,KAAK,CAAC,CAAC,KAAK,CAAC,KAAK,WAAW,CAAC,KAAK,uBAAuB,OAAO,CAAC,GAAG,GAAG,gBAAgB,CAAC,CAAC,CAAC;AACrI;;;AC9CA,MAAM,eAAe,OAAO,IAAI,+BAA+B;AAC/D,MAAM,wBAAwB,OAAO,IAAI,kCAAkC;AAC3E,MAAM,sBAAsB,OAAO,IAAI,gCAAgC;AACvE,MAAM,aAAa;AACnB,MAAM,iBAAiB,MAAM,QAAQ;AACrC,MAAM,mBAAmB,OAAO,eAAe,OAAO,OAAO,EAAE,MAAM,OAAO,OAAO,CAAC,GAAG,CAAC,OAAO,OAAO,OAAO,QAAQ,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,OAAO,MAAM,UAAU,CAAC;AACjK,IAAI,2BAA2B,cAAc,OAAO,YAAY,CAAC,CAAC,uBAAuB,EAAE,WAAW,OAAO,OAAO,CAAC,CAAC,CAAC,CAAC;AAExH,MAAM,4BAA4B,yBAAyB,KAAK,OAAO,MAAM,UAAU,CAAC;AACxF,MAAM,YAAY,UAAU,UAAU,YAAY,OAAO,YAAY,IAAI,MAAM,gBAAgB,OAAO,QAAQ,KAAK;AACnH,SAAS,uBAAuB;CAC/B,MAAM,OAAO,WAAW,CAAC;CACzB,KAAK,YAAY,WAAW,UAAU;EACrC,OAAO;EACP,WAAW;GACV,OAAO,KAAK;EACb;CACD,CAAC;CACD,OAAO;AACR;AACA,MAAM,mBAAmB,qBAAqB;AAC9C,IAAI,kBAAkB,MAAM,wBAAwB,iBAAiB;CACpE,CAAC;CACD,YAAY,QAAQ,WAAW;EAC9B,MAAM;EACN,KAAK,gBAAgB;EACrB,IAAI,cAAc,KAAK,GAAG,OAAO,eAAe,MAAM,uBAAuB,EAAE,OAAO,UAAU,CAAC;CAClG;CACA,MAAM,OAAO;EACZ,MAAM,cAAc,CAAC;EACrB,KAAK,MAAM,CAAC,KAAK,YAAY,OAAO,QAAQ,KAAK,GAAG,IAAI,UAAU,WAAW,OAAO,GAAG,YAAY,QAAQ,YAAY,SAAS,QAAQ,OAAO,CAAC;EAChJ,MAAM,gBAAgB,KAAK;EAC3B,MAAM,SAAS,OAAO,UAAU,eAAe,WAAW;EAC1D,OAAO,IAAI,gBAAgB,MAAM;CAClC;AACD;AACA,IAAI,qBAAqB,MAAM;CAC9B,CAAC,uBAAuB;AACzB;AACA,MAAM,iBAAiB,UAAU;CAChC,IAAI,CAAC,UAAU,YAAY,OAAO,qBAAqB,GAAG,OAAO,KAAK;CACtE,OAAO,MAAM;AACd;AAGA,MAAM,mBAAmB,WAAW,UAAU,YAAY,QAAQ,qBAAqB,KAAK,UAAU,SAAS,OAAO,sBAAsB,KAAK,UAAU,YAAY,OAAO,wBAAwB,MAAM,KAAK,OAAO,sBAAsB,CAAC,SAAS;AACxP,MAAM,WAAW,UAAU,IAAI,gBAAgB,OAAO,QAAQ,KAAK,GAAG;CACrE,MAAM;CACN;AACD,CAAC;AACD,MAAM,QAAQ,UAAU,IAAI,gBAAgB,OAAO,KAAK,KAAK,GAAG;CAC/D,MAAM;CACN;AACD,CAAC;AACD,MAAM,aAAa,SAAS;CAC3B,OAAO,IAAI,gBAAgB,OAAO,IAAI,IAAI,CAAC;AAC5C;AACA,MAAM,QAAQ,SAAS,KAAK,IAAI,QAAQ,aAAa;CACpD,IAAI,kBAAkB,oBAAoB;EACzC,IAAI,SAAS,YAAY,KAAK,GAAG,MAAM,IAAI,MAAM,8CAA8C;EAC/F,OAAO,SAAS,QAAQ;CACzB;CACA,IAAI,CAAC,UAAU,YAAY,QAAQ,YAAY,GAAG,MAAM,IAAI,MAAM,gCAAgC;CAClG,MAAM,YAAY,cAAc,MAAM;CACtC,IAAI,WAAW,SAAS,WAAW;EAClC,MAAM,QAAQ,UAAU;EACxB,OAAO,SAAS,MAAM,KAAK;CAC5B;CACA,IAAI,CAAC,gBAAgB,MAAM,GAAG,MAAM,IAAI,MAAM,yCAAyC;CACvF,MAAM,QAAQ,OAAO,sBAAsB,CAAC;CAC5C,IAAI,MAAM,SAAS,uBAAuB;EACzC,MAAM,gBAAgB,OAAO,kBAAkB,yBAAyB,CAAC,CAAC,KAAK;EAC/E,MAAM,UAAU,SAAS;EACzB,IAAI,YAAY,KAAK,GAAG,MAAM;EAC9B,OAAO,QAAQ,aAAa;CAC7B;CACA,MAAM,eAAe,SAAS;CAC9B,IAAI,iBAAiB,KAAK,GAAG,MAAM,IAAI,MAAM,+BAA+B,MAAM,KAAK,EAAE;CACzF,IAAI,UAAU,WAAW,YAAY,GAAG,OAAO,aAAa,KAAK;CACjE,MAAM,WAAW;CACjB,MAAM,UAAU,OAAO,OAAO,UAAU,MAAM,IAAI,IAAI,SAAS,MAAM,QAAQ,KAAK;CAClF,IAAI,YAAY,KAAK,GAAG,MAAM,IAAI,MAAM,+BAA+B,MAAM,KAAK,EAAE;CACpF,OAAO,QAAQ,KAAK;AACrB,CAAC;AACD,MAAM,gBAAgB,IAAI,mBAAmB;AAC7C,MAAM,mBAAmB,OAAO,YAAY,CAAC,MAAM;CAClD,MAAM,gBAAgB,OAAO,oBAAoB,yBAAyB,CAAC,CAAC,KAAK;CACjF,IAAI,OAAO,OAAO,aAAa,GAAG,OAAO,KAAK,cAAc,KAAK;CACjE,MAAM,UAAU,OAAO,oBAAoB,gBAAgB,CAAC,CAAC,KAAK;CAClE,IAAI,OAAO,OAAO,OAAO,GAAG,MAAM,IAAI,MAAM,mDAAmD;CAC/F,MAAM,WAAW,sBAAsB,QAAQ,OAAO,SAAS;CAC/D,OAAO,KAAK,eAAe;EAC1B,GAAG;EACH,MAAM,QAAQ,MAAM;CACrB,CAAC,CAAC;AACH;AAMA,MAAM,SAAS;CACd;CACA;CACA;CACA,KAAK;AACN"}