@thinair/factory 0.1.175 → 0.1.179
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/cli/evaluate.ts +1 -6
- package/cli/load.ts +2 -3
- package/domain/load.ts +0 -5
- package/domain/system-elements/node.ts +0 -2
- package/domain/system-elements/registry.ts +5 -7
- package/package.json +1 -1
package/cli/evaluate.ts
CHANGED
|
@@ -26,12 +26,8 @@ export const EvaluateInput = Schema.Struct({
|
|
|
26
26
|
});
|
|
27
27
|
export type EvaluateInput = typeof EvaluateInput.Type;
|
|
28
28
|
|
|
29
|
-
const EvaluateNotice = Schema.Struct({ node: Schema.NullOr(NodeId), at: Schema.NullOr(SourceAt), message: Schema.String });
|
|
30
|
-
|
|
31
29
|
export const EvaluateOutput = Schema.Struct({
|
|
32
30
|
program: Schema.NullOr(Program),
|
|
33
|
-
/** Notes that hold nothing: a retired constructor the code still calls runs as its replacement. */
|
|
34
|
-
notices: Schema.Array(EvaluateNotice),
|
|
35
31
|
problems: Schema.Array(Schema.Struct({
|
|
36
32
|
/** `evaluate`: the code threw while it loaded. `value`: the encoder's checks. */
|
|
37
33
|
step: Schema.Literals(["evaluate", "value"]),
|
|
@@ -77,13 +73,12 @@ const evaluate = Effect.fn("factory.evaluate")(function* (inputPath: string) {
|
|
|
77
73
|
hash: (text) => createHash("sha256").update(text).digest("hex"),
|
|
78
74
|
files: input.files,
|
|
79
75
|
});
|
|
80
|
-
return { program: encoded.program,
|
|
76
|
+
return { program: encoded.program, problems: encoded.problems.map((problem) => ({ step: "value" as const, ...problem })) };
|
|
81
77
|
},
|
|
82
78
|
catch: (error) => error,
|
|
83
79
|
})),
|
|
84
80
|
Effect.catch((error) => Effect.succeed<EvaluateOutput>({
|
|
85
81
|
program: null,
|
|
86
|
-
notices: [],
|
|
87
82
|
problems: [{ step: "evaluate", node: null, at: throwAt(error, input.tree), message: `The factory's code threw while it loaded: ${error instanceof Error ? error.message : String(error)}` }],
|
|
88
83
|
})),
|
|
89
84
|
);
|
package/cli/load.ts
CHANGED
|
@@ -6,7 +6,7 @@ import { createRequire } from "node:module";
|
|
|
6
6
|
import path from "node:path";
|
|
7
7
|
import { fileURLToPath } from "node:url";
|
|
8
8
|
import { Context, Effect, Layer, Result, Schema } from "effect";
|
|
9
|
-
import {
|
|
9
|
+
import { LOAD_VERSION, LoadJson, LoadPost, type Finding, type Load } from "../domain/load";
|
|
10
10
|
import { appShapeProblems, AUTHORING_MODULES, folderKey, IGNORED_FOLDERS, isLoadedPath, memberFiles } from "../domain/system-elements/app-shape";
|
|
11
11
|
import { FrameworkVersion, holesOf, type Node, type Program } from "../domain/system-elements/program";
|
|
12
12
|
import { EvaluateOutputJson, type EvaluateInput } from "./evaluate";
|
|
@@ -272,7 +272,6 @@ const evaluate = Effect.fn("factory.load.evaluate")(function* (input: Omit<Evalu
|
|
|
272
272
|
program: output.program,
|
|
273
273
|
findings: [
|
|
274
274
|
...output.problems.map((problem) => finding(problem.step, problem.message, { node: problem.node, file: problem.at?.file ?? null, line: problem.at?.line ?? null })),
|
|
275
|
-
...output.notices.map((notice) => ({ ...finding("value", notice.message, { node: notice.node, file: notice.at?.file ?? null, line: notice.at?.line ?? null }), notice: true as const })),
|
|
276
275
|
],
|
|
277
276
|
};
|
|
278
277
|
});
|
|
@@ -357,7 +356,7 @@ export const loadFactory = Effect.fn("factory.load")(function* (input: Readonly<
|
|
|
357
356
|
|
|
358
357
|
const load: Load = yield* timed(steps, "encode", Effect.sync((): Load => {
|
|
359
358
|
const all = findings.map(pinned(program));
|
|
360
|
-
return { version: LOAD_VERSION, framework, key: snapshot.key, state: all.
|
|
359
|
+
return { version: LOAD_VERSION, framework, key: snapshot.key, state: all.length > 0 ? "held" : "ready", program, holes: program === null ? [] : holesOf(program), findings: all, cached: false, steps };
|
|
361
360
|
}));
|
|
362
361
|
const encoded = yield* Schema.encodeEffect(LoadJson)(load).pipe(Effect.mapError((error) => new FactoryLoadFailed({ message: `The load does not encode: ${error.message}` })));
|
|
363
362
|
yield* Effect.tryPromise({ try: () => mkdir(path.dirname(cacheFile), { recursive: true }).then(() => writeFile(cacheFile, JSON.stringify(encoded))), catch: failed("Could not write the load cache.") });
|
package/domain/load.ts
CHANGED
|
@@ -22,12 +22,7 @@ export const Finding = Schema.Struct({
|
|
|
22
22
|
file: Schema.NullOr(Schema.String),
|
|
23
23
|
line: Schema.NullOr(Schema.Int),
|
|
24
24
|
message: Schema.String,
|
|
25
|
-
/** A note that holds nothing: the code still runs as written (a retired constructor runs as its replacement). */
|
|
26
|
-
notice: Schema.optionalKey(Schema.Literal(true)),
|
|
27
25
|
});
|
|
28
|
-
|
|
29
|
-
/** Whether a finding holds the load: every finding but a notice does. */
|
|
30
|
-
export const holds = (finding: Readonly<{ notice?: true | undefined }>) => finding.notice !== true;
|
|
31
26
|
export type Finding = typeof Finding.Type;
|
|
32
27
|
|
|
33
28
|
/** `ready` runs (live) or draws (preview). `held` keeps the last good revision: its findings say why. */
|
|
@@ -158,8 +158,6 @@ export interface Encoder {
|
|
|
158
158
|
readonly ref: <T extends NodeTag>(to: T, value: Slot<T>) => Ref<T>;
|
|
159
159
|
/** A problem with this node's settings, pinned to it. */
|
|
160
160
|
readonly problem: (message: string) => void;
|
|
161
|
-
/** A note on this node that holds nothing, pinned to it: its code still runs as written. */
|
|
162
|
-
readonly notice: (message: string) => void;
|
|
163
161
|
}
|
|
164
162
|
|
|
165
163
|
/** The rows a floor reads, by the node each belongs to. The records name their nodes by id. */
|
|
@@ -67,7 +67,7 @@ export type EncodeOptions = Readonly<{
|
|
|
67
67
|
files: Readonly<Record<string, FileFacts>>;
|
|
68
68
|
}>;
|
|
69
69
|
|
|
70
|
-
export type Encoded = Readonly<{ program: Program | null; problems: ReadonlyArray<EncodeProblem
|
|
70
|
+
export type Encoded = Readonly<{ program: Program | null; problems: ReadonlyArray<EncodeProblem> }>;
|
|
71
71
|
|
|
72
72
|
/** JSON with keys sorted at every level: two values are the same when this is. */
|
|
73
73
|
const canonicalJson = (value: unknown): string => JSON.stringify(value, (_key, item: unknown) =>
|
|
@@ -80,7 +80,6 @@ type Draft = Readonly<{ node: Readonly<Record<string, unknown>> & { readonly at:
|
|
|
80
80
|
/** Encode a factory's root, as `factory.ts` exports it, into its Program. */
|
|
81
81
|
export const encodeFactory = (root: unknown, options: EncodeOptions): Encoded => {
|
|
82
82
|
const problems: EncodeProblem[] = [];
|
|
83
|
-
const notices: EncodeProblem[] = [];
|
|
84
83
|
const drafts = new Map<NodeId, Draft>();
|
|
85
84
|
const encodedValues = new Map<object, NodeId>();
|
|
86
85
|
const visiting = new Set<object>();
|
|
@@ -118,7 +117,6 @@ export const encodeFactory = (root: unknown, options: EncodeOptions): Encoded =>
|
|
|
118
117
|
const encoder: Encoder = {
|
|
119
118
|
ref: (tag, slot) => encode(tag, slot, { node: id, at }),
|
|
120
119
|
problem: (message) => problems.push({ node: id, at, message }),
|
|
121
|
-
notice: (message) => notices.push({ node: id, at, message }),
|
|
122
120
|
};
|
|
123
121
|
const settings = (definitions[made.tag] as Definition<Tag>).make(value as never, encoder);
|
|
124
122
|
visiting.delete(value);
|
|
@@ -134,10 +132,10 @@ export const encodeFactory = (root: unknown, options: EncodeOptions): Encoded =>
|
|
|
134
132
|
|
|
135
133
|
if (!isAuthored(root) || headOf(root).tag !== "Factory") {
|
|
136
134
|
problems.push({ node: null, at: { file: "factory.ts", line: 1 }, message: "factory.ts's default export is the factory: export default defineFactory({ ... })." });
|
|
137
|
-
return { program: null, problems
|
|
135
|
+
return { program: null, problems };
|
|
138
136
|
}
|
|
139
137
|
encode("Factory", root, null);
|
|
140
|
-
if (broken) return { program: null, problems
|
|
138
|
+
if (broken) return { program: null, problems };
|
|
141
139
|
|
|
142
140
|
// A node's digest covers its content and, when it holds code, the import closure of its file,
|
|
143
141
|
// stopping at files that make other nodes: those nodes have digests of their own.
|
|
@@ -167,9 +165,9 @@ export const encodeFactory = (root: unknown, options: EncodeOptions): Encoded =>
|
|
|
167
165
|
const decoded = Schema.decodeUnknownResult(Program)({ version: LANGUAGE_VERSION, framework: options.framework, root: ROOT_ID, nodes });
|
|
168
166
|
if (Result.isFailure(decoded)) {
|
|
169
167
|
problems.push({ node: null, at: null, message: `The program does not decode: ${decoded.failure.message}` });
|
|
170
|
-
return { program: null, problems
|
|
168
|
+
return { program: null, problems };
|
|
171
169
|
}
|
|
172
170
|
for (const problem of graphProblems(decoded.success))
|
|
173
171
|
problems.push({ node: problem.node, at: (decoded.success.nodes[problem.node] as Node | undefined)?.at ?? null, message: problem.message });
|
|
174
|
-
return { program: decoded.success, problems
|
|
172
|
+
return { program: decoded.success, problems };
|
|
175
173
|
};
|
package/package.json
CHANGED