@ai-matrx/records 0.8.0 → 0.16.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/CHANGELOG.md +163 -0
- package/dist/core/index.cjs +524 -13
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +280 -5
- package/dist/core/index.d.ts +280 -5
- package/dist/core/index.js +524 -13
- package/dist/core/index.js.map +1 -1
- package/dist/index.cjs +116 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +845 -10
- package/dist/index.d.ts +845 -10
- package/dist/index.js +116 -8
- package/dist/index.js.map +1 -1
- package/dist/react/index.cjs +592 -10
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +1138 -12
- package/dist/react/index.d.ts +1138 -12
- package/dist/react/index.js +592 -10
- package/dist/react/index.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,168 @@
|
|
|
1
1
|
# Changelog — @ai-matrx/records
|
|
2
2
|
|
|
3
|
+
## 0.16.0
|
|
4
|
+
|
|
5
|
+
**A column is declared, and a client type can finally say so.**
|
|
6
|
+
|
|
7
|
+
`NewFieldDeclaration` now names what `custom.field_declare` has actually taken
|
|
8
|
+
since 2026-09-20: `type` (the one word every agent, script and import reaches
|
|
9
|
+
for — the store resolves the thirteen parity types, the five behaviours and the
|
|
10
|
+
plain synonyms, and refuses a word that means nothing by name), `config` (a long
|
|
11
|
+
text's `multiline`, a list's existing options table — the door always read it and
|
|
12
|
+
no client could send it), `relation_target` and `on_target_delete` (a column that
|
|
13
|
+
points at another of this organization's own tables, which no client type could
|
|
14
|
+
express at all), and `format` (the one shape `custom.doc_sign` accepts).
|
|
15
|
+
|
|
16
|
+
`FieldPatch` gains the door's BEHAVIOUR arm — `parity_type`, `plain`, `type`,
|
|
17
|
+
`multi` — plus `relation_target`, `on_target_delete`, `promoted`, `unique` and
|
|
18
|
+
`depends_on`. It named only the settings, so the one caller that needed to move a
|
|
19
|
+
column back onto the behaviour it is written against had no door and reached for
|
|
20
|
+
`custom.record_update` instead, writing the document *under* the guards rather
|
|
21
|
+
than through them. **`multi` is read only inside that arm: send the behaviour
|
|
22
|
+
word with it or nothing happens.**
|
|
23
|
+
|
|
24
|
+
**The columns come back in the order they were declared.** `custom.applicable_fields`
|
|
25
|
+
answers a SET — its order is the plan's and it moves between calls — so every
|
|
26
|
+
consumer of `client.fields()` was drawing columns in an arbitrary order. A table
|
|
27
|
+
declared Title, Day rate, Due came back Day rate, Title, Due. The Field's own
|
|
28
|
+
`sort` is applied once, here, so every screen, export, form and agent inherits it.
|
|
29
|
+
|
|
30
|
+
**22007 is mapped.** The live-door census caught `custom.dashboard_window_sql`
|
|
31
|
+
raising it; it reads as `invalid_argument`, like 42703 before it.
|
|
32
|
+
|
|
33
|
+
**The live-door suite declared its own fixture the way the store no longer
|
|
34
|
+
allows** — `custom.record_write` into the field kernel — so eighteen of its
|
|
35
|
+
thirty-three clauses were red on `main` against the live store. It uses
|
|
36
|
+
`custom.field_declare`. 33/33.
|
|
37
|
+
## 0.15.0
|
|
38
|
+
|
|
39
|
+
**A client portal has an owner's side, and this package can reach it.**
|
|
40
|
+
`custom.portals`, `custom.portal_card`, `custom.portal_declare`,
|
|
41
|
+
`custom.portal_invite`, `custom.portal_revoke` and `custom.portal_preview` have
|
|
42
|
+
been live on the database and no client could call them, so the six doors that
|
|
43
|
+
decide who signs in from outside an organization — and what they see — existed
|
|
44
|
+
with nothing able to ask them. `store.generated.ts` was regenerated from the
|
|
45
|
+
live store (372 → 387 doors) and the six are now on `client`:
|
|
46
|
+
|
|
47
|
+
- `client.portals()` — every portal over this organization, with its client
|
|
48
|
+
Table, how many Tables it exposes, how many people are invited and how many
|
|
49
|
+
have actually signed in. The store filters the list on whether you may open
|
|
50
|
+
the client Table, so it never reveals a Table.
|
|
51
|
+
- `client.portalCard({ portal_id })` — one portal in full: each exposed Table
|
|
52
|
+
with the relation Field that says whose a record is and the fields a client
|
|
53
|
+
sees and may change, every person with `signed_in` and `is_active` kept
|
|
54
|
+
APART, and `external_lane_open`.
|
|
55
|
+
- `client.portalDeclare(...)` — create or RE-STATE one. Re-stating replaces
|
|
56
|
+
what the portal exposes and leaves the people alone.
|
|
57
|
+
- `client.portalInvite({ portal_id, client_record_id, email })` — and it takes
|
|
58
|
+
no `user_id` on purpose. From a screen that value is always null: an
|
|
59
|
+
invitation confers NOTHING until the person follows their own sign-in link,
|
|
60
|
+
which is what the door's own `say` sentence states. A client that passed an
|
|
61
|
+
id would be granting access on somebody else's behalf.
|
|
62
|
+
- `client.portalRevoke({ portal_id, principal_id })` — the answer's `say` names
|
|
63
|
+
the consequence in the past tense.
|
|
64
|
+
- `client.portalPreview({ portal_id, principal_id, table_id })` — "view as this
|
|
65
|
+
client". The door asks `custom.visible_set` for HER user id, the same call
|
|
66
|
+
`custom.read_records` makes when she opens the page, so it cannot disagree
|
|
67
|
+
with what she sees. It REFUSES (`02000`, mapped to `not_found`) when she has
|
|
68
|
+
not signed in, rather than answering an empty list.
|
|
69
|
+
|
|
70
|
+
New module `portal`, exported from the root: `PortalSummary`,
|
|
71
|
+
`PortalTableExposure`, `PortalPrincipal`, `PortalCard`, `PortalInvitation`,
|
|
72
|
+
`PortalRevocation`, `PortalPreviewRow`, and `portalPath(slug)` — the one place
|
|
73
|
+
`/portal/c/<slug>` is written down.
|
|
74
|
+
|
|
75
|
+
**Consumer action:** none required; every addition is new surface. A host that
|
|
76
|
+
already builds a portal address by hand should use `portalPath` so there is one
|
|
77
|
+
spelling of it.
|
|
78
|
+
|
|
79
|
+
## 0.13.0
|
|
80
|
+
|
|
81
|
+
**A choice value is the choice's own word, and this package says what that means.**
|
|
82
|
+
A list Field's cell used to hold the option RECORD'S ID, so every read, filter,
|
|
83
|
+
group-by, export and agent got back a uuid — the seventh independent pass failed
|
|
84
|
+
acceptance test T8 on exactly that. The store now holds the option's own stable
|
|
85
|
+
key, the read doors hand back the LABEL and name the key beside it in
|
|
86
|
+
`_choices`, and a caller may write the label, the key or (so nothing that worked
|
|
87
|
+
yesterday breaks) the option's id.
|
|
88
|
+
|
|
89
|
+
New module `choice`, exported from the root: `optionKey`, `optionLabel`,
|
|
90
|
+
`isTheChosen`, `choiceValuesOf`, `choicesOf`, `holdsARetiredChoice`,
|
|
91
|
+
`choiceSlug`, `looksLikeAnId`, and the `ChoiceOption` type. `isTheChosen` is the
|
|
92
|
+
one a control wants: it recognises a choice by its key, its label or its option
|
|
93
|
+
id, which is what lets one picker read a document from any of the three eras.
|
|
94
|
+
|
|
95
|
+
**Consumer action:** a control that compared a cell to `option.id` must use
|
|
96
|
+
`isTheChosen` and write `optionKey(option)` — comparing against the id alone now
|
|
97
|
+
shows nothing selected, because the read door hands back the label.
|
|
98
|
+
|
|
99
|
+
## 0.12.0
|
|
100
|
+
|
|
101
|
+
**A person can see what they are being told about, and switch one off.**
|
|
102
|
+
`custom.subscriptions` and `custom.subscription_mute` have been live on the
|
|
103
|
+
database since 20 September and no client could call them, so a form's "tell me
|
|
104
|
+
when somebody answers" could be turned ON by an agent and never turned off by
|
|
105
|
+
the person it was telling. `client.subscriptions({ table_id })` answers mine
|
|
106
|
+
plus anyone's over a Table I hold admin on — narrowed to Tables I can already
|
|
107
|
+
open, so the list never reveals one — and `client.subscriptionMute({ rule_id,
|
|
108
|
+
muted })` is the switch. `MySubscription` carries the two things a screen needs
|
|
109
|
+
and the notifier does not: `muted`, and `i_may_mute`.
|
|
110
|
+
|
|
111
|
+
`aggSubscriptions` is unchanged and is still the NOTIFIER's reader, which no
|
|
112
|
+
client can call. Muting is honoured inside that one reader, so a screen can
|
|
113
|
+
never say a subscription is off while it keeps firing.
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
## 0.11.0
|
|
117
|
+
|
|
118
|
+
**The publish gate stops red-lighting on other lanes' migrations.** `the
|
|
119
|
+
generated door catalogue is the store's` asserted `STORE_DOORS.length === live`,
|
|
120
|
+
so every publish failed in which anybody anywhere had shipped a new `custom`
|
|
121
|
+
routine — 337 mirrored against 342 live on 2026-09-20, and not one of the five
|
|
122
|
+
was this package's. A release that red-lights on somebody else's work teaches
|
|
123
|
+
everyone to ignore red.
|
|
124
|
+
|
|
125
|
+
What the package must be right about is asserted and still gates: **every door
|
|
126
|
+
this mirror names exists in the live store**. A name here the store does not
|
|
127
|
+
have is this package claiming a door it cannot open, which is the whole reason
|
|
128
|
+
`store.generated.ts` is generated rather than typed. Doors the store has and the
|
|
129
|
+
mirror has not seen are REPORTED by name, loudly, and gate nothing.
|
|
130
|
+
|
|
131
|
+
### Consumer action
|
|
132
|
+
|
|
133
|
+
None. No API changed.
|
|
134
|
+
|
|
135
|
+
## 0.10.0
|
|
136
|
+
|
|
137
|
+
**The work layer has client doors, and this package can reach them.** Until lane
|
|
138
|
+
WORK-DOORS (2026-09-20) all nineteen `custom.work_*` functions were SECURITY
|
|
139
|
+
INVOKER, held no EXECUTE for `authenticated` and carried zero rows in
|
|
140
|
+
`platform.client_callable_door`: REC-69 (assignment and action state), REC-70
|
|
141
|
+
(template instantiation) and REC-71 (the slot hold) were live in the store and
|
|
142
|
+
unreachable from a browser. Thirteen new client methods, all against doors that
|
|
143
|
+
ask the one ladder first:
|
|
144
|
+
|
|
145
|
+
* `workInbox` — **THE ONE QUEUE.** Assignments, approvals and the agent's
|
|
146
|
+
proposals in one ordered list with one row shape (PRODUCTS.md row 6).
|
|
147
|
+
* `workList` — "my work", "work I assigned", "waiting on somebody being chosen",
|
|
148
|
+
across every Table in the organization, every row decided by the one ladder.
|
|
149
|
+
* `workAssign` — the Assignee value AND editor access, in one transaction. An
|
|
150
|
+
assignment that did not give access put a row in somebody's inbox that they
|
|
151
|
+
were refused when they opened it.
|
|
152
|
+
* `workRecordStates` / `workSetState` — the moves the workflow model allows, with
|
|
153
|
+
the sentence for each one it does not, so a screen offers real moves.
|
|
154
|
+
* `workApprovalRequest` / `workApprovalMayDecide` / `workApprovalDecide` /
|
|
155
|
+
`workApprovalRead` / `workApprovalApprovers` — asking for a change instead of
|
|
156
|
+
making it, and a decision that **applies** the change in the same transaction.
|
|
157
|
+
* `workPerson`, `workTemplates`.
|
|
158
|
+
|
|
159
|
+
New types in `work.ts`: `WorkInboxItem`, `WorkListItem`, `WorkRecordState`,
|
|
160
|
+
`WorkApprover`, `WorkApprovalFiled`, `WorkApprovalDecision`, `WorkAssignment`,
|
|
161
|
+
`WorkChange`, `WorkInboxKind`, `WorkOrigin`, `WorkDueState`, `WorkListFlavour`.
|
|
162
|
+
|
|
163
|
+
**Consumer action:** none required — every addition is new surface. A host that
|
|
164
|
+
wants the inbox takes `@ai-matrx/records-ui` 0.15.0 with it.
|
|
165
|
+
|
|
3
166
|
## 0.7.2
|
|
4
167
|
|
|
5
168
|
**The door catalogue, regenerated while the store was still growing.** 0.7.1
|