@fieldia/core 0.20.0 → 0.21.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 (116) hide show
  1. package/package.json +1 -1
  2. package/schema/page.schema.json +24 -0
  3. package/src/lib/expression/parser.js +4 -4
  4. package/src/lib/expression/parser.js.map +1 -1
  5. package/src/lib/expression/parser.mjs +5 -5
  6. package/src/lib/expression/parser.mjs.map +1 -1
  7. package/src/lib/expression/tokenizer.d.mts +12 -0
  8. package/src/lib/expression/tokenizer.d.ts +12 -0
  9. package/src/lib/expression/tokenizer.js +21 -12
  10. package/src/lib/expression/tokenizer.js.map +1 -1
  11. package/src/lib/expression/tokenizer.mjs +20 -12
  12. package/src/lib/expression/tokenizer.mjs.map +1 -1
  13. package/src/lib/format/field.d.mts +16 -0
  14. package/src/lib/format/field.d.ts +16 -0
  15. package/src/lib/format/field.js +11 -1
  16. package/src/lib/format/field.js.map +1 -1
  17. package/src/lib/format/field.mjs +11 -1
  18. package/src/lib/format/field.mjs.map +1 -1
  19. package/src/lib/format/page.d.mts +18 -0
  20. package/src/lib/format/page.d.ts +18 -0
  21. package/src/lib/format/page.js +1 -0
  22. package/src/lib/format/page.js.map +1 -1
  23. package/src/lib/format/page.mjs +1 -0
  24. package/src/lib/format/page.mjs.map +1 -1
  25. package/src/lib/format/pattern.d.mts +10 -0
  26. package/src/lib/format/pattern.d.ts +10 -0
  27. package/src/lib/format/pattern.js +33 -0
  28. package/src/lib/format/pattern.js.map +1 -0
  29. package/src/lib/format/pattern.mjs +30 -0
  30. package/src/lib/format/pattern.mjs.map +1 -0
  31. package/src/lib/format/references.js +8 -0
  32. package/src/lib/format/references.js.map +1 -1
  33. package/src/lib/format/references.mjs +8 -0
  34. package/src/lib/format/references.mjs.map +1 -1
  35. package/src/lib/format/translate.js +3 -2
  36. package/src/lib/format/translate.js.map +1 -1
  37. package/src/lib/format/translate.mjs +3 -2
  38. package/src/lib/format/translate.mjs.map +1 -1
  39. package/src/lib/record/check.d.mts +13 -3
  40. package/src/lib/record/check.d.ts +13 -3
  41. package/src/lib/record/check.js +87 -17
  42. package/src/lib/record/check.js.map +1 -1
  43. package/src/lib/record/check.mjs +85 -17
  44. package/src/lib/record/check.mjs.map +1 -1
  45. package/src/lib/record/filter.js +14 -2
  46. package/src/lib/record/filter.js.map +1 -1
  47. package/src/lib/record/filter.mjs +14 -2
  48. package/src/lib/record/filter.mjs.map +1 -1
  49. package/src/lib/record/form.d.mts +44 -0
  50. package/src/lib/record/form.d.ts +44 -0
  51. package/src/lib/record/form.js +249 -20
  52. package/src/lib/record/form.js.map +1 -1
  53. package/src/lib/record/form.mjs +251 -22
  54. package/src/lib/record/form.mjs.map +1 -1
  55. package/src/lib/record/input-rules.d.mts +277 -0
  56. package/src/lib/record/input-rules.d.ts +277 -0
  57. package/src/lib/record/input-rules.js +724 -0
  58. package/src/lib/record/input-rules.js.map +1 -0
  59. package/src/lib/record/input-rules.mjs +705 -0
  60. package/src/lib/record/input-rules.mjs.map +1 -0
  61. package/src/lib/record/inputs.d.mts +25 -0
  62. package/src/lib/record/inputs.d.ts +25 -0
  63. package/src/lib/record/inputs.js +135 -9
  64. package/src/lib/record/inputs.js.map +1 -1
  65. package/src/lib/record/inputs.mjs +131 -9
  66. package/src/lib/record/inputs.mjs.map +1 -1
  67. package/src/lib/record/locales/ar.js +13 -2
  68. package/src/lib/record/locales/ar.js.map +1 -1
  69. package/src/lib/record/locales/ar.mjs +13 -2
  70. package/src/lib/record/locales/ar.mjs.map +1 -1
  71. package/src/lib/record/locales/de.js +13 -2
  72. package/src/lib/record/locales/de.js.map +1 -1
  73. package/src/lib/record/locales/de.mjs +13 -2
  74. package/src/lib/record/locales/de.mjs.map +1 -1
  75. package/src/lib/record/locales/fr.js +13 -2
  76. package/src/lib/record/locales/fr.js.map +1 -1
  77. package/src/lib/record/locales/fr.mjs +13 -2
  78. package/src/lib/record/locales/fr.mjs.map +1 -1
  79. package/src/lib/record/memory-data-source.js +7 -3
  80. package/src/lib/record/memory-data-source.js.map +1 -1
  81. package/src/lib/record/memory-data-source.mjs +7 -3
  82. package/src/lib/record/memory-data-source.mjs.map +1 -1
  83. package/src/lib/record/messages.d.mts +22 -0
  84. package/src/lib/record/messages.d.ts +22 -0
  85. package/src/lib/record/messages.js +13 -2
  86. package/src/lib/record/messages.js.map +1 -1
  87. package/src/lib/record/messages.mjs +13 -2
  88. package/src/lib/record/messages.mjs.map +1 -1
  89. package/src/lib/record/rules.js +3 -1
  90. package/src/lib/record/rules.js.map +1 -1
  91. package/src/lib/record/rules.mjs +3 -1
  92. package/src/lib/record/rules.mjs.map +1 -1
  93. package/src/lib/record/run.d.mts +3 -2
  94. package/src/lib/record/run.d.ts +3 -2
  95. package/src/lib/record/run.js +1 -1
  96. package/src/lib/record/run.js.map +1 -1
  97. package/src/lib/record/run.mjs +1 -1
  98. package/src/lib/record/run.mjs.map +1 -1
  99. package/src/lib/record/search.d.mts +8 -1
  100. package/src/lib/record/search.d.ts +8 -1
  101. package/src/lib/record/search.js +28 -8
  102. package/src/lib/record/search.js.map +1 -1
  103. package/src/lib/record/search.mjs +28 -8
  104. package/src/lib/record/search.mjs.map +1 -1
  105. package/src/lib/record/structures.d.mts +8 -3
  106. package/src/lib/record/structures.d.ts +8 -3
  107. package/src/lib/record/structures.js +51 -7
  108. package/src/lib/record/structures.js.map +1 -1
  109. package/src/lib/record/structures.mjs +48 -6
  110. package/src/lib/record/structures.mjs.map +1 -1
  111. package/src/runtime.d.mts +5 -2
  112. package/src/runtime.d.ts +5 -2
  113. package/src/runtime.js +31 -1
  114. package/src/runtime.js.map +1 -1
  115. package/src/runtime.mjs +5 -2
  116. package/src/runtime.mjs.map +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"filter.mjs","sourceRoot":"","sources":["../../../../../../libs/core/src/lib/record/filter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"filter.mjs","sourceRoot":"","sources":["../../../../../../libs/core/src/lib/record/filter.ts"],"names":[],"mappings":"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"}
@@ -42,6 +42,17 @@ export interface FormState {
42
42
  readonly choices: Readonly<Record<string, Choices>>;
43
43
  /** The definitions loaded for a properties field with `definitionsFrom`, by field, once asked for. */
44
44
  readonly definitions: Readonly<Record<string, Definitions>>;
45
+ /**
46
+ * Text a person left in a box that does not read as its field's value — "12 34" in a number, "31/02/2026" in a
47
+ * date — by its path (`field`, or a line's `field.lineKey.subfield`), with why in words. The field keeps the
48
+ * value it held as the box was entered; validate and save refuse with the words until the text is fixed.
49
+ */
50
+ readonly unread: Readonly<Record<string, UnreadText>>;
51
+ }
52
+ /** Text left in a box that does not read, and why, as `FormState.unread` keeps it. */
53
+ export interface UnreadText {
54
+ readonly text: string;
55
+ readonly message: string;
45
56
  }
46
57
  /** A properties field's definitions from the app, as they load. */
47
58
  export interface Definitions {
@@ -228,6 +239,39 @@ export interface Form {
228
239
  fieldReadonly(name: string): boolean;
229
240
  /** What a field would be told if the form were checked now, or null when it passes. Nothing is shown. */
230
241
  problem(field: string): string | null;
242
+ /**
243
+ * Keep text a person left in a box that does not read (`FormState.unread`), by its path — `field`, or a line's
244
+ * `field.lineKey.subfield` — with why in words; null once it reads, or is let go. Nothing is shown until the box
245
+ * is left (`leave`) or the form is checked.
246
+ */
247
+ setUnread(path: string, unread: UnreadText | null): void;
248
+ /**
249
+ * A person left a field's box, by its path: its own problem — text that does not read, a format, min or max, a
250
+ * whole number, decimals, a pattern — is shown now, in the words Save would use. That it is required waits for Save.
251
+ */
252
+ leave(path: string): void;
253
+ /**
254
+ * How a box reads what is typed in it and not yet read — a number, hours, a date, a colour's code, a name looked
255
+ * up — now, as if it were left: every save and send, every check and step forward runs these first (`settle`), so
256
+ * Ctrl+Enter, a button's key, a pager or the app's own save keep what the box shows, or refuse it with its words,
257
+ * and never save a value passed on the way ("1" of "1.5") or the one the box held before. The viewer gives one
258
+ * for the box that has the focus (a change, which each box reads); a box whose reading waits — a name looked up
259
+ * among records — gives its own, which keeps the text unread with why at once, and returns the wait: a save
260
+ * waits for it, while a check or a step forward, which cannot wait, refuses meanwhile. `typing` says whether the
261
+ * box is still being typed in (typed since it last read): autosave, which nobody pressed, waits while it is, and
262
+ * never reads text under the person's keys ("12." of "12.5", "Office " of "Office Park"). Returns what stops it.
263
+ */
264
+ settling(read: () => void | Promise<unknown>, typing?: () => boolean): () => void;
265
+ /**
266
+ * Read what is typed and not yet read in every box (`settling`), as if each were left: a save does it first.
267
+ * Resolves once every reading that waits (a name looked up) has ended.
268
+ */
269
+ settle(): Promise<void>;
270
+ /**
271
+ * Whether a box's reading of what was typed still waits (a name being looked up): a check or a step forward made
272
+ * now refuses its text with "still looking", so a caller that can wait for it (`settle`) checks again after.
273
+ */
274
+ reading(): boolean;
231
275
  validate(): boolean;
232
276
  save(): Promise<boolean>;
233
277
  reset(): void;
@@ -42,6 +42,17 @@ export interface FormState {
42
42
  readonly choices: Readonly<Record<string, Choices>>;
43
43
  /** The definitions loaded for a properties field with `definitionsFrom`, by field, once asked for. */
44
44
  readonly definitions: Readonly<Record<string, Definitions>>;
45
+ /**
46
+ * Text a person left in a box that does not read as its field's value — "12 34" in a number, "31/02/2026" in a
47
+ * date — by its path (`field`, or a line's `field.lineKey.subfield`), with why in words. The field keeps the
48
+ * value it held as the box was entered; validate and save refuse with the words until the text is fixed.
49
+ */
50
+ readonly unread: Readonly<Record<string, UnreadText>>;
51
+ }
52
+ /** Text left in a box that does not read, and why, as `FormState.unread` keeps it. */
53
+ export interface UnreadText {
54
+ readonly text: string;
55
+ readonly message: string;
45
56
  }
46
57
  /** A properties field's definitions from the app, as they load. */
47
58
  export interface Definitions {
@@ -228,6 +239,39 @@ export interface Form {
228
239
  fieldReadonly(name: string): boolean;
229
240
  /** What a field would be told if the form were checked now, or null when it passes. Nothing is shown. */
230
241
  problem(field: string): string | null;
242
+ /**
243
+ * Keep text a person left in a box that does not read (`FormState.unread`), by its path — `field`, or a line's
244
+ * `field.lineKey.subfield` — with why in words; null once it reads, or is let go. Nothing is shown until the box
245
+ * is left (`leave`) or the form is checked.
246
+ */
247
+ setUnread(path: string, unread: UnreadText | null): void;
248
+ /**
249
+ * A person left a field's box, by its path: its own problem — text that does not read, a format, min or max, a
250
+ * whole number, decimals, a pattern — is shown now, in the words Save would use. That it is required waits for Save.
251
+ */
252
+ leave(path: string): void;
253
+ /**
254
+ * How a box reads what is typed in it and not yet read — a number, hours, a date, a colour's code, a name looked
255
+ * up — now, as if it were left: every save and send, every check and step forward runs these first (`settle`), so
256
+ * Ctrl+Enter, a button's key, a pager or the app's own save keep what the box shows, or refuse it with its words,
257
+ * and never save a value passed on the way ("1" of "1.5") or the one the box held before. The viewer gives one
258
+ * for the box that has the focus (a change, which each box reads); a box whose reading waits — a name looked up
259
+ * among records — gives its own, which keeps the text unread with why at once, and returns the wait: a save
260
+ * waits for it, while a check or a step forward, which cannot wait, refuses meanwhile. `typing` says whether the
261
+ * box is still being typed in (typed since it last read): autosave, which nobody pressed, waits while it is, and
262
+ * never reads text under the person's keys ("12." of "12.5", "Office " of "Office Park"). Returns what stops it.
263
+ */
264
+ settling(read: () => void | Promise<unknown>, typing?: () => boolean): () => void;
265
+ /**
266
+ * Read what is typed and not yet read in every box (`settling`), as if each were left: a save does it first.
267
+ * Resolves once every reading that waits (a name looked up) has ended.
268
+ */
269
+ settle(): Promise<void>;
270
+ /**
271
+ * Whether a box's reading of what was typed still waits (a name being looked up): a check or a step forward made
272
+ * now refuses its text with "still looking", so a caller that can wait for it (`settle`) checks again after.
273
+ */
274
+ reading(): boolean;
231
275
  validate(): boolean;
232
276
  save(): Promise<boolean>;
233
277
  reset(): void;
@@ -27,6 +27,8 @@ const values_1 = require("./values");
27
27
  function createForm(options) {
28
28
  return innerForm(options, []).form;
29
29
  }
30
+ /** A line's cell whose line is no longer there. */
31
+ const gone = Symbol('gone');
30
32
  const isRecord = (value) => value !== null && typeof value === 'object' && !Array.isArray(value);
31
33
  /** A saved form's answers, as the one value they are in the form round it. */
32
34
  const asValue = (values) => values;
@@ -112,6 +114,38 @@ function innerForm(options, within) {
112
114
  parts.set(node.id, node.source);
113
115
  /** Those given their page, with the inner form that holds their answers. */
114
116
  const attached = new Map();
117
+ /** How each box with text typed and not yet read reads it now (`settling`). */
118
+ const readers = new Set();
119
+ /** Whether each box that says so is still being typed in (`settling`'s `typing`): autosave waits for them. */
120
+ const typings = new Set();
121
+ /** A box of this form, or of a saved form placed on it, still being typed in. */
122
+ const typingNow = () => [...typings].some((typing) => typing()) || [...attached.values()].some((part) => part.inner.typing());
123
+ /** Readings of typed text still waiting, as readTyped started them. */
124
+ let readingNow = 0;
125
+ /**
126
+ * Every box's text read now, this form's and its saved forms' placed on the page, before it is checked or saved:
127
+ * what a reading that waits (a name looked up) is waiting for, or null when none does. Such a box keeps its text
128
+ * unread meanwhile, so a check made now refuses it; a save waits.
129
+ */
130
+ function readTyped() {
131
+ const waits = [];
132
+ for (const read of [...readers]) {
133
+ const wait = read();
134
+ if (wait && typeof wait.then === 'function')
135
+ waits.push(wait.catch(() => undefined));
136
+ }
137
+ for (const part of attached.values()) {
138
+ const inner = part.inner.form;
139
+ const wait = inner.settle();
140
+ if (inner.reading())
141
+ waits.push(wait);
142
+ }
143
+ if (!waits.length)
144
+ return null;
145
+ // Waiting on its own readings, or a saved form's: `reading` says so until they end.
146
+ readingNow++;
147
+ return Promise.all(waits).then(() => void readingNow--);
148
+ }
115
149
  /** The page's fields, and each saved form's answers as a JSON value: what is loaded, told as changed and saved. */
116
150
  const fields = { ...page.fields };
117
151
  for (const part of parts.values())
@@ -205,6 +239,7 @@ function innerForm(options, within) {
205
239
  saveProblem: null,
206
240
  choices: {},
207
241
  definitions: {},
242
+ unread: {},
208
243
  };
209
244
  started = true;
210
245
  /** Field errors a refused save brought, each kept until its field changes from the value it was refused with. */
@@ -317,8 +352,24 @@ function innerForm(options, within) {
317
352
  function checked(name) {
318
353
  const def = page.fields[name];
319
354
  const loaded = state.choices[name]?.options;
355
+ if (def.type === 'properties' && def.definitionsFrom) {
356
+ // The definitions the linked record keeps, once loaded: each property checked as one of its kind.
357
+ const definitions = state.definitions[name]?.definitions;
358
+ return definitions ? { ...def, definitions } : def;
359
+ }
320
360
  return def.type === 'selection' && def.optionsFrom && loaded ? { ...def, options: loaded, optionsFrom: undefined } : def;
321
361
  }
362
+ /** A properties field's problems, each at its property's path (`field.property`), as its row shows them. */
363
+ function propertyProblems(name) {
364
+ const def = checked(name);
365
+ if (def.type !== 'properties')
366
+ return {};
367
+ return Object.fromEntries(Object.entries((0, check_1.checkProperties)(def.definitions, state.values[name], messages, today())).map(([property, message]) => [`${name}.${property}`, message]));
368
+ }
369
+ /** A field's own problem, less what its properties' rows say of themselves. */
370
+ function besidesRows(name, message) {
371
+ return message !== undefined && page.fields[name]?.type === 'properties' && Object.values(propertyProblems(name)).includes(message) ? undefined : message;
372
+ }
322
373
  function track(promise) {
323
374
  pending.add(promise);
324
375
  const done = () => pending.delete(promise);
@@ -367,8 +418,8 @@ function innerForm(options, within) {
367
418
  ...(node.pressed ? { pressed: node.pressed.evaluate(ctx, env) } : {}),
368
419
  };
369
420
  }
370
- /** Field nodes — or saved forms placed on the page — inside `root` (or the whole page), visible right now. */
371
- function visibleFieldNodes(root, kind = 'field') {
421
+ /** Field nodes — or saved forms placed on the page — inside `root` (or the whole page), visible right now; `field`'s alone, when named. */
422
+ function visibleFieldNodes(root, kind = 'field', field) {
372
423
  const inside = (node) => {
373
424
  if (!root)
374
425
  return true;
@@ -386,7 +437,7 @@ function innerForm(options, within) {
386
437
  return true;
387
438
  return false;
388
439
  };
389
- return [...index.values()].filter((node) => node.kind === kind && inside(node) && !skipped(node) && !nodeState(node.id).invisible);
440
+ return [...index.values()].filter((node) => node.kind === kind && (field === undefined || node.field === field) && inside(node) && !skipped(node) && !nodeState(node.id).invisible);
390
441
  }
391
442
  /** What a field node's answer rules say of its value now: the first error and the first warning. */
392
443
  function ruleCheck(node) {
@@ -433,16 +484,52 @@ function innerForm(options, within) {
433
484
  state = previous;
434
485
  }
435
486
  }
487
+ /** A range's last day (`options.endField` of a `daterange`), the field it writes besides its own; null for any other node. */
488
+ function rangeEnd(node) {
489
+ const source = node.source;
490
+ const end = source.widget === 'daterange' ? source.options?.['endField'] : undefined;
491
+ return typeof end === 'string' && page.fields[end] && end !== node.field ? end : null;
492
+ }
493
+ /**
494
+ * A range's end, a field of its own though no node shows it alone: its required, min, max and days, and that it
495
+ * is not before its start ("Ends can’t be before Starts"). Required when its field is, or the range is.
496
+ */
497
+ function rangeEndError(node, end, required = nodeState(node.id).required) {
498
+ const def = page.fields[end];
499
+ const value = state.values[end];
500
+ const own = (0, check_1.checkValue)(checked(end), value, required || def.required === true, messages, today());
501
+ if (own)
502
+ return own;
503
+ const start = state.values[node.field];
504
+ if (typeof start !== 'string' || typeof value !== 'string' || !start || !value)
505
+ return undefined;
506
+ const at = (v) => (def.type === 'datetime' ? Date.parse(v) : Date.parse(v.slice(0, 10)));
507
+ if (at(value) < at(start))
508
+ return (0, messages_1.fill)(messages.endBeforeStart, { end: def.label, start: page.fields[node.field].label });
509
+ return undefined;
510
+ }
436
511
  /** Errors for the visible fields under `root`, without publishing them. */
437
512
  function collectErrors(root) {
438
513
  const errors = {};
514
+ const seen = new Set();
439
515
  for (const node of visibleFieldNodes(root)) {
440
516
  const name = node.field;
517
+ seen.add(name);
518
+ const end = rangeEnd(node);
519
+ if (end) {
520
+ seen.add(end);
521
+ const problem = errors[end] ? undefined : rangeEndError(node, end);
522
+ if (problem)
523
+ errors[end] = problem;
524
+ }
441
525
  if (errors[name])
442
526
  continue;
443
527
  const def = page.fields[name];
444
528
  const message = nodeError(node);
445
- if (message)
529
+ // A property says its own problem on its row; the field, only what is its own (that it is required).
530
+ if (def.type === 'properties')
531
+ Object.assign(errors, propertyProblems(name));
532
+ if (besidesRows(name, message))
446
533
  errors[name] = message;
447
534
  if (def.type === 'one2many') {
448
535
  for (const line of state.values[name] ?? []) {
@@ -463,6 +550,10 @@ function innerForm(options, within) {
463
550
  }
464
551
  }
465
552
  }
553
+ // Text left in a box that does not read answers for its field, in the words it was left with.
554
+ for (const [path, unread] of Object.entries(state.unread))
555
+ if (seen.has(path.split('.')[0]))
556
+ errors[path] = unread.message;
466
557
  // A saved form placed here answers for its fields by its own page's rules.
467
558
  for (const node of visibleFieldNodes(root, 'form')) {
468
559
  const part = attached.get(node.id);
@@ -472,6 +563,63 @@ function innerForm(options, within) {
472
563
  }
473
564
  return errors;
474
565
  }
566
+ /** The value at a path: a field's, or a line's cell (`field.lineKey.subfield`); `gone` when the line is not there. */
567
+ function valueAt(values, path) {
568
+ const parts = path.split('.');
569
+ // A property of a properties field (`field.property`).
570
+ if (parts.length === 2 && page.fields[parts[0]]?.type === 'properties') {
571
+ const held = values[parts[0]];
572
+ return held && typeof held === 'object' && !Array.isArray(held) ? held[parts[1]] : undefined;
573
+ }
574
+ if (parts.length < 3)
575
+ return values[path];
576
+ const [field, sub] = [parts[0], parts[parts.length - 1]];
577
+ const key = parts.slice(1, -1).join('.');
578
+ const line = (values[field] ?? []).find((l) => l.key === key);
579
+ return line ? line.values[sub] : gone;
580
+ }
581
+ /** Unread text whose field has since been written another way — a value typed that reads, the app's — is let go. */
582
+ function unreadKept(values) {
583
+ let kept = null;
584
+ for (const path of Object.keys(state.unread)) {
585
+ const now = valueAt(values, path);
586
+ if (now !== gone && now === valueAt(state.values, path))
587
+ continue;
588
+ kept ??= { ...state.unread };
589
+ delete kept[path];
590
+ }
591
+ return kept ?? state.unread;
592
+ }
593
+ /** A field's own problem as its box is left, never that it is required: undefined when it has none, or is not shown. */
594
+ function leftProblem(path) {
595
+ const parts = path.split('.');
596
+ const field = parts[0];
597
+ const shown = visibleFieldNodes(undefined, 'field', field);
598
+ // A range's end is left from its own box in the range: its problems, that it is before its start too.
599
+ const range = shown.length ? undefined : visibleFieldNodes().find((node) => rangeEnd(node) === field);
600
+ if (!shown.length && !range)
601
+ return undefined;
602
+ if (state.unread[path])
603
+ return state.unread[path].message;
604
+ if (range)
605
+ return (0, values_1.isEmpty)(fieldDef(field), state.values[field]) ? undefined : rangeEndError(range, field, false);
606
+ if (parts.length === 1) {
607
+ const value = state.values[field];
608
+ if ((0, values_1.isEmpty)(fieldDef(field), value))
609
+ return undefined;
610
+ return (shown.map((node) => (0, inputs_1.checkInput)(page.fields[field], node.source, value, messages)).find(Boolean) ??
611
+ besidesRows(field, (0, check_1.checkValue)(checked(field), value, false, messages, today())) ??
612
+ shown.map((node) => ruleCheck(node).error).find(Boolean));
613
+ }
614
+ if (parts.length === 2 && page.fields[field]?.type === 'properties')
615
+ return propertyProblems(field)[path];
616
+ const def = lineField(field);
617
+ const sub = def.fields[parts[parts.length - 1]];
618
+ const value = valueAt(state.values, path);
619
+ if (!sub || value === gone || (0, values_1.isEmpty)(sub, value))
620
+ return undefined;
621
+ return (0, check_1.checkValue)(sub, value, false, messages, today());
622
+ }
475
623
  /**
476
624
  * Answers changed from outside a saved form — loaded, put back, set — handed
477
625
  * to it, and what it holds after taken back: its defaults and worked-out
@@ -518,26 +666,32 @@ function innerForm(options, within) {
518
666
  /** Write values someone or something changed. `fresh` values are a starting point instead (a restored draft). */
519
667
  function writeValues(written, extra = {}, fresh = false) {
520
668
  const values = syncParts(fresh ? startFrom(written) : settle(written), fresh ? 'fresh' : 'edit');
521
- let errors = Object.keys(state.errors).length ? revalidateShown(values) : state.errors;
522
- // Words typed where a number goes are said at once, as Flectra marks a box it cannot read; what is missing waits for sending.
523
- const unread = {};
669
+ // Text left unread in a box goes once its field is written another way, and its words with it.
670
+ const unread = unreadKept(values);
671
+ const before = state;
672
+ state = { ...state, unread };
673
+ let errors = Object.keys(before.errors).length ? revalidateShown(values) : before.errors;
674
+ state = before;
675
+ // Words where a number goes — from a server or an old draft: a box never sets them — are said at once; what is
676
+ // missing waits for sending.
677
+ const words = {};
524
678
  for (const name of Object.keys(written)) {
525
679
  const def = page.fields[name];
526
680
  if (written[name] === state.values[name] || !def)
527
681
  continue;
528
682
  if (notANumber(def, written[name]))
529
- unread[name] = (0, check_1.checkValue)(def, written[name], false, messages);
683
+ words[name] = (0, check_1.checkValue)(def, written[name], false, messages);
530
684
  if (def.type !== 'one2many')
531
685
  continue;
532
686
  for (const line of written[name] ?? []) {
533
687
  for (const [sub, v] of Object.entries(line.values))
534
688
  if (notANumber(def.fields[sub], v))
535
- unread[`${name}.${line.key}.${sub}`] = (0, check_1.checkValue)(def.fields[sub], v, false, messages);
689
+ words[`${name}.${line.key}.${sub}`] = (0, check_1.checkValue)(def.fields[sub], v, false, messages);
536
690
  }
537
691
  }
538
- if (Object.keys(unread).length)
539
- errors = { ...errors, ...unread };
540
- set({ values, dirty: dirtyFields(values), errors, warnings: withValues(values, collectWarnings), ...extra });
692
+ if (Object.keys(words).length)
693
+ errors = { ...errors, ...words };
694
+ set({ values, dirty: dirtyFields(values), errors, warnings: withValues(values, collectWarnings), unread, ...extra });
541
695
  }
542
696
  /** Once errors are on screen, keep them current as the person fixes things. */
543
697
  function revalidateShown(values) {
@@ -599,6 +753,10 @@ function innerForm(options, within) {
599
753
  scheduler.clearTimeout(autosaveTimer);
600
754
  autosaveTimer = scheduler.setTimeout(() => {
601
755
  autosaveTimer = null;
756
+ // Nobody pressed anything: a box still typed in is never read under the person's keys. The save waits until it is
757
+ // left (or Enter is pressed in it), and reads it then, as any save does.
758
+ if (typingNow())
759
+ return scheduleAutosave();
602
760
  if (state.dirty.length && Object.keys(collectErrors()).length === 0)
603
761
  void track(save());
604
762
  }, autosave.delayMs);
@@ -669,6 +827,11 @@ function innerForm(options, within) {
669
827
  * and a stop keeps it unsaved; `afterSave` runs once it is saved.
670
828
  */
671
829
  async function saving(chain) {
830
+ // What is still typed in a box is read first: it is what is saved, or why nothing is. A name still being looked
831
+ // up is waited for, so the record it names is what is saved — or, named by none, why nothing is.
832
+ const waiting = readTyped();
833
+ if (waiting)
834
+ await waiting;
672
835
  if (page.on?.beforeSave) {
673
836
  const before = await moment('on.beforeSave', page.on.beforeSave, chain, false);
674
837
  if (!before.done) {
@@ -713,7 +876,7 @@ function innerForm(options, within) {
713
876
  // Lines the save brings back load again, in their tables' orders, as Flectra's reload after a save.
714
877
  const values = syncParts(startFrom(result.values ? ordered({ ...state.values, ...result.values }, Object.keys(result.values)) : state.values), 'start');
715
878
  baseline = (0, values_1.structuredCopy)(values);
716
- set({ status: 'saved', recordId: result.id, values, dirty: [], warnings: withValues(values, collectWarnings) });
879
+ set({ status: 'saved', recordId: result.id, values, dirty: [], warnings: withValues(values, collectWarnings), unread: {} });
717
880
  emit('save', { recordId: state.recordId, values: state.values });
718
881
  void track(moment('on.afterSave', page.on?.afterSave, chain, false));
719
882
  return null;
@@ -787,9 +950,15 @@ function innerForm(options, within) {
787
950
  changed(field, by);
788
951
  return key;
789
952
  }
790
- /** Check the form, or only these fields, showing what is found as sending does. */
791
- function check(names) {
953
+ /**
954
+ * Check the form, or only these fields, showing what is found as sending does: a step's check, which waits for a
955
+ * name still being looked up in a box, as a save does.
956
+ */
957
+ async function check(names) {
792
958
  names?.forEach(fieldDef);
959
+ const waiting = readTyped();
960
+ if (waiting)
961
+ await waiting;
793
962
  const all = collectErrors();
794
963
  const found = names ? Object.fromEntries(Object.entries(all).filter(([key]) => names.some((name) => key === name || key.startsWith(`${name}.`)))) : all;
795
964
  set({ errors: found });
@@ -797,11 +966,15 @@ function innerForm(options, within) {
797
966
  return first === undefined ? null : { reason: 'check', message: first };
798
967
  }
799
968
  /** Go to a wizard's step for a run; undefined when the target is no step of it, but a tab. */
800
- function goToStep(target, chain) {
969
+ async function goToStep(target, chain) {
801
970
  if (!steps.includes(target))
802
971
  return undefined;
803
972
  if (!form.steps().includes(target))
804
973
  return { reason: 'cannot', message: `The step "${target}" does not apply now` };
974
+ // A name still being looked up in a box on the way is waited for, as a save waits for it.
975
+ const waiting = readTyped();
976
+ if (waiting)
977
+ await waiting;
805
978
  let went = false;
806
979
  inRun(chain, () => (went = form.goTo(target)));
807
980
  return went ? null : { reason: 'check', message: Object.values(state.errors)[0] };
@@ -873,7 +1046,7 @@ function innerForm(options, within) {
873
1046
  return;
874
1047
  // Lines load in their tables' orders; where a person moves them after, they stay.
875
1048
  baseline = syncParts(startFrom(ordered({ ...(0, values_1.initialValues)(fields, today()), ...loaded })), 'start');
876
- set({ status: 'ready', values: (0, values_1.structuredCopy)(baseline), dirty: [], errors: {}, warnings: withValues(baseline, collectWarnings) });
1049
+ set({ status: 'ready', values: (0, values_1.structuredCopy)(baseline), dirty: [], errors: {}, warnings: withValues(baseline, collectWarnings), unread: {} });
877
1050
  if (again)
878
1051
  return;
879
1052
  offerDraft();
@@ -895,7 +1068,7 @@ function innerForm(options, within) {
895
1068
  serverErrors = {};
896
1069
  told = null;
897
1070
  showing = false;
898
- const fresh = { dirty: [], errors: {}, warning: null, warningField: null, error: null, draft: null, step: steps[0] ?? null, skipped: [], saveProblem: null };
1071
+ const fresh = { dirty: [], errors: {}, warning: null, warningField: null, error: null, draft: null, step: steps[0] ?? null, skipped: [], saveProblem: null, unread: {} };
899
1072
  if (id != null) {
900
1073
  set({ ...fresh, recordId: id, status: 'idle' });
901
1074
  return load();
@@ -1026,12 +1199,65 @@ function innerForm(options, within) {
1026
1199
  const shown = visibleFieldNodes().filter((node) => node.field === name);
1027
1200
  if (!shown.length)
1028
1201
  return null;
1202
+ if (state.unread[name])
1203
+ return state.unread[name].message;
1204
+ // A property's text left unread answers for its field.
1205
+ if (page.fields[name].type === 'properties') {
1206
+ const row = Object.keys(state.unread).find((path) => path.startsWith(`${name}.`));
1207
+ if (row)
1208
+ return state.unread[row].message;
1209
+ }
1029
1210
  const own = shown.map(unticked).find(Boolean) ??
1030
1211
  shown.map((node) => (0, inputs_1.checkInput)(page.fields[name], node.source, state.values[name], messages)).find(Boolean) ??
1031
1212
  (0, check_1.checkValue)(checked(name), state.values[name], shown.some((node) => nodeState(node.id).required), messages, today());
1032
1213
  return own ?? shown.map((node) => ruleCheck(node).error).find((error) => error !== undefined) ?? null;
1033
1214
  },
1215
+ setUnread(path, unread) {
1216
+ const field = path.split('.')[0];
1217
+ // A line's cell (`field.lineKey.subfield`), or a property (`field.property`).
1218
+ const def = fieldDef(field);
1219
+ if (path.includes('.') && def.type !== 'properties')
1220
+ lineField(field);
1221
+ const had = state.unread[path];
1222
+ if (!unread && !had)
1223
+ return;
1224
+ // A line taken away takes its cells' text with it: a box of it still reading (a name looked up) keeps none.
1225
+ if (unread && !had && path.split('.').length >= 3 && def.type !== 'properties' && valueAt(state.values, path) === gone)
1226
+ return;
1227
+ if (unread && had && had.text === unread.text && had.message === unread.message)
1228
+ return;
1229
+ const next = { ...state.unread };
1230
+ if (unread)
1231
+ next[path] = { text: unread.text, message: unread.message };
1232
+ else
1233
+ delete next[path];
1234
+ // Problems on screen stay current: an unread text put right takes its words with it.
1235
+ const before = state;
1236
+ state = { ...state, unread: next };
1237
+ const errors = Object.keys(before.errors).length ? revalidateShown(state.values) : before.errors;
1238
+ state = before;
1239
+ set({ unread: next, errors });
1240
+ },
1241
+ leave(path) {
1242
+ const problem = leftProblem(path);
1243
+ if (!problem || state.errors[path] === problem)
1244
+ return;
1245
+ set({ errors: { ...state.errors, [path]: problem } });
1246
+ },
1247
+ settling(read, typing) {
1248
+ readers.add(read);
1249
+ if (typing)
1250
+ typings.add(typing);
1251
+ return () => {
1252
+ readers.delete(read);
1253
+ if (typing)
1254
+ typings.delete(typing);
1255
+ };
1256
+ },
1257
+ settle: () => readTyped() ?? Promise.resolve(),
1258
+ reading: () => readingNow > 0 || [...attached.values()].some((part) => part.inner.form.reading()),
1034
1259
  validate() {
1260
+ readTyped();
1035
1261
  const errors = collectErrors();
1036
1262
  set({ errors });
1037
1263
  return Object.keys(errors).length === 0;
@@ -1042,7 +1268,7 @@ function innerForm(options, within) {
1042
1268
  serverErrors = {};
1043
1269
  holding = setWhen.holding(baseline);
1044
1270
  const values = syncParts((0, values_1.structuredCopy)(baseline), 'start');
1045
- set({ values, dirty: [], errors: {}, warnings: withValues(values, collectWarnings), warning: null, warningField: null, draft: null, step: steps[0] ?? null, skipped: [], saveProblem: null });
1271
+ set({ values, dirty: [], errors: {}, warnings: withValues(values, collectWarnings), warning: null, warningField: null, draft: null, step: steps[0] ?? null, skipped: [], saveProblem: null, unread: {} });
1046
1272
  },
1047
1273
  changes,
1048
1274
  addLine: (field, values = {}) => addLine(field, values, 'person'),
@@ -1137,6 +1363,7 @@ function innerForm(options, within) {
1137
1363
  next() {
1138
1364
  if (!state.step)
1139
1365
  return false;
1366
+ readTyped();
1140
1367
  // A step skipped before and gone back to is answered now, and checked like any other.
1141
1368
  if (state.skipped.includes(state.step))
1142
1369
  set({ skipped: state.skipped.filter((id) => id !== state.step) });
@@ -1183,6 +1410,7 @@ function innerForm(options, within) {
1183
1410
  set({ step: target, errors: {} });
1184
1411
  return true;
1185
1412
  }
1413
+ readTyped();
1186
1414
  const skipped = [...state.skipped];
1187
1415
  for (const id of visible.slice(at, to)) {
1188
1416
  if (skipped.includes(id))
@@ -1385,9 +1613,10 @@ function innerForm(options, within) {
1385
1613
  return writeValues({ ...(0, values_1.initialValues)(page.fields, today()), ...values }, {}, how === 'fresh');
1386
1614
  baseline = startFrom({ ...(0, values_1.initialValues)(page.fields, today()), ...(0, values_1.structuredCopy)(values) });
1387
1615
  const start = syncParts((0, values_1.structuredCopy)(baseline), 'start');
1388
- set({ values: start, dirty: [], errors: {}, warnings: withValues(start, collectWarnings), warning: null, warningField: null });
1616
+ set({ values: start, dirty: [], errors: {}, warnings: withValues(start, collectWarnings), warning: null, warningField: null, unread: {} });
1389
1617
  },
1390
1618
  errorsNow: () => collectErrors(),
1619
+ typing: typingNow,
1391
1620
  show(errors) {
1392
1621
  if (JSON.stringify(errors) !== JSON.stringify(state.errors))
1393
1622
  set({ errors });