@fieldia/core 0.9.2 → 0.11.0
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 +199 -0
- package/package.json +1 -1
- package/schema/page.schema.json +1837 -94
- package/src/index.d.mts +1 -0
- package/src/index.d.ts +1 -0
- package/src/index.js +4 -1
- package/src/index.js.map +1 -1
- package/src/index.mjs +1 -0
- package/src/index.mjs.map +1 -1
- package/src/lib/expression/evaluator.d.mts +6 -5
- package/src/lib/expression/evaluator.d.ts +6 -5
- package/src/lib/expression/evaluator.js +37 -22
- package/src/lib/expression/evaluator.js.map +1 -1
- package/src/lib/expression/evaluator.mjs +32 -18
- package/src/lib/expression/evaluator.mjs.map +1 -1
- package/src/lib/expression/expression.d.mts +21 -0
- package/src/lib/expression/expression.d.ts +21 -0
- package/src/lib/expression/expression.js +29 -0
- package/src/lib/expression/expression.js.map +1 -0
- package/src/lib/expression/expression.mjs +26 -0
- package/src/lib/expression/expression.mjs.map +1 -0
- package/src/lib/expression/extractFieldNames.js +6 -1
- package/src/lib/expression/extractFieldNames.js.map +1 -1
- package/src/lib/expression/extractFieldNames.mjs +6 -1
- package/src/lib/expression/extractFieldNames.mjs.map +1 -1
- package/src/lib/expression/functions.d.mts +35 -0
- package/src/lib/expression/functions.d.ts +35 -0
- package/src/lib/expression/functions.js +129 -0
- package/src/lib/expression/functions.js.map +1 -0
- package/src/lib/expression/functions.mjs +124 -0
- package/src/lib/expression/functions.mjs.map +1 -0
- package/src/lib/expression/modifier.d.mts +3 -1
- package/src/lib/expression/modifier.d.ts +3 -1
- package/src/lib/expression/modifier.js +4 -27
- package/src/lib/expression/modifier.js.map +1 -1
- package/src/lib/expression/modifier.mjs +3 -26
- package/src/lib/expression/modifier.mjs.map +1 -1
- package/src/lib/expression/operations.d.mts +25 -0
- package/src/lib/expression/operations.d.ts +25 -0
- package/src/lib/expression/operations.js +81 -0
- package/src/lib/expression/operations.js.map +1 -0
- package/src/lib/expression/operations.mjs +72 -0
- package/src/lib/expression/operations.mjs.map +1 -0
- package/src/lib/expression/order.d.mts +11 -0
- package/src/lib/expression/order.d.ts +11 -0
- package/src/lib/expression/order.js +36 -0
- package/src/lib/expression/order.js.map +1 -0
- package/src/lib/expression/order.mjs +33 -0
- package/src/lib/expression/order.mjs.map +1 -0
- package/src/lib/expression/parser.d.mts +34 -4
- package/src/lib/expression/parser.d.ts +34 -4
- package/src/lib/expression/parser.js +72 -6
- package/src/lib/expression/parser.js.map +1 -1
- package/src/lib/expression/parser.mjs +72 -6
- package/src/lib/expression/parser.mjs.map +1 -1
- package/src/lib/expression/reads.d.mts +8 -0
- package/src/lib/expression/reads.d.ts +8 -0
- package/src/lib/expression/reads.js +48 -0
- package/src/lib/expression/reads.js.map +1 -0
- package/src/lib/expression/reads.mjs +44 -0
- package/src/lib/expression/reads.mjs.map +1 -0
- package/src/lib/expression/tokenizer.d.mts +7 -6
- package/src/lib/expression/tokenizer.d.ts +7 -6
- package/src/lib/expression/tokenizer.js +28 -18
- package/src/lib/expression/tokenizer.js.map +1 -1
- package/src/lib/expression/tokenizer.mjs +28 -18
- package/src/lib/expression/tokenizer.mjs.map +1 -1
- package/src/lib/format/actions.d.mts +692 -0
- package/src/lib/format/actions.d.ts +692 -0
- package/src/lib/format/actions.js +53 -0
- package/src/lib/format/actions.js.map +1 -0
- package/src/lib/format/actions.mjs +50 -0
- package/src/lib/format/actions.mjs.map +1 -0
- package/src/lib/format/field.d.mts +686 -5
- package/src/lib/format/field.d.ts +686 -5
- package/src/lib/format/field.js +117 -13
- package/src/lib/format/field.js.map +1 -1
- package/src/lib/format/field.mjs +116 -12
- package/src/lib/format/field.mjs.map +1 -1
- package/src/lib/format/layout.d.mts +1130 -22
- package/src/lib/format/layout.d.ts +1130 -22
- package/src/lib/format/layout.js +67 -5
- package/src/lib/format/layout.js.map +1 -1
- package/src/lib/format/layout.mjs +66 -4
- package/src/lib/format/layout.mjs.map +1 -1
- package/src/lib/format/layout.types.d.mts +2 -1
- package/src/lib/format/layout.types.d.ts +2 -1
- package/src/lib/format/names.d.mts +1 -1
- package/src/lib/format/names.d.ts +1 -1
- package/src/lib/format/names.js +1 -0
- package/src/lib/format/names.js.map +1 -1
- package/src/lib/format/names.mjs +1 -0
- package/src/lib/format/names.mjs.map +1 -1
- package/src/lib/format/page.d.mts +1007 -7
- package/src/lib/format/page.d.ts +1007 -7
- package/src/lib/format/page.js +28 -0
- package/src/lib/format/page.js.map +1 -1
- package/src/lib/format/page.mjs +28 -0
- package/src/lib/format/page.mjs.map +1 -1
- package/src/lib/format/part-look.d.mts +36 -0
- package/src/lib/format/part-look.d.ts +36 -0
- package/src/lib/format/part-look.js +23 -0
- package/src/lib/format/part-look.js.map +1 -0
- package/src/lib/format/part-look.mjs +20 -0
- package/src/lib/format/part-look.mjs.map +1 -0
- package/src/lib/format/references.d.mts +33 -1
- package/src/lib/format/references.d.ts +33 -1
- package/src/lib/format/references.js +227 -10
- package/src/lib/format/references.js.map +1 -1
- package/src/lib/format/references.mjs +227 -10
- package/src/lib/format/references.mjs.map +1 -1
- package/src/lib/format/translate.d.mts +20 -0
- package/src/lib/format/translate.d.ts +20 -0
- package/src/lib/format/translate.js +79 -21
- package/src/lib/format/translate.js.map +1 -1
- package/src/lib/format/translate.mjs +76 -21
- package/src/lib/format/translate.mjs.map +1 -1
- package/src/lib/record/check.d.mts +19 -1
- package/src/lib/record/check.d.ts +19 -1
- package/src/lib/record/check.js +84 -21
- package/src/lib/record/check.js.map +1 -1
- package/src/lib/record/check.mjs +82 -21
- package/src/lib/record/check.mjs.map +1 -1
- package/src/lib/record/compute.d.mts +24 -0
- package/src/lib/record/compute.d.ts +24 -0
- package/src/lib/record/compute.js +107 -0
- package/src/lib/record/compute.js.map +1 -0
- package/src/lib/record/compute.mjs +103 -0
- package/src/lib/record/compute.mjs.map +1 -0
- package/src/lib/record/data-source.d.mts +14 -2
- package/src/lib/record/data-source.d.ts +14 -2
- package/src/lib/record/data-source.js.map +1 -1
- package/src/lib/record/data-source.mjs.map +1 -1
- package/src/lib/record/env.d.mts +9 -0
- package/src/lib/record/env.d.ts +9 -0
- package/src/lib/record/env.js +28 -0
- package/src/lib/record/env.js.map +1 -0
- package/src/lib/record/env.mjs +25 -0
- package/src/lib/record/env.mjs.map +1 -0
- package/src/lib/record/form.d.mts +110 -18
- package/src/lib/record/form.d.ts +110 -18
- package/src/lib/record/form.js +497 -72
- package/src/lib/record/form.js.map +1 -1
- package/src/lib/record/form.mjs +497 -72
- package/src/lib/record/form.mjs.map +1 -1
- package/src/lib/record/inputs.d.mts +5 -0
- package/src/lib/record/inputs.d.ts +5 -0
- package/src/lib/record/inputs.js +47 -0
- package/src/lib/record/inputs.js.map +1 -0
- package/src/lib/record/inputs.mjs +44 -0
- package/src/lib/record/inputs.mjs.map +1 -0
- package/src/lib/record/limits.d.mts +13 -0
- package/src/lib/record/limits.d.ts +13 -0
- package/src/lib/record/limits.js +45 -0
- package/src/lib/record/limits.js.map +1 -0
- package/src/lib/record/limits.mjs +41 -0
- package/src/lib/record/limits.mjs.map +1 -0
- package/src/lib/record/locales/all.d.mts +7 -0
- package/src/lib/record/locales/all.d.ts +7 -0
- package/src/lib/record/locales/all.js +13 -0
- package/src/lib/record/locales/all.js.map +1 -0
- package/src/lib/record/locales/all.mjs +10 -0
- package/src/lib/record/locales/all.mjs.map +1 -0
- package/src/lib/record/locales/ar.d.mts +3 -0
- package/src/lib/record/locales/ar.d.ts +3 -0
- package/src/lib/record/locales/ar.js +55 -0
- package/src/lib/record/locales/ar.js.map +1 -0
- package/src/lib/record/locales/ar.mjs +52 -0
- package/src/lib/record/locales/ar.mjs.map +1 -0
- package/src/lib/record/locales/de.d.mts +3 -0
- package/src/lib/record/locales/de.d.ts +3 -0
- package/src/lib/record/locales/de.js +55 -0
- package/src/lib/record/locales/de.js.map +1 -0
- package/src/lib/record/locales/de.mjs +52 -0
- package/src/lib/record/locales/de.mjs.map +1 -0
- package/src/lib/record/locales/fr.d.mts +3 -0
- package/src/lib/record/locales/fr.d.ts +3 -0
- package/src/lib/record/locales/fr.js +55 -0
- package/src/lib/record/locales/fr.js.map +1 -0
- package/src/lib/record/locales/fr.mjs +52 -0
- package/src/lib/record/locales/fr.mjs.map +1 -0
- package/src/lib/record/memory-data-source.d.mts +3 -0
- package/src/lib/record/memory-data-source.d.ts +3 -0
- package/src/lib/record/memory-data-source.js +8 -0
- package/src/lib/record/memory-data-source.js.map +1 -1
- package/src/lib/record/memory-data-source.mjs +8 -0
- package/src/lib/record/memory-data-source.mjs.map +1 -1
- package/src/lib/record/messages.d.mts +46 -0
- package/src/lib/record/messages.d.ts +46 -0
- package/src/lib/record/messages.js +58 -101
- package/src/lib/record/messages.js.map +1 -1
- package/src/lib/record/messages.mjs +58 -101
- package/src/lib/record/messages.mjs.map +1 -1
- package/src/lib/record/rules.d.mts +33 -0
- package/src/lib/record/rules.d.ts +33 -0
- package/src/lib/record/rules.js +83 -0
- package/src/lib/record/rules.js.map +1 -0
- package/src/lib/record/rules.mjs +79 -0
- package/src/lib/record/rules.mjs.map +1 -0
- package/src/lib/record/run.d.mts +169 -0
- package/src/lib/record/run.d.ts +169 -0
- package/src/lib/record/run.js +350 -0
- package/src/lib/record/run.js.map +1 -0
- package/src/lib/record/run.mjs +345 -0
- package/src/lib/record/run.mjs.map +1 -0
- package/src/lib/record/score.d.mts +16 -0
- package/src/lib/record/score.d.ts +16 -0
- package/src/lib/record/score.js +35 -0
- package/src/lib/record/score.js.map +1 -0
- package/src/lib/record/score.mjs +32 -0
- package/src/lib/record/score.mjs.map +1 -0
- package/src/lib/record/set-when.d.mts +24 -0
- package/src/lib/record/set-when.d.ts +24 -0
- package/src/lib/record/set-when.js +68 -0
- package/src/lib/record/set-when.js.map +1 -0
- package/src/lib/record/set-when.mjs +65 -0
- package/src/lib/record/set-when.mjs.map +1 -0
- package/src/lib/record/structures.d.mts +14 -0
- package/src/lib/record/structures.d.ts +14 -0
- package/src/lib/record/structures.js +32 -0
- package/src/lib/record/structures.js.map +1 -0
- package/src/lib/record/structures.mjs +28 -0
- package/src/lib/record/structures.mjs.map +1 -0
- package/src/lib/record/values.d.mts +10 -5
- package/src/lib/record/values.d.ts +10 -5
- package/src/lib/record/values.js +20 -6
- package/src/lib/record/values.js.map +1 -1
- package/src/lib/record/values.mjs +19 -6
- package/src/lib/record/values.mjs.map +1 -1
- package/src/runtime.d.mts +13 -7
- package/src/runtime.d.ts +13 -7
- package/src/runtime.js +14 -1
- package/src/runtime.js.map +1 -1
- package/src/runtime.mjs +6 -2
- package/src/runtime.mjs.map +1 -1
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
import { compileExpression } from '../expression/expression.mjs';
|
|
2
|
+
import { compileModifier } from '../expression/modifier.mjs';
|
|
3
|
+
import { FIELD_NAME } from '../format/names.mjs';
|
|
4
|
+
import { fitTo } from './compute.mjs';
|
|
5
|
+
import { emptyValue, structuredCopy } from './values.mjs';
|
|
6
|
+
export const DONE = Object.freeze({ done: true });
|
|
7
|
+
/** The kinds of field an expression gives a value to; the rest hold records, lines or files, and take a field named alone whole. */
|
|
8
|
+
const EXPRESSIBLE = new Set(['char', 'text', 'html', 'integer', 'float', 'monetary', 'boolean', 'date', 'datetime', 'selection', 'json']);
|
|
9
|
+
const wordsOf = (error) => (error instanceof Error ? error.message : String(error));
|
|
10
|
+
/** Steps run against one form. Expressions are read once and kept. */
|
|
11
|
+
export function createRunner(form) {
|
|
12
|
+
const expressions = new Map();
|
|
13
|
+
const conditions = new Map();
|
|
14
|
+
const expression = (source) => {
|
|
15
|
+
let found = expressions.get(source);
|
|
16
|
+
if (!found)
|
|
17
|
+
expressions.set(source, (found = compileExpression(source)));
|
|
18
|
+
return found;
|
|
19
|
+
};
|
|
20
|
+
function holds(when) {
|
|
21
|
+
if (typeof when === 'boolean')
|
|
22
|
+
return when;
|
|
23
|
+
let found = conditions.get(when);
|
|
24
|
+
if (!found)
|
|
25
|
+
conditions.set(when, (found = compileModifier(when)));
|
|
26
|
+
const { context, env } = form.reading();
|
|
27
|
+
return found.evaluate(context, env);
|
|
28
|
+
}
|
|
29
|
+
/** A field named alone, when its value is taken whole. */
|
|
30
|
+
const named = (source) => {
|
|
31
|
+
const name = source.trim();
|
|
32
|
+
return FIELD_NAME.test(name) ? name : null;
|
|
33
|
+
};
|
|
34
|
+
/** An expression over this form's values. A field named alone is taken whole when `whole` — a link with its name, the lines themselves. */
|
|
35
|
+
function read(source, whole) {
|
|
36
|
+
const name = named(source);
|
|
37
|
+
if (whole && name !== null && name in form.fields)
|
|
38
|
+
return structuredCopy(form.values()[name]);
|
|
39
|
+
const { context, env } = form.reading();
|
|
40
|
+
return expression(source).evaluate(context, env);
|
|
41
|
+
}
|
|
42
|
+
/** The name this form knows a record by, from a link to the same model it holds. */
|
|
43
|
+
function knownLabel(relation, id) {
|
|
44
|
+
const values = form.values();
|
|
45
|
+
for (const [name, def] of Object.entries(form.fields)) {
|
|
46
|
+
if ((def.type !== 'many2one' && def.type !== 'many2many') || def.relation !== relation)
|
|
47
|
+
continue;
|
|
48
|
+
const held = values[name];
|
|
49
|
+
const records = (Array.isArray(held) ? held : held ? [held] : []);
|
|
50
|
+
const found = records.find((record) => record && record.id === id);
|
|
51
|
+
if (found)
|
|
52
|
+
return found.label;
|
|
53
|
+
}
|
|
54
|
+
return undefined;
|
|
55
|
+
}
|
|
56
|
+
/** What a value from an expression, the app or another form becomes in a field: a link from an id or a record, anything else as `compute` fits it. */
|
|
57
|
+
function fit(def, raw, label = () => undefined) {
|
|
58
|
+
const link = (item) => {
|
|
59
|
+
if (item === null || item === undefined || item === false || item === '')
|
|
60
|
+
return null;
|
|
61
|
+
const relation = def.relation;
|
|
62
|
+
const labelOf = (id) => label(id) ?? knownLabel(relation, id) ?? String(id);
|
|
63
|
+
if (typeof item === 'number' || typeof item === 'string')
|
|
64
|
+
return { id: item, label: labelOf(item) };
|
|
65
|
+
if (typeof item === 'object' && !Array.isArray(item) && 'id' in item) {
|
|
66
|
+
const record = item;
|
|
67
|
+
return { id: record.id, label: typeof record.label === 'string' ? record.label : labelOf(record.id) };
|
|
68
|
+
}
|
|
69
|
+
return null;
|
|
70
|
+
};
|
|
71
|
+
if (def.type === 'many2one')
|
|
72
|
+
return link(raw);
|
|
73
|
+
if (def.type === 'many2many')
|
|
74
|
+
return (Array.isArray(raw) ? raw : [raw]).map(link).filter((record) => record !== null);
|
|
75
|
+
return fitTo(def, raw);
|
|
76
|
+
}
|
|
77
|
+
function fieldOf(name) {
|
|
78
|
+
const def = form.fields[name];
|
|
79
|
+
if (!def)
|
|
80
|
+
throw new Error(`The page has no field "${name}"`);
|
|
81
|
+
return def;
|
|
82
|
+
}
|
|
83
|
+
async function ask(message) {
|
|
84
|
+
if (form.host)
|
|
85
|
+
return form.host.ask(message);
|
|
86
|
+
if (form.confirm)
|
|
87
|
+
return form.confirm(message);
|
|
88
|
+
return true;
|
|
89
|
+
}
|
|
90
|
+
function cannot(message) {
|
|
91
|
+
return { reason: 'cannot', message };
|
|
92
|
+
}
|
|
93
|
+
/** Open a page through the host, take its answers back, and run its `then`. */
|
|
94
|
+
async function open(step, scope) {
|
|
95
|
+
const host = form.host;
|
|
96
|
+
if (!host)
|
|
97
|
+
return cannot(`Nothing can open "${step.page}" here: the form has no host`);
|
|
98
|
+
const record = step.record !== undefined ? read(step.record, false) : null;
|
|
99
|
+
const request = {
|
|
100
|
+
page: step.page,
|
|
101
|
+
...(step.version !== undefined ? { version: step.version } : {}),
|
|
102
|
+
as: step.as ?? 'dialog',
|
|
103
|
+
...(step.side && step.as === 'panel' ? { side: step.side } : {}),
|
|
104
|
+
...(step.title !== undefined ? { title: step.title } : {}),
|
|
105
|
+
recordId: typeof record === 'number' || (typeof record === 'string' && record !== '') ? record : null,
|
|
106
|
+
...(step.values ? { values: readMap(step.values) } : {}),
|
|
107
|
+
};
|
|
108
|
+
let result;
|
|
109
|
+
try {
|
|
110
|
+
result = await host.open(request);
|
|
111
|
+
}
|
|
112
|
+
catch (error) {
|
|
113
|
+
return { reason: 'cannot', message: wordsOf(error), error };
|
|
114
|
+
}
|
|
115
|
+
if (!result.saved)
|
|
116
|
+
return { reason: 'closed' };
|
|
117
|
+
if (step.into)
|
|
118
|
+
form.write(into(step.into, result));
|
|
119
|
+
if (!step.then)
|
|
120
|
+
return null;
|
|
121
|
+
const then = await runSteps(step.then, scope);
|
|
122
|
+
return then.done ? null : { reason: then.reason, message: then.message, step: then.step, error: then.error };
|
|
123
|
+
}
|
|
124
|
+
/** What a new page starts with: each an expression over this form's values, a field named alone taken whole. */
|
|
125
|
+
function readMap(map) {
|
|
126
|
+
const values = {};
|
|
127
|
+
for (const [name, source] of Object.entries(map))
|
|
128
|
+
values[name] = (read(source, true) ?? null);
|
|
129
|
+
return values;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* This form's fields from an opened page's answers: each an expression over
|
|
133
|
+
* its values, where `id` is the record it saved. A link set to that record
|
|
134
|
+
* is labelled by the host's `label`, else its `display_name`, else its
|
|
135
|
+
* `name`, else its id.
|
|
136
|
+
*/
|
|
137
|
+
function into(map, result) {
|
|
138
|
+
const answers = result.values ?? {};
|
|
139
|
+
const id = result.recordId ?? null;
|
|
140
|
+
const context = { ...asRead(answers), id };
|
|
141
|
+
const title = [result.label, answers['display_name'], answers['name']].find((text) => typeof text === 'string' && text !== '');
|
|
142
|
+
const label = (other) => (other === id ? title : undefined);
|
|
143
|
+
const values = {};
|
|
144
|
+
for (const [name, source] of Object.entries(map)) {
|
|
145
|
+
const def = fieldOf(name);
|
|
146
|
+
const alone = named(source);
|
|
147
|
+
const raw = alone === 'id' ? id : alone !== null && !EXPRESSIBLE.has(def.type) && alone in answers ? answers[alone] : expression(source).evaluate(context, { today: form.today });
|
|
148
|
+
values[name] = fit(def, raw, label);
|
|
149
|
+
}
|
|
150
|
+
return values;
|
|
151
|
+
}
|
|
152
|
+
async function call(step, scope) {
|
|
153
|
+
const request = {
|
|
154
|
+
id: scope.id,
|
|
155
|
+
action: step.action,
|
|
156
|
+
...(step.params ? { params: structuredCopy(step.params) } : {}),
|
|
157
|
+
recordId: form.recordId(),
|
|
158
|
+
values: structuredCopy(form.values()),
|
|
159
|
+
...(scope.recordIds ? { recordIds: [...scope.recordIds] } : {}),
|
|
160
|
+
};
|
|
161
|
+
if (!form.onAction)
|
|
162
|
+
return null;
|
|
163
|
+
let answer;
|
|
164
|
+
try {
|
|
165
|
+
answer = (await form.onAction(request)) ?? undefined;
|
|
166
|
+
}
|
|
167
|
+
catch (error) {
|
|
168
|
+
return { reason: 'app', message: wordsOf(error), error };
|
|
169
|
+
}
|
|
170
|
+
form.answered(request, answer);
|
|
171
|
+
if (!answer)
|
|
172
|
+
return null;
|
|
173
|
+
if (answer.values) {
|
|
174
|
+
const known = {};
|
|
175
|
+
for (const [name, value] of Object.entries(answer.values))
|
|
176
|
+
if (name in form.fields)
|
|
177
|
+
known[name] = fit(form.fields[name], value);
|
|
178
|
+
form.write(known);
|
|
179
|
+
}
|
|
180
|
+
if (answer.say !== undefined) {
|
|
181
|
+
const said = typeof answer.say === 'string' ? { message: answer.say } : answer.say;
|
|
182
|
+
form.host?.say(said.message, said.tone ?? 'info');
|
|
183
|
+
}
|
|
184
|
+
if (answer.open) {
|
|
185
|
+
const opened = await open(answer.open, scope);
|
|
186
|
+
if (opened)
|
|
187
|
+
return opened;
|
|
188
|
+
}
|
|
189
|
+
if (answer.stop) {
|
|
190
|
+
if (typeof answer.stop === 'string')
|
|
191
|
+
form.host?.say(answer.stop, 'warning');
|
|
192
|
+
return { reason: 'app', ...(typeof answer.stop === 'string' ? { message: answer.stop } : {}) };
|
|
193
|
+
}
|
|
194
|
+
return null;
|
|
195
|
+
}
|
|
196
|
+
async function runStep(step, scope) {
|
|
197
|
+
switch (step.do) {
|
|
198
|
+
case 'set': {
|
|
199
|
+
const def = fieldOf(step.field);
|
|
200
|
+
form.write({ [step.field]: fit(def, read(step.value, !EXPRESSIBLE.has(def.type))) });
|
|
201
|
+
return null;
|
|
202
|
+
}
|
|
203
|
+
case 'clear':
|
|
204
|
+
form.write({ [step.field]: emptyValue(fieldOf(step.field)) });
|
|
205
|
+
return null;
|
|
206
|
+
case 'addLine': {
|
|
207
|
+
const def = fieldOf(step.field);
|
|
208
|
+
if (def.type !== 'one2many')
|
|
209
|
+
return cannot(`"${step.field}" is a ${def.type}; a line is added to a one2many`);
|
|
210
|
+
const values = {};
|
|
211
|
+
for (const [name, source] of Object.entries(step.values ?? {})) {
|
|
212
|
+
const sub = def.fields[name];
|
|
213
|
+
if (!sub)
|
|
214
|
+
return cannot(`The lines of "${step.field}" have no field "${name}"`);
|
|
215
|
+
values[name] = fit(sub, read(source, !EXPRESSIBLE.has(sub.type)));
|
|
216
|
+
}
|
|
217
|
+
form.addLine(step.field, values);
|
|
218
|
+
return null;
|
|
219
|
+
}
|
|
220
|
+
case 'check':
|
|
221
|
+
return form.check(step.fields);
|
|
222
|
+
case 'save':
|
|
223
|
+
return form.save(scope.chain);
|
|
224
|
+
case 'reset':
|
|
225
|
+
form.reset();
|
|
226
|
+
return null;
|
|
227
|
+
case 'goTo': {
|
|
228
|
+
const stepped = form.goTo(step.target, scope.chain);
|
|
229
|
+
if (stepped !== undefined)
|
|
230
|
+
return stepped;
|
|
231
|
+
const show = form.host?.show;
|
|
232
|
+
if (!show)
|
|
233
|
+
return cannot(`Nothing can show "${step.target}" here: the form has no host that shows tabs`);
|
|
234
|
+
form.showing(scope.chain, () => show.call(form.host, step.target));
|
|
235
|
+
return null;
|
|
236
|
+
}
|
|
237
|
+
case 'say':
|
|
238
|
+
form.host?.say(step.message, step.tone ?? 'info');
|
|
239
|
+
return null;
|
|
240
|
+
case 'ask':
|
|
241
|
+
return (await ask(step.message)) ? null : { reason: 'no', message: step.message };
|
|
242
|
+
case 'call':
|
|
243
|
+
return call(step, scope);
|
|
244
|
+
case 'open':
|
|
245
|
+
return open(step, scope);
|
|
246
|
+
case 'close': {
|
|
247
|
+
const close = form.host?.close;
|
|
248
|
+
if (!close)
|
|
249
|
+
return cannot('Nothing can close this form: it has no host, or was not opened in a dialog or panel');
|
|
250
|
+
close.call(form.host);
|
|
251
|
+
return null;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
async function runSteps(steps, scope) {
|
|
256
|
+
for (let at = 0; at < steps.length; at++) {
|
|
257
|
+
const step = steps[at];
|
|
258
|
+
let stopped;
|
|
259
|
+
try {
|
|
260
|
+
if (step.when !== undefined && !holds(step.when))
|
|
261
|
+
continue;
|
|
262
|
+
stopped = await runStep(step, scope);
|
|
263
|
+
}
|
|
264
|
+
catch (error) {
|
|
265
|
+
stopped = { reason: 'cannot', message: wordsOf(error), error };
|
|
266
|
+
}
|
|
267
|
+
if (stopped) {
|
|
268
|
+
return {
|
|
269
|
+
done: false,
|
|
270
|
+
stoppedAt: at,
|
|
271
|
+
step: stopped.step ?? step,
|
|
272
|
+
reason: stopped.reason,
|
|
273
|
+
...(stopped.message !== undefined ? { message: stopped.message } : {}),
|
|
274
|
+
...(stopped.error !== undefined ? { error: stopped.error } : {}),
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
return DONE;
|
|
279
|
+
}
|
|
280
|
+
return { runSteps, ask };
|
|
281
|
+
}
|
|
282
|
+
/** What an expression reads in another form's answers, its fields unknown: a link as its id, links as their ids, a reference as "model,id", lines by their keys, a file by its name. */
|
|
283
|
+
function asRead(values) {
|
|
284
|
+
const read = {};
|
|
285
|
+
const one = (value) => {
|
|
286
|
+
if (value === null || typeof value !== 'object')
|
|
287
|
+
return value;
|
|
288
|
+
const object = value;
|
|
289
|
+
if ('key' in object && 'values' in object)
|
|
290
|
+
return object['key'];
|
|
291
|
+
if ('model' in object && 'id' in object)
|
|
292
|
+
return `${object['model']},${object['id']}`;
|
|
293
|
+
if ('id' in object)
|
|
294
|
+
return object['id'];
|
|
295
|
+
if ('name' in object && 'type' in object && 'size' in object)
|
|
296
|
+
return object['name'];
|
|
297
|
+
return value;
|
|
298
|
+
};
|
|
299
|
+
for (const [name, value] of Object.entries(values))
|
|
300
|
+
read[name] = Array.isArray(value) ? value.map(one) : one(value);
|
|
301
|
+
return read;
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* One run of each moment at a time. A moment set off by a step of its own
|
|
305
|
+
* run — or a run it set off — does not run. Set off while a run of it is
|
|
306
|
+
* going: `again` moments (open, change, show) run once more after it, with
|
|
307
|
+
* the values as they are then, however many times they were set off
|
|
308
|
+
* meanwhile; the others (beforeSave, afterSave) do not run — a save made
|
|
309
|
+
* meanwhile goes ahead without them, so nothing waits on itself.
|
|
310
|
+
*/
|
|
311
|
+
export function createMoments(run) {
|
|
312
|
+
const slots = new Map();
|
|
313
|
+
return function moment(key, steps, chain, again) {
|
|
314
|
+
if (!steps?.length || chain.includes(key))
|
|
315
|
+
return Promise.resolve(DONE);
|
|
316
|
+
/** A run of it, known as running before its first step does: a step that sets it off again finds it busy. */
|
|
317
|
+
const go = (slot) => {
|
|
318
|
+
let settle;
|
|
319
|
+
const running = new Promise((resolve) => (settle = resolve)).finally(() => {
|
|
320
|
+
if (slot.running === running && !slot.queued)
|
|
321
|
+
slots.delete(key);
|
|
322
|
+
});
|
|
323
|
+
slot.running = running;
|
|
324
|
+
settle(run(key, steps, [...chain, key]));
|
|
325
|
+
return running;
|
|
326
|
+
};
|
|
327
|
+
const busy = slots.get(key);
|
|
328
|
+
if (!busy) {
|
|
329
|
+
const slot = { running: Promise.resolve(DONE) };
|
|
330
|
+
slots.set(key, slot);
|
|
331
|
+
return go(slot);
|
|
332
|
+
}
|
|
333
|
+
if (!again)
|
|
334
|
+
return Promise.resolve(DONE);
|
|
335
|
+
if (!busy.queued) {
|
|
336
|
+
const next = () => {
|
|
337
|
+
busy.queued = undefined;
|
|
338
|
+
return go(busy);
|
|
339
|
+
};
|
|
340
|
+
busy.queued = busy.running.then(next, next);
|
|
341
|
+
}
|
|
342
|
+
return busy.queued;
|
|
343
|
+
};
|
|
344
|
+
}
|
|
345
|
+
//# sourceMappingURL=run.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run.mjs","sourceRoot":"","sources":["../../../../../../libs/core/src/lib/record/run.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Page } from '../format/page.mjs';
|
|
2
|
+
import type { Values } from './values.mjs';
|
|
3
|
+
/**
|
|
4
|
+
* A quiz's points. Each option may carry a `score`; the answers earn the
|
|
5
|
+
* scores of the options chosen — the one of a single choice, every one of
|
|
6
|
+
* several, the column chosen in each row of a matrix — out of the most they
|
|
7
|
+
* could earn: the best option of a single choice, every option worth
|
|
8
|
+
* something of several, the best column of each row. An answer in one's own
|
|
9
|
+
* words, or none, earns nothing. Only questions with points count; a page
|
|
10
|
+
* with none has no score.
|
|
11
|
+
*/
|
|
12
|
+
export interface Score {
|
|
13
|
+
score: number;
|
|
14
|
+
max: number;
|
|
15
|
+
}
|
|
16
|
+
export declare function scoreOf(page: Page, values: Values): Score | null;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Page } from '../format/page';
|
|
2
|
+
import type { Values } from './values';
|
|
3
|
+
/**
|
|
4
|
+
* A quiz's points. Each option may carry a `score`; the answers earn the
|
|
5
|
+
* scores of the options chosen — the one of a single choice, every one of
|
|
6
|
+
* several, the column chosen in each row of a matrix — out of the most they
|
|
7
|
+
* could earn: the best option of a single choice, every option worth
|
|
8
|
+
* something of several, the best column of each row. An answer in one's own
|
|
9
|
+
* words, or none, earns nothing. Only questions with points count; a page
|
|
10
|
+
* with none has no score.
|
|
11
|
+
*/
|
|
12
|
+
export interface Score {
|
|
13
|
+
score: number;
|
|
14
|
+
max: number;
|
|
15
|
+
}
|
|
16
|
+
export declare function scoreOf(page: Page, values: Values): Score | null;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.scoreOf = scoreOf;
|
|
4
|
+
/** Sums of tenths and the like without a computer's crumbs: 0.1 + 0.2 is 0.3. */
|
|
5
|
+
const tidy = (n) => Math.round(n * 1e9) / 1e9;
|
|
6
|
+
const pointsOf = (options, value) => options.find((o) => o.value === value)?.score ?? 0;
|
|
7
|
+
const best = (options) => options.reduce((most, o) => Math.max(most, o.score ?? 0), 0);
|
|
8
|
+
const allWorth = (options) => options.reduce((sum, o) => sum + Math.max(0, o.score ?? 0), 0);
|
|
9
|
+
/** The points of the options a single or a several answer chose. */
|
|
10
|
+
const earned = (options, answer, several) => several ? (Array.isArray(answer) ? answer.reduce((sum, v) => sum + pointsOf(options, v), 0) : 0) : pointsOf(options, answer);
|
|
11
|
+
function scoreOf(page, values) {
|
|
12
|
+
let score = 0;
|
|
13
|
+
let max = 0;
|
|
14
|
+
let scored = false;
|
|
15
|
+
for (const [name, field] of Object.entries(page.fields)) {
|
|
16
|
+
if (field.type === 'selection' && field.options.some((o) => o.score !== undefined)) {
|
|
17
|
+
scored = true;
|
|
18
|
+
const several = field.multiple === true;
|
|
19
|
+
score += earned(field.options, values[name], several);
|
|
20
|
+
max += several ? allWorth(field.options) : best(field.options);
|
|
21
|
+
}
|
|
22
|
+
else if (field.type === 'matrix' && field.columns.some((c) => c.score !== undefined)) {
|
|
23
|
+
scored = true;
|
|
24
|
+
const several = field.multiple === true;
|
|
25
|
+
const answers = values[name];
|
|
26
|
+
const byRow = answers && typeof answers === 'object' && !Array.isArray(answers) ? answers : {};
|
|
27
|
+
for (const row of field.rows) {
|
|
28
|
+
score += earned(field.columns, byRow[String(row.value)], several);
|
|
29
|
+
max += several ? allWorth(field.columns) : best(field.columns);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return scored ? { score: tidy(score), max: tidy(max) } : null;
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=score.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"score.js","sourceRoot":"","sources":["../../../../../../libs/core/src/lib/record/score.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/** Sums of tenths and the like without a computer's crumbs: 0.1 + 0.2 is 0.3. */
|
|
2
|
+
const tidy = (n) => Math.round(n * 1e9) / 1e9;
|
|
3
|
+
const pointsOf = (options, value) => options.find((o) => o.value === value)?.score ?? 0;
|
|
4
|
+
const best = (options) => options.reduce((most, o) => Math.max(most, o.score ?? 0), 0);
|
|
5
|
+
const allWorth = (options) => options.reduce((sum, o) => sum + Math.max(0, o.score ?? 0), 0);
|
|
6
|
+
/** The points of the options a single or a several answer chose. */
|
|
7
|
+
const earned = (options, answer, several) => several ? (Array.isArray(answer) ? answer.reduce((sum, v) => sum + pointsOf(options, v), 0) : 0) : pointsOf(options, answer);
|
|
8
|
+
export function scoreOf(page, values) {
|
|
9
|
+
let score = 0;
|
|
10
|
+
let max = 0;
|
|
11
|
+
let scored = false;
|
|
12
|
+
for (const [name, field] of Object.entries(page.fields)) {
|
|
13
|
+
if (field.type === 'selection' && field.options.some((o) => o.score !== undefined)) {
|
|
14
|
+
scored = true;
|
|
15
|
+
const several = field.multiple === true;
|
|
16
|
+
score += earned(field.options, values[name], several);
|
|
17
|
+
max += several ? allWorth(field.options) : best(field.options);
|
|
18
|
+
}
|
|
19
|
+
else if (field.type === 'matrix' && field.columns.some((c) => c.score !== undefined)) {
|
|
20
|
+
scored = true;
|
|
21
|
+
const several = field.multiple === true;
|
|
22
|
+
const answers = values[name];
|
|
23
|
+
const byRow = answers && typeof answers === 'object' && !Array.isArray(answers) ? answers : {};
|
|
24
|
+
for (const row of field.rows) {
|
|
25
|
+
score += earned(field.columns, byRow[String(row.value)], several);
|
|
26
|
+
max += several ? allWorth(field.columns) : best(field.columns);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return scored ? { score: tidy(score), max: tidy(max) } : null;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=score.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"score.mjs","sourceRoot":"","sources":["../../../../../../libs/core/src/lib/record/score.ts"],"names":[],"mappings":"AAmBA,iFAAiF;AACjF,MAAM,IAAI,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC;AAEtD,MAAM,QAAQ,GAAG,CAAC,OAA0B,EAAE,KAAc,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,EAAE,KAAK,IAAI,CAAC,CAAC;AACpH,MAAM,IAAI,GAAG,CAAC,OAA0B,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAC1G,MAAM,QAAQ,GAAG,CAAC,OAA0B,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAChH,oEAAoE;AACpE,MAAM,MAAM,GAAG,CAAC,OAA0B,EAAE,MAAe,EAAE,OAAgB,EAAE,EAAE,CAC/E,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,GAAW,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;AAEvI,MAAM,UAAU,OAAO,CAAC,IAAU,EAAE,MAAc;IAChD,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,IAAI,MAAM,GAAG,KAAK,CAAC;IACnB,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QACxD,IAAI,KAAK,CAAC,IAAI,KAAK,WAAW,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,SAAS,CAAC,EAAE,CAAC;YACnF,MAAM,GAAG,IAAI,CAAC;YACd,MAAM,OAAO,GAAG,KAAK,CAAC,QAAQ,KAAK,IAAI,CAAC;YACxC,KAAK,IAAI,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,CAAC;YACtD,GAAG,IAAI,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACjE,CAAC;aAAM,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,SAAS,CAAC,EAAE,CAAC;YACvF,MAAM,GAAG,IAAI,CAAC;YACd,MAAM,OAAO,GAAG,KAAK,CAAC,QAAQ,KAAK,IAAI,CAAC;YACxC,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;YAC7B,MAAM,KAAK,GAAG,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAE,OAAmC,CAAC,CAAC,CAAC,EAAE,CAAC;YAC5H,KAAK,MAAM,GAAG,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;gBAC7B,KAAK,IAAI,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;gBAClE,GAAG,IAAI,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YACjE,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AAChE,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { Page } from '../format/page.mjs';
|
|
2
|
+
import { type Values } from './values.mjs';
|
|
3
|
+
/**
|
|
4
|
+
* Values set when a condition starts to hold: a field's `setWhen`. A rule acts
|
|
5
|
+
* only as its condition goes from not holding to holding — so people may
|
|
6
|
+
* still change the value afterwards — and rules act in the order the field
|
|
7
|
+
* lists them. Each rule is known by a key (`discount#0`, or in a line
|
|
8
|
+
* `lines.<line key>.pallet#0`), so what held before can be remembered.
|
|
9
|
+
*/
|
|
10
|
+
export interface SetWhenRules {
|
|
11
|
+
/** The keys of the conditions holding for these values: a starting point, where nothing is set. */
|
|
12
|
+
holding(values: Values): Set<string>;
|
|
13
|
+
/**
|
|
14
|
+
* The values with each field whose condition holds now, and did not in
|
|
15
|
+
* `before`, set to its value; and the conditions holding now. The values
|
|
16
|
+
* come back as they were when nothing was set.
|
|
17
|
+
*/
|
|
18
|
+
apply(values: Values, before: ReadonlySet<string>): {
|
|
19
|
+
values: Values;
|
|
20
|
+
holding: Set<string>;
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
/** Read every `setWhen` of a page once. `today` is the day `today()` gives. */
|
|
24
|
+
export declare function compileSetWhen(page: Page, today: () => string): SetWhenRules;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { Page } from '../format/page';
|
|
2
|
+
import { type Values } from './values';
|
|
3
|
+
/**
|
|
4
|
+
* Values set when a condition starts to hold: a field's `setWhen`. A rule acts
|
|
5
|
+
* only as its condition goes from not holding to holding — so people may
|
|
6
|
+
* still change the value afterwards — and rules act in the order the field
|
|
7
|
+
* lists them. Each rule is known by a key (`discount#0`, or in a line
|
|
8
|
+
* `lines.<line key>.pallet#0`), so what held before can be remembered.
|
|
9
|
+
*/
|
|
10
|
+
export interface SetWhenRules {
|
|
11
|
+
/** The keys of the conditions holding for these values: a starting point, where nothing is set. */
|
|
12
|
+
holding(values: Values): Set<string>;
|
|
13
|
+
/**
|
|
14
|
+
* The values with each field whose condition holds now, and did not in
|
|
15
|
+
* `before`, set to its value; and the conditions holding now. The values
|
|
16
|
+
* come back as they were when nothing was set.
|
|
17
|
+
*/
|
|
18
|
+
apply(values: Values, before: ReadonlySet<string>): {
|
|
19
|
+
values: Values;
|
|
20
|
+
holding: Set<string>;
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
/** Read every `setWhen` of a page once. `today` is the day `today()` gives. */
|
|
24
|
+
export declare function compileSetWhen(page: Page, today: () => string): SetWhenRules;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.compileSetWhen = compileSetWhen;
|
|
4
|
+
const expression_1 = require("../expression/expression");
|
|
5
|
+
const modifier_1 = require("../expression/modifier");
|
|
6
|
+
const compute_1 = require("./compute");
|
|
7
|
+
const env_1 = require("./env");
|
|
8
|
+
const values_1 = require("./values");
|
|
9
|
+
function rules(fields) {
|
|
10
|
+
return Object.entries(fields).flatMap(([name, def]) => (def.setWhen ?? []).map((rule, i) => ({ key: `${name}#${i}`, name, def, when: (0, modifier_1.compileModifier)(rule.when), value: (0, expression_1.compileExpression)(rule.value) })));
|
|
11
|
+
}
|
|
12
|
+
/** Before anything was known: every condition counts as holding, so none starts. */
|
|
13
|
+
const EVERYTHING = { has: () => true };
|
|
14
|
+
/** Read every `setWhen` of a page once. `today` is the day `today()` gives. */
|
|
15
|
+
function compileSetWhen(page, today) {
|
|
16
|
+
const own = rules(page.fields);
|
|
17
|
+
const lineRules = new Map();
|
|
18
|
+
for (const [name, def] of Object.entries(page.fields)) {
|
|
19
|
+
if (def.type !== 'one2many')
|
|
20
|
+
continue;
|
|
21
|
+
const found = rules(def.fields);
|
|
22
|
+
if (found.length)
|
|
23
|
+
lineRules.set(name, { def, rules: found });
|
|
24
|
+
}
|
|
25
|
+
const lineEnv = { today };
|
|
26
|
+
/** One set of values (the record's, or a line's): every rule read against them as they are, before any is set. */
|
|
27
|
+
function run(values, list, fields, env, prefix, before, now) {
|
|
28
|
+
let next = values;
|
|
29
|
+
const context = (0, values_1.expressionContext)(values, fields);
|
|
30
|
+
for (const rule of list) {
|
|
31
|
+
if (!rule.when.evaluate(context, env))
|
|
32
|
+
continue;
|
|
33
|
+
const key = prefix + rule.key;
|
|
34
|
+
now.add(key);
|
|
35
|
+
if (before.has(key))
|
|
36
|
+
continue;
|
|
37
|
+
const value = (0, compute_1.fitTo)(rule.def, rule.value.evaluate(context, env));
|
|
38
|
+
if (!(0, values_1.sameValue)(value, next[rule.name]))
|
|
39
|
+
next = { ...next, [rule.name]: value };
|
|
40
|
+
}
|
|
41
|
+
return next;
|
|
42
|
+
}
|
|
43
|
+
function apply(values, before) {
|
|
44
|
+
const now = new Set();
|
|
45
|
+
let next = own.length ? run(values, own, page.fields, (0, env_1.expressionEnv)(values, page.fields, today), '', before, now) : values;
|
|
46
|
+
for (const [field, { def, rules: list }] of lineRules) {
|
|
47
|
+
const current = values[field];
|
|
48
|
+
if (!Array.isArray(current))
|
|
49
|
+
continue;
|
|
50
|
+
let changed = false;
|
|
51
|
+
const updated = current.map((line) => {
|
|
52
|
+
// A section or a note has nothing to set.
|
|
53
|
+
if ((0, values_1.lineKind)(def, line.values) !== null)
|
|
54
|
+
return line;
|
|
55
|
+
const set = run(line.values, list, def.fields, lineEnv, `${field}.${line.key}.`, before, now);
|
|
56
|
+
if (set === line.values)
|
|
57
|
+
return line;
|
|
58
|
+
changed = true;
|
|
59
|
+
return { ...line, values: set };
|
|
60
|
+
});
|
|
61
|
+
if (changed)
|
|
62
|
+
next = { ...next, [field]: updated };
|
|
63
|
+
}
|
|
64
|
+
return { values: next, holding: now };
|
|
65
|
+
}
|
|
66
|
+
return { apply, holding: (values) => apply(values, EVERYTHING).holding };
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=set-when.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"set-when.js","sourceRoot":"","sources":["../../../../../../libs/core/src/lib/record/set-when.ts"],"names":[],"mappings":";;AA4CA,wCA8CC;AAxFD,yDAA0G;AAC1G,qDAAgF;AAChF,uCAAkC;AAClC,+BAAsC;AACtC,qCAA0F;AA4B1F,SAAS,KAAK,CAAC,MAAyC;IACtD,OAAO,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,CACpD,CAAC,GAAG,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,IAAa,EAAE,CAAC,EAAQ,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,IAAI,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,IAAA,0BAAe,EAAC,IAAI,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,IAAA,8BAAiB,EAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAClK,CAAC;AACJ,CAAC;AAED,oFAAoF;AACpF,MAAM,UAAU,GAAwB,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,IAAI,EAAoC,CAAC;AAE9F,+EAA+E;AAC/E,SAAgB,cAAc,CAAC,IAAU,EAAE,KAAmB;IAC5D,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC/B,MAAM,SAAS,GAAG,IAAI,GAAG,EAAwE,CAAC;IAClG,KAAK,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QACtD,IAAI,GAAG,CAAC,IAAI,KAAK,UAAU;YAAE,SAAS;QACtC,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAChC,IAAI,KAAK,CAAC,MAAM;YAAE,SAAS,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;IAC/D,CAAC;IACD,MAAM,OAAO,GAAkB,EAAE,KAAK,EAAE,CAAC;IAEzC,kHAAkH;IAClH,SAAS,GAAG,CAAC,MAAc,EAAE,IAAY,EAAE,MAAyC,EAAE,GAAkB,EAAE,MAAc,EAAE,MAA2B,EAAE,GAAgB;QACrK,IAAI,IAAI,GAAG,MAAM,CAAC;QAClB,MAAM,OAAO,GAAG,IAAA,0BAAiB,EAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAClD,KAAK,MAAM,IAAI,IAAI,IAAI,EAAE,CAAC;YACxB,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,GAAG,CAAC;gBAAE,SAAS;YAChD,MAAM,GAAG,GAAG,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC;YAC9B,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACb,IAAI,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC;gBAAE,SAAS;YAC9B,MAAM,KAAK,GAAG,IAAA,eAAK,EAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC;YACjE,IAAI,CAAC,IAAA,kBAAS,EAAC,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAAE,IAAI,GAAG,EAAE,GAAG,IAAI,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC;QACjF,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,SAAS,KAAK,CAAC,MAAc,EAAE,MAA2B;QACxD,MAAM,GAAG,GAAG,IAAI,GAAG,EAAU,CAAC;QAC9B,IAAI,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,EAAE,IAAI,CAAC,MAAM,EAAE,IAAA,mBAAa,EAAC,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;QAC3H,KAAK,MAAM,CAAC,KAAK,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,IAAI,SAAS,EAAE,CAAC;YACtD,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;YAC9B,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC;gBAAE,SAAS;YACtC,IAAI,OAAO,GAAG,KAAK,CAAC;YACpB,MAAM,OAAO,GAAI,OAAkB,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;gBAC/C,0CAA0C;gBAC1C,IAAI,IAAA,iBAAQ,EAAC,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK,IAAI;oBAAE,OAAO,IAAI,CAAC;gBACrD,MAAM,GAAG,GAAG,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,KAAK,IAAI,IAAI,CAAC,GAAG,GAAG,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC;gBAC9F,IAAI,GAAG,KAAK,IAAI,CAAC,MAAM;oBAAE,OAAO,IAAI,CAAC;gBACrC,OAAO,GAAG,IAAI,CAAC;gBACf,OAAO,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;YAClC,CAAC,CAAC,CAAC;YACH,IAAI,OAAO;gBAAE,IAAI,GAAG,EAAE,GAAG,IAAI,EAAE,CAAC,KAAK,CAAC,EAAE,OAAO,EAAE,CAAC;QACpD,CAAC;QACD,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC;IACxC,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,OAAO,EAAE,CAAC;AAC3E,CAAC"}
|