ignotum 0.0.16 → 0.0.17

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 (123) hide show
  1. package/README.md +6 -6
  2. package/dist/cli/bin.mjs +13256 -2688
  3. package/dist/cli/bin.mjs.map +1 -1
  4. package/dist/platform/_headers +3 -0
  5. package/dist/platform/_ignotum/v1.0/client.js +12 -0
  6. package/dist/runtime/{api-B4fwp5a2.d.ts → api-BnUKx9cj-D49Tf0rX.d.ts} +4 -3
  7. package/dist/runtime/api-C-tltz6s.js +31 -0
  8. package/dist/runtime/api-C-tltz6s.js.map +1 -0
  9. package/dist/runtime/artifact-BB5qzoa6.js +42 -0
  10. package/dist/runtime/artifact-BB5qzoa6.js.map +1 -0
  11. package/dist/runtime/{bootstrap-BTFScKAc.d.ts → bootstrap-DjTwGJao-DBx5zdFI.d.ts} +64 -64
  12. package/dist/runtime/{bootstrap-BISQSn_O.js → bootstrap-DlNIfH-r.js} +9 -9
  13. package/dist/runtime/bootstrap-DlNIfH-r.js.map +1 -0
  14. package/dist/runtime/client.d.ts +24 -20
  15. package/dist/runtime/client.js +9 -9
  16. package/dist/runtime/client.js.map +1 -1
  17. package/dist/runtime/id-BI08JkmR.d.ts +1 -0
  18. package/dist/runtime/{id--1m0NuUL.js → id-BrEnxY-r.js} +118 -53
  19. package/dist/runtime/id-BrEnxY-r.js.map +1 -0
  20. package/dist/runtime/{image-Djtjy4Z8.js → image-gofzZeCm.js} +2 -2
  21. package/dist/runtime/image-gofzZeCm.js.map +1 -0
  22. package/dist/runtime/{index-D4seNHlX.d.ts → index-Biaw5vdF.d.ts} +2 -2
  23. package/dist/runtime/internal/api.d.ts +1 -1
  24. package/dist/runtime/internal/api.js +1 -30
  25. package/dist/runtime/internal/bootstrap.d.ts +1 -1
  26. package/dist/runtime/internal/bootstrap.js +1 -1
  27. package/dist/runtime/internal/client.d.ts +2 -2
  28. package/dist/runtime/internal/client.js +4 -4
  29. package/dist/runtime/internal/client.js.map +1 -1
  30. package/dist/runtime/internal/host.d.ts +4 -4
  31. package/dist/runtime/internal/host.js +4 -4
  32. package/dist/runtime/internal/routes.d.ts +1 -1
  33. package/dist/runtime/internal/routes.js +1 -1
  34. package/dist/runtime/internal/server.d.ts +3 -2
  35. package/dist/runtime/internal/server.js +2 -2
  36. package/dist/runtime/internal/server.js.map +1 -1
  37. package/dist/runtime/internal/types.d.ts +2 -2
  38. package/dist/runtime/internal/types.js +1 -1
  39. package/dist/runtime/{pagination-D3qd6s9N.js → pagination--f4kMKf6.js} +2 -2
  40. package/dist/runtime/{pagination-D3qd6s9N.js.map → pagination--f4kMKf6.js.map} +1 -1
  41. package/dist/runtime/pagination-BI08JkmR.d.ts +1 -0
  42. package/dist/runtime/{router-BSBI1oN1.js → router-C1eC9yy5.js} +462 -419
  43. package/dist/runtime/router-C1eC9yy5.js.map +1 -0
  44. package/dist/runtime/routes-DnU39R7c.js +152 -0
  45. package/dist/runtime/routes-DnU39R7c.js.map +1 -0
  46. package/dist/runtime/{schema-D1wOqiNH.js → schema-BSjepoNF.js} +271 -6
  47. package/dist/runtime/schema-BSjepoNF.js.map +1 -0
  48. package/dist/runtime/server.d.ts +5 -4
  49. package/dist/runtime/server.js +3 -3
  50. package/dist/runtime/server.js.map +1 -1
  51. package/dist/runtime/{sync-DzUwA8W9.js → sync-BwgS19Xy.js} +4 -16
  52. package/dist/runtime/sync-BwgS19Xy.js.map +1 -0
  53. package/dist/runtime/{sync-D-GK2sv9.d.ts → sync-By2hX5ev.d.ts} +1 -2
  54. package/dist/runtime/{types-DeCCyqLU-BIm7rU-0.d.ts → types-DeCCyqLU-CHx7KFtx.d.ts} +2 -2
  55. package/package.json +8 -2
  56. package/src/cli/agent-files.ts +2 -0
  57. package/src/cli/build/asset-names.ts +190 -0
  58. package/src/cli/build/managed-client.ts +151 -81
  59. package/src/cli/build/managed-server.ts +4 -4
  60. package/src/cli/build/managed.ts +5 -6
  61. package/src/cli/command.ts +6 -15
  62. package/src/cli/control-client.ts +7 -9
  63. package/src/cli/deploy.ts +45 -15
  64. package/src/cli/dev.ts +50 -99
  65. package/src/cli/image-assets.ts +5 -2
  66. package/src/cli/managed-client-boundaries.ts +6 -6
  67. package/src/cli/managed-dev-platform.ts +52 -66
  68. package/src/cli/managed-exports.ts +5 -66
  69. package/src/cli/new-app.ts +7 -2
  70. package/src/cli/upload-journal.ts +130 -0
  71. package/src/client/bootstrap.ts +1 -110
  72. package/src/client/errors.ts +1 -70
  73. package/src/client/files.ts +1 -233
  74. package/src/client/hooks.ts +1 -367
  75. package/src/client/id.ts +1 -263
  76. package/src/client/image.ts +1 -28
  77. package/src/client/index.ts +1 -126
  78. package/src/client/jsx-dev-runtime.ts +1 -2
  79. package/src/client/jsx-runtime.ts +1 -2
  80. package/src/client/managed-client.ts +1 -729
  81. package/src/client/managed-upgrade.ts +1 -283
  82. package/src/client/page-observers.ts +1 -77
  83. package/src/client/query.ts +1 -17
  84. package/src/client/recovery-journal.ts +1 -195
  85. package/src/client/route-boundaries.ts +1 -184
  86. package/src/client/router-history.ts +1 -152
  87. package/src/client/router-store.ts +1 -644
  88. package/src/client/router.ts +1 -324
  89. package/src/client/routes.ts +1 -28
  90. package/src/client/sync.ts +1 -286
  91. package/src/dev-runtime/id.ts +1 -1
  92. package/src/dev-runtime/managed-functions.ts +10 -18
  93. package/src/dev-runtime/managed-sync.ts +16 -16
  94. package/src/dev-runtime/sync.ts +6 -4
  95. package/src/internal/api.ts +1 -156
  96. package/src/internal/client.ts +1 -186
  97. package/src/internal/host.ts +1 -1
  98. package/src/internal/http-paths.ts +1 -4
  99. package/src/internal/routes.ts +1 -45
  100. package/src/internal/server.ts +1 -3
  101. package/src/internal/types.ts +1 -2
  102. package/src/server/index.ts +1 -27
  103. package/dist/cli/managed-release-WHYLZwaS.mjs +0 -10902
  104. package/dist/cli/managed-release-WHYLZwaS.mjs.map +0 -1
  105. package/dist/cli/managed-release.d.mts +0 -1
  106. package/dist/cli/managed-release.mjs +0 -14
  107. package/dist/cli/managed-release.mjs.map +0 -1
  108. package/dist/runtime/bootstrap-BISQSn_O.js.map +0 -1
  109. package/dist/runtime/descriptor-CTY4mtwS-cS43EbwS.js +0 -269
  110. package/dist/runtime/descriptor-CTY4mtwS-cS43EbwS.js.map +0 -1
  111. package/dist/runtime/id--1m0NuUL.js.map +0 -1
  112. package/dist/runtime/id-CBOt2kDo.d.ts +0 -1
  113. package/dist/runtime/identity-QjtJRxBD.d.ts +0 -2
  114. package/dist/runtime/image-Djtjy4Z8.js.map +0 -1
  115. package/dist/runtime/internal/api.js.map +0 -1
  116. package/dist/runtime/pagination-CBOt2kDo.d.ts +0 -1
  117. package/dist/runtime/router-BSBI1oN1.js.map +0 -1
  118. package/dist/runtime/routes-Ce8TVP-T.js +0 -690
  119. package/dist/runtime/routes-Ce8TVP-T.js.map +0 -1
  120. package/dist/runtime/schema-D1wOqiNH.js.map +0 -1
  121. package/dist/runtime/sync-DzUwA8W9.js.map +0 -1
  122. package/src/cli/managed-release-bin.ts +0 -13
  123. package/src/cli/managed-release.ts +0 -260
@@ -3,17 +3,16 @@ import { Crypto, Effect, Encoding, FileSystem, Path, Predicate, Schema } from "e
3
3
  import type { ViteDevServer } from "vite";
4
4
  import { parseSync } from "oxc-parser";
5
5
  import { prepareManagedExecution, type ManagedExecution } from "@ignotum/runtime/quickjs";
6
+ import type { BundledGuest } from "@ignotum/runtime/managed-graph";
6
7
  import { apiFunctionParts } from "@ignotum/contracts/runtime/sync";
7
8
  import { getFunctionEnvironment } from "@ignotum/contracts/runtime/schema";
8
9
  import * as serverNamespace from "../server/index.js";
9
10
  import * as internalServerNamespace from "../internal/server.js";
10
11
  import * as apiNamespace from "../internal/api.js";
11
- import { validateManagedReleaseGraph } from "@ignotum/versions/managed-release";
12
12
  import { descriptorCodec } from "@ignotum/runtime/schema";
13
13
  import { SchemaSnapshotField } from "@ignotum/contracts/version";
14
14
  import { attachValueDescriptor, defineEnv, emptyEnv } from "@ignotum/contracts/schema";
15
15
  import type { ManagedServerBuildResult } from "../cli/build/managed-server.js";
16
- import type { buildManagedReleaseGraph } from "../cli/managed-release.js";
17
16
 
18
17
  type DevelopmentModule = Awaited<ReturnType<ViteDevServer["ssrLoadModule"]>>;
19
18
  const literal = Schema.encodeSync(Schema.fromJsonString(Schema.String));
@@ -39,8 +38,8 @@ export interface ManagedFunctionLoader {
39
38
  }
40
39
 
41
40
  export interface ManagedFunctionSelection {
42
- readonly guest: Effect.Success<ReturnType<typeof buildManagedReleaseGraph>>;
43
- readonly release: ManagedExecution["release"];
41
+ readonly guest: BundledGuest;
42
+ readonly platform: ManagedExecution["platform"];
44
43
  readonly requirements: ManagedExecution["requirements"];
45
44
  }
46
45
 
@@ -70,18 +69,14 @@ export const createManagedFunctionLoader = Effect.fn("ManagedFunctions.createLoa
70
69
  ["ignotum/internal/server", internalServerNamespace],
71
70
  ["ignotum/internal/api", apiNamespace],
72
71
  ]);
73
- const guest = yield* validateManagedReleaseGraph(
74
- selection.guest.manifestBytes,
75
- [...selection.guest.files].map(([path, bytes]) => ({ path, bytes })),
76
- );
72
+ const guest = selection.guest;
77
73
  const bridges = new Map<string, string>();
78
74
  for (const [specifier, namespace] of namespaces) {
79
- const entry = guest.manifest.modules.find(
80
- (module) => module.path === guest.manifest.entries[specifier],
81
- );
82
- if (entry === undefined || entry.exports.some((name) => !Object.hasOwn(namespace, name))) {
75
+ const entry = guest.manifest.entries[specifier];
76
+ if (entry === undefined || guest.sources[entry] === undefined) {
83
77
  throw new Error(`The local SDK cannot supply managed entry ${specifier}.`);
84
78
  }
79
+ const exports = Object.keys(namespace);
85
80
  const filename = path.join(directory, `${encodeURIComponent(specifier)}.mjs`);
86
81
  const key = Symbol.for(filename);
87
82
  // A facade captures the existing SDK namespace so schemas and codecs retain their owner.
@@ -94,7 +89,7 @@ export const createManagedFunctionLoader = Effect.fn("ManagedFunctions.createLoa
94
89
  Effect.gen(function* () {
95
90
  const source =
96
91
  `const namespace = globalThis[Symbol.for(${literal(filename)})];\n` +
97
- entry.exports
92
+ exports
98
93
  .map(
99
94
  (name, index) =>
100
95
  `const binding${index} = namespace[${literal(name)}]; export { binding${index} as ${name} };`,
@@ -122,12 +117,9 @@ export const createManagedFunctionLoader = Effect.fn("ManagedFunctions.createLoa
122
117
  artifacts: build.artifacts,
123
118
  bytes: build.bytes,
124
119
  entry: build.server.schema.entry,
125
- release: selection.release,
120
+ platform: selection.platform,
126
121
  requirements: selection.requirements,
127
- guest: {
128
- manifestBytes: selection.guest.manifestBytes,
129
- files: [...selection.guest.files].map(([path, bytes]) => ({ path, bytes })),
130
- },
122
+ guest,
131
123
  },
132
124
  "schema",
133
125
  ).pipe(Effect.provideService(Crypto.Crypto, crypto));
@@ -1,8 +1,9 @@
1
1
  import { canonicalInvocationInput } from "@ignotum/contracts/runtime/hosted";
2
+ import { VersionId } from "@ignotum/contracts/runtime/identity";
2
3
  import { ManagedClientMessage, ManagedServerMessage } from "@ignotum/contracts/managed-sync";
3
4
  import {
4
- sameExecutionSelection,
5
- ExecutionSelection,
5
+ sameSelection,
6
+ ServingSelection,
6
7
  type RecoveryIdentity,
7
8
  type RecoverySessionId,
8
9
  } from "@ignotum/contracts/platform";
@@ -15,7 +16,8 @@ import { LocalApplicationFiles } from "./files.js";
15
16
  import { MutationReplay, QueryInvalidation, createLocalSession } from "./sync.js";
16
17
 
17
18
  export interface ManagedSyncOptions {
18
- readonly selection: () => ExecutionSelection;
19
+ readonly selection: () => ServingSelection;
20
+ readonly versionId?: VersionId;
19
21
  readonly loadModule?: ViteDevServer["ssrLoadModule"];
20
22
  readonly isServerDependency?: (file: string) => boolean;
21
23
  readonly beforeReload?: (file: string, event: "add" | "change" | "unlink") => Promise<void>;
@@ -37,7 +39,7 @@ export const runManagedSession = Effect.fn("ManagedLocalSync.runSession")(functi
37
39
  const write = yield* socket.writer;
38
40
  const writes = yield* Semaphore.make(1);
39
41
  const messages = yield* Semaphore.make(1);
40
- let selection: ExecutionSelection | undefined;
42
+ let selection: ServingSelection | undefined;
41
43
  let session: Effect.Success<ReturnType<typeof createLocalSession>> | undefined;
42
44
  let clientSessionId: RecoverySessionId | undefined;
43
45
  let expired = false;
@@ -69,8 +71,7 @@ export const runManagedSession = Effect.fn("ManagedLocalSync.runSession")(functi
69
71
  });
70
72
  const checkSelection = Effect.fn("ManagedLocalSync.checkSelection")(function* () {
71
73
  if (expired) return false;
72
- if (selection === undefined || sameExecutionSelection(selection, options.selection()))
73
- return true;
74
+ if (selection === undefined || sameSelection(selection, options.selection())) return true;
74
75
  expired = true;
75
76
  yield* send({ type: "UpgradeRequired", selection: options.selection() });
76
77
  yield* close;
@@ -107,12 +108,12 @@ export const runManagedSession = Effect.fn("ManagedLocalSync.runSession")(functi
107
108
  }>`SELECT input, prepared, clientSessionId, sessionEpoch, selection FROM managed_invocation_owners WHERE id = ${invocationId}`;
108
109
  const owns = (
109
110
  row: { clientSessionId: string; sessionEpoch: string; selection: string },
110
- original: ExecutionSelection,
111
+ original: ServingSelection,
111
112
  ) =>
112
113
  row.clientSessionId === clientSessionId &&
113
114
  row.sessionEpoch === identity.sessionEpoch &&
114
- sameExecutionSelection(
115
- Schema.decodeSync(Schema.fromJsonString(ExecutionSelection))(row.selection),
115
+ sameSelection(
116
+ Schema.decodeSync(Schema.fromJsonString(ServingSelection))(row.selection),
116
117
  original,
117
118
  );
118
119
  const outcome = Effect.fn("ManagedLocalSync.outcome")(function* (
@@ -167,17 +168,16 @@ export const runManagedSession = Effect.fn("ManagedLocalSync.runSession")(functi
167
168
  if (selection !== undefined)
168
169
  return yield* error("InvalidMessage", "Connect has already been accepted.");
169
170
  const current = options.selection();
170
- if (
171
- message.protocolVersion !== 1 ||
172
- !sameExecutionSelection(message.selection, current)
173
- ) {
171
+ if (message.protocolVersion !== 1 || !sameSelection(message.selection, current)) {
174
172
  yield* send({ type: "UpgradeRequired", selection: current });
175
173
  return;
176
174
  }
177
175
  if (!(yield* checkIdentity())) return;
178
176
  selection = current;
179
177
  clientSessionId = message.clientSessionId;
180
- session = yield* createLocalSession(current, identity, deliver);
178
+ const versionId =
179
+ options.versionId ?? VersionId.make(`dep_${current.appId.slice("app_".length)}`);
180
+ session = yield* createLocalSession(current, versionId, identity, deliver);
181
181
  yield* send({
182
182
  type: "Handshake",
183
183
  protocolVersion: 1,
@@ -195,7 +195,7 @@ export const runManagedSession = Effect.fn("ManagedLocalSync.runSession")(functi
195
195
  return yield* outcome(message.id, message.identity);
196
196
  if (message.type === "Invoke" || message.type === "Prepare") {
197
197
  const input = canonicalInvocationInput(
198
- selection.versionId,
198
+ options.versionId ?? VersionId.make(`dep_${selection.appId.slice("app_".length)}`),
199
199
  "Mutation",
200
200
  message.function,
201
201
  message.args,
@@ -218,7 +218,7 @@ export const runManagedSession = Effect.fn("ManagedLocalSync.runSession")(functi
218
218
  message.invocationId,
219
219
  );
220
220
  const encodedSelection = yield* Schema.encodeEffect(
221
- Schema.fromJsonString(ExecutionSelection),
221
+ Schema.fromJsonString(ServingSelection),
222
222
  )(selection).pipe(Effect.orDie);
223
223
  const inserted =
224
224
  yield* sql`INSERT OR IGNORE INTO managed_invocation_owners (id, input, prepared, clientSessionId, sessionEpoch, selection) VALUES (${message.invocationId}, ${input}, ${message.type === "Prepare" ? 1 : 0}, ${clientSessionId!}, ${identity.sessionEpoch}, ${encodedSelection}) RETURNING id`.pipe(
@@ -26,7 +26,8 @@ import {
26
26
  canonicalQueryKey,
27
27
  } from "@ignotum/contracts/runtime/hosted";
28
28
  import { SubscriptionId, type FunctionAddress } from "@ignotum/contracts/runtime/sync";
29
- import type { ExecutionSelection } from "@ignotum/contracts/platform";
29
+ import type { VersionId } from "@ignotum/contracts/runtime/identity";
30
+ import type { ServingSelection } from "@ignotum/contracts/platform";
30
31
  import {
31
32
  Effect,
32
33
  Clock,
@@ -216,7 +217,8 @@ const syncError = (code: LocalErrorCode, message: string, id: string): ManagedSe
216
217
 
217
218
  /** Executes admitted session commands directly; the transport owns framing and selection checks. */
218
219
  export const createLocalSession = Effect.fn("LocalSession.create")(function* (
219
- selection: ExecutionSelection,
220
+ selection: ServingSelection,
221
+ versionId: VersionId,
220
222
  identity: SessionState,
221
223
  send: (message: ManagedServerMessage) => Effect.Effect<void, Socket.SocketError>,
222
224
  ) {
@@ -405,7 +407,7 @@ export const createLocalSession = Effect.fn("LocalSession.create")(function* (
405
407
  args: message.args,
406
408
  function: message.function,
407
409
  grantId: yield* ids.generate(SubscriptionId),
408
- queryKey: canonicalQueryKey(selection.versionId, message.function, message.args),
410
+ queryKey: canonicalQueryKey(versionId, message.function, message.args),
409
411
  refreshGeneration: 0,
410
412
  };
411
413
  yield* Ref.update(subscriptions, HashMap.set(message.id, subscription));
@@ -449,7 +451,7 @@ export const createLocalSession = Effect.fn("LocalSession.create")(function* (
449
451
  }
450
452
 
451
453
  const input = canonicalInvocationInput(
452
- selection.versionId,
454
+ versionId,
453
455
  "Mutation",
454
456
  message.function,
455
457
  message.args,
@@ -1,156 +1 @@
1
- import { Predicate } from "effect";
2
- import type { Effect } from "effect";
3
-
4
- import type { ErrorValue, InternalServerError } from "@ignotum/contracts/runtime/result";
5
- import { FunctionAddress } from "@ignotum/contracts/runtime/sync";
6
- import type { FileValue } from "@ignotum/contracts/schema/file";
7
-
8
- const FunctionReferenceTypeId: unique symbol = Symbol.for("ignotum/internal/api/FunctionReference");
9
- declare const FunctionReferenceTypesTypeId: unique symbol;
10
-
11
- type FunctionKind = "Mutation" | "Query";
12
-
13
- export type MutationInput<Value> = Value extends FileValue
14
- ? Value | File
15
- : Value extends Date
16
- ? Value
17
- : Value extends ReadonlyArray<infer Item>
18
- ? ReadonlyArray<MutationInput<Item>>
19
- : Value extends object
20
- ? { readonly [Key in keyof Value]: MutationInput<Value[Key]> }
21
- : Value;
22
-
23
- export interface FunctionReference<
24
- Kind extends FunctionKind,
25
- Args,
26
- Success,
27
- Failure extends ErrorValue,
28
- > {
29
- readonly [FunctionReferenceTypeId]: FunctionAddress;
30
- readonly [FunctionReferenceTypesTypeId]?: {
31
- readonly kind: Kind;
32
- readonly args: Args;
33
- readonly value: Success;
34
- readonly error: Failure;
35
- };
36
- }
37
-
38
- type ReferenceTypes<Reference> = Reference extends {
39
- readonly [FunctionReferenceTypesTypeId]?: infer Types;
40
- }
41
- ? Exclude<Types, undefined>
42
- : never;
43
-
44
- export declare namespace FunctionReference {
45
- type Args<Reference> =
46
- ReferenceTypes<Reference> extends { readonly args: infer Args } ? Args : never;
47
- type Failure<Reference> =
48
- ReferenceTypes<Reference> extends {
49
- readonly error: infer Failure;
50
- }
51
- ? Failure
52
- : never;
53
- type Kind<Reference> =
54
- ReferenceTypes<Reference> extends { readonly kind: infer Kind } ? Kind : never;
55
- type Success<Reference> =
56
- ReferenceTypes<Reference> extends {
57
- readonly value: infer Success;
58
- }
59
- ? Success
60
- : never;
61
- }
62
-
63
- type ReferenceOf<Definition> = Definition extends {
64
- readonly _tag: infer Kind extends FunctionKind;
65
- readonly handler: (
66
- ...arguments_: infer HandlerArguments
67
- ) => Generator<infer Yielded, infer Success, never>;
68
- }
69
- ? HandlerArguments extends readonly [infer _Context, ...infer Rest]
70
- ? FunctionReference<
71
- Kind,
72
- Rest extends readonly [infer Args, ...ReadonlyArray<unknown>]
73
- ? Kind extends "Mutation"
74
- ? MutationInput<Args>
75
- : Args
76
- : void,
77
- Success,
78
- | (Yielded extends Effect.Effect<unknown, infer Failure extends ErrorValue, never>
79
- ? Failure
80
- : never)
81
- | InternalServerError
82
- >
83
- : never
84
- : never;
85
-
86
- type ApiModule<Module> = {
87
- readonly [FunctionName in keyof Module as FunctionName extends string
88
- ? ReferenceOf<Module[FunctionName]> extends never
89
- ? never
90
- : FunctionName
91
- : never]: ReferenceOf<Module[FunctionName]>;
92
- };
93
-
94
- export type Api<Modules> = {
95
- readonly [ModuleName in keyof Modules]: ApiModule<Modules[ModuleName]>;
96
- };
97
-
98
- export const functionPathOf = <
99
- Kind extends FunctionKind,
100
- Args,
101
- Success,
102
- Failure extends ErrorValue,
103
- >(
104
- reference: FunctionReference<Kind, Args, Success, Failure>,
105
- ) => reference[FunctionReferenceTypeId];
106
-
107
- const makeModuleReference = (moduleName: string) => {
108
- const references = new Map<string, object>();
109
-
110
- return new Proxy(
111
- {},
112
- {
113
- get: (_target, functionName) => {
114
- if (!Predicate.isString(functionName)) {
115
- return undefined;
116
- }
117
-
118
- const existing = references.get(functionName);
119
- if (existing !== undefined) {
120
- return existing;
121
- }
122
-
123
- const reference = {
124
- [FunctionReferenceTypeId]: FunctionAddress.make(`api.${moduleName}.${functionName}`),
125
- };
126
- references.set(functionName, reference);
127
- return reference;
128
- },
129
- },
130
- );
131
- };
132
-
133
- export function createApi<Modules>(): Api<Modules>;
134
- export function createApi() {
135
- const modules = new Map<string, object>();
136
-
137
- return new Proxy(
138
- {},
139
- {
140
- get: (_target, moduleName) => {
141
- if (!Predicate.isString(moduleName)) {
142
- return undefined;
143
- }
144
-
145
- const existing = modules.get(moduleName);
146
- if (existing !== undefined) {
147
- return existing;
148
- }
149
-
150
- const moduleReference = makeModuleReference(moduleName);
151
- modules.set(moduleName, moduleReference);
152
- return moduleReference;
153
- },
154
- },
155
- );
156
- }
1
+ export * from "@ignotum/platform/versions/1/common/api";
@@ -1,186 +1 @@
1
- import {
2
- LayoutMetadata,
3
- RouteDefinition,
4
- StaticMetadata,
5
- UrlValueDescriptor,
6
- UrlScalarDescriptor,
7
- } from "@ignotum/contracts/app-definition";
8
- import type { Id } from "@ignotum/contracts/schema";
9
- import { Schema } from "effect";
10
- import type { ComponentChildren, ComponentType } from "preact";
11
- import type { RouteLocation } from "../client/routes.js";
12
-
13
- export { createImageSource } from "../client/image.js";
14
-
15
- declare const UrlValueTypeId: unique symbol;
16
- type Scalar = string | number | boolean;
17
- type RequiredDescriptor = Exclude<UrlValueDescriptor, { type: "optional" | "default" }>;
18
- type Mode = "required" | "optional" | "default";
19
-
20
- export interface UrlValue<
21
- Value,
22
- Kind extends "scalar" | "array" = "scalar" | "array",
23
- Presence extends Mode = Mode,
24
- > {
25
- readonly descriptor: UrlValueDescriptor;
26
- readonly [UrlValueTypeId]?: {
27
- readonly value: Value;
28
- readonly kind: Kind;
29
- readonly presence: Presence;
30
- };
31
- }
32
- export interface RequiredUrlValue<Value, Kind extends "scalar" | "array"> extends UrlValue<
33
- Value,
34
- Kind,
35
- "required"
36
- > {
37
- default(value: Value): UrlValue<Value, Kind, "default">;
38
- }
39
- export type UrlFields = Readonly<Record<string, UrlValue<unknown>>>;
40
- export type PathFields = Readonly<
41
- Record<
42
- string,
43
- UrlValue<unknown, "scalar", "required"> | UrlValue<readonly string[], "array", "required">
44
- >
45
- >;
46
- type ValueOf<Value> = Value extends UrlValue<infer Decoded> ? Decoded : never;
47
- type OptionalKeys<Fields extends UrlFields> = {
48
- [Key in keyof Fields]: Fields[Key] extends UrlValue<
49
- unknown,
50
- "scalar" | "array",
51
- "optional" | "default"
52
- >
53
- ? Key
54
- : never;
55
- }[keyof Fields];
56
- export type DecodedFields<Fields extends UrlFields> = {
57
- readonly [Key in keyof Fields]: Fields[Key] extends UrlValue<
58
- unknown,
59
- "scalar" | "array",
60
- "optional"
61
- >
62
- ? ValueOf<Fields[Key]> | undefined
63
- : ValueOf<Fields[Key]>;
64
- };
65
- export type InputFields<Fields extends UrlFields> = {
66
- readonly [Key in Exclude<keyof Fields, OptionalKeys<Fields>>]: ValueOf<Fields[Key]>;
67
- } & { readonly [Key in OptionalKeys<Fields>]?: ValueOf<Fields[Key]> | undefined };
68
-
69
- const validateValue = Schema.decodeUnknownSync(UrlValueDescriptor);
70
- const required = <Value, Kind extends "scalar" | "array">(
71
- descriptor: RequiredDescriptor,
72
- ): RequiredUrlValue<Value, Kind> => {
73
- const checked = validateValue(descriptor);
74
- return {
75
- descriptor: checked,
76
- default: (value) => ({
77
- descriptor: validateValue({ type: "default", value: checked, default: value }),
78
- }),
79
- };
80
- };
81
-
82
- export interface UrlValues<DataModel> {
83
- string(): RequiredUrlValue<string, "scalar">;
84
- id<Table extends Extract<keyof DataModel, string>>(
85
- table: Table,
86
- ): RequiredUrlValue<Id<Table>, "scalar">;
87
- number(): RequiredUrlValue<number, "scalar">;
88
- integer(): RequiredUrlValue<number, "scalar">;
89
- boolean(): RequiredUrlValue<boolean, "scalar">;
90
- literal<const Value extends Scalar>(value: Value): RequiredUrlValue<Value, "scalar">;
91
- literals<const Values extends readonly [Scalar, ...Scalar[]]>(
92
- ...values: Values
93
- ): RequiredUrlValue<Values[number], "scalar">;
94
- optional<Value, Kind extends "scalar" | "array">(
95
- value: RequiredUrlValue<Value, Kind>,
96
- ): UrlValue<Value, Kind, "optional">;
97
- array<Value>(
98
- value: RequiredUrlValue<Value, "scalar">,
99
- ): RequiredUrlValue<readonly Value[], "array">;
100
- }
101
-
102
- export interface RouteErrorProps {
103
- readonly error: unknown;
104
- readonly retry: () => void;
105
- }
106
- export interface InvalidRouteProps {
107
- readonly location: RouteLocation;
108
- readonly issues: ReadonlyArray<{
109
- readonly source: "params" | "searchParams";
110
- readonly field?: string | undefined;
111
- readonly message: string;
112
- }>;
113
- }
114
- export interface PageDefinition<
115
- Params extends PathFields | undefined = PathFields | undefined,
116
- Search extends UrlFields = UrlFields,
117
- > extends StaticMetadata {
118
- readonly params?: Params;
119
- readonly searchParams?: Search;
120
- readonly component: ComponentType<{
121
- readonly params: Params extends PathFields
122
- ? DecodedFields<Params>
123
- : Readonly<Record<string, string | readonly string[]>>;
124
- readonly searchParams: DecodedFields<Search>;
125
- }>;
126
- readonly error?: ComponentType<RouteErrorProps>;
127
- readonly invalid?: ComponentType<InvalidRouteProps>;
128
- }
129
- export interface LayoutDefinition extends LayoutMetadata {
130
- readonly component: ComponentType<{ readonly children: ComponentChildren }>;
131
- readonly error?: ComponentType<RouteErrorProps>;
132
- readonly invalid?: ComponentType<InvalidRouteProps>;
133
- readonly notFound?: ComponentType<{ readonly location: RouteLocation }>;
134
- }
135
-
136
- export const bindSchema = <DataModel>() => {
137
- const values: UrlValues<DataModel> = {
138
- string: () => required({ type: "string" }),
139
- id: (table) => required({ type: "id", table }),
140
- number: () => required({ type: "number" }),
141
- integer: () => required({ type: "integer" }),
142
- boolean: () => required({ type: "boolean" }),
143
- literal: (value) => required({ type: "literal", value }),
144
- literals: (...values) => required({ type: "literals", values }),
145
- optional: (value) => ({
146
- descriptor: validateValue({ type: "optional", value: value.descriptor }),
147
- }),
148
- array: (value) =>
149
- required({
150
- type: "array",
151
- value: Schema.decodeUnknownSync(UrlScalarDescriptor)(value.descriptor),
152
- }),
153
- };
154
- const route = <
155
- const Params extends PathFields | undefined = undefined,
156
- const Search extends UrlFields = {},
157
- >(
158
- definition: PageDefinition<Params, Search>,
159
- ): PageDefinition<Params, Search> => {
160
- Schema.decodeUnknownSync(StaticMetadata)({ title: definition.title, meta: definition.meta });
161
- const params: PathFields = definition.params ?? {};
162
- Schema.decodeUnknownSync(RouteDefinition.fields.params)(
163
- Object.entries(params).map(([name, value]) => ({
164
- name,
165
- value: value.descriptor,
166
- })),
167
- );
168
- for (const value of Object.values(definition.searchParams ?? {}))
169
- validateValue(value.descriptor);
170
- return definition;
171
- };
172
- const layout = (definition: LayoutDefinition): LayoutDefinition => {
173
- Schema.decodeUnknownSync(LayoutMetadata)({
174
- title: definition.title,
175
- titleTemplate: definition.titleTemplate,
176
- meta: definition.meta,
177
- });
178
- return definition;
179
- };
180
- return { route, layout, values };
181
- };
182
-
183
- export { createRouteReference, getRouteDefinition } from "./routes.js";
184
-
185
- export { mountClient } from "../client/bootstrap.js";
186
- export type { ClientRegistration, RegisteredClientModule } from "../client/router-store.js";
1
+ export * from "@ignotum/platform/versions/1/browser/internal/client";
@@ -1 +1 @@
1
- export { evolve, invoke } from "@ignotum/runtime/guest";
1
+ export * from "@ignotum/platform/versions/1/guest/internal/host";
@@ -1,4 +1 @@
1
- export const ignotumPathPrefix = "/_ignotum";
2
-
3
- export const isIgnotumPath = (pathname: string): boolean =>
4
- pathname === ignotumPathPrefix || pathname.startsWith(`${ignotumPathPrefix}/`);
1
+ export * from "@ignotum/platform/versions/1/common/http-paths";
@@ -1,45 +1 @@
1
- import { RouteDefinition } from "@ignotum/contracts/app-definition";
2
- import { Schema } from "effect";
3
-
4
- import type { DecodedFields, InputFields, PathFields, UrlFields } from "./client.js";
5
-
6
- const RouteReferenceTypeId: unique symbol = Symbol.for("ignotum/internal/routes/RouteReference");
7
- declare const RouteReferenceTypesTypeId: unique symbol;
8
-
9
- export interface RouteReference<Params = unknown, Search = unknown, SearchInputs = unknown> {
10
- readonly [RouteReferenceTypeId]: RouteDefinition;
11
- readonly [RouteReferenceTypesTypeId]?: {
12
- readonly params: Params;
13
- readonly searchParams: Search;
14
- readonly searchInputs: SearchInputs;
15
- };
16
- }
17
- export type ReferenceTypes<Reference> =
18
- Reference extends RouteReference<infer Params, infer Search, infer SearchInputs>
19
- ? {
20
- readonly params: Params;
21
- readonly searchParams: Search;
22
- readonly searchInputs: SearchInputs;
23
- }
24
- : never;
25
- type ParamsOf<Page, Inferred> = Page extends { readonly params?: infer Params }
26
- ? Params extends PathFields
27
- ? DecodedFields<Params>
28
- : Inferred
29
- : Inferred;
30
- type SearchOf<Page> = Page extends { readonly searchParams?: infer Search extends UrlFields }
31
- ? Search
32
- : {};
33
-
34
- export const createRouteReference = <Page, InferredParams>(
35
- definition: typeof RouteDefinition.Encoded,
36
- ): RouteReference<
37
- ParamsOf<Page, InferredParams>,
38
- DecodedFields<SearchOf<Page>>,
39
- InputFields<SearchOf<Page>>
40
- > => ({
41
- [RouteReferenceTypeId]: Schema.decodeUnknownSync(RouteDefinition)(definition),
42
- });
43
-
44
- export const getRouteDefinition = (reference: RouteReference): RouteDefinition =>
45
- reference[RouteReferenceTypeId];
1
+ export * from "@ignotum/platform/versions/1/browser/internal/routes";
@@ -1,3 +1 @@
1
- import { bindSchema as bindContractSchema } from "@ignotum/contracts/schema";
2
-
3
- export const bindSchema: typeof bindContractSchema = bindContractSchema;
1
+ export * from "@ignotum/platform/versions/1/guest/internal/server";
@@ -1,2 +1 @@
1
- export { SchemaDefinitionTypeId } from "@ignotum/contracts/schema";
2
- export type { Document, Id, SchemaDefinitionOf } from "@ignotum/contracts/schema";
1
+ export * from "@ignotum/platform/versions/1/common/types";
@@ -1,27 +1 @@
1
- import { Result as contractResult } from "@ignotum/contracts/runtime/result";
2
- import type { ErrorValue, Result as ContractResult } from "@ignotum/contracts/runtime/result";
3
- import {
4
- defineEnv as defineContractEnv,
5
- defineSchema as defineContractSchema,
6
- Secret as contractSecret,
7
- } from "@ignotum/contracts/schema";
8
- import type { Secret as ContractSecret } from "@ignotum/contracts/schema";
9
-
10
- export const Result: typeof contractResult = contractResult;
11
- export type Result<Success, Failure extends ErrorValue> = ContractResult<Success, Failure>;
12
- export const defineEnv: typeof defineContractEnv = defineContractEnv;
13
- export const defineSchema: typeof defineContractSchema = defineContractSchema;
14
- export const Secret: typeof contractSecret = contractSecret;
15
- export type Secret<Value> = ContractSecret<Value>;
16
- export type {
17
- DefinedEnv,
18
- DefinedSchema,
19
- EnvironmentAuthoring,
20
- FileFormat,
21
- FileMetadata,
22
- FileMimeType,
23
- FileValue,
24
- SchemaAuthoring,
25
- } from "@ignotum/contracts/schema";
26
-
27
- export type { User, UserId } from "@ignotum/contracts/id";
1
+ export * from "@ignotum/platform/versions/1/guest/server/index";