ignotum 0.0.13 → 0.0.15
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 +6111 -4448
- package/dist/cli/bin.mjs.map +1 -1
- package/dist/cli/emscripten-module-D5GzfUNv.mjs +533 -0
- package/dist/cli/emscripten-module-D5GzfUNv.mjs.map +1 -0
- package/dist/cli/ffi-7IElU4Co.mjs +148 -0
- package/dist/cli/ffi-7IElU4Co.mjs.map +1 -0
- package/dist/cli/managed-release-WHYLZwaS.mjs +10902 -0
- package/dist/cli/managed-release-WHYLZwaS.mjs.map +1 -0
- package/dist/cli/managed-release.d.mts +1 -0
- package/dist/cli/managed-release.mjs +14 -0
- package/dist/cli/managed-release.mjs.map +1 -0
- package/dist/cli/module-ES6BEMUI-D36I4NVn.mjs +1289 -0
- package/dist/cli/module-ES6BEMUI-D36I4NVn.mjs.map +1 -0
- package/dist/runtime/{api-Cv3hMbzo.d.ts → api-B4fwp5a2.d.ts} +4 -4
- package/dist/runtime/bootstrap-BISQSn_O.js +916 -0
- package/dist/runtime/bootstrap-BISQSn_O.js.map +1 -0
- package/dist/runtime/bootstrap-BTFScKAc.d.ts +545 -0
- package/dist/runtime/client.d.ts +50 -15
- package/dist/runtime/client.js +7 -1138
- package/dist/runtime/client.js.map +1 -1
- package/dist/runtime/descriptor-CTY4mtwS-cS43EbwS.js +269 -0
- package/dist/runtime/descriptor-CTY4mtwS-cS43EbwS.js.map +1 -0
- package/dist/runtime/{id-Bt9XWRGL.js → id--1m0NuUL.js} +4 -4
- package/dist/runtime/id--1m0NuUL.js.map +1 -0
- package/dist/runtime/{id-BzFHf3Wo-DGPCjgrf.d.ts → id-7an3nxTu-DZJSM5xh.d.ts} +2 -2
- package/dist/runtime/id-CBOt2kDo.d.ts +1 -0
- package/dist/runtime/identity-QjtJRxBD.d.ts +2 -0
- package/dist/runtime/image-Djtjy4Z8.js +19 -0
- package/dist/runtime/image-Djtjy4Z8.js.map +1 -0
- package/dist/runtime/index-D4seNHlX.d.ts +184 -0
- package/dist/runtime/internal/api.d.ts +1 -1
- package/dist/runtime/internal/api.js +30 -1
- package/dist/runtime/internal/api.js.map +1 -0
- package/dist/runtime/internal/bootstrap.d.ts +2 -0
- package/dist/runtime/internal/bootstrap.js +2 -0
- package/dist/runtime/internal/client.d.ts +2 -0
- package/dist/runtime/internal/client.js +75 -0
- package/dist/runtime/internal/client.js.map +1 -0
- package/dist/runtime/internal/host.d.ts +25 -8
- package/dist/runtime/internal/host.js +27 -6
- package/dist/runtime/internal/host.js.map +1 -1
- package/dist/runtime/internal/routes.d.ts +2 -0
- package/dist/runtime/internal/routes.js +2 -0
- package/dist/runtime/internal/server.d.ts +1 -1
- package/dist/runtime/internal/server.js +1 -1
- package/dist/runtime/internal/types.d.ts +2 -1
- package/dist/runtime/internal/types.js +1 -1
- package/dist/runtime/pagination-CBOt2kDo.d.ts +1 -0
- package/dist/runtime/pagination-D3qd6s9N.js +33 -0
- package/dist/runtime/pagination-D3qd6s9N.js.map +1 -0
- package/dist/runtime/result-BkziOG1L.d.ts +1 -0
- package/dist/runtime/router-BSBI1oN1.js +2377 -0
- package/dist/runtime/router-BSBI1oN1.js.map +1 -0
- package/dist/runtime/routes-Ce8TVP-T.js +690 -0
- package/dist/runtime/routes-Ce8TVP-T.js.map +1 -0
- package/dist/runtime/{schema-1Zs03-iS.js → schema-D1wOqiNH.js} +40 -12
- package/dist/runtime/schema-D1wOqiNH.js.map +1 -0
- package/dist/runtime/server.d.ts +5 -5
- package/dist/runtime/server.js +2 -2
- package/dist/runtime/{sync-Bs8J3fIr.d.ts → sync-D-GK2sv9.d.ts} +3 -2
- package/dist/runtime/{api-CAgKDij7.js → sync-DzUwA8W9.js} +22 -41
- package/dist/runtime/sync-DzUwA8W9.js.map +1 -0
- package/dist/runtime/types-DeCCyqLU-BIm7rU-0.d.ts +341 -0
- package/package.json +29 -4
- package/src/cli/agent-files.ts +14 -8
- package/src/cli/build/managed-client.ts +411 -0
- package/src/cli/build/managed-server.ts +294 -0
- package/src/cli/build/managed.ts +67 -0
- package/src/cli/build/output.ts +47 -0
- package/src/cli/build/server.ts +51 -220
- package/src/cli/client-config.ts +1 -140
- package/src/cli/client-styles.ts +1 -0
- package/src/cli/codegen.ts +9 -4
- package/src/cli/command.ts +28 -5
- package/src/cli/control-client.ts +84 -101
- package/src/cli/deploy.ts +133 -177
- package/src/cli/dev.ts +506 -107
- package/src/cli/image-assets.ts +499 -0
- package/src/cli/managed-client-boundaries.ts +103 -0
- package/src/cli/managed-dev-platform.ts +118 -0
- package/src/cli/managed-exports.ts +219 -0
- package/src/cli/managed-release-bin.ts +13 -0
- package/src/cli/managed-release.ts +260 -0
- package/src/cli/module-boundaries.ts +11 -1
- package/src/cli/new-app.ts +111 -87
- package/src/cli/route-codegen.ts +311 -0
- package/src/cli/route-static.ts +710 -0
- package/src/client/bootstrap.ts +110 -0
- package/src/client/errors.ts +13 -7
- package/src/client/files.ts +64 -0
- package/src/client/id.ts +9 -5
- package/src/client/image.ts +28 -0
- package/src/client/index.ts +25 -2
- package/src/client/managed-client.ts +729 -0
- package/src/client/managed-upgrade.ts +283 -0
- package/src/client/recovery-journal.ts +195 -0
- package/src/client/route-boundaries.ts +184 -0
- package/src/client/router-history.ts +152 -0
- package/src/client/router-store.ts +644 -0
- package/src/client/router.ts +324 -0
- package/src/client/routes.ts +28 -0
- package/src/client/sync.ts +66 -592
- package/src/dev-runtime/database.ts +77 -2
- package/src/dev-runtime/functions.ts +3 -3
- package/src/dev-runtime/id.ts +19 -4
- package/src/dev-runtime/managed-functions.ts +255 -0
- package/src/dev-runtime/managed-sync.ts +263 -0
- package/src/dev-runtime/managed-websocket.ts +71 -0
- package/src/dev-runtime/migrations.ts +20 -0
- package/src/dev-runtime/sync.ts +236 -236
- package/src/image-assets.d.ts +36 -0
- package/src/internal/client.ts +186 -0
- package/src/internal/host.ts +1 -1
- package/src/internal/http-paths.ts +0 -3
- package/src/internal/routes.ts +45 -0
- package/dist/runtime/api-CAgKDij7.js.map +0 -1
- package/dist/runtime/descriptor-Cyo9FP9n-C0SRVXNW.js +0 -154
- package/dist/runtime/descriptor-Cyo9FP9n-C0SRVXNW.js.map +0 -1
- package/dist/runtime/id-Bt9XWRGL.js.map +0 -1
- package/dist/runtime/id-Dz0apuB3.d.ts +0 -1
- package/dist/runtime/index-D54flWtH.d.ts +0 -402
- package/dist/runtime/pagination-DnKg3dkI-r5ZUxBBx.d.ts +0 -112
- package/dist/runtime/pagination-Dz0apuB3.d.ts +0 -1
- package/dist/runtime/result-DKAA4gpS.d.ts +0 -1
- package/dist/runtime/schema-1Zs03-iS.js.map +0 -1
- package/src/cli/build/client.ts +0 -119
- package/src/cli/build/public.ts +0 -186
- package/src/cli/client-entry.ts +0 -152
- package/src/cli/client-plugin.ts +0 -136
- package/src/client/app.ts +0 -15
package/src/cli/build/server.ts
CHANGED
|
@@ -3,31 +3,12 @@ import process from "node:process";
|
|
|
3
3
|
import { fileURLToPath } from "node:url";
|
|
4
4
|
|
|
5
5
|
import * as Config from "effect/Config";
|
|
6
|
-
import {
|
|
7
|
-
Array,
|
|
8
|
-
Crypto,
|
|
9
|
-
Effect,
|
|
10
|
-
Encoding,
|
|
11
|
-
FileSystem,
|
|
12
|
-
Path,
|
|
13
|
-
Predicate,
|
|
14
|
-
Schema,
|
|
15
|
-
Stream,
|
|
16
|
-
String,
|
|
17
|
-
} from "effect";
|
|
6
|
+
import { Array, Effect, FileSystem, Path, Predicate, Schema, Stream, String } from "effect";
|
|
18
7
|
import { ChildProcess, ChildProcessSpawner } from "effect/unstable/process";
|
|
19
8
|
import { createServer, defaultServerConditions, normalizePath } from "vite";
|
|
20
|
-
import type {
|
|
9
|
+
import type { ViteDevServer } from "vite";
|
|
21
10
|
|
|
22
|
-
import {
|
|
23
|
-
ServerBuildManifest,
|
|
24
|
-
SchemaSnapshot,
|
|
25
|
-
SchemaSnapshotField,
|
|
26
|
-
EnvironmentArtifact,
|
|
27
|
-
schemaSnapshotPath,
|
|
28
|
-
serverEnvironmentPath,
|
|
29
|
-
type ServerFunctionArtifact,
|
|
30
|
-
} from "@ignotum/contracts/deployment";
|
|
11
|
+
import { SchemaSnapshot, SchemaSnapshotField } from "@ignotum/contracts/version";
|
|
31
12
|
import { FunctionAddress } from "@ignotum/contracts/runtime/sync";
|
|
32
13
|
import type { FunctionKind } from "@ignotum/contracts/runtime/functions";
|
|
33
14
|
import {
|
|
@@ -38,31 +19,19 @@ import {
|
|
|
38
19
|
isDefinedEnv,
|
|
39
20
|
isDefinedSchema,
|
|
40
21
|
ValueDescriptor,
|
|
22
|
+
evolutionRules,
|
|
23
|
+
SchemaDefinitionTypeId,
|
|
41
24
|
type DefinedSchema,
|
|
42
25
|
type Tables,
|
|
43
26
|
} from "@ignotum/contracts/schema";
|
|
44
|
-
import {
|
|
45
|
-
artifactReference,
|
|
46
|
-
encodeCanonical,
|
|
47
|
-
encodeSchemaSnapshot,
|
|
48
|
-
makeSchemaSnapshot,
|
|
49
|
-
utf8Bytes,
|
|
50
|
-
} from "@ignotum/deployment";
|
|
27
|
+
import { encodeCanonical, makeSchemaSnapshot } from "@ignotum/versions";
|
|
51
28
|
|
|
52
29
|
import { inspectRuntimeFunctionDefinition } from "../../internal/function-definition.js";
|
|
53
30
|
import { loadEnvironment } from "../environment.js";
|
|
54
31
|
import { moduleBoundariesPlugin, BuildBoundaryViolation } from "../module-boundaries.js";
|
|
55
|
-
import {
|
|
56
|
-
causeMessage,
|
|
57
|
-
InvalidBuildOutput,
|
|
58
|
-
runViteBuild,
|
|
59
|
-
sourceMapPathTransform,
|
|
60
|
-
ViteBuildFailed,
|
|
61
|
-
type GeneratedChunk,
|
|
62
|
-
} from "./artifact.js";
|
|
32
|
+
import { causeMessage, InvalidBuildOutput, ViteBuildFailed } from "./artifact.js";
|
|
63
33
|
|
|
64
|
-
|
|
65
|
-
const encodeJavaScriptString = Schema.encodeSync(Schema.fromJsonString(Schema.String));
|
|
34
|
+
import { compileManagedServer } from "./managed-server.js";
|
|
66
35
|
|
|
67
36
|
const DiscoveredServerFunction = Schema.Struct({
|
|
68
37
|
address: FunctionAddress,
|
|
@@ -85,7 +54,15 @@ interface DiscoveredServerFunction {
|
|
|
85
54
|
readonly returns?: ValueDescriptor;
|
|
86
55
|
}
|
|
87
56
|
|
|
57
|
+
const DiscoveredConversion = Schema.Struct({
|
|
58
|
+
table: Schema.String,
|
|
59
|
+
field: Schema.String,
|
|
60
|
+
from: ValueDescriptor,
|
|
61
|
+
to: ValueDescriptor,
|
|
62
|
+
});
|
|
63
|
+
|
|
88
64
|
const ServerDiscoveryManifest = Schema.Struct({
|
|
65
|
+
conversions: Schema.Array(DiscoveredConversion),
|
|
89
66
|
environment: Schema.Struct({
|
|
90
67
|
fields: Schema.Array(SchemaSnapshotField),
|
|
91
68
|
hasDefinition: Schema.Boolean,
|
|
@@ -94,19 +71,10 @@ const ServerDiscoveryManifest = Schema.Struct({
|
|
|
94
71
|
functions: Schema.Array(DiscoveredServerFunction),
|
|
95
72
|
schema: SchemaSnapshot,
|
|
96
73
|
});
|
|
97
|
-
type ServerDiscoveryManifest = typeof ServerDiscoveryManifest.Type;
|
|
74
|
+
export type ServerDiscoveryManifest = typeof ServerDiscoveryManifest.Type;
|
|
98
75
|
const ServerDiscoveryManifestJson = Schema.fromJsonString(ServerDiscoveryManifest);
|
|
99
76
|
const ServerModuleNamesJson = Schema.fromJsonString(Schema.Array(Schema.String));
|
|
100
77
|
|
|
101
|
-
export interface ServerBuildResult {
|
|
102
|
-
readonly environment: {
|
|
103
|
-
readonly bytes: Uint8Array;
|
|
104
|
-
readonly path: typeof serverEnvironmentPath;
|
|
105
|
-
};
|
|
106
|
-
readonly functions: number;
|
|
107
|
-
readonly manifestPath: string;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
78
|
export class ServerFunctionDiscoveryFailed extends Schema.TaggedError<ServerFunctionDiscoveryFailed>()(
|
|
111
79
|
"ServerFunctionDiscoveryFailed",
|
|
112
80
|
{
|
|
@@ -160,6 +128,7 @@ const acquireModuleRunner = Effect.fn("Deploy.acquireServerModuleRunner")(functi
|
|
|
160
128
|
},
|
|
161
129
|
root: appDirectory,
|
|
162
130
|
server: {
|
|
131
|
+
hmr: false,
|
|
163
132
|
forwardConsole: false,
|
|
164
133
|
middlewareMode: true,
|
|
165
134
|
fs: { strict: true, allow: [appDirectory] },
|
|
@@ -397,7 +366,34 @@ export const runServerDiscoveryWorker = Effect.fn("Deploy.runServerDiscoveryWork
|
|
|
397
366
|
message: "The application schema does not have canonical Ignotum descriptors.",
|
|
398
367
|
}),
|
|
399
368
|
});
|
|
369
|
+
const conversions: Array<typeof DiscoveredConversion.Type> = [];
|
|
370
|
+
const visit = (table: string, field: string, value: Schema.Constraint): void => {
|
|
371
|
+
const rules = evolutionRules(value);
|
|
372
|
+
const to = getValueDescriptor(value);
|
|
373
|
+
for (const previous of rules.previous ?? []) {
|
|
374
|
+
const from = getValueDescriptor(previous.schema);
|
|
375
|
+
if (from !== undefined && to !== undefined) conversions.push({ table, field, from, to });
|
|
376
|
+
visit(table, field, previous.schema);
|
|
377
|
+
}
|
|
378
|
+
const children = rules.children;
|
|
379
|
+
if (children?.type === "object") {
|
|
380
|
+
for (const child of Object.values(children.fields)) visit(table, field, child);
|
|
381
|
+
} else if (children?.type === "union") {
|
|
382
|
+
for (const child of children.members) visit(table, field, child);
|
|
383
|
+
} else if (children !== undefined) visit(table, field, children.value);
|
|
384
|
+
};
|
|
385
|
+
for (const [table, definition] of Object.entries(discovered.schema[SchemaDefinitionTypeId])) {
|
|
386
|
+
for (const [field, value] of Object.entries(definition.fields)) visit(table, field, value);
|
|
387
|
+
}
|
|
400
388
|
return yield* Schema.encodeEffect(ServerDiscoveryManifestJson)({
|
|
389
|
+
conversions: [
|
|
390
|
+
...new Map(
|
|
391
|
+
conversions.map((conversion) => [
|
|
392
|
+
encodeCanonical(DiscoveredConversion, conversion),
|
|
393
|
+
conversion,
|
|
394
|
+
]),
|
|
395
|
+
).values(),
|
|
396
|
+
],
|
|
401
397
|
environment: discovered.environment,
|
|
402
398
|
functions: discovered.functions,
|
|
403
399
|
schema,
|
|
@@ -513,181 +509,16 @@ const discoverServerFunctions = Effect.fn("Deploy.discoverServerFunctionsIsolate
|
|
|
513
509
|
);
|
|
514
510
|
});
|
|
515
511
|
|
|
516
|
-
const
|
|
517
|
-
const entryId = `virtual:ignotum/server-function/${definition.address}`;
|
|
518
|
-
const resolvedEntryId = `\0${entryId}`;
|
|
519
|
-
const source = `import { call } from ${encodeJavaScriptString(hostModuleId)}
|
|
520
|
-
import { invoke } from "ignotum/internal/host"
|
|
521
|
-
import { ${definition.exportName} as definition } from ${encodeJavaScriptString(normalizePath(definition.modulePath))}
|
|
522
|
-
|
|
523
|
-
export default async function handler(encodedRequest, encodedEnvironment) {
|
|
524
|
-
return invoke(definition, JSON.parse(encodedRequest), call, JSON.parse(encodedEnvironment))
|
|
525
|
-
}
|
|
526
|
-
`;
|
|
527
|
-
|
|
528
|
-
return {
|
|
529
|
-
name: "ignotum:server-function-entry",
|
|
530
|
-
load: (id) => (id === resolvedEntryId ? source : undefined),
|
|
531
|
-
resolveId: (id) => (id === entryId ? resolvedEntryId : undefined),
|
|
532
|
-
};
|
|
533
|
-
};
|
|
534
|
-
|
|
535
|
-
const buildServerFunction = Effect.fn("Deploy.buildServerFunction")(function* (
|
|
536
|
-
appDirectory: string,
|
|
537
|
-
serverOutputDirectory: string,
|
|
538
|
-
conditions: ReadonlyArray<string>,
|
|
539
|
-
definition: DiscoveredServerFunction,
|
|
540
|
-
) {
|
|
541
|
-
const fileSystem = yield* FileSystem.FileSystem;
|
|
542
|
-
const path = yield* Path.Path;
|
|
543
|
-
const functionDirectory = path.join(serverOutputDirectory, "functions", definition.moduleName);
|
|
544
|
-
const transformSourceMapPath = yield* sourceMapPathTransform(appDirectory);
|
|
545
|
-
const boundaries = yield* moduleBoundariesPlugin("Server", appDirectory);
|
|
546
|
-
const entryId = `virtual:ignotum/server-function/${definition.address}`;
|
|
547
|
-
yield* fileSystem.makeDirectory(functionDirectory, { recursive: true });
|
|
548
|
-
|
|
549
|
-
const output = yield* runViteBuild(definition.address, {
|
|
550
|
-
build: {
|
|
551
|
-
cssCodeSplit: false,
|
|
552
|
-
emptyOutDir: false,
|
|
553
|
-
minify: "oxc",
|
|
554
|
-
modulePreload: false,
|
|
555
|
-
outDir: functionDirectory,
|
|
556
|
-
rolldownOptions: {
|
|
557
|
-
external: [hostModuleId],
|
|
558
|
-
input: entryId,
|
|
559
|
-
preserveEntrySignatures: "strict",
|
|
560
|
-
treeshake: {
|
|
561
|
-
manualPureFunctions: ["mutation", "query"],
|
|
562
|
-
},
|
|
563
|
-
output: {
|
|
564
|
-
codeSplitting: false,
|
|
565
|
-
entryFileNames: `${definition.exportName}-[hash].mjs`,
|
|
566
|
-
format: "es",
|
|
567
|
-
sourcemapPathTransform: transformSourceMapPath,
|
|
568
|
-
},
|
|
569
|
-
},
|
|
570
|
-
sourcemap: true,
|
|
571
|
-
target: "es2020",
|
|
572
|
-
},
|
|
573
|
-
configFile: false,
|
|
574
|
-
logLevel: "warn",
|
|
575
|
-
mode: "production",
|
|
576
|
-
plugins: [boundaries, serverFunctionEntryPlugin(definition)],
|
|
577
|
-
publicDir: false,
|
|
578
|
-
resolve: {
|
|
579
|
-
conditions: [...conditions],
|
|
580
|
-
noExternal: true,
|
|
581
|
-
tsconfigPaths: true,
|
|
582
|
-
},
|
|
583
|
-
root: appDirectory,
|
|
584
|
-
});
|
|
585
|
-
const entries = Array.filter(
|
|
586
|
-
output,
|
|
587
|
-
(item): item is GeneratedChunk => item.type === "chunk" && item.isEntry,
|
|
588
|
-
);
|
|
589
|
-
if (entries.length !== 1) {
|
|
590
|
-
return yield* InvalidBuildOutput.make({
|
|
591
|
-
message: `${definition.address} did not emit exactly one entry chunk.`,
|
|
592
|
-
});
|
|
593
|
-
}
|
|
594
|
-
const entry = entries[0];
|
|
595
|
-
if (entry === undefined) {
|
|
596
|
-
return yield* InvalidBuildOutput.make({
|
|
597
|
-
message: `${definition.address} did not emit an entry chunk.`,
|
|
598
|
-
});
|
|
599
|
-
}
|
|
600
|
-
if (
|
|
601
|
-
entry.dynamicImports.length > 0 ||
|
|
602
|
-
entry.imports.length !== 1 ||
|
|
603
|
-
entry.imports[0] !== hostModuleId ||
|
|
604
|
-
!entry.exports.includes("default")
|
|
605
|
-
) {
|
|
606
|
-
return yield* InvalidBuildOutput.make({
|
|
607
|
-
message: `${definition.address} is not a self-contained default-exported handler. Imports: ${entry.imports.join(", ") || "none"}; dynamic imports: ${entry.dynamicImports.join(", ") || "none"}; exports: ${entry.exports.join(", ") || "none"}.`,
|
|
608
|
-
});
|
|
609
|
-
}
|
|
610
|
-
|
|
611
|
-
const relativeFile = normalizePath(path.join("functions", definition.moduleName, entry.fileName));
|
|
612
|
-
const relativeSourceMap = `${relativeFile}.map`;
|
|
613
|
-
const absoluteFile = path.join(serverOutputDirectory, relativeFile);
|
|
614
|
-
const absoluteSourceMap = path.join(serverOutputDirectory, relativeSourceMap);
|
|
615
|
-
const sourceMapExists = yield* fileSystem.exists(absoluteSourceMap);
|
|
616
|
-
if (!sourceMapExists) {
|
|
617
|
-
return yield* InvalidBuildOutput.make({
|
|
618
|
-
message: `${definition.address} did not emit a source map.`,
|
|
619
|
-
});
|
|
620
|
-
}
|
|
621
|
-
const bundlePath = normalizePath(path.join("server", relativeFile));
|
|
622
|
-
const sourceMapPath = normalizePath(path.join("server", relativeSourceMap));
|
|
623
|
-
|
|
624
|
-
const artifact = {
|
|
625
|
-
address: definition.address,
|
|
626
|
-
kind: definition.kind,
|
|
627
|
-
bundle: yield* artifactReference(bundlePath, yield* fileSystem.readFile(absoluteFile)),
|
|
628
|
-
sourceMap: yield* artifactReference(
|
|
629
|
-
sourceMapPath,
|
|
630
|
-
yield* fileSystem.readFile(absoluteSourceMap),
|
|
631
|
-
),
|
|
632
|
-
};
|
|
633
|
-
const withArgs =
|
|
634
|
-
definition.args === undefined ? artifact : { ...artifact, args: definition.args };
|
|
635
|
-
const withErrors =
|
|
636
|
-
definition.errors === undefined ? withArgs : { ...withArgs, errors: definition.errors };
|
|
637
|
-
return definition.returns === undefined
|
|
638
|
-
? (withErrors satisfies ServerFunctionArtifact)
|
|
639
|
-
: ({ ...withErrors, returns: definition.returns } satisfies ServerFunctionArtifact);
|
|
640
|
-
});
|
|
641
|
-
|
|
642
|
-
export const buildServer = Effect.fn("Deploy.buildServer")(function* (
|
|
512
|
+
export const buildManagedServer = Effect.fn("Deploy.buildManagedServer")(function* (
|
|
643
513
|
appDirectory: string,
|
|
644
514
|
outputDirectory: string,
|
|
645
515
|
functionModules: ReadonlyArray<string>,
|
|
646
516
|
) {
|
|
647
|
-
const fileSystem = yield* FileSystem.FileSystem;
|
|
648
|
-
const path = yield* Path.Path;
|
|
649
|
-
const conditions = yield* serverConditions();
|
|
650
517
|
const discovered = yield* discoverServerFunctions(appDirectory, functionModules);
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
} satisfies EnvironmentArtifact;
|
|
657
|
-
const environmentBytes = utf8Bytes(
|
|
658
|
-
`${encodeCanonical(EnvironmentArtifact, environmentArtifact)}\n`,
|
|
659
|
-
);
|
|
660
|
-
|
|
661
|
-
yield* fileSystem.makeDirectory(outputDirectory, { recursive: true });
|
|
662
|
-
const encodedSnapshot = encodeSchemaSnapshot(discovered.schema);
|
|
663
|
-
const snapshotBytes = utf8Bytes(encodedSnapshot);
|
|
664
|
-
yield* fileSystem.writeFile(path.join(outputDirectory, "schema.json"), snapshotBytes);
|
|
665
|
-
const functions = yield* Effect.forEach(
|
|
666
|
-
discovered.functions,
|
|
667
|
-
(definition) => buildServerFunction(appDirectory, outputDirectory, conditions, definition),
|
|
668
|
-
{ concurrency: 4 },
|
|
518
|
+
return yield* compileManagedServer(
|
|
519
|
+
appDirectory,
|
|
520
|
+
outputDirectory,
|
|
521
|
+
yield* serverConditions(),
|
|
522
|
+
discovered,
|
|
669
523
|
);
|
|
670
|
-
const manifest = {
|
|
671
|
-
formatVersion: 3,
|
|
672
|
-
environment: {
|
|
673
|
-
artifact: yield* artifactReference(serverEnvironmentPath, environmentBytes),
|
|
674
|
-
fields: discovered.environment.fields,
|
|
675
|
-
},
|
|
676
|
-
schema: yield* artifactReference(schemaSnapshotPath, snapshotBytes),
|
|
677
|
-
functions,
|
|
678
|
-
} satisfies ServerBuildManifest;
|
|
679
|
-
const encodedManifest = `${encodeCanonical(ServerBuildManifest, manifest)}\n`;
|
|
680
|
-
const manifestPath = path.join(outputDirectory, "manifest.json");
|
|
681
|
-
yield* fileSystem.writeFileString(manifestPath, encodedManifest);
|
|
682
|
-
yield* Schema.decodeEffect(Schema.fromJsonString(ServerBuildManifest))(encodedManifest).pipe(
|
|
683
|
-
Effect.mapError(() =>
|
|
684
|
-
InvalidBuildOutput.make({ message: "Ignotum emitted an invalid server manifest." }),
|
|
685
|
-
),
|
|
686
|
-
);
|
|
687
|
-
|
|
688
|
-
return {
|
|
689
|
-
environment: { bytes: environmentBytes, path: serverEnvironmentPath },
|
|
690
|
-
functions: functions.length,
|
|
691
|
-
manifestPath,
|
|
692
|
-
} satisfies ServerBuildResult;
|
|
693
524
|
});
|
package/src/cli/client-config.ts
CHANGED
|
@@ -1,29 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { fileURLToPath } from "node:url";
|
|
3
|
-
|
|
4
|
-
import { Effect, FileSystem, Path, Schema } from "effect";
|
|
5
|
-
import { defaultClientConditions, normalizePath } from "vite";
|
|
6
|
-
import type { Alias } from "vite";
|
|
7
|
-
|
|
8
|
-
const clientEntryFileName = "index.tsx";
|
|
9
|
-
const clientIconFileName = "icon.svg";
|
|
10
|
-
const preactSpecifiers = [
|
|
11
|
-
"preact/jsx-dev-runtime",
|
|
12
|
-
"preact/jsx-runtime",
|
|
13
|
-
"preact/devtools",
|
|
14
|
-
"preact/debug",
|
|
15
|
-
"preact/hooks",
|
|
16
|
-
"preact",
|
|
17
|
-
] as const;
|
|
18
|
-
const prefreshSpecifiers = ["@prefresh/core", "@prefresh/utils"] as const;
|
|
19
|
-
|
|
20
|
-
export class ClientFileNotFound extends Schema.TaggedError<ClientFileNotFound>()(
|
|
21
|
-
"ClientFileNotFound",
|
|
22
|
-
{
|
|
23
|
-
message: Schema.String,
|
|
24
|
-
path: Schema.String,
|
|
25
|
-
},
|
|
26
|
-
) {}
|
|
1
|
+
import { Schema } from "effect";
|
|
27
2
|
|
|
28
3
|
export class InvalidClientFile extends Schema.TaggedError<InvalidClientFile>()(
|
|
29
4
|
"InvalidClientFile",
|
|
@@ -32,117 +7,3 @@ export class InvalidClientFile extends Schema.TaggedError<InvalidClientFile>()(
|
|
|
32
7
|
path: Schema.String,
|
|
33
8
|
},
|
|
34
9
|
) {}
|
|
35
|
-
|
|
36
|
-
export class ClientRuntimeResolutionFailed extends Schema.TaggedError<ClientRuntimeResolutionFailed>()(
|
|
37
|
-
"ClientRuntimeResolutionFailed",
|
|
38
|
-
{
|
|
39
|
-
cause: Schema.Defect(),
|
|
40
|
-
message: Schema.String,
|
|
41
|
-
},
|
|
42
|
-
) {}
|
|
43
|
-
|
|
44
|
-
export interface ClientBuildConfig {
|
|
45
|
-
readonly aliases: ReadonlyArray<Alias>;
|
|
46
|
-
readonly conditions: ReadonlyArray<string>;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
export interface ClientFiles {
|
|
50
|
-
readonly clientDirectory: string;
|
|
51
|
-
readonly entryPath: string;
|
|
52
|
-
readonly iconPath: string | undefined;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
export const validateClientFiles = Effect.fn("ClientConfig.validateFiles")(function* (
|
|
56
|
-
appDirectory: string,
|
|
57
|
-
) {
|
|
58
|
-
const fileSystem = yield* FileSystem.FileSystem;
|
|
59
|
-
const path = yield* Path.Path;
|
|
60
|
-
const clientDirectory = path.join(appDirectory, "client");
|
|
61
|
-
const nestedPublicDirectory = path.join(clientDirectory, "public");
|
|
62
|
-
if (yield* fileSystem.exists(nestedPublicDirectory)) {
|
|
63
|
-
return yield* InvalidClientFile.make({
|
|
64
|
-
message: `Client public files must be placed in the top-level public directory, not ${nestedPublicDirectory}.`,
|
|
65
|
-
path: nestedPublicDirectory,
|
|
66
|
-
});
|
|
67
|
-
}
|
|
68
|
-
const entryPath = path.join(clientDirectory, clientEntryFileName);
|
|
69
|
-
if (!(yield* fileSystem.exists(entryPath))) {
|
|
70
|
-
return yield* ClientFileNotFound.make({
|
|
71
|
-
message: `Required client file not found: ${entryPath}`,
|
|
72
|
-
path: entryPath,
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
|
-
const entryInfo = yield* fileSystem.stat(entryPath);
|
|
76
|
-
if (entryInfo.type !== "File") {
|
|
77
|
-
return yield* InvalidClientFile.make({
|
|
78
|
-
message: `Required client entry is not a regular file: ${entryPath}`,
|
|
79
|
-
path: entryPath,
|
|
80
|
-
});
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
const iconPath = path.join(clientDirectory, clientIconFileName);
|
|
84
|
-
const hasIcon = yield* fileSystem.exists(iconPath);
|
|
85
|
-
if (hasIcon) {
|
|
86
|
-
const iconInfo = yield* fileSystem.stat(iconPath);
|
|
87
|
-
if (iconInfo.type !== "File") {
|
|
88
|
-
return yield* InvalidClientFile.make({
|
|
89
|
-
message: `Optional client icon is not a regular file: ${iconPath}`,
|
|
90
|
-
path: iconPath,
|
|
91
|
-
});
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
return {
|
|
96
|
-
clientDirectory,
|
|
97
|
-
entryPath,
|
|
98
|
-
iconPath: hasIcon ? iconPath : undefined,
|
|
99
|
-
} satisfies ClientFiles;
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
export const resolveClientBuildConfig = Effect.fn("ClientConfig.resolve")(function* (
|
|
103
|
-
includePrefresh: boolean,
|
|
104
|
-
) {
|
|
105
|
-
const fileSystem = yield* FileSystem.FileSystem;
|
|
106
|
-
const sourceClientEntry = fileURLToPath(new URL("../../src/client/index.ts", import.meta.url));
|
|
107
|
-
const sourceContractsEntry = fileURLToPath(
|
|
108
|
-
new URL("../../../contracts/src/schema/index.ts", import.meta.url),
|
|
109
|
-
);
|
|
110
|
-
const hasSourceClient = yield* fileSystem.exists(sourceClientEntry);
|
|
111
|
-
const hasSourceContracts = yield* fileSystem.exists(sourceContractsEntry);
|
|
112
|
-
const hasWorkspaceSourceExports = hasSourceClient && hasSourceContracts;
|
|
113
|
-
|
|
114
|
-
return yield* Effect.try({
|
|
115
|
-
try: (): ClientBuildConfig => {
|
|
116
|
-
const prefreshRequire = createRequire(import.meta.resolve("@prefresh/vite"));
|
|
117
|
-
const aliases: ReadonlyArray<Alias> = [
|
|
118
|
-
{
|
|
119
|
-
find: /^tailwindcss$/,
|
|
120
|
-
replacement: normalizePath(fileURLToPath(import.meta.resolve("tailwindcss/index.css"))),
|
|
121
|
-
},
|
|
122
|
-
...preactSpecifiers.map((specifier) => ({
|
|
123
|
-
find: specifier,
|
|
124
|
-
replacement: normalizePath(fileURLToPath(import.meta.resolve(specifier))),
|
|
125
|
-
})),
|
|
126
|
-
...(includePrefresh
|
|
127
|
-
? prefreshSpecifiers.map((specifier) => ({
|
|
128
|
-
find: specifier,
|
|
129
|
-
replacement: normalizePath(prefreshRequire.resolve(specifier)),
|
|
130
|
-
}))
|
|
131
|
-
: []),
|
|
132
|
-
];
|
|
133
|
-
|
|
134
|
-
return {
|
|
135
|
-
aliases,
|
|
136
|
-
conditions: [
|
|
137
|
-
...(hasWorkspaceSourceExports ? ["@ignotum/source"] : []),
|
|
138
|
-
...defaultClientConditions,
|
|
139
|
-
],
|
|
140
|
-
};
|
|
141
|
-
},
|
|
142
|
-
catch: (cause) =>
|
|
143
|
-
ClientRuntimeResolutionFailed.make({
|
|
144
|
-
cause,
|
|
145
|
-
message: "Ignotum could not resolve its client runtime.",
|
|
146
|
-
}),
|
|
147
|
-
});
|
|
148
|
-
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const clientStylesSource = '@import "tailwindcss";\n';
|
package/src/cli/codegen.ts
CHANGED
|
@@ -2,7 +2,8 @@ import { Array, Effect, FileSystem, Path, Schema, String } from "effect";
|
|
|
2
2
|
|
|
3
3
|
import { FunctionNamePart } from "@ignotum/contracts/runtime/sync";
|
|
4
4
|
|
|
5
|
-
const generatedHeader = "// Generated by `ignotum codegen`. Do not edit.";
|
|
5
|
+
export const generatedHeader = "// Generated by `ignotum codegen`. Do not edit.";
|
|
6
|
+
export const generatedImageTypes = '/// <reference types="ignotum/image-assets" />';
|
|
6
7
|
|
|
7
8
|
export class SchemaNotFound extends Schema.TaggedError<SchemaNotFound>()("SchemaNotFound", {
|
|
8
9
|
message: Schema.String,
|
|
@@ -25,7 +26,7 @@ export class GeneratedFileConflict extends Schema.TaggedError<GeneratedFileConfl
|
|
|
25
26
|
},
|
|
26
27
|
) {}
|
|
27
28
|
|
|
28
|
-
interface GeneratedOutput {
|
|
29
|
+
export interface GeneratedOutput {
|
|
29
30
|
readonly content: string;
|
|
30
31
|
readonly path: string;
|
|
31
32
|
}
|
|
@@ -99,6 +100,8 @@ const renderApi = (moduleNames: ReadonlyArray<string>): string => {
|
|
|
99
100
|
});
|
|
100
101
|
return `${generatedHeader}
|
|
101
102
|
|
|
103
|
+
${generatedImageTypes}
|
|
104
|
+
|
|
102
105
|
import { createApi } from "ignotum/internal/api";
|
|
103
106
|
|
|
104
107
|
type Modules = {
|
|
@@ -109,7 +112,9 @@ export const api = createApi<Modules>();
|
|
|
109
112
|
`;
|
|
110
113
|
};
|
|
111
114
|
|
|
112
|
-
const inspectOutput = Effect.fn("Codegen.inspectOutput")(function* (
|
|
115
|
+
export const inspectOutput = Effect.fn("Codegen.inspectOutput")(function* (
|
|
116
|
+
output: GeneratedOutput,
|
|
117
|
+
) {
|
|
113
118
|
const fileSystem = yield* FileSystem.FileSystem;
|
|
114
119
|
const exists = yield* fileSystem.exists(output.path);
|
|
115
120
|
|
|
@@ -133,7 +138,7 @@ const inspectOutput = Effect.fn("Codegen.inspectOutput")(function* (output: Gene
|
|
|
133
138
|
return "write" as const;
|
|
134
139
|
});
|
|
135
140
|
|
|
136
|
-
const writeOutput = Effect.fn("Codegen.writeOutput")(function* (output: GeneratedOutput) {
|
|
141
|
+
export const writeOutput = Effect.fn("Codegen.writeOutput")(function* (output: GeneratedOutput) {
|
|
137
142
|
const fileSystem = yield* FileSystem.FileSystem;
|
|
138
143
|
const path = yield* Path.Path;
|
|
139
144
|
const directory = path.dirname(output.path);
|
package/src/cli/command.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { AppSlug } from "@ignotum/contracts/control";
|
|
|
5
5
|
import { IdGenerator } from "@ignotum/shared/id";
|
|
6
6
|
|
|
7
7
|
import packageJson from "../../package.json" with { type: "json" };
|
|
8
|
-
import {
|
|
8
|
+
import { generateClientRoutes } from "./route-codegen.js";
|
|
9
9
|
import {
|
|
10
10
|
AuthCredentialStore,
|
|
11
11
|
login as runLogin,
|
|
@@ -13,7 +13,8 @@ import {
|
|
|
13
13
|
status as readAuthStatus,
|
|
14
14
|
} from "./auth-client.js";
|
|
15
15
|
import { ControlClient } from "./control-client.js";
|
|
16
|
-
import { deploy as runDeploy } from "./deploy.js";
|
|
16
|
+
import { deploy as runDeploy, resumeVersion } from "./deploy.js";
|
|
17
|
+
import { VersionId } from "@ignotum/contracts/runtime/identity";
|
|
17
18
|
import { resetDevDatabase } from "../dev-runtime/dev-database.js";
|
|
18
19
|
import { dev as runDev } from "./dev.js";
|
|
19
20
|
import { createApp } from "./new-app.js";
|
|
@@ -79,7 +80,7 @@ const codegen = Command.make(
|
|
|
79
80
|
Effect.fn("codegen")(function* () {
|
|
80
81
|
const path = yield* Path.Path;
|
|
81
82
|
const terminal = yield* Terminal.Terminal;
|
|
82
|
-
const result = yield*
|
|
83
|
+
const result = yield* generateClientRoutes(path.resolve(".")).pipe(
|
|
83
84
|
Effect.mapError((error) =>
|
|
84
85
|
CliError.UserError.make({ cause: error, userMessage: error.message }),
|
|
85
86
|
),
|
|
@@ -144,15 +145,37 @@ const dev = Command.make(
|
|
|
144
145
|
const deploy = Command.make(
|
|
145
146
|
"deploy",
|
|
146
147
|
{
|
|
148
|
+
resume: Flag.string("resume").pipe(
|
|
149
|
+
Flag.withDescription("Finish activation of an already uploaded version."),
|
|
150
|
+
Flag.withSchema(VersionId),
|
|
151
|
+
Flag.optional,
|
|
152
|
+
),
|
|
147
153
|
app: Flag.string("app").pipe(
|
|
148
154
|
Flag.withDescription("Create or link this app slug on the first deploy."),
|
|
149
155
|
Flag.withSchema(AppSlug),
|
|
150
156
|
Flag.optional,
|
|
151
157
|
),
|
|
152
158
|
},
|
|
153
|
-
Effect.fn("deploy")(function* ({ app }) {
|
|
159
|
+
Effect.fn("deploy")(function* ({ app, resume }) {
|
|
154
160
|
const path = yield* Path.Path;
|
|
155
161
|
const terminal = yield* Terminal.Terminal;
|
|
162
|
+
if (Option.isSome(resume)) {
|
|
163
|
+
const result = yield* resumeVersion(
|
|
164
|
+
path.resolve("."),
|
|
165
|
+
resume.value,
|
|
166
|
+
Option.getOrUndefined(app),
|
|
167
|
+
).pipe(
|
|
168
|
+
// @effect-diagnostics-next-line strictEffectProvide:off This command owns the authenticated control client.
|
|
169
|
+
Effect.provide(ControlClient.layer),
|
|
170
|
+
Effect.mapError((error) =>
|
|
171
|
+
CliError.UserError.make({ cause: error, userMessage: error.message }),
|
|
172
|
+
),
|
|
173
|
+
);
|
|
174
|
+
yield* terminal.display(
|
|
175
|
+
`Version ${result.versionNumber} is live.\n\nApp: ${result.appUrl}\nVersion ID: ${result.versionId}\n`,
|
|
176
|
+
);
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
156
179
|
const result = yield* runDeploy(path.resolve("."), Option.getOrUndefined(app)).pipe(
|
|
157
180
|
// @effect-diagnostics-next-line strictEffectProvide:off The deploy subcommand owns this client layer for its full lifetime.
|
|
158
181
|
Effect.provide(ControlClient.layer),
|
|
@@ -162,7 +185,7 @@ const deploy = Command.make(
|
|
|
162
185
|
);
|
|
163
186
|
|
|
164
187
|
yield* terminal.display(
|
|
165
|
-
`
|
|
188
|
+
`Version ${result.versionNumber} is live.\n\nApp: ${result.appUrl}\nVersion ID: ${result.versionId}\n`,
|
|
166
189
|
);
|
|
167
190
|
}),
|
|
168
191
|
).pipe(Command.withDescription("Build and deploy the application to Ignotum Cloud."));
|