@fnndsc/brasa 0.45.0 → 0.46.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.
Files changed (82) hide show
  1. package/dist/api/models.d.ts +37 -0
  2. package/dist/api/models.js.map +1 -1
  3. package/dist/buildinfo.json +1 -1
  4. package/dist/builtins/fs/pull.args.d.ts +0 -10
  5. package/dist/builtins/fs/pull.args.js +5 -30
  6. package/dist/builtins/fs/pull.args.js.map +1 -1
  7. package/dist/builtins/fs/pull.js +2 -48
  8. package/dist/builtins/fs/pull.js.map +1 -1
  9. package/dist/builtins/help.js +21 -5
  10. package/dist/builtins/help.js.map +1 -1
  11. package/dist/builtins/helpSections.js +3 -3
  12. package/dist/builtins/helpSections.js.map +1 -1
  13. package/dist/builtins/net/query.js +0 -3
  14. package/dist/builtins/net/query.js.map +1 -1
  15. package/dist/builtins/pluginExecute.d.ts +4 -1
  16. package/dist/builtins/pluginExecute.js +11 -12
  17. package/dist/builtins/pluginExecute.js.map +1 -1
  18. package/dist/builtins/res/expect.js +5 -2
  19. package/dist/builtins/res/expect.js.map +1 -1
  20. package/dist/builtins/res/gather.d.ts +2 -2
  21. package/dist/builtins/res/gather.js +11 -3
  22. package/dist/builtins/res/gather.js.map +1 -1
  23. package/dist/builtins/res/gather.kind.d.ts +9 -0
  24. package/dist/builtins/res/gather.kind.js +10 -0
  25. package/dist/builtins/res/gather.kind.js.map +1 -0
  26. package/dist/builtins/res/gather.process.d.ts +29 -0
  27. package/dist/builtins/res/gather.process.js +177 -0
  28. package/dist/builtins/res/gather.process.js.map +1 -0
  29. package/dist/builtins/res/pipeline.d.ts +16 -0
  30. package/dist/builtins/res/pipeline.js +38 -13
  31. package/dist/builtins/res/pipeline.js.map +1 -1
  32. package/dist/builtins/res/play.d.ts +2 -0
  33. package/dist/builtins/res/play.js +30 -7
  34. package/dist/builtins/res/play.js.map +1 -1
  35. package/dist/builtins/res/plugin.js +9 -30
  36. package/dist/builtins/res/plugin.js.map +1 -1
  37. package/dist/builtins/res/runWait.d.ts +10 -0
  38. package/dist/builtins/res/runWait.js +14 -0
  39. package/dist/builtins/res/runWait.js.map +1 -1
  40. package/dist/builtins/sys/variables.d.ts +25 -0
  41. package/dist/builtins/sys/variables.js +113 -0
  42. package/dist/builtins/sys/variables.js.map +1 -0
  43. package/dist/builtins/variablesPage.d.ts +9 -0
  44. package/dist/builtins/variablesPage.js +54 -0
  45. package/dist/builtins/variablesPage.js.map +1 -0
  46. package/dist/chris/binExecutables.d.ts +19 -0
  47. package/dist/chris/binExecutables.js +18 -0
  48. package/dist/chris/binExecutables.js.map +1 -0
  49. package/dist/chris/commandFallback.js +6 -22
  50. package/dist/chris/commandFallback.js.map +1 -1
  51. package/dist/chris/help.d.ts +2 -2
  52. package/dist/chris/help.js +27 -44
  53. package/dist/chris/help.js.map +1 -1
  54. package/dist/chris/references.js +14 -75
  55. package/dist/chris/references.js.map +1 -1
  56. package/dist/core/assignment.d.ts +13 -0
  57. package/dist/core/assignment.js +98 -0
  58. package/dist/core/assignment.js.map +1 -0
  59. package/dist/core/coreCommands.js +5 -0
  60. package/dist/core/coreCommands.js.map +1 -1
  61. package/dist/core/engine.js +14 -3
  62. package/dist/core/engine.js.map +1 -1
  63. package/dist/core/expansion.d.ts +13 -7
  64. package/dist/core/expansion.js +36 -19
  65. package/dist/core/expansion.js.map +1 -1
  66. package/dist/core/sink.d.ts +33 -0
  67. package/dist/core/sink.js +48 -0
  68. package/dist/core/sink.js.map +1 -1
  69. package/dist/core/variables.d.ts +121 -0
  70. package/dist/core/variables.js +316 -0
  71. package/dist/core/variables.js.map +1 -0
  72. package/dist/lib/parser.js +2 -2
  73. package/dist/notes.json +1 -1
  74. package/dist/session/answerAdapters.js +12 -0
  75. package/dist/session/answerAdapters.js.map +1 -1
  76. package/package.json +1 -1
  77. package/dist/builtins/pronouns.d.ts +0 -8
  78. package/dist/builtins/pronouns.js +0 -39
  79. package/dist/builtins/pronouns.js.map +0 -1
  80. package/dist/session/recent.d.ts +0 -68
  81. package/dist/session/recent.js +0 -99
  82. package/dist/session/recent.js.map +0 -1
@@ -0,0 +1,316 @@
1
+ /**
2
+ * @file The session's variables: a name a line gives to what a command
3
+ * answered, so a later line can say which thing it means.
4
+ *
5
+ * `A=$(pl-dcm2niix …)` holds the run's whole answer, its model, rather than
6
+ * the text it printed; `${A.instanceId}` reads one field of it. A command
7
+ * that answers no model is held as its text, one row per line. A literal,
8
+ * `LABEL='sag cohort'`, is one word and stays one.
9
+ *
10
+ * Variables belong to the session, so every surface attached to it sees the
11
+ * same ones. A manifest's play gets a scope of its own: it sees its
12
+ * parameters (read-only) and nothing of the caller's, and what it sets ends
13
+ * with it. A nested play gets its own again. The scope follows the async
14
+ * path, so a play running in the daemon never leaks into a line typed at
15
+ * another surface at the same moment.
16
+ *
17
+ * Reading follows one rule everywhere: a dot is a field of the model, as the
18
+ * model names it. A field holding a list reaches through it, one operand per
19
+ * element; a bare name is its rows when the answer has rows, and refuses by
20
+ * name when it is one thing with several fields. There is no indexing:
21
+ * naming one row is what the `@` handles are for.
22
+ *
23
+ * @module
24
+ */
25
+ import { AsyncLocalStorage } from 'node:async_hooks';
26
+ import { answerRows_of } from '../session/answer.js';
27
+ /** The kind a variable holding text has: a literal, a parameter, or a command with no model. */
28
+ export const TEXT_KIND = 'text';
29
+ /** What a name may be: a letter or underscore, then letters, digits, underscores. */
30
+ export const VARIABLE_NAME = /^[A-Za-z_][A-Za-z0-9_]*$/;
31
+ /** The session's own variables. */
32
+ const sessionScope = new Map();
33
+ /** The scope of the play running on this async path, when one is. */
34
+ const playScope = new AsyncLocalStorage();
35
+ /**
36
+ * The scope a line on this async path reads and writes.
37
+ *
38
+ * @returns The play's scope inside a play, else the session's.
39
+ */
40
+ function scope_current() {
41
+ return playScope.getStore() ?? sessionScope;
42
+ }
43
+ /**
44
+ * Whether the work on this async path is a play's.
45
+ *
46
+ * @returns True inside a play's scope.
47
+ */
48
+ export function variableScope_isPlay() {
49
+ return playScope.getStore() !== undefined;
50
+ }
51
+ /**
52
+ * A text answer: a literal, a parameter's value, or what a command printed.
53
+ *
54
+ * @param text - The text.
55
+ * @param source - The line that gave it.
56
+ * @returns The answer.
57
+ */
58
+ export function textAnswer_make(text, source) {
59
+ return { source, kind: TEXT_KIND, rows: [], data: text };
60
+ }
61
+ /**
62
+ * Runs work in a fresh scope holding only the given parameters, read-only:
63
+ * a manifest's play.
64
+ *
65
+ * @param params - The parameters, already checked for completeness.
66
+ * @param operation - The work to run.
67
+ * @returns The operation's result.
68
+ */
69
+ export async function variableScope_run(params, operation) {
70
+ const scope = new Map();
71
+ for (const [name, value] of params) {
72
+ scope.set(name, { answer: textAnswer_make(value, `@param ${name}`), readOnly: true });
73
+ }
74
+ return await playScope.run(scope, operation);
75
+ }
76
+ /**
77
+ * The variable a name holds in the current scope.
78
+ *
79
+ * @param name - The variable's name.
80
+ * @returns It, or undefined when the scope has none of that name.
81
+ */
82
+ export function variable_get(name) {
83
+ return scope_current().get(name);
84
+ }
85
+ /**
86
+ * Sets a variable in the current scope.
87
+ *
88
+ * @param name - Its name, already checked.
89
+ * @param answer - What it holds.
90
+ * @returns A refusal, or null when it was set.
91
+ */
92
+ export function variable_set(name, answer) {
93
+ const scope = scope_current();
94
+ if (scope.get(name)?.readOnly === true)
95
+ return `${name} is a parameter of this manifest; it is read-only`;
96
+ scope.set(name, { answer, readOnly: false });
97
+ return null;
98
+ }
99
+ /**
100
+ * Removes a variable from the current scope.
101
+ *
102
+ * @param name - Its name.
103
+ * @returns A refusal, or null when it was removed (or was never set).
104
+ */
105
+ export function variable_unset(name) {
106
+ const scope = scope_current();
107
+ if (scope.get(name)?.readOnly === true)
108
+ return `${name} is a parameter of this manifest; it is read-only`;
109
+ scope.delete(name);
110
+ return null;
111
+ }
112
+ /**
113
+ * Every variable in the current scope, by name.
114
+ *
115
+ * @returns The variables, sorted by name.
116
+ */
117
+ export function variables_list() {
118
+ return Array.from(scope_current().entries())
119
+ .map(([name, variable]) => ({ name, ...variable }))
120
+ .sort((left, right) => left.name.localeCompare(right.name));
121
+ }
122
+ /** Kind to its bare operands, for records that are not listings. */
123
+ const operandReaders = new Map();
124
+ /**
125
+ * Says what a bare `${NAME}` holding a record of this kind expands to. A
126
+ * listing's rows need no reader (its answer adapter numbers them); this is
127
+ * for a record that is not a listing and must not become the held one, as a
128
+ * scheduled pipeline's nodes are not rows to number.
129
+ *
130
+ * @param kind - The model kind.
131
+ * @param reader - Reads the operands out of that model.
132
+ */
133
+ export function answerOperands_register(kind, reader) {
134
+ operandReaders.set(kind, reader);
135
+ }
136
+ /**
137
+ * A value's own field names, for a refusal that says what can be named.
138
+ *
139
+ * @param value - An object.
140
+ * @returns Its keys.
141
+ */
142
+ function fields_of(value) {
143
+ return Object.keys(value).join(', ');
144
+ }
145
+ /**
146
+ * Whether a value is a scalar an operand can be made of.
147
+ *
148
+ * @param value - Anything.
149
+ * @returns True for a string, number or boolean.
150
+ */
151
+ function scalar_is(value) {
152
+ return typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean';
153
+ }
154
+ /**
155
+ * The operands a value is, at the end of a dotted name.
156
+ *
157
+ * @param value - The value reached.
158
+ * @param trail - The name as far as it went, for a refusal.
159
+ * @param kind - The answer's kind, named when the whole model is an object.
160
+ * @returns Its operands, or why it has none.
161
+ */
162
+ function leaf_read(value, trail, kind) {
163
+ if (value === null || value === undefined)
164
+ return { refused: `${trail} is empty` };
165
+ if (scalar_is(value))
166
+ return { values: [String(value)] };
167
+ if (Array.isArray(value)) {
168
+ if (value.length === 0)
169
+ return { refused: `${trail} is empty` };
170
+ if (value.every(scalar_is))
171
+ return { values: value.map((element) => String(element)) };
172
+ const first = value.find((element) => element !== null && typeof element === 'object');
173
+ return { refused: `${trail} holds records; name a field: ${first === undefined ? '' : fields_of(first)}` };
174
+ }
175
+ return { refused: `${trail} is ${kind === null ? 'a record' : `a ${kind}`}; name a field: ${fields_of(value)}` };
176
+ }
177
+ /**
178
+ * Walks a dotted name into a value. A field that is a list is reached
179
+ * through: every element gives its operands.
180
+ *
181
+ * @param value - Where the walk stands.
182
+ * @param fields - The fields still to walk.
183
+ * @param trail - The name as far as it went.
184
+ * @param kind - The answer's kind, for the bare refusal.
185
+ * @returns The operands, or why there are none.
186
+ */
187
+ function fields_walk(value, fields, trail, kind) {
188
+ if (fields.length === 0)
189
+ return leaf_read(value, trail, kind);
190
+ const [field, ...rest] = fields;
191
+ if (Array.isArray(value)) {
192
+ const values = [];
193
+ for (const element of value) {
194
+ const reading = fields_walk(element, fields, trail, null);
195
+ if ('refused' in reading)
196
+ return reading;
197
+ values.push(...reading.values);
198
+ }
199
+ if (values.length === 0)
200
+ return { refused: `${trail} is empty` };
201
+ return { values };
202
+ }
203
+ if (value === null || typeof value !== 'object')
204
+ return { refused: `${trail} is a value; it has no field ${field}` };
205
+ if (!(field in value))
206
+ return { refused: `${trail} has no field ${field}; it has ${fields_of(value)}` };
207
+ return fields_walk(value[field], rest, `${trail}.${field}`, null);
208
+ }
209
+ /**
210
+ * The lines of a text answer, the trailing newline not making an empty one.
211
+ *
212
+ * @param text - The text.
213
+ * @returns One string per line.
214
+ */
215
+ function lines_of(text) {
216
+ const lines = text.split('\n');
217
+ if (lines.length > 0 && lines[lines.length - 1] === '')
218
+ lines.pop();
219
+ return lines;
220
+ }
221
+ /**
222
+ * Reads an answer by a dotted name: bare, its rows (or its lines, or its
223
+ * one value); with fields, the fields as the model names them.
224
+ *
225
+ * @param answer - What the variable holds.
226
+ * @param name - The variable's name, for a refusal.
227
+ * @param fields - The fields after it, in order.
228
+ * @returns The operands, or why there are none.
229
+ */
230
+ export function answer_read(answer, name, fields) {
231
+ if (answer.kind === TEXT_KIND) {
232
+ if (fields.length > 0)
233
+ return { refused: `${name} is text; it has no field ${fields[0]}` };
234
+ const lines = lines_of(typeof answer.data === 'string' ? answer.data : '');
235
+ return lines.length === 0 ? { refused: `${name} is empty` } : { values: lines };
236
+ }
237
+ if (fields.length > 0)
238
+ return fields_walk(answer.data, fields, name, answer.kind);
239
+ const rows = answerRows_of(answer.kind, answer.data);
240
+ if (rows !== null) {
241
+ const values = rows.flatMap((row) => row.values);
242
+ return values.length === 0 ? { refused: `${name} is empty` } : { values };
243
+ }
244
+ const operands = operandReaders.get(answer.kind)?.(answer.data) ?? null;
245
+ if (operands !== null)
246
+ return operands.length === 0 ? { refused: `${name} is empty` } : { values: operands };
247
+ return leaf_read(answer.data, name, answer.kind);
248
+ }
249
+ /**
250
+ * Finds the end of a `$(…)` that opens at a position: the parenthesis that
251
+ * closes it, skipping any inside quotes or nested parentheses.
252
+ *
253
+ * @param text - The text.
254
+ * @param open - Where `$(` begins.
255
+ * @returns The index of the closing parenthesis, or -1 when it never closes.
256
+ */
257
+ export function substitution_end(text, open) {
258
+ let depth = 0;
259
+ let quote = null;
260
+ for (let at = open + 1; at < text.length; at++) {
261
+ const char = text[at];
262
+ if (quote !== null) {
263
+ if (char === '\\' && quote === '"') {
264
+ at++;
265
+ continue;
266
+ }
267
+ if (char === quote)
268
+ quote = null;
269
+ continue;
270
+ }
271
+ if (char === '\\') {
272
+ at++;
273
+ continue;
274
+ }
275
+ if (char === '"' || char === "'") {
276
+ quote = char;
277
+ continue;
278
+ }
279
+ if (char === '(')
280
+ depth++;
281
+ else if (char === ')') {
282
+ depth--;
283
+ if (depth === 0)
284
+ return at;
285
+ }
286
+ }
287
+ return -1;
288
+ }
289
+ /**
290
+ * Reads a line as an assignment, when it is one: `NAME=$(command)` or
291
+ * `NAME=word`.
292
+ *
293
+ * @param line - The trimmed line.
294
+ * @returns The assignment, or null when the line is not one.
295
+ */
296
+ export function assignment_parse(line) {
297
+ const match = line.match(/^([A-Za-z_][A-Za-z0-9_]*)=(.*)$/s);
298
+ if (match === null)
299
+ return null;
300
+ const name = match[1];
301
+ const value = match[2];
302
+ if (!value.startsWith('$('))
303
+ return { name, literal: value };
304
+ const end = substitution_end(value, 0);
305
+ if (end === -1)
306
+ return { name, refused: `${name}=$(…): the $( never closes` };
307
+ if (value.slice(end + 1).trim() !== '')
308
+ return { name, refused: `${name}=$(…): a capture is the whole value; nothing may follow its )` };
309
+ const capture = value.slice(2, end).trim();
310
+ if (capture === '')
311
+ return { name, refused: `${name}=$(): there is no command to capture` };
312
+ if (capture.startsWith('$(') || /(^|[^\\])\$\(/.test(capture))
313
+ return { name, refused: `${name}=$(…): a capture holds one command line, not another capture` };
314
+ return { name, capture };
315
+ }
316
+ //# sourceMappingURL=variables.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"variables.js","sourceRoot":"","sources":["../../src/core/variables.ts"],"names":[],"mappings":"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"}
@@ -8,8 +8,8 @@
8
8
  /**
9
9
  * What a reference looks like: `${name}` or a bare `$NAME`.
10
10
  *
11
- * A braced name may carry dots, which is how a session pronoun names part
12
- * of what it refers to (`${gather.first.place}`); a bare one may not, so
11
+ * A braced name may carry dots, which is how a variable names a field
12
+ * of what it refers to (`${gather.series.folderPath}`); a bare one may not, so
13
13
  * `$HOME.txt` keeps its extension.
14
14
  */
15
15
  const REFERENCE_PATTERN = /^\$(?:\{([A-Za-z_][A-Za-z0-9_.]*)\}|([A-Za-z_][A-Za-z0-9_]*))/;