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.
- package/README.md +6 -6
- package/dist/cli/bin.mjs +13256 -2688
- package/dist/cli/bin.mjs.map +1 -1
- package/dist/platform/_headers +3 -0
- package/dist/platform/_ignotum/v1.0/client.js +12 -0
- package/dist/runtime/{api-B4fwp5a2.d.ts → api-BnUKx9cj-D49Tf0rX.d.ts} +4 -3
- package/dist/runtime/api-C-tltz6s.js +31 -0
- package/dist/runtime/api-C-tltz6s.js.map +1 -0
- package/dist/runtime/artifact-BB5qzoa6.js +42 -0
- package/dist/runtime/artifact-BB5qzoa6.js.map +1 -0
- package/dist/runtime/{bootstrap-BTFScKAc.d.ts → bootstrap-DjTwGJao-DBx5zdFI.d.ts} +64 -64
- package/dist/runtime/{bootstrap-BISQSn_O.js → bootstrap-DlNIfH-r.js} +9 -9
- package/dist/runtime/bootstrap-DlNIfH-r.js.map +1 -0
- package/dist/runtime/client.d.ts +24 -20
- package/dist/runtime/client.js +9 -9
- package/dist/runtime/client.js.map +1 -1
- package/dist/runtime/id-BI08JkmR.d.ts +1 -0
- package/dist/runtime/{id--1m0NuUL.js → id-BrEnxY-r.js} +118 -53
- package/dist/runtime/id-BrEnxY-r.js.map +1 -0
- package/dist/runtime/{image-Djtjy4Z8.js → image-gofzZeCm.js} +2 -2
- package/dist/runtime/image-gofzZeCm.js.map +1 -0
- package/dist/runtime/{index-D4seNHlX.d.ts → index-Biaw5vdF.d.ts} +2 -2
- package/dist/runtime/internal/api.d.ts +1 -1
- package/dist/runtime/internal/api.js +1 -30
- package/dist/runtime/internal/bootstrap.d.ts +1 -1
- package/dist/runtime/internal/bootstrap.js +1 -1
- package/dist/runtime/internal/client.d.ts +2 -2
- package/dist/runtime/internal/client.js +4 -4
- package/dist/runtime/internal/client.js.map +1 -1
- package/dist/runtime/internal/host.d.ts +4 -4
- package/dist/runtime/internal/host.js +4 -4
- package/dist/runtime/internal/routes.d.ts +1 -1
- package/dist/runtime/internal/routes.js +1 -1
- package/dist/runtime/internal/server.d.ts +3 -2
- package/dist/runtime/internal/server.js +2 -2
- package/dist/runtime/internal/server.js.map +1 -1
- package/dist/runtime/internal/types.d.ts +2 -2
- package/dist/runtime/internal/types.js +1 -1
- package/dist/runtime/{pagination-D3qd6s9N.js → pagination--f4kMKf6.js} +2 -2
- package/dist/runtime/{pagination-D3qd6s9N.js.map → pagination--f4kMKf6.js.map} +1 -1
- package/dist/runtime/pagination-BI08JkmR.d.ts +1 -0
- package/dist/runtime/{router-BSBI1oN1.js → router-C1eC9yy5.js} +462 -419
- package/dist/runtime/router-C1eC9yy5.js.map +1 -0
- package/dist/runtime/routes-DnU39R7c.js +152 -0
- package/dist/runtime/routes-DnU39R7c.js.map +1 -0
- package/dist/runtime/{schema-D1wOqiNH.js → schema-BSjepoNF.js} +271 -6
- package/dist/runtime/schema-BSjepoNF.js.map +1 -0
- package/dist/runtime/server.d.ts +5 -4
- package/dist/runtime/server.js +3 -3
- package/dist/runtime/server.js.map +1 -1
- package/dist/runtime/{sync-DzUwA8W9.js → sync-BwgS19Xy.js} +4 -16
- package/dist/runtime/sync-BwgS19Xy.js.map +1 -0
- package/dist/runtime/{sync-D-GK2sv9.d.ts → sync-By2hX5ev.d.ts} +1 -2
- package/dist/runtime/{types-DeCCyqLU-BIm7rU-0.d.ts → types-DeCCyqLU-CHx7KFtx.d.ts} +2 -2
- package/package.json +8 -2
- package/src/cli/agent-files.ts +2 -0
- package/src/cli/build/asset-names.ts +190 -0
- package/src/cli/build/managed-client.ts +151 -81
- package/src/cli/build/managed-server.ts +4 -4
- package/src/cli/build/managed.ts +5 -6
- package/src/cli/command.ts +6 -15
- package/src/cli/control-client.ts +7 -9
- package/src/cli/deploy.ts +45 -15
- package/src/cli/dev.ts +50 -99
- package/src/cli/image-assets.ts +5 -2
- package/src/cli/managed-client-boundaries.ts +6 -6
- package/src/cli/managed-dev-platform.ts +52 -66
- package/src/cli/managed-exports.ts +5 -66
- package/src/cli/new-app.ts +7 -2
- package/src/cli/upload-journal.ts +130 -0
- package/src/client/bootstrap.ts +1 -110
- package/src/client/errors.ts +1 -70
- package/src/client/files.ts +1 -233
- package/src/client/hooks.ts +1 -367
- package/src/client/id.ts +1 -263
- package/src/client/image.ts +1 -28
- package/src/client/index.ts +1 -126
- package/src/client/jsx-dev-runtime.ts +1 -2
- package/src/client/jsx-runtime.ts +1 -2
- package/src/client/managed-client.ts +1 -729
- package/src/client/managed-upgrade.ts +1 -283
- package/src/client/page-observers.ts +1 -77
- package/src/client/query.ts +1 -17
- package/src/client/recovery-journal.ts +1 -195
- package/src/client/route-boundaries.ts +1 -184
- package/src/client/router-history.ts +1 -152
- package/src/client/router-store.ts +1 -644
- package/src/client/router.ts +1 -324
- package/src/client/routes.ts +1 -28
- package/src/client/sync.ts +1 -286
- package/src/dev-runtime/id.ts +1 -1
- package/src/dev-runtime/managed-functions.ts +10 -18
- package/src/dev-runtime/managed-sync.ts +16 -16
- package/src/dev-runtime/sync.ts +6 -4
- package/src/internal/api.ts +1 -156
- package/src/internal/client.ts +1 -186
- package/src/internal/host.ts +1 -1
- package/src/internal/http-paths.ts +1 -4
- package/src/internal/routes.ts +1 -45
- package/src/internal/server.ts +1 -3
- package/src/internal/types.ts +1 -2
- package/src/server/index.ts +1 -27
- package/dist/cli/managed-release-WHYLZwaS.mjs +0 -10902
- package/dist/cli/managed-release-WHYLZwaS.mjs.map +0 -1
- package/dist/cli/managed-release.d.mts +0 -1
- package/dist/cli/managed-release.mjs +0 -14
- package/dist/cli/managed-release.mjs.map +0 -1
- package/dist/runtime/bootstrap-BISQSn_O.js.map +0 -1
- package/dist/runtime/descriptor-CTY4mtwS-cS43EbwS.js +0 -269
- package/dist/runtime/descriptor-CTY4mtwS-cS43EbwS.js.map +0 -1
- package/dist/runtime/id--1m0NuUL.js.map +0 -1
- package/dist/runtime/id-CBOt2kDo.d.ts +0 -1
- package/dist/runtime/identity-QjtJRxBD.d.ts +0 -2
- package/dist/runtime/image-Djtjy4Z8.js.map +0 -1
- package/dist/runtime/internal/api.js.map +0 -1
- package/dist/runtime/pagination-CBOt2kDo.d.ts +0 -1
- package/dist/runtime/router-BSBI1oN1.js.map +0 -1
- package/dist/runtime/routes-Ce8TVP-T.js +0 -690
- package/dist/runtime/routes-Ce8TVP-T.js.map +0 -1
- package/dist/runtime/schema-D1wOqiNH.js.map +0 -1
- package/dist/runtime/sync-DzUwA8W9.js.map +0 -1
- package/src/cli/managed-release-bin.ts +0 -13
- 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:
|
|
43
|
-
readonly
|
|
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 =
|
|
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.
|
|
80
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
5
|
-
|
|
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: () =>
|
|
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:
|
|
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 ||
|
|
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:
|
|
111
|
+
original: ServingSelection,
|
|
111
112
|
) =>
|
|
112
113
|
row.clientSessionId === clientSessionId &&
|
|
113
114
|
row.sessionEpoch === identity.sessionEpoch &&
|
|
114
|
-
|
|
115
|
-
Schema.decodeSync(Schema.fromJsonString(
|
|
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
|
-
|
|
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.
|
|
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(
|
|
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(
|
package/src/dev-runtime/sync.ts
CHANGED
|
@@ -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 {
|
|
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:
|
|
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(
|
|
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
|
-
|
|
454
|
+
versionId,
|
|
453
455
|
"Mutation",
|
|
454
456
|
message.function,
|
|
455
457
|
message.args,
|
package/src/internal/api.ts
CHANGED
|
@@ -1,156 +1 @@
|
|
|
1
|
-
|
|
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";
|
package/src/internal/client.ts
CHANGED
|
@@ -1,186 +1 @@
|
|
|
1
|
-
|
|
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";
|
package/src/internal/host.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export
|
|
1
|
+
export * from "@ignotum/platform/versions/1/guest/internal/host";
|
package/src/internal/routes.ts
CHANGED
|
@@ -1,45 +1 @@
|
|
|
1
|
-
|
|
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";
|
package/src/internal/server.ts
CHANGED
package/src/internal/types.ts
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
export
|
|
2
|
-
export type { Document, Id, SchemaDefinitionOf } from "@ignotum/contracts/schema";
|
|
1
|
+
export * from "@ignotum/platform/versions/1/common/types";
|
package/src/server/index.ts
CHANGED
|
@@ -1,27 +1 @@
|
|
|
1
|
-
|
|
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";
|