ignotum 0.0.2 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +23 -7
- package/dist/cli/bin.mjs +32313 -751
- package/dist/cli/bin.mjs.map +1 -1
- package/dist/runtime/{api-Cpx57mk3.d.ts → api-D2bsAz4T.d.ts} +3 -2
- package/dist/runtime/{api-BXXIZc_Q.js → api-DtX8qPrq.js} +58 -27
- package/dist/runtime/api-DtX8qPrq.js.map +1 -0
- package/dist/runtime/client.d.ts +11 -4
- package/dist/runtime/client.js +343 -79
- package/dist/runtime/client.js.map +1 -1
- package/dist/runtime/{result-B2W-z2wG.js → descriptor-t6BOEGw9-BTHR-ZMv.js} +119 -4
- package/dist/runtime/descriptor-t6BOEGw9-BTHR-ZMv.js.map +1 -0
- package/dist/runtime/id-Btwac71X-B9OeBzvq.d.ts +9 -0
- package/dist/runtime/id-D570vudg.js +26 -0
- package/dist/runtime/id-D570vudg.js.map +1 -0
- package/dist/runtime/{index-BgWROoyk.d.ts → index-Dl_VQGmA.d.ts} +114 -31
- package/dist/runtime/internal/api.d.ts +1 -1
- package/dist/runtime/internal/api.js +1 -1
- package/dist/runtime/internal/host.d.ts +44 -0
- package/dist/runtime/internal/host.js +213 -0
- package/dist/runtime/internal/host.js.map +1 -0
- package/dist/runtime/internal/server.d.ts +1 -1
- package/dist/runtime/internal/server.js +1 -1
- package/dist/runtime/internal/types.d.ts +1 -1
- package/dist/runtime/internal/types.js +1 -1
- package/dist/runtime/{result-C1ZdsM6Y.d.ts → result-BgcHn25t.d.ts} +21 -6
- package/dist/runtime/schema-B-jMZEbs.js +227 -0
- package/dist/runtime/schema-B-jMZEbs.js.map +1 -0
- package/dist/runtime/server.d.ts +2 -2
- package/dist/runtime/server.js +2 -2
- package/package.json +15 -5
- package/src/cli/agent-files.ts +6 -2
- package/src/cli/app-configuration.ts +135 -0
- package/src/cli/bin.ts +24 -1
- package/src/cli/build/artifact.ts +95 -0
- package/src/cli/build/client.ts +103 -0
- package/src/cli/build/server.ts +526 -0
- package/src/cli/client-config.ts +141 -0
- package/src/cli/client-entry.ts +152 -0
- package/src/cli/client-plugin.ts +86 -16
- package/src/cli/codegen.ts +5 -5
- package/src/cli/command.ts +41 -9
- package/src/cli/control-client.ts +343 -0
- package/src/cli/deploy.ts +217 -0
- package/src/cli/dev.ts +43 -108
- package/src/cli/module-boundaries.ts +183 -0
- package/src/cli/{new-project.ts → new-app.ts} +86 -86
- package/src/cli/package-manager.ts +9 -9
- package/src/client/app.ts +15 -0
- package/src/client/errors.ts +1 -17
- package/src/client/index.ts +2 -0
- package/src/client/sync.ts +172 -120
- package/src/dev-runtime/database.ts +253 -96
- package/src/dev-runtime/dev-database.ts +14 -14
- package/src/dev-runtime/functions.ts +57 -88
- package/src/dev-runtime/id.ts +2 -10
- package/src/dev-runtime/migrations.ts +68 -0
- package/src/dev-runtime/sync.ts +266 -83
- package/src/internal/function-definition.ts +77 -0
- package/src/internal/host.ts +1 -0
- package/src/internal/http-paths.ts +3 -1
- package/dist/runtime/api-BXXIZc_Q.js.map +0 -1
- package/dist/runtime/result-B2W-z2wG.js.map +0 -1
- package/dist/runtime/schema-CNEVLF7D.js +0 -116
- package/dist/runtime/schema-CNEVLF7D.js.map +0 -1
|
@@ -1,39 +1,36 @@
|
|
|
1
1
|
import { Effect, FileSystem, Path, Schema, String } from "effect";
|
|
2
2
|
import { ChildProcess, ChildProcessSpawner } from "effect/unstable/process";
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import { agentAppFiles, type AppFile } from "./agent-files.js";
|
|
5
5
|
import { generate } from "./codegen.js";
|
|
6
6
|
import { installDependencies, type PackageManager } from "./package-manager.js";
|
|
7
7
|
|
|
8
|
-
export interface
|
|
8
|
+
export interface NewAppOptions {
|
|
9
9
|
readonly currentDirectory: string;
|
|
10
10
|
readonly directory: string;
|
|
11
11
|
readonly git: boolean;
|
|
12
12
|
readonly install: boolean;
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
export interface
|
|
15
|
+
export interface NewAppResult {
|
|
16
16
|
readonly directory: string;
|
|
17
17
|
readonly gitInitialized: boolean;
|
|
18
18
|
readonly packageManager: PackageManager | null;
|
|
19
|
-
readonly
|
|
19
|
+
readonly appName: string;
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
export class
|
|
23
|
-
"
|
|
22
|
+
export class AppDirectoryNotEmpty extends Schema.TaggedError<AppDirectoryNotEmpty>()(
|
|
23
|
+
"AppDirectoryNotEmpty",
|
|
24
24
|
{
|
|
25
25
|
message: Schema.String,
|
|
26
26
|
path: Schema.String,
|
|
27
27
|
},
|
|
28
28
|
) {}
|
|
29
29
|
|
|
30
|
-
export class
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
path: Schema.String,
|
|
35
|
-
},
|
|
36
|
-
) {}
|
|
30
|
+
export class InvalidAppName extends Schema.TaggedError<InvalidAppName>()("InvalidAppName", {
|
|
31
|
+
message: Schema.String,
|
|
32
|
+
path: Schema.String,
|
|
33
|
+
}) {}
|
|
37
34
|
|
|
38
35
|
export class GitInitializationFailed extends Schema.TaggedError<GitInitializationFailed>()(
|
|
39
36
|
"GitInitializationFailed",
|
|
@@ -44,12 +41,12 @@ export class GitInitializationFailed extends Schema.TaggedError<GitInitializatio
|
|
|
44
41
|
},
|
|
45
42
|
) {}
|
|
46
43
|
|
|
47
|
-
const packageJson = (
|
|
44
|
+
const packageJson = (appName: string): string =>
|
|
48
45
|
`${JSON.stringify(
|
|
49
46
|
{
|
|
50
|
-
name:
|
|
47
|
+
name: appName,
|
|
51
48
|
private: true,
|
|
52
|
-
version: "
|
|
49
|
+
version: "1.0.0",
|
|
53
50
|
type: "module",
|
|
54
51
|
scripts: {
|
|
55
52
|
typecheck: "ignotum codegen && tsc --noEmit",
|
|
@@ -138,12 +135,12 @@ export const increment = mutation({
|
|
|
138
135
|
});
|
|
139
136
|
`;
|
|
140
137
|
|
|
141
|
-
const app = `import { Result, useMutation, useQuery } from "ignotum/client";
|
|
138
|
+
const app = `import { app, Result, useMutation, useQuery } from "ignotum/client";
|
|
142
139
|
|
|
143
140
|
import { api } from "@/_generated/api.js";
|
|
144
141
|
import { counterIncrement } from "@/shared/utils.js";
|
|
145
142
|
|
|
146
|
-
|
|
143
|
+
function App() {
|
|
147
144
|
const count = useQuery(api.counter.get);
|
|
148
145
|
const increment = useMutation(api.counter.increment);
|
|
149
146
|
|
|
@@ -168,22 +165,30 @@ export default function App() {
|
|
|
168
165
|
</main>
|
|
169
166
|
);
|
|
170
167
|
}
|
|
168
|
+
|
|
169
|
+
export default app({
|
|
170
|
+
title: "Counter",
|
|
171
|
+
component: App,
|
|
172
|
+
});
|
|
171
173
|
`;
|
|
172
174
|
|
|
173
|
-
const
|
|
175
|
+
const icon = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
|
176
|
+
<rect width="64" height="64" rx="14" fill="#18181b" />
|
|
177
|
+
<path d="M20 32h24M32 20v24" stroke="#fafafa" stroke-width="6" stroke-linecap="round" />
|
|
178
|
+
</svg>
|
|
174
179
|
`;
|
|
175
180
|
|
|
176
|
-
const
|
|
181
|
+
const utils = `export const counterIncrement = 1;
|
|
177
182
|
`;
|
|
178
183
|
|
|
179
|
-
const readme = (
|
|
184
|
+
const readme = (appName: string): string => `# ${appName}
|
|
180
185
|
|
|
181
186
|
A small Ignotum counter app.
|
|
182
187
|
|
|
183
188
|
## Getting started
|
|
184
189
|
|
|
185
|
-
You need Node.js 22.18 or newer. The
|
|
186
|
-
created the
|
|
190
|
+
You need Node.js 22.18 or newer. The app generator installs dependencies by default. If you
|
|
191
|
+
created the app with \`--no-install\`, install them now:
|
|
187
192
|
|
|
188
193
|
\`\`\`sh
|
|
189
194
|
npx ignotum install
|
|
@@ -199,15 +204,16 @@ npx ignotum dev
|
|
|
199
204
|
|
|
200
205
|
Open <http://127.0.0.1:3210>.
|
|
201
206
|
|
|
202
|
-
The
|
|
207
|
+
The app generator creates \`_generated\`. The dev server checks those files before it starts
|
|
203
208
|
and updates them when the schema or server functions change.
|
|
204
209
|
|
|
205
|
-
##
|
|
210
|
+
## App files
|
|
206
211
|
|
|
207
212
|
- \`server/schema.ts\` defines the database tables.
|
|
208
213
|
- \`server/counter.ts\` defines the query and mutation used by the counter.
|
|
209
|
-
- \`client/
|
|
210
|
-
- \`client/
|
|
214
|
+
- \`client/index.tsx\` defines the app title and UI.
|
|
215
|
+
- \`client/icon.svg\` is the optional app icon.
|
|
216
|
+
- Ignotum loads Tailwind CSS automatically. Custom CSS files are ordinary client modules.
|
|
211
217
|
- \`shared/utils.ts\` contains code shared across the app.
|
|
212
218
|
- \`_generated\` contains Ignotum's generated types and bindings. Do not edit it by hand.
|
|
213
219
|
|
|
@@ -221,43 +227,43 @@ npx tsc --noEmit
|
|
|
221
227
|
## Claude Code
|
|
222
228
|
|
|
223
229
|
If you use Claude Code, rename \`AGENTS.md\` to \`CLAUDE.md\` and \`.agents\` to \`.claude\` so it
|
|
224
|
-
can find the
|
|
230
|
+
can find the app instructions and Ignotum skill.
|
|
225
231
|
`;
|
|
226
232
|
|
|
227
|
-
const
|
|
228
|
-
{ content: app, path: "client/
|
|
229
|
-
{ content:
|
|
233
|
+
const appFiles = (appName: string): ReadonlyArray<AppFile> => [
|
|
234
|
+
{ content: app, path: "client/index.tsx" },
|
|
235
|
+
{ content: icon, path: "client/icon.svg" },
|
|
230
236
|
{ content: counterFunctions, path: "server/counter.ts" },
|
|
231
237
|
{ content: schema, path: "server/schema.ts" },
|
|
232
238
|
{ content: utils, path: "shared/utils.ts" },
|
|
233
|
-
{ content: packageJson(
|
|
239
|
+
{ content: packageJson(appName), path: "package.json" },
|
|
234
240
|
{ content: tsconfig, path: "tsconfig.json" },
|
|
235
241
|
{ content: gitignore, path: ".gitignore" },
|
|
236
|
-
{ content: readme(
|
|
237
|
-
...
|
|
242
|
+
{ content: readme(appName), path: "README.md" },
|
|
243
|
+
...agentAppFiles,
|
|
238
244
|
];
|
|
239
245
|
|
|
240
|
-
const
|
|
241
|
-
|
|
242
|
-
file:
|
|
246
|
+
const writeAppFile = Effect.fn("NewApp.writeAppFile")(function* (
|
|
247
|
+
appDirectory: string,
|
|
248
|
+
file: AppFile,
|
|
243
249
|
) {
|
|
244
250
|
const fileSystem = yield* FileSystem.FileSystem;
|
|
245
251
|
const path = yield* Path.Path;
|
|
246
|
-
const filePath = path.join(
|
|
252
|
+
const filePath = path.join(appDirectory, file.path);
|
|
247
253
|
|
|
248
254
|
yield* fileSystem.makeDirectory(path.dirname(filePath), { recursive: true });
|
|
249
255
|
yield* fileSystem.writeFileString(filePath, file.content, { flag: "wx" });
|
|
250
256
|
});
|
|
251
257
|
|
|
252
|
-
const gitExitCode = Effect.fn("
|
|
253
|
-
|
|
258
|
+
const gitExitCode = Effect.fn("NewApp.gitExitCode")(function* (
|
|
259
|
+
appDirectory: string,
|
|
254
260
|
args: ReadonlyArray<string>,
|
|
255
261
|
) {
|
|
256
262
|
const spawner = yield* ChildProcessSpawner.ChildProcessSpawner;
|
|
257
263
|
return yield* spawner
|
|
258
264
|
.exitCode(
|
|
259
265
|
ChildProcess.make("git", args, {
|
|
260
|
-
cwd:
|
|
266
|
+
cwd: appDirectory,
|
|
261
267
|
stderr: "ignore",
|
|
262
268
|
stdout: "ignore",
|
|
263
269
|
}),
|
|
@@ -266,36 +272,36 @@ const gitExitCode = Effect.fn("NewProject.gitExitCode")(function* (
|
|
|
266
272
|
Effect.mapError((cause) =>
|
|
267
273
|
GitInitializationFailed.make({
|
|
268
274
|
cause,
|
|
269
|
-
message: `Could not run Git in ${
|
|
270
|
-
path:
|
|
275
|
+
message: `Could not run Git in ${appDirectory}.`,
|
|
276
|
+
path: appDirectory,
|
|
271
277
|
}),
|
|
272
278
|
),
|
|
273
279
|
);
|
|
274
280
|
});
|
|
275
281
|
|
|
276
|
-
const runGit = Effect.fn("
|
|
277
|
-
|
|
282
|
+
const runGit = Effect.fn("NewApp.runGit")(function* (
|
|
283
|
+
appDirectory: string,
|
|
278
284
|
args: ReadonlyArray<string>,
|
|
279
285
|
action: string,
|
|
280
286
|
) {
|
|
281
|
-
const exitCode = yield* gitExitCode(
|
|
287
|
+
const exitCode = yield* gitExitCode(appDirectory, args);
|
|
282
288
|
|
|
283
289
|
if (exitCode !== ChildProcessSpawner.ExitCode(0)) {
|
|
284
290
|
return yield* GitInitializationFailed.make({
|
|
285
|
-
message: `Git exited with code ${exitCode} while ${action} in ${
|
|
286
|
-
path:
|
|
291
|
+
message: `Git exited with code ${exitCode} while ${action} in ${appDirectory}.`,
|
|
292
|
+
path: appDirectory,
|
|
287
293
|
});
|
|
288
294
|
}
|
|
289
295
|
});
|
|
290
296
|
|
|
291
|
-
const initializeGit = Effect.fn("
|
|
292
|
-
yield* runGit(
|
|
293
|
-
yield* runGit(
|
|
297
|
+
const initializeGit = Effect.fn("NewApp.initializeGit")(function* (appDirectory: string) {
|
|
298
|
+
yield* runGit(appDirectory, ["init", "--quiet"], "initializing the repository");
|
|
299
|
+
yield* runGit(appDirectory, ["add", "--all"], "staging the initial files");
|
|
294
300
|
|
|
295
301
|
const [hasName, hasEmail] = yield* Effect.all(
|
|
296
302
|
[
|
|
297
|
-
gitExitCode(
|
|
298
|
-
gitExitCode(
|
|
303
|
+
gitExitCode(appDirectory, ["config", "user.name"]),
|
|
304
|
+
gitExitCode(appDirectory, ["config", "user.email"]),
|
|
299
305
|
],
|
|
300
306
|
{ concurrency: "unbounded" },
|
|
301
307
|
).pipe(
|
|
@@ -309,69 +315,63 @@ const initializeGit = Effect.fn("NewProject.initializeGit")(function* (projectDi
|
|
|
309
315
|
: ["-c", "user.name=Ignotum", "-c", "user.email=ignotum@localhost"];
|
|
310
316
|
|
|
311
317
|
yield* runGit(
|
|
312
|
-
|
|
318
|
+
appDirectory,
|
|
313
319
|
[...identity, "commit", "--quiet", "--no-gpg-sign", "-m", "Init"],
|
|
314
320
|
"creating the initial commit",
|
|
315
321
|
);
|
|
316
322
|
});
|
|
317
323
|
|
|
318
|
-
export const
|
|
319
|
-
options: NewProjectOptions,
|
|
320
|
-
) {
|
|
324
|
+
export const createApp = Effect.fn("NewApp.createApp")(function* (options: NewAppOptions) {
|
|
321
325
|
const fileSystem = yield* FileSystem.FileSystem;
|
|
322
326
|
const path = yield* Path.Path;
|
|
323
|
-
const
|
|
324
|
-
const
|
|
327
|
+
const appDirectory = path.resolve(options.currentDirectory, options.directory);
|
|
328
|
+
const appName = String.kebabCase(path.basename(appDirectory));
|
|
325
329
|
|
|
326
|
-
if (
|
|
327
|
-
return yield*
|
|
328
|
-
message: `Could not derive a package name from ${
|
|
329
|
-
path:
|
|
330
|
+
if (appName.length === 0) {
|
|
331
|
+
return yield* InvalidAppName.make({
|
|
332
|
+
message: `Could not derive a package name from ${appDirectory}.`,
|
|
333
|
+
path: appDirectory,
|
|
330
334
|
});
|
|
331
335
|
}
|
|
332
336
|
|
|
333
|
-
const exists = yield* fileSystem.exists(
|
|
337
|
+
const exists = yield* fileSystem.exists(appDirectory);
|
|
334
338
|
|
|
335
339
|
if (exists) {
|
|
336
|
-
const info = yield* fileSystem.stat(
|
|
340
|
+
const info = yield* fileSystem.stat(appDirectory);
|
|
337
341
|
if (info.type !== "Directory") {
|
|
338
|
-
return yield*
|
|
339
|
-
message: `${
|
|
340
|
-
path:
|
|
342
|
+
return yield* AppDirectoryNotEmpty.make({
|
|
343
|
+
message: `${appDirectory} already exists and is not an empty directory.`,
|
|
344
|
+
path: appDirectory,
|
|
341
345
|
});
|
|
342
346
|
}
|
|
343
347
|
|
|
344
|
-
const entries = yield* fileSystem.readDirectory(
|
|
348
|
+
const entries = yield* fileSystem.readDirectory(appDirectory);
|
|
345
349
|
if (entries.length > 0) {
|
|
346
|
-
return yield*
|
|
347
|
-
message: `${
|
|
348
|
-
path:
|
|
350
|
+
return yield* AppDirectoryNotEmpty.make({
|
|
351
|
+
message: `${appDirectory} is not empty. Choose an empty directory.`,
|
|
352
|
+
path: appDirectory,
|
|
349
353
|
});
|
|
350
354
|
}
|
|
351
355
|
} else {
|
|
352
|
-
yield* fileSystem.makeDirectory(
|
|
356
|
+
yield* fileSystem.makeDirectory(appDirectory, { recursive: true });
|
|
353
357
|
}
|
|
354
358
|
|
|
355
|
-
yield* Effect.forEach(
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
{
|
|
359
|
-
discard: true,
|
|
360
|
-
},
|
|
361
|
-
);
|
|
359
|
+
yield* Effect.forEach(appFiles(appName), (file) => writeAppFile(appDirectory, file), {
|
|
360
|
+
discard: true,
|
|
361
|
+
});
|
|
362
362
|
|
|
363
|
-
yield* generate(
|
|
363
|
+
yield* generate(appDirectory);
|
|
364
364
|
|
|
365
|
-
const packageManager = options.install ? yield* installDependencies(
|
|
365
|
+
const packageManager = options.install ? yield* installDependencies(appDirectory) : null;
|
|
366
366
|
|
|
367
367
|
if (options.git) {
|
|
368
|
-
yield* initializeGit(
|
|
368
|
+
yield* initializeGit(appDirectory);
|
|
369
369
|
}
|
|
370
370
|
|
|
371
371
|
return {
|
|
372
|
-
directory:
|
|
372
|
+
directory: appDirectory,
|
|
373
373
|
gitInitialized: options.git,
|
|
374
374
|
packageManager,
|
|
375
|
-
|
|
376
|
-
} satisfies
|
|
375
|
+
appName,
|
|
376
|
+
} satisfies NewAppResult;
|
|
377
377
|
});
|
|
@@ -13,13 +13,13 @@ export class DependencyInstallationFailed extends Schema.TaggedError<DependencyI
|
|
|
13
13
|
) {}
|
|
14
14
|
|
|
15
15
|
const installWith = Effect.fn("PackageManager.installWith")(function* (
|
|
16
|
-
|
|
16
|
+
appDirectory: string,
|
|
17
17
|
packageManager: PackageManager,
|
|
18
18
|
) {
|
|
19
19
|
const spawner = yield* ChildProcessSpawner.ChildProcessSpawner;
|
|
20
20
|
const exitCode = yield* spawner.exitCode(
|
|
21
21
|
ChildProcess.make(packageManager, ["install"], {
|
|
22
|
-
cwd:
|
|
22
|
+
cwd: appDirectory,
|
|
23
23
|
stderr: "inherit",
|
|
24
24
|
stdin: "inherit",
|
|
25
25
|
stdout: "inherit",
|
|
@@ -28,8 +28,8 @@ const installWith = Effect.fn("PackageManager.installWith")(function* (
|
|
|
28
28
|
|
|
29
29
|
if (exitCode !== ChildProcessSpawner.ExitCode(0)) {
|
|
30
30
|
return yield* DependencyInstallationFailed.make({
|
|
31
|
-
message: `${packageManager} install exited with code ${exitCode} in ${
|
|
32
|
-
path:
|
|
31
|
+
message: `${packageManager} install exited with code ${exitCode} in ${appDirectory}.`,
|
|
32
|
+
path: appDirectory,
|
|
33
33
|
});
|
|
34
34
|
}
|
|
35
35
|
|
|
@@ -37,18 +37,18 @@ const installWith = Effect.fn("PackageManager.installWith")(function* (
|
|
|
37
37
|
});
|
|
38
38
|
|
|
39
39
|
export const installDependencies = Effect.fn("PackageManager.installDependencies")(function* (
|
|
40
|
-
|
|
40
|
+
appDirectory: string,
|
|
41
41
|
) {
|
|
42
|
-
return yield* installWith(
|
|
42
|
+
return yield* installWith(appDirectory, "pnpm").pipe(
|
|
43
43
|
Effect.catchReasons("PlatformError", {
|
|
44
|
-
NotFound: () => installWith(
|
|
44
|
+
NotFound: () => installWith(appDirectory, "npm"),
|
|
45
45
|
}),
|
|
46
46
|
Effect.catchTags({
|
|
47
47
|
PlatformError: (cause) =>
|
|
48
48
|
DependencyInstallationFailed.make({
|
|
49
49
|
cause,
|
|
50
|
-
message: `Could not run pnpm or npm in ${
|
|
51
|
-
path:
|
|
50
|
+
message: `Could not run pnpm or npm in ${appDirectory}.`,
|
|
51
|
+
path: appDirectory,
|
|
52
52
|
}),
|
|
53
53
|
}),
|
|
54
54
|
);
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { ComponentType } from "preact";
|
|
2
|
+
|
|
3
|
+
export interface AppDefinition<Component extends ComponentType<{}> = ComponentType<{}>> {
|
|
4
|
+
readonly component: Component;
|
|
5
|
+
readonly title: string;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export const app = <Component extends ComponentType<{}>>(
|
|
9
|
+
definition: AppDefinition<Component>,
|
|
10
|
+
): AppDefinition<Component> => {
|
|
11
|
+
if (definition.title.trim().length === 0) {
|
|
12
|
+
throw new Error("The app title must contain a non-whitespace character.");
|
|
13
|
+
}
|
|
14
|
+
return definition;
|
|
15
|
+
};
|
package/src/client/errors.ts
CHANGED
|
@@ -1,12 +1,7 @@
|
|
|
1
1
|
/** @effect-diagnostics globalConsole:skip-file */
|
|
2
2
|
import { Cause, Effect, ErrorReporter, Schema } from "effect";
|
|
3
3
|
|
|
4
|
-
import {
|
|
5
|
-
FunctionAddress,
|
|
6
|
-
Operation,
|
|
7
|
-
ProtocolErrorCode,
|
|
8
|
-
RequestId,
|
|
9
|
-
} from "@ignotum/contracts/runtime/sync";
|
|
4
|
+
import { FunctionAddress, Operation, ProtocolErrorCode } from "@ignotum/contracts/runtime/sync";
|
|
10
5
|
|
|
11
6
|
export class ConnectionUnavailable extends Schema.TaggedError<ConnectionUnavailable>()(
|
|
12
7
|
"ConnectionUnavailable",
|
|
@@ -50,23 +45,12 @@ export class ServerProtocolError extends Schema.TaggedError<ServerProtocolError>
|
|
|
50
45
|
},
|
|
51
46
|
) {}
|
|
52
47
|
|
|
53
|
-
export class MutationOutcomeUnknown extends Schema.TaggedError<MutationOutcomeUnknown>()(
|
|
54
|
-
"MutationOutcomeUnknown",
|
|
55
|
-
{
|
|
56
|
-
cause: Schema.optional(Schema.Defect()),
|
|
57
|
-
function: FunctionAddress,
|
|
58
|
-
id: RequestId,
|
|
59
|
-
message: Schema.String,
|
|
60
|
-
},
|
|
61
|
-
) {}
|
|
62
|
-
|
|
63
48
|
export const ClientInfrastructureError = Schema.Union([
|
|
64
49
|
ConnectionUnavailable,
|
|
65
50
|
InvalidClientMessage,
|
|
66
51
|
InvalidMutationArguments,
|
|
67
52
|
InvalidServerMessage,
|
|
68
53
|
ServerProtocolError,
|
|
69
|
-
MutationOutcomeUnknown,
|
|
70
54
|
]);
|
|
71
55
|
export type ClientInfrastructureError = typeof ClientInfrastructureError.Type;
|
|
72
56
|
|
package/src/client/index.ts
CHANGED
|
@@ -12,6 +12,8 @@ export type { InternalServerError } from "@ignotum/contracts/runtime/result";
|
|
|
12
12
|
export { useMutation, useQuery } from "./hooks.js";
|
|
13
13
|
export { Query } from "./query.js";
|
|
14
14
|
export type { QuerySkip } from "./query.js";
|
|
15
|
+
export { app } from "./app.js";
|
|
16
|
+
export type { AppDefinition } from "./app.js";
|
|
15
17
|
|
|
16
18
|
export {
|
|
17
19
|
Component,
|