@ai-matrx/records-ui 0.4.3 → 0.5.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,84 @@
1
1
  # Changelog — @ai-matrx/records-ui
2
2
 
3
+ ## 0.5.4
4
+
5
+ Makes the live FormBuilder certification wait for the editor state that follows
6
+ the saved-form tab, instead of asserting synchronously between the two React
7
+ effects.
8
+
9
+ ### Consumer action
10
+
11
+ None. This changes only the live certification harness.
12
+
13
+ ## 0.5.3
14
+
15
+ Makes the certification harness's raw record selector hide soft-deleted rows
16
+ by default, matching the active-record behavior of the store's public read
17
+ doors. An explicit `deleted_at` filter still allows a test to inspect
18
+ tombstones intentionally.
19
+
20
+ ### Consumer action
21
+
22
+ None. This changes only the live certification harness.
23
+
24
+ ## 0.5.2
25
+
26
+ Resets records inside the test organization's harness-owned `records_ui_*`
27
+ package Tables through the real delete door when certification starts. A view,
28
+ form, or action edited by an earlier run can no longer override the next run's
29
+ declared seed while product behavior continues to preserve real user edits.
30
+
31
+ ### Consumer action
32
+
33
+ None. This changes only the live certification harness.
34
+
35
+ ## 0.5.1
36
+
37
+ Builds the 0.5.0 system-table reconciliation against the refreshed 240-door
38
+ `@ai-matrx/records` contract after the dependency's live release guard caught
39
+ two newly registered store doors.
40
+
41
+ ### Consumer action
42
+
43
+ None. The public API is unchanged.
44
+
45
+ ## 0.5.0
46
+
47
+ **A package Table that changed SHAPE under an organization that already had a
48
+ copy.** `ActionInbox` could not record an outcome in one organization: its copy
49
+ of `records_ui_action` held `status` as a uuid-shaped Field while this package
50
+ declares it `text`, so every outcome write was refused `22P02 invalid input
51
+ syntax for type uuid: "open"`. The store was right; this package was the one out
52
+ of date. `ensureSystemTable` reconciled a MISSING Field on every load and never
53
+ looked at a Field it already had, so the organization that got its copy first
54
+ was the one where the package quietly stopped working.
55
+
56
+ Reconciliation is now two questions, not one — which Fields are missing, and
57
+ which are there with the wrong shape. Shape means exactly the two properties
58
+ that decide what a value is MADE OF, and therefore what the store will accept:
59
+ the behaviour (FLD-1) and whether it is multi (FLD-2). Label, sort, required and
60
+ config are deliberately left alone — they are presentation and policy, an
61
+ organization may legitimately have moved them, and none of them can make a write
62
+ fail. Nothing is ever renamed or removed.
63
+
64
+ Also fixed alongside it: a refusal from the FIRST declaration of a package Table
65
+ was both returned as this package's never-throw envelope and left as an
66
+ unhandled promise rejection, so a refusal that had in fact been reported
67
+ properly also produced a red console (and, under a test runner, a failed run).
68
+
69
+ Proved against the LIVE store in `demo/system-table-shape.test.tsx`: the Table
70
+ is declared with the old behaviour, the module is reloaded — which is what a
71
+ page load is, and the only way an organization ever meets a newer package — and
72
+ the new spec is ensured over it. RED without the fix: `expected 'range' to be
73
+ 'text'`.
74
+
75
+ ### Consumer action
76
+
77
+ None. The public API is unchanged, and the reconciliation is automatic on the
78
+ next load of any screen that opens a package-owned Table. An organization whose
79
+ copy drifted is levelled the first time a person opens that screen — there is
80
+ nothing to run and nothing to migrate.
81
+
3
82
  ## 0.4.3
4
83
 
5
84
  Resets the harness-owned demo table through the store's real read and delete
package/dist/index.cjs CHANGED
@@ -980,17 +980,18 @@ async function ensureSystemTable(client, spec) {
980
980
  if (found) {
981
981
  const grown = await addMissingFields(client, spec, found.id);
982
982
  if (!grown.ok) return grown;
983
+ const levelled = await reconcileFieldShapes(client, spec, found.id);
984
+ if (!levelled.ok) return levelled;
983
985
  return { ok: true, data: found.id };
984
986
  }
985
987
  let settle = () => void 0;
986
988
  let fail = () => void 0;
987
- inFlight.set(
988
- cacheKey,
989
- new Promise((resolve, reject) => {
990
- settle = resolve;
991
- fail = reject;
992
- })
993
- );
989
+ const pending = new Promise((resolve, reject) => {
990
+ settle = resolve;
991
+ fail = reject;
992
+ });
993
+ pending.catch(() => void 0);
994
+ inFlight.set(cacheKey, pending);
994
995
  const declared = await declare(client, spec);
995
996
  if (declared.ok) settle(declared.data);
996
997
  else {
@@ -1019,6 +1020,22 @@ async function addMissingFields(client, spec, tableId) {
1019
1020
  }
1020
1021
  return { ok: true, data: true };
1021
1022
  }
1023
+ async function reconcileFieldShapes(client, spec, tableId) {
1024
+ const held = await client.fields({ table_id: tableId });
1025
+ if (!held.ok) return held;
1026
+ const byKey = new Map(held.data.map((f) => [f.key, f]));
1027
+ for (const field of spec.fields) {
1028
+ const have = byKey.get(field.key);
1029
+ if (!have) continue;
1030
+ const patch = {};
1031
+ if (have.type !== field.type) patch.type = field.type;
1032
+ if (have.multi !== (field.multi ?? false)) patch.multi = field.multi ?? false;
1033
+ if (Object.keys(patch).length === 0) continue;
1034
+ const written = await client.recordUpdate({ record_id: have.id, patch });
1035
+ if (!written.ok) return written;
1036
+ }
1037
+ return { ok: true, data: true };
1038
+ }
1022
1039
  function fieldDocument(field, tableId) {
1023
1040
  return {
1024
1041
  key: field.key,