@ai-matrx/records 0.87.32 → 0.92.1
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 +100 -0
- package/README.md +115 -0
- package/dist/{client-E0VQ0NPO.d.ts → client-Cn3odIIB.d.cts} +10 -5
- package/dist/{client-C3ZZNfGH.d.cts → client-Dzd8gtAo.d.ts} +10 -5
- package/dist/core/index.cjs +28 -10
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +23 -12
- package/dist/core/index.d.ts +23 -12
- package/dist/core/index.js +28 -10
- package/dist/core/index.js.map +1 -1
- package/dist/data/index.cjs +22 -10
- package/dist/data/index.cjs.map +1 -1
- package/dist/data/index.d.cts +12 -142
- package/dist/data/index.d.ts +12 -142
- package/dist/data/index.js +22 -10
- package/dist/data/index.js.map +1 -1
- package/dist/{declareTable-BK3zufr7.d.cts → declareTable-CrL6AZKB.d.cts} +4 -4
- package/dist/{declareTable-B12XybRp.d.ts → declareTable-ZRW5EsTQ.d.ts} +4 -4
- package/dist/entity/index.cjs +984 -0
- package/dist/entity/index.cjs.map +1 -0
- package/dist/entity/index.d.cts +36 -0
- package/dist/entity/index.d.ts +36 -0
- package/dist/entity/index.js +964 -0
- package/dist/entity/index.js.map +1 -0
- package/dist/entity/react.cjs +1024 -0
- package/dist/entity/react.cjs.map +1 -0
- package/dist/entity/react.d.cts +511 -0
- package/dist/entity/react.d.ts +511 -0
- package/dist/entity/react.js +1015 -0
- package/dist/entity/react.js.map +1 -0
- package/dist/{field-BanTVGK2.d.cts → field-CCY1rG9l.d.cts} +1 -1
- package/dist/{field-BPABOJ2Y.d.ts → field-enufS5ry.d.ts} +1 -1
- package/dist/forms/index.cjs +984 -0
- package/dist/forms/index.cjs.map +1 -0
- package/dist/forms/index.d.cts +333 -0
- package/dist/forms/index.d.ts +333 -0
- package/dist/forms/index.js +961 -0
- package/dist/forms/index.js.map +1 -0
- package/dist/index.cjs +10 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +11 -8
- package/dist/index.d.ts +11 -8
- package/dist/index.js +10 -1
- package/dist/index.js.map +1 -1
- package/dist/memory/index.d.cts +7 -6
- package/dist/memory/index.d.ts +7 -6
- package/dist/port-C54ykAOv.d.ts +301 -0
- package/dist/port-Drioh9al.d.cts +301 -0
- package/dist/portal-DRdmZ-xv.d.cts +331 -0
- package/dist/portal-or_f7BkT.d.ts +331 -0
- package/dist/{ports-TMWX-t9l.d.ts → ports-BeOgjwYl.d.ts} +2 -2
- package/dist/{ports-D8-iuY1P.d.cts → ports-s0D2jvqn.d.cts} +2 -2
- package/dist/react/index.cjs +58 -526
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +16 -1
- package/dist/react/index.d.ts +16 -1
- package/dist/react/index.js +55 -530
- package/dist/react/index.js.map +1 -1
- package/dist/realtime/index.d.cts +2 -2
- package/dist/realtime/index.d.ts +2 -2
- package/dist/{record-DpB2QgAZ.d.cts → record-BwCf9wKW.d.cts} +7 -1
- package/dist/{record-DpB2QgAZ.d.ts → record-BwCf9wKW.d.ts} +7 -1
- package/dist/relation-8vAWCa67.d.cts +230 -0
- package/dist/relation-eLMgv_dV.d.ts +230 -0
- package/dist/rule-D9yNiorf.d.ts +250 -0
- package/dist/rule-wHI5B0Ka.d.cts +250 -0
- package/dist/search/index.cjs +283 -0
- package/dist/search/index.cjs.map +1 -0
- package/dist/search/index.d.cts +44 -0
- package/dist/search/index.d.ts +44 -0
- package/dist/search/index.js +260 -0
- package/dist/search/index.js.map +1 -0
- package/dist/setup/index.cjs +6854 -0
- package/dist/setup/index.cjs.map +1 -0
- package/dist/setup/index.d.cts +87 -0
- package/dist/setup/index.d.ts +87 -0
- package/dist/setup/index.js +6829 -0
- package/dist/setup/index.js.map +1 -0
- package/dist/{subscription-D7KQBHXN.d.ts → subscription-BynsG1K6.d.ts} +3 -249
- package/dist/{subscription-BD9DnJxX.d.cts → subscription-CdoI-UaB.d.cts} +3 -249
- package/dist/{table-kind-BZu8mtND.d.cts → table-kind-DzctQ7dO.d.cts} +3 -558
- package/dist/{table-kind-xKxTHtrV.d.ts → table-kind-i3lZJa3f.d.ts} +3 -558
- package/dist/templates/index.d.cts +10 -9
- package/dist/templates/index.d.ts +10 -9
- package/dist/typed-table/index.cjs +22 -10
- package/dist/typed-table/index.cjs.map +1 -1
- package/dist/typed-table/index.d.cts +10 -7
- package/dist/typed-table/index.d.ts +10 -7
- package/dist/typed-table/index.js +22 -10
- package/dist/typed-table/index.js.map +1 -1
- package/dist/types-BKYEeFt4.d.cts +139 -0
- package/dist/{types-Dv61jStB.d.ts → types-BvL_oKFl.d.ts} +2 -2
- package/dist/{types-CLP5H4Wk.d.cts → types-D8qdG3Lg.d.cts} +2 -2
- package/dist/{types-C2uspRtf.d.cts → types-DAFP6XFe.d.cts} +2 -2
- package/dist/{types-DmPkWQic.d.ts → types-DYzXhD7j.d.ts} +2 -2
- package/dist/types-cpKY7Pjb.d.ts +139 -0
- package/dist/use-cases/index.d.cts +5 -5
- package/dist/use-cases/index.d.ts +5 -5
- package/dist/{validate-CWVToe1T.d.ts → validate-DbvAParj.d.ts} +1 -1
- package/dist/{validate-DEB_mn4Y.d.cts → validate-DfNMxjmU.d.cts} +1 -1
- package/dist/versions/index.cjs +375 -0
- package/dist/versions/index.cjs.map +1 -0
- package/dist/versions/index.d.cts +160 -0
- package/dist/versions/index.d.ts +160 -0
- package/dist/versions/index.js +353 -0
- package/dist/versions/index.js.map +1 -0
- package/package.json +62 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,105 @@
|
|
|
1
1
|
# Changelog — @ai-matrx/records
|
|
2
2
|
|
|
3
|
+
## 0.92.1
|
|
4
|
+
|
|
5
|
+
**`recordRead`'s version is opt-in: `recordRead({ record_id, withVersion: true })`.** 0.92.0 read the header on
|
|
6
|
+
every call, so a screen that draws first and versions later (the record form) waited for the slower of the two.
|
|
7
|
+
|
|
8
|
+
**Consumer action:** none for screens; a host that wants the version with the read passes `withVersion: true`.
|
|
9
|
+
|
|
10
|
+
## 0.92.0
|
|
11
|
+
|
|
12
|
+
**A member of an archived organization is told so.** Every store door used to refuse an archived organization with
|
|
13
|
+
"You are not a member of that organization", even to its members. The store now says "This organization is archived"
|
|
14
|
+
(same refusal code `door`, the store's sentence and restore hint carried verbatim) with DETAIL
|
|
15
|
+
`organization_archived:<organization id>`. New `archivedOrganizationId(error)` (from `@ai-matrx/records` and
|
|
16
|
+
`@ai-matrx/records/core`) reads that organization out so a screen can offer "Restore" (the owner's
|
|
17
|
+
`iam.organization_restore` door). A non-member still gets the old sentence and `null` from it.
|
|
18
|
+
|
|
19
|
+
**The withheld note is said once.** For a reader who may not see a confidential measure, `custom.record_aggregate`
|
|
20
|
+
used to repeat the same `_withheld` explanation on every group row; the store now says it once (first row) and
|
|
21
|
+
`liftWithheld` puts it on every row's `row.withheld`, so totals and charts read exactly what they read before.
|
|
22
|
+
|
|
23
|
+
**Consumer action:** none. Hosts that read `measures._withheld` off the raw door (not through the client) must read it
|
|
24
|
+
from the first row.
|
|
25
|
+
|
|
26
|
+
## 0.92.0
|
|
27
|
+
|
|
28
|
+
**New section `@ai-matrx/records/versions`** — the version rule for any screen a company builds, moved whole
|
|
29
|
+
from `@ai-matrx/records-ui`: `useRecordVersions` / `useTableVersion`, the write doors that carry the version
|
|
30
|
+
the person saw (`updateRecordAt`, `changeRecordsAt`, `movePipelineCardAt(s)`, `restoreAt`,
|
|
31
|
+
`updateOnTheWinningVersion`), `askOnce` (one question in flight per client) and `refusal` (a refusal shaped
|
|
32
|
+
like the store's own). React is the only peer it needs.
|
|
33
|
+
|
|
34
|
+
**`recordRead({ record_id, withVersion: true })` answers `version`.** The read asks the record's header in the
|
|
35
|
+
same round of requests, so a safe edit (`recordUpdate` with `expected_version`) needs no second call. `null`
|
|
36
|
+
when the version could not be read (the record still comes back). Off by default, so a screen that draws
|
|
37
|
+
before its version lands is never held back.
|
|
38
|
+
|
|
39
|
+
**Consumer action:** none. Hosts that read a record and then asked `recordHeaders` for its version can use
|
|
40
|
+
`read.data.version` instead.
|
|
41
|
+
|
|
42
|
+
## 0.91.0
|
|
43
|
+
|
|
44
|
+
**`typedAnswersFor(fields, values)` in `@ai-matrx/records/forms`** — what a stranger typed on a public form or
|
|
45
|
+
booking page, turned into values against the Fields that page published, with one refusal sentence in question
|
|
46
|
+
order (moved whole from the website's `features/unified-data/typedAnswers.ts`). Every public door a company builds
|
|
47
|
+
coerces the same way the grid, the import and our own pages do.
|
|
48
|
+
|
|
49
|
+
**Consumer action:** hosts with their own copy (the website's `typedAnswers.ts`) import
|
|
50
|
+
`typedAnswersFor` from `@ai-matrx/records/forms` and delete the copy.
|
|
51
|
+
|
|
52
|
+
## 0.90.0
|
|
53
|
+
|
|
54
|
+
**New section `@ai-matrx/records/setup`** — `createRecords({ auth: sessionAuth(supabase), organizationId })`:
|
|
55
|
+
one call that composes the typed client, live changes (one realtime manager over the session), search
|
|
56
|
+
across tables, platform records and a slot for the host's associations store. Signing in is a port
|
|
57
|
+
(`RecordsAuthPort`); an organization API key will plug in as a second mode without changing anything else.
|
|
58
|
+
The README opens with a quick start a company follows to list, create, edit, archive and watch records.
|
|
59
|
+
|
|
60
|
+
**Consumer action:** none.
|
|
61
|
+
|
|
62
|
+
## 0.89.0
|
|
63
|
+
|
|
64
|
+
**New section `@ai-matrx/records/forms`** — the form document (flows, looks, endings, jumps, embeds,
|
|
65
|
+
the form doors' arguments) and which read a public address does, moved whole from `@ai-matrx/records-ui`
|
|
66
|
+
(`forms.ts`, `publicBinding.ts`), so a company's own screens can build and run forms without ours.
|
|
67
|
+
|
|
68
|
+
**New section `@ai-matrx/records/search`** — `searchRecords(dataSource, { search, tableIds?, organizationIds? })`
|
|
69
|
+
and `listStoreRecordCandidates(dataSource, { search })`: search across every table the person can see
|
|
70
|
+
through `custom.records_search` (never narrowed by the active organization), moved from the website.
|
|
71
|
+
|
|
72
|
+
**Consumer action:** `@ai-matrx/records-ui` users need none. Hosts with their own copy of record search
|
|
73
|
+
(the website's `storeRecordCandidates.ts`) call `listStoreRecordCandidates(supabase, args)` instead.
|
|
74
|
+
|
|
75
|
+
## 0.88.1
|
|
76
|
+
|
|
77
|
+
**One data engine instance across sections.** `records/react` carried its own private copy of
|
|
78
|
+
`records/data/react` (its `DataPortContext` and host-event bus) because the build copies every module
|
|
79
|
+
into each entry that reaches it. It now imports the published `records/data/react`, as `records/entity/react`
|
|
80
|
+
does, so a `DataPortProvider` mounted from either section is the one every hook reads. The shared-state
|
|
81
|
+
gate gained a census: each module that holds React context or page-local state (data-engine provider,
|
|
82
|
+
seed provider, shape revisions) must live in exactly one section's dist files — proven red on a planted copy.
|
|
83
|
+
|
|
84
|
+
**Consumer action:** none.
|
|
85
|
+
|
|
86
|
+
## 0.88.0
|
|
87
|
+
|
|
88
|
+
**New sections `@ai-matrx/records/entity` and `@ai-matrx/records/entity/react`** — the former
|
|
89
|
+
`@ai-matrx/entity-data` package, moved in whole (same API, same behaviour): platform records (contacts,
|
|
90
|
+
projects, tasks) through the entity doors, the entity `DataPort`, entity live notices, and the
|
|
91
|
+
token-first hooks (`EntityDataProvider`, `useEntityList`, `useEntityWrite`, …). `records/entity/react`
|
|
92
|
+
imports the published `records/react` and `records/data/react` instead of carrying a private copy, so
|
|
93
|
+
the providers a host mounted are the ones it reads.
|
|
94
|
+
|
|
95
|
+
The shared-state gate (`scripts/check-shared-state.mjs`, run on the packed tarball) now also proves an
|
|
96
|
+
entity write's op id lands in the one op ledger (ESM and CJS) and that `entity/react` holds no private
|
|
97
|
+
copy of the data-engine or seed providers.
|
|
98
|
+
|
|
99
|
+
**Consumer action:** replace `@ai-matrx/entity-data`, `@ai-matrx/entity-data/core` and
|
|
100
|
+
`@ai-matrx/entity-data/port` with `@ai-matrx/records/entity`, and `@ai-matrx/entity-data/react` with
|
|
101
|
+
`@ai-matrx/records/entity/react`; then drop the `@ai-matrx/entity-data` dependency.
|
|
102
|
+
|
|
3
103
|
## 0.87.32
|
|
4
104
|
|
|
5
105
|
Automatic changed-only republish (docs/metadata drift since the last tag — see
|
package/README.md
CHANGED
|
@@ -24,6 +24,69 @@ import {
|
|
|
24
24
|
} from "@ai-matrx/records";
|
|
25
25
|
```
|
|
26
26
|
|
|
27
|
+
## Quick start — our record store inside your own system
|
|
28
|
+
|
|
29
|
+
Everything a company needs to list, create, edit, archive and watch records from its own screens or
|
|
30
|
+
scripts, with none of ours. One package; each section loads only when imported.
|
|
31
|
+
|
|
32
|
+
```sh
|
|
33
|
+
npm install @ai-matrx/records @supabase/supabase-js
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
```ts
|
|
37
|
+
import { createClient } from "@supabase/supabase-js";
|
|
38
|
+
import { createRecords, sessionAuth } from "@ai-matrx/records/setup";
|
|
39
|
+
import { ensureTable } from "@ai-matrx/records/core";
|
|
40
|
+
|
|
41
|
+
// 1. Sign in. The database address is https://db.matrxserver.com; the publishable key is on your
|
|
42
|
+
// AI Matrx account page. Any supabase-js sign-in works (password, magic link, SSO, server cookies).
|
|
43
|
+
const supabase = createClient("https://db.matrxserver.com", PUBLISHABLE_KEY);
|
|
44
|
+
await supabase.auth.signInWithPassword({ email, password });
|
|
45
|
+
|
|
46
|
+
// 2. One call. You choose the organization new records are saved in; reads span all of yours.
|
|
47
|
+
const matrx = await createRecords({ auth: sessionAuth(supabase), organizationId: (orgs) => orgs[0] ?? null });
|
|
48
|
+
|
|
49
|
+
// 3. A table (found by its slug, or made the first time), then records.
|
|
50
|
+
const table = await ensureTable(matrx.records, { name: "Service callbacks", slug: "service_callbacks",
|
|
51
|
+
fields: [{ key: "caller", label: "Caller", type: "text" }, { key: "phone", label: "Phone", type: "phone" }] });
|
|
52
|
+
if (!table.ok) throw new Error(table.error.message);
|
|
53
|
+
const tableId = table.data; // the table id
|
|
54
|
+
|
|
55
|
+
const created = await matrx.records.recordWrite({ table_id: tableId, data: { caller: "Marcus Delgado", phone: "+14155550178" } });
|
|
56
|
+
const page = await matrx.records.list({ table_id: tableId, limit: 50 }); // { rows, total }
|
|
57
|
+
const record_id = created.ok ? created.data : "";
|
|
58
|
+
const read = await matrx.records.recordRead({ record_id }); // .data.document
|
|
59
|
+
const heads = await matrx.records.recordHeaders({ ids: [record_id] }); // .data[0].version
|
|
60
|
+
const expectedVersion = heads.ok ? heads.data[0]?.version : undefined;
|
|
61
|
+
const edited = await matrx.records.recordUpdate({ record_id, patch: { phone: "+14155550199" }, expectedVersion }); // answers the new version
|
|
62
|
+
// Always send expectedVersion: a colleague's newer edit is then refused (`stale_write`, field by field), never overwritten.
|
|
63
|
+
const archived = await matrx.records.recordDelete({ record_id }); // soft: recordRestore brings it back
|
|
64
|
+
|
|
65
|
+
// 4. Live: other people's changes to this table (this setup's own writes are not echoed back).
|
|
66
|
+
const stop = matrx.watch(tableId, { records: (ids) => console.log("changed", ids) });
|
|
67
|
+
|
|
68
|
+
// 5. Search across every table you can see; platform records (contacts…) through matrx.entities.
|
|
69
|
+
const hits = await matrx.search({ search: "Delgado" });
|
|
70
|
+
|
|
71
|
+
stop(); matrx.close(); // a script closes the live socket before it exits
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Every call answers `{ ok: true, data } | { ok: false, error }` — the store's own sentence, never a
|
|
75
|
+
throw. React hosts add `@ai-matrx/records/react` or `@ai-matrx/records/data/react` hooks on the same
|
|
76
|
+
client; `@ai-matrx/records-ui` is our optional set of screens. Organization API keys plug into `auth`
|
|
77
|
+
as a second mode (planned); today `auth` is a signed-in session.
|
|
78
|
+
|
|
79
|
+
| Section | What |
|
|
80
|
+
|---|---|
|
|
81
|
+
| `records/setup` | `createRecords`, `sessionAuth` — the one call above |
|
|
82
|
+
| `records/core` | the typed client over every door (tables, records, versions, views, forms, totals) |
|
|
83
|
+
| `records/realtime` | the live-changes port setup uses |
|
|
84
|
+
| `records/search` | `searchRecords`, `listStoreRecordCandidates` |
|
|
85
|
+
| `records/forms` | the form document, embeds and which read a public address does |
|
|
86
|
+
| `records/entity`, `records/entity/react` | platform records (contacts, projects, tasks) |
|
|
87
|
+
| `records/data`, `records/data/react` | one data port and TanStack hooks over custom tables and entities |
|
|
88
|
+
| `records/react` | provider + hooks over the client |
|
|
89
|
+
|
|
27
90
|
## /core — the typed client over the doors
|
|
28
91
|
|
|
29
92
|
```ts
|
|
@@ -278,6 +341,58 @@ const { write, update, remove, conflict } = useRecordMutation();
|
|
|
278
341
|
`live` is never quietly false: when realtime is not bound, `liveOffReason` says
|
|
279
342
|
why in a sentence a screen can show.
|
|
280
343
|
|
|
344
|
+
## /entity — platform records (contacts, projects, tasks) through the same port
|
|
345
|
+
Platform records (contacts, projects, tasks…) through the same `DataPort` an Applet reads a custom
|
|
346
|
+
table with. A thin typed client over the store's entity doors, and a host `DataPort` for entity
|
|
347
|
+
aliases, and token-first React hooks over records' one data engine (`@ai-matrx/records/data/react`).
|
|
348
|
+
|
|
349
|
+
**Reads and writes.** `create` saves into the active organization the host names (none → refused
|
|
350
|
+
`organization_required`), `update` sends the version the person saw (a stale one is refused with the
|
|
351
|
+
store's sentence), `archive` / `restore` move a row to the trash and back. **Lists are live** when the host passes `realtime: createEntityRealtime({ manager })`
|
|
352
|
+
(and `organization`, the active one): other people's changes arrive as `rows:<alias>` events naming the ids.
|
|
353
|
+
|
|
354
|
+
```ts
|
|
355
|
+
import { createEntityDataPort } from "@ai-matrx/records/entity";
|
|
356
|
+
import { DataPortProvider, hostEvents, useDataRows } from "@ai-matrx/records/data/react";
|
|
357
|
+
|
|
358
|
+
const port = createEntityDataPort({
|
|
359
|
+
dataSource: supabase, // the signed-in person's supabase-js client
|
|
360
|
+
aliases: { contacts: { kind: "entity", token: "party", organizationId } },
|
|
361
|
+
});
|
|
362
|
+
|
|
363
|
+
// in React:
|
|
364
|
+
// <DataPortProvider port={port} events={hostEvents(port)} portKey="applet-1" queryClient={qc}>
|
|
365
|
+
// const { rows, hasMore, loadMore, error } = useDataRows("contacts", { org: organizationId, sort: [{ column: "display_name" }] });
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
In a React app, name the type and let the engine do the rest:
|
|
369
|
+
|
|
370
|
+
```tsx
|
|
371
|
+
import { EntityDataProvider, useEntityList, useEntityWrite } from "@ai-matrx/records/entity/react";
|
|
372
|
+
|
|
373
|
+
// once, high: <EntityDataProvider dataSource={supabase} activeOrganizationId={activeOrg}>…
|
|
374
|
+
const contacts = useEntityList("party", { where: [{ column: "last_name", op: "eq", value: "Ellis" }] });
|
|
375
|
+
const write = useEntityWrite("party");
|
|
376
|
+
await write.update(contacts.rows[0]._id, { first_name: "Ada" }); // drawn at once, rolled back on refusal
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
### Entries
|
|
380
|
+
|
|
381
|
+
| Entry | What |
|
|
382
|
+
|---|---|
|
|
383
|
+
| `@ai-matrx/records/entity` | `createEntityClient({ dataSource })` → `list`, `get`, `columns`, `insert`, `update`, `archive`, `unarchive`; `toWire`; `mapEntityError`; `createEntityDataPort({ client \| dataSource, aliases, activeOrganizationId })` → `HostDataPort` + `describe`; `createEntityRealtime` |
|
|
384
|
+
| `@ai-matrx/records/entity/react` | `EntityDataProvider`, `useEntityList`, `useEntityColumns`, `useEntityType`, `useEntityRow`, `useEntityWrite` |
|
|
385
|
+
|
|
386
|
+
### Behaviour worth knowing
|
|
387
|
+
|
|
388
|
+
- The lane defaults to the type's own landing lane, decided by the store; `org` is a filter and never a lock.
|
|
389
|
+
- Paging is keyset: the cursor is the store's `next_after`.
|
|
390
|
+
- A filter or sort the store does not offer yet is refused by name with the store's sentence, never emulated in the browser.
|
|
391
|
+
- Custom fields read from `row._custom` and filter as `_custom.<key>`; a field the person may not read arrives `null`.
|
|
392
|
+
- A total that stopped at the store's count cap is reported as `null` (unknown), never as a wrong number.
|
|
393
|
+
|
|
394
|
+
Local mechanics: `src/entity/FEATURE.md`. Formerly the package `@ai-matrx/entity-data` (deprecated; same API, renamed imports: `/core` and `/port` → `records/entity`, `/react` → `records/entity/react`).
|
|
395
|
+
|
|
281
396
|
## Drill-down — declared definitions
|
|
282
397
|
|
|
283
398
|
A server drill (`platform.drill_describe` / `platform.drill_ask`) answers a standard table from
|
|
@@ -1,8 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { d as StoreFilter,
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { a as
|
|
1
|
+
import { C as ChoiceNudge, T as TableArchiveProgress, a as TableRestoreProgress, b as TableDuplicateProgress, c as TableDuplicated, d as TableCopyInProgress, A as ArchiveLane, e as ArchivedRow, f as Table, g as TableHome, h as TableMoved, i as ChoiceUsage, j as ChoiceRehome, k as ChoiceCellBack, l as ChoicesRehomed, m as TableCapacity, F as FieldDrift, n as FieldRetyped, R as RecordsMerged, M as MigrationUndone, o as TableKindFacts, p as TableLevelFacts, q as TableReaderRule, r as TableLevelSet, E as EntityTableFacts, s as EntityFieldsAcross, N as NewEntityFieldDeclaration, t as EntityFieldRights, u as EntityRecordRead, v as EntityBackLinks, w as EntityRowWritten, x as EntityRecordsFound, P as Pipeline, y as PipelineColumn, z as PipelineVerdict, B as PipelineMoveResult, D as PipelineMoveManyItem, G as PipelineMoveMany, H as PipelineSpec, I as PipelineDeclared, S as StageRuleOnFail, J as StageRuleEnforcement, K as StagePending, L as StagePendingOnBoard, O as PipelineGate, Q as PipelineGatePreview, U as ImportPlan, V as ImportPolicy, W as ImportOpened, X as ImportColumnsDeclared, Y as ImportBatchResult, Z as ImportFinished, _ as ImportReport, $ as ImportRun, a0 as InboundDeclared, a1 as InboundAddress, a2 as FormArchiveAnswer, a3 as ArchivedForm, a4 as ArchivedChecklistTemplate, a5 as TableRowDefaults, a6 as TableRowDefaultsPatch, a7 as RowDefaultsApplied, a8 as RecordRowControls, a9 as CaptureSheetSummary, aa as CaptureSheetFace, ab as CaptureFileRef, ac as CaptureOutcome, ad as EnrichmentSummary, ae as EnrichDeclared, af as EnrichDueRow, ag as EnrichCell, ah as EnrichRun, ai as DrillSource, aj as DrillDefinition, ak as DrillQuestion, al as DrillAnswer, am as DrillRowsPage, an as DocToken, ao as DocUnresolvedToken, ap as DocTemplateRow, aq as DocRenderRow, ar as DocSignatureRow, as as RecordHistoryEntry, at as RecordScopeContext, au as ConversationScope, av as ConversationScopeContext, aw as FieldHistoryEntry, ax as RestorePreview, ay as RestoreResult, az as CommentThreadRead, aA as CommentWritten, aB as AnonTokenBinding, aC as ChecklistSpec, aD as ChecklistDeclared, aE as ChecklistTemplateSummary, aF as ChecklistTemplateShape, aG as ChecklistRunStarted, aH as ChecklistRunStep, aI as ChecklistRunSummary, aJ as ChecklistStepCompleted, aK as WorkState, aL as WorkGraph, aM as WorkInstantiation, aN as WorkTurn, aO as WorkAssignmentField, aP as WorkSlotHold, aQ as WorkInboxView, aR as WorkInboxItem, aS as InboxStateChange, aT as InboxCounts, aU as WorkListFlavour, aV as WorkListItem, aW as WorkAssignment, aX as WorkRecordState, aY as WorkApprover, aZ as WorkChange, a_ as WorkApprovalFiled, a$ as WorkApprovalDecision, b0 as WorkDecideManyItem, b1 as WorkDecideMany, b2 as ExternalPrincipalCard, b3 as PublishBinding, b4 as ResolvedPublishBinding, b5 as ResolvedPublishBindingKind, b6 as MyLevel, b7 as DecorationPath, b8 as TableDecorations, b9 as GridLayout, ba as FormulaParse, bb as FormulaPreview, bc as RowAction, bd as ActionRunResult, be as AutomationSpec, bf as AutomationDeclared, bg as AutomationList, bh as AutomationFlipped, bi as AutomationRuns, bj as RecordEvent, bk as TableWebhookDeclared, bl as TableWebhook, bm as IoExportPage, bn as TableListEntry, bo as DataHomeTable, bp as TableSyncSpec, bq as TableSyncResult, br as TableRowCount, bs as RecordHeader, bt as OutsideShareAnswer, bu as ViewOrderSet } from './table-kind-DzctQ7dO.cjs';
|
|
2
|
+
import { d as StoreFilter, e as DashboardSummary, f as DashboardBlock, R as RecordFilter, g as AggregateCompare, c as AggregateBucket, h as DashboardRunResult, i as StuckRow, b as AggregateMeasure, j as AggregateRow, k as Subscription, M as MySubscription, l as SubscriptionSpec, m as DigestPreview, n as SavedViewRow, o as SavedViewSpecIn, p as RowTemplateRow } from './subscription-CdoI-UaB.cjs';
|
|
3
|
+
import { R as RelationCoordinate, a as RelationWordsManyArgs, b as RelationIcons, c as ReverseColumn, d as ReverseLinksManyArgs, e as ReverseLinks, f as ReverseLinksFieldsArgs, S as SourceArchived } from './relation-8vAWCa67.cjs';
|
|
4
|
+
import { b as Field, c as FieldPatch, N as NewFieldDeclaration, R as RelationNamesAnswer, d as FieldDuplicated, e as FieldProposal, T as TableProposal, B as ButtonPressed } from './field-CCY1rG9l.cjs';
|
|
5
|
+
import { F as FormSummary, B as BookingSummary, a as BookingAvailability, b as BookingDeclared, c as FormRoute, d as FormResults } from './rule-wHI5B0Ka.cjs';
|
|
6
|
+
import { F as FormLookOptions, P as PortalSummary, a as PortalArchiveFilter, b as PortalArchiveAnswer, c as PortalTableRef, d as PortalCard, e as PortalConfigInput, f as PortalFormSpec, g as PortalFormAnswer, h as PortalInvitation, i as PortalRevocation, j as PortalPreviewRow } from './portal-DRdmZ-xv.cjs';
|
|
7
|
+
import { T as Timestamp, U as Uuid, k as RecordsErrorCode, l as RecordDocument, R as RecordsResult, m as RecordChange, n as RecordChangeResult, o as RecordGraphWritten, p as RecordRead, q as ReadRow, r as RecordPageSort, s as RecordPage, t as RecordKeysetPage, u as StoredRecord, v as RecordRevision, w as ReadValue, a as RecordsError, W as WriteConflict } from './record-BwCf9wKW.cjs';
|
|
8
|
+
import { a as RecordsConfig } from './ports-s0D2jvqn.cjs';
|
|
6
9
|
|
|
7
10
|
/**
|
|
8
11
|
* DOOR-8. As-of on EITHER clock, and they are different questions:
|
|
@@ -372,6 +375,8 @@ interface RecordsClient {
|
|
|
372
375
|
recordRead(args: {
|
|
373
376
|
record_id: Uuid;
|
|
374
377
|
withComputed?: boolean;
|
|
378
|
+
/** Also answer `version` (read in the same round, so the read takes as long as the slower of the two). */
|
|
379
|
+
withVersion?: boolean;
|
|
375
380
|
organization_id?: Uuid | null;
|
|
376
381
|
}): Promise<RecordsResult<RecordRead>>;
|
|
377
382
|
/**
|
|
@@ -1,8 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { d as StoreFilter,
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { a as
|
|
1
|
+
import { C as ChoiceNudge, T as TableArchiveProgress, a as TableRestoreProgress, b as TableDuplicateProgress, c as TableDuplicated, d as TableCopyInProgress, A as ArchiveLane, e as ArchivedRow, f as Table, g as TableHome, h as TableMoved, i as ChoiceUsage, j as ChoiceRehome, k as ChoiceCellBack, l as ChoicesRehomed, m as TableCapacity, F as FieldDrift, n as FieldRetyped, R as RecordsMerged, M as MigrationUndone, o as TableKindFacts, p as TableLevelFacts, q as TableReaderRule, r as TableLevelSet, E as EntityTableFacts, s as EntityFieldsAcross, N as NewEntityFieldDeclaration, t as EntityFieldRights, u as EntityRecordRead, v as EntityBackLinks, w as EntityRowWritten, x as EntityRecordsFound, P as Pipeline, y as PipelineColumn, z as PipelineVerdict, B as PipelineMoveResult, D as PipelineMoveManyItem, G as PipelineMoveMany, H as PipelineSpec, I as PipelineDeclared, S as StageRuleOnFail, J as StageRuleEnforcement, K as StagePending, L as StagePendingOnBoard, O as PipelineGate, Q as PipelineGatePreview, U as ImportPlan, V as ImportPolicy, W as ImportOpened, X as ImportColumnsDeclared, Y as ImportBatchResult, Z as ImportFinished, _ as ImportReport, $ as ImportRun, a0 as InboundDeclared, a1 as InboundAddress, a2 as FormArchiveAnswer, a3 as ArchivedForm, a4 as ArchivedChecklistTemplate, a5 as TableRowDefaults, a6 as TableRowDefaultsPatch, a7 as RowDefaultsApplied, a8 as RecordRowControls, a9 as CaptureSheetSummary, aa as CaptureSheetFace, ab as CaptureFileRef, ac as CaptureOutcome, ad as EnrichmentSummary, ae as EnrichDeclared, af as EnrichDueRow, ag as EnrichCell, ah as EnrichRun, ai as DrillSource, aj as DrillDefinition, ak as DrillQuestion, al as DrillAnswer, am as DrillRowsPage, an as DocToken, ao as DocUnresolvedToken, ap as DocTemplateRow, aq as DocRenderRow, ar as DocSignatureRow, as as RecordHistoryEntry, at as RecordScopeContext, au as ConversationScope, av as ConversationScopeContext, aw as FieldHistoryEntry, ax as RestorePreview, ay as RestoreResult, az as CommentThreadRead, aA as CommentWritten, aB as AnonTokenBinding, aC as ChecklistSpec, aD as ChecklistDeclared, aE as ChecklistTemplateSummary, aF as ChecklistTemplateShape, aG as ChecklistRunStarted, aH as ChecklistRunStep, aI as ChecklistRunSummary, aJ as ChecklistStepCompleted, aK as WorkState, aL as WorkGraph, aM as WorkInstantiation, aN as WorkTurn, aO as WorkAssignmentField, aP as WorkSlotHold, aQ as WorkInboxView, aR as WorkInboxItem, aS as InboxStateChange, aT as InboxCounts, aU as WorkListFlavour, aV as WorkListItem, aW as WorkAssignment, aX as WorkRecordState, aY as WorkApprover, aZ as WorkChange, a_ as WorkApprovalFiled, a$ as WorkApprovalDecision, b0 as WorkDecideManyItem, b1 as WorkDecideMany, b2 as ExternalPrincipalCard, b3 as PublishBinding, b4 as ResolvedPublishBinding, b5 as ResolvedPublishBindingKind, b6 as MyLevel, b7 as DecorationPath, b8 as TableDecorations, b9 as GridLayout, ba as FormulaParse, bb as FormulaPreview, bc as RowAction, bd as ActionRunResult, be as AutomationSpec, bf as AutomationDeclared, bg as AutomationList, bh as AutomationFlipped, bi as AutomationRuns, bj as RecordEvent, bk as TableWebhookDeclared, bl as TableWebhook, bm as IoExportPage, bn as TableListEntry, bo as DataHomeTable, bp as TableSyncSpec, bq as TableSyncResult, br as TableRowCount, bs as RecordHeader, bt as OutsideShareAnswer, bu as ViewOrderSet } from './table-kind-i3lZJa3f.js';
|
|
2
|
+
import { d as StoreFilter, e as DashboardSummary, f as DashboardBlock, R as RecordFilter, g as AggregateCompare, c as AggregateBucket, h as DashboardRunResult, i as StuckRow, b as AggregateMeasure, j as AggregateRow, k as Subscription, M as MySubscription, l as SubscriptionSpec, m as DigestPreview, n as SavedViewRow, o as SavedViewSpecIn, p as RowTemplateRow } from './subscription-BynsG1K6.js';
|
|
3
|
+
import { R as RelationCoordinate, a as RelationWordsManyArgs, b as RelationIcons, c as ReverseColumn, d as ReverseLinksManyArgs, e as ReverseLinks, f as ReverseLinksFieldsArgs, S as SourceArchived } from './relation-eLMgv_dV.js';
|
|
4
|
+
import { b as Field, c as FieldPatch, N as NewFieldDeclaration, R as RelationNamesAnswer, d as FieldDuplicated, e as FieldProposal, T as TableProposal, B as ButtonPressed } from './field-enufS5ry.js';
|
|
5
|
+
import { F as FormSummary, B as BookingSummary, a as BookingAvailability, b as BookingDeclared, c as FormRoute, d as FormResults } from './rule-D9yNiorf.js';
|
|
6
|
+
import { F as FormLookOptions, P as PortalSummary, a as PortalArchiveFilter, b as PortalArchiveAnswer, c as PortalTableRef, d as PortalCard, e as PortalConfigInput, f as PortalFormSpec, g as PortalFormAnswer, h as PortalInvitation, i as PortalRevocation, j as PortalPreviewRow } from './portal-or_f7BkT.js';
|
|
7
|
+
import { T as Timestamp, U as Uuid, k as RecordsErrorCode, l as RecordDocument, R as RecordsResult, m as RecordChange, n as RecordChangeResult, o as RecordGraphWritten, p as RecordRead, q as ReadRow, r as RecordPageSort, s as RecordPage, t as RecordKeysetPage, u as StoredRecord, v as RecordRevision, w as ReadValue, a as RecordsError, W as WriteConflict } from './record-BwCf9wKW.js';
|
|
8
|
+
import { a as RecordsConfig } from './ports-BeOgjwYl.js';
|
|
6
9
|
|
|
7
10
|
/**
|
|
8
11
|
* DOOR-8. As-of on EITHER clock, and they are different questions:
|
|
@@ -372,6 +375,8 @@ interface RecordsClient {
|
|
|
372
375
|
recordRead(args: {
|
|
373
376
|
record_id: Uuid;
|
|
374
377
|
withComputed?: boolean;
|
|
378
|
+
/** Also answer `version` (read in the same round, so the read takes as long as the slower of the two). */
|
|
379
|
+
withVersion?: boolean;
|
|
375
380
|
organization_id?: Uuid | null;
|
|
376
381
|
}): Promise<RecordsResult<RecordRead>>;
|
|
377
382
|
/**
|
package/dist/core/index.cjs
CHANGED
|
@@ -120,6 +120,7 @@ __export(core_exports, {
|
|
|
120
120
|
announceRecordChanged: () => announceRecordChanged,
|
|
121
121
|
announceTableStructureChanged: () => announceTableStructureChanged,
|
|
122
122
|
archivedByLine: () => archivedByLine,
|
|
123
|
+
archivedOrganizationId: () => archivedOrganizationId,
|
|
123
124
|
archivedWhen: () => archivedWhen,
|
|
124
125
|
asChoiceNudge: () => asChoiceNudge,
|
|
125
126
|
asPermissionLevel: () => asPermissionLevel,
|
|
@@ -1627,9 +1628,18 @@ function stableFilterKey(filter) {
|
|
|
1627
1628
|
return `{${parts.join(",")}}`;
|
|
1628
1629
|
}
|
|
1629
1630
|
function liftWithheld(rows2) {
|
|
1631
|
+
let shared;
|
|
1632
|
+
for (const row of rows2) {
|
|
1633
|
+
const m = (row.measures ?? {})["_withheld"];
|
|
1634
|
+
if (m !== void 0 && m !== null && typeof m === "object") {
|
|
1635
|
+
shared = m;
|
|
1636
|
+
break;
|
|
1637
|
+
}
|
|
1638
|
+
}
|
|
1630
1639
|
return rows2.map((row) => {
|
|
1631
1640
|
const measures = row.measures ?? {};
|
|
1632
|
-
const
|
|
1641
|
+
const own = measures["_withheld"];
|
|
1642
|
+
const marker = own !== void 0 && own !== null && typeof own === "object" ? own : shared;
|
|
1633
1643
|
const rowCount = row.row_count ?? 0;
|
|
1634
1644
|
if (marker === void 0 || marker === null || typeof marker !== "object") {
|
|
1635
1645
|
return rowCount === row.row_count ? row : { ...row, row_count: rowCount };
|
|
@@ -2472,6 +2482,11 @@ function staleWriteDetail(error) {
|
|
|
2472
2482
|
contested_fields: detail.contested_fields ?? {}
|
|
2473
2483
|
};
|
|
2474
2484
|
}
|
|
2485
|
+
function archivedOrganizationId(error) {
|
|
2486
|
+
if (error.code !== "door" || typeof error.detail !== "string") return null;
|
|
2487
|
+
const m = /^organization_archived:([0-9a-f-]{36})$/i.exec(error.detail.trim());
|
|
2488
|
+
return m ? m[1] : null;
|
|
2489
|
+
}
|
|
2475
2490
|
|
|
2476
2491
|
// src/relation.ts
|
|
2477
2492
|
var import_uuid4 = require("@ai-matrx/kit/uuid");
|
|
@@ -6883,24 +6898,27 @@ function createRecordsClient(given) {
|
|
|
6883
6898
|
if (!pass.ok) return pass;
|
|
6884
6899
|
return carryOnCopy(pass.data, onProgress);
|
|
6885
6900
|
},
|
|
6886
|
-
async recordRead({ record_id, withComputed = false, organization_id }) {
|
|
6901
|
+
async recordRead({ record_id, withComputed = false, withVersion = false, organization_id }) {
|
|
6887
6902
|
if (organization_id && organization_id !== org) {
|
|
6888
|
-
return clientFor(organization_id).recordRead({ record_id, withComputed, organization_id });
|
|
6903
|
+
return clientFor(organization_id).recordRead({ record_id, withComputed, withVersion, organization_id });
|
|
6889
6904
|
}
|
|
6890
6905
|
if (readOrgs(organization_id).length > 1) {
|
|
6891
6906
|
return openInOwnOrg(
|
|
6892
6907
|
record_id,
|
|
6893
6908
|
organization_id,
|
|
6894
|
-
(sub) => sub.recordRead({ record_id, withComputed, organization_id: sub.config.organizationId }),
|
|
6909
|
+
(sub) => sub.recordRead({ record_id, withComputed, withVersion, organization_id: sub.config.organizationId }),
|
|
6895
6910
|
() => true
|
|
6896
6911
|
);
|
|
6897
6912
|
}
|
|
6898
|
-
const door = await
|
|
6899
|
-
DOORS.readRecord,
|
|
6900
|
-
|
|
6901
|
-
"recordRead"
|
|
6902
|
-
|
|
6913
|
+
const [door, header] = await Promise.all([
|
|
6914
|
+
callDoor(DOORS.readRecord, { p_organization_id: org, p_record_id: record_id }, "recordRead"),
|
|
6915
|
+
// A version that cannot be read never takes the record away: it comes back as null.
|
|
6916
|
+
withVersion ? callDoor(DOORS.recordHeaders, { p_organization_id: org, p_ids: [record_id] }, "recordRead.version").catch(
|
|
6917
|
+
() => null
|
|
6918
|
+
) : Promise.resolve(null)
|
|
6919
|
+
]);
|
|
6903
6920
|
if (!door.ok) return err(door.error);
|
|
6921
|
+
const version = header && header.ok ? header.data?.find((h) => h.id === record_id)?.version ?? null : null;
|
|
6904
6922
|
const { document, hidden } = unfold(door.data);
|
|
6905
6923
|
let computed = [];
|
|
6906
6924
|
let computedUnavailable = null;
|
|
@@ -6913,7 +6931,7 @@ function createRecordsClient(given) {
|
|
|
6913
6931
|
if (provenance.ok) computed = provenance.data ?? [];
|
|
6914
6932
|
else computedUnavailable = provenance.error;
|
|
6915
6933
|
}
|
|
6916
|
-
return ok({ record_id, document, hidden, computed, computedUnavailable });
|
|
6934
|
+
return ok({ record_id, document, hidden, computed, computedUnavailable, ...withVersion ? { version } : {} });
|
|
6917
6935
|
},
|
|
6918
6936
|
async listByIds({ table_id, ids }) {
|
|
6919
6937
|
if (ids.length === 0) return ok([]);
|