@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.
Files changed (107) hide show
  1. package/CHANGELOG.md +100 -0
  2. package/README.md +115 -0
  3. package/dist/{client-E0VQ0NPO.d.ts → client-Cn3odIIB.d.cts} +10 -5
  4. package/dist/{client-C3ZZNfGH.d.cts → client-Dzd8gtAo.d.ts} +10 -5
  5. package/dist/core/index.cjs +28 -10
  6. package/dist/core/index.cjs.map +1 -1
  7. package/dist/core/index.d.cts +23 -12
  8. package/dist/core/index.d.ts +23 -12
  9. package/dist/core/index.js +28 -10
  10. package/dist/core/index.js.map +1 -1
  11. package/dist/data/index.cjs +22 -10
  12. package/dist/data/index.cjs.map +1 -1
  13. package/dist/data/index.d.cts +12 -142
  14. package/dist/data/index.d.ts +12 -142
  15. package/dist/data/index.js +22 -10
  16. package/dist/data/index.js.map +1 -1
  17. package/dist/{declareTable-BK3zufr7.d.cts → declareTable-CrL6AZKB.d.cts} +4 -4
  18. package/dist/{declareTable-B12XybRp.d.ts → declareTable-ZRW5EsTQ.d.ts} +4 -4
  19. package/dist/entity/index.cjs +984 -0
  20. package/dist/entity/index.cjs.map +1 -0
  21. package/dist/entity/index.d.cts +36 -0
  22. package/dist/entity/index.d.ts +36 -0
  23. package/dist/entity/index.js +964 -0
  24. package/dist/entity/index.js.map +1 -0
  25. package/dist/entity/react.cjs +1024 -0
  26. package/dist/entity/react.cjs.map +1 -0
  27. package/dist/entity/react.d.cts +511 -0
  28. package/dist/entity/react.d.ts +511 -0
  29. package/dist/entity/react.js +1015 -0
  30. package/dist/entity/react.js.map +1 -0
  31. package/dist/{field-BanTVGK2.d.cts → field-CCY1rG9l.d.cts} +1 -1
  32. package/dist/{field-BPABOJ2Y.d.ts → field-enufS5ry.d.ts} +1 -1
  33. package/dist/forms/index.cjs +984 -0
  34. package/dist/forms/index.cjs.map +1 -0
  35. package/dist/forms/index.d.cts +333 -0
  36. package/dist/forms/index.d.ts +333 -0
  37. package/dist/forms/index.js +961 -0
  38. package/dist/forms/index.js.map +1 -0
  39. package/dist/index.cjs +10 -1
  40. package/dist/index.cjs.map +1 -1
  41. package/dist/index.d.cts +11 -8
  42. package/dist/index.d.ts +11 -8
  43. package/dist/index.js +10 -1
  44. package/dist/index.js.map +1 -1
  45. package/dist/memory/index.d.cts +7 -6
  46. package/dist/memory/index.d.ts +7 -6
  47. package/dist/port-C54ykAOv.d.ts +301 -0
  48. package/dist/port-Drioh9al.d.cts +301 -0
  49. package/dist/portal-DRdmZ-xv.d.cts +331 -0
  50. package/dist/portal-or_f7BkT.d.ts +331 -0
  51. package/dist/{ports-TMWX-t9l.d.ts → ports-BeOgjwYl.d.ts} +2 -2
  52. package/dist/{ports-D8-iuY1P.d.cts → ports-s0D2jvqn.d.cts} +2 -2
  53. package/dist/react/index.cjs +58 -526
  54. package/dist/react/index.cjs.map +1 -1
  55. package/dist/react/index.d.cts +16 -1
  56. package/dist/react/index.d.ts +16 -1
  57. package/dist/react/index.js +55 -530
  58. package/dist/react/index.js.map +1 -1
  59. package/dist/realtime/index.d.cts +2 -2
  60. package/dist/realtime/index.d.ts +2 -2
  61. package/dist/{record-DpB2QgAZ.d.cts → record-BwCf9wKW.d.cts} +7 -1
  62. package/dist/{record-DpB2QgAZ.d.ts → record-BwCf9wKW.d.ts} +7 -1
  63. package/dist/relation-8vAWCa67.d.cts +230 -0
  64. package/dist/relation-eLMgv_dV.d.ts +230 -0
  65. package/dist/rule-D9yNiorf.d.ts +250 -0
  66. package/dist/rule-wHI5B0Ka.d.cts +250 -0
  67. package/dist/search/index.cjs +283 -0
  68. package/dist/search/index.cjs.map +1 -0
  69. package/dist/search/index.d.cts +44 -0
  70. package/dist/search/index.d.ts +44 -0
  71. package/dist/search/index.js +260 -0
  72. package/dist/search/index.js.map +1 -0
  73. package/dist/setup/index.cjs +6854 -0
  74. package/dist/setup/index.cjs.map +1 -0
  75. package/dist/setup/index.d.cts +87 -0
  76. package/dist/setup/index.d.ts +87 -0
  77. package/dist/setup/index.js +6829 -0
  78. package/dist/setup/index.js.map +1 -0
  79. package/dist/{subscription-D7KQBHXN.d.ts → subscription-BynsG1K6.d.ts} +3 -249
  80. package/dist/{subscription-BD9DnJxX.d.cts → subscription-CdoI-UaB.d.cts} +3 -249
  81. package/dist/{table-kind-BZu8mtND.d.cts → table-kind-DzctQ7dO.d.cts} +3 -558
  82. package/dist/{table-kind-xKxTHtrV.d.ts → table-kind-i3lZJa3f.d.ts} +3 -558
  83. package/dist/templates/index.d.cts +10 -9
  84. package/dist/templates/index.d.ts +10 -9
  85. package/dist/typed-table/index.cjs +22 -10
  86. package/dist/typed-table/index.cjs.map +1 -1
  87. package/dist/typed-table/index.d.cts +10 -7
  88. package/dist/typed-table/index.d.ts +10 -7
  89. package/dist/typed-table/index.js +22 -10
  90. package/dist/typed-table/index.js.map +1 -1
  91. package/dist/types-BKYEeFt4.d.cts +139 -0
  92. package/dist/{types-Dv61jStB.d.ts → types-BvL_oKFl.d.ts} +2 -2
  93. package/dist/{types-CLP5H4Wk.d.cts → types-D8qdG3Lg.d.cts} +2 -2
  94. package/dist/{types-C2uspRtf.d.cts → types-DAFP6XFe.d.cts} +2 -2
  95. package/dist/{types-DmPkWQic.d.ts → types-DYzXhD7j.d.ts} +2 -2
  96. package/dist/types-cpKY7Pjb.d.ts +139 -0
  97. package/dist/use-cases/index.d.cts +5 -5
  98. package/dist/use-cases/index.d.ts +5 -5
  99. package/dist/{validate-CWVToe1T.d.ts → validate-DbvAParj.d.ts} +1 -1
  100. package/dist/{validate-DEB_mn4Y.d.cts → validate-DfNMxjmU.d.cts} +1 -1
  101. package/dist/versions/index.cjs +375 -0
  102. package/dist/versions/index.cjs.map +1 -0
  103. package/dist/versions/index.d.cts +160 -0
  104. package/dist/versions/index.d.ts +160 -0
  105. package/dist/versions/index.js +353 -0
  106. package/dist/versions/index.js.map +1 -0
  107. package/package.json +62 -2
@@ -1,144 +1,14 @@
1
- import { bP as EntityRefWithWords } from '../table-kind-BZu8mtND.cjs';
2
- import { U as Uuid, i as RecordsResult, o as RecordPageSort, n as ReadRow } from '../record-DpB2QgAZ.cjs';
3
- import { R as RecordsClient } from '../client-C3ZZNfGH.cjs';
4
- import { b as Field } from '../field-BanTVGK2.cjs';
5
- import { u as RuleExpression } from '../subscription-BD9DnJxX.cjs';
6
- import '../ports-D8-iuY1P.cjs';
7
-
8
- /** §0. A link to any thing: `{token, id, label}`. A custom row's token is `record`. Every link reads as `EntityRef[]`. */
9
- type EntityRef = EntityRefWithWords;
10
- /** The token a custom table's row carries (platform.entity_types maps `record` → `custom.record`). */
11
- declare const CUSTOM_ROW_TOKEN = "record";
12
- /** §0. One column, read live — never from a generated file. */
13
- interface Column {
14
- /** The store's stable field key — never derived from the label. No platform key starts with "_". */
15
- key: string;
16
- label: string;
17
- /** The store's word for what the value is: text, number, date, datetime, boolean, list, relation, formula, … */
18
- type: string;
19
- origin: "platform" | "custom";
20
- required: boolean;
21
- /** For a choice column: the words a person picks from (what a cell reads as and a write takes). */
22
- choices?: string[];
23
- /** For a link column: what it may point at (a custom table's id, or entity tokens). */
24
- linksTo?: string[];
25
- /**
26
- * For a link column: the alias, in the SAME port, that serves the table it points at — so a form can list
27
- * the linked rows to pick from. Absent when no source of this Applet serves that table.
28
- */
29
- linksToSource?: string;
30
- /**
31
- * The store's own answer to "does this column hold more than one value" (`custom.field.multi`). A choice
32
- * column's type is `list` whether it takes one word or many — only this tells them apart (Status, one
33
- * value, drew as four switches and the store refused the list it sent: social planner, 2026-10-08).
34
- */
35
- multi?: boolean;
36
- /** The column a row is named by (the table's `title_field`) — what a link to the row reads as. */
37
- title?: boolean;
38
- readOnly: boolean;
39
- }
40
- /** §0. One row, keyed by `Column.key`. Underscore keys are the runtime's own. */
41
- interface Row {
42
- _id: Uuid;
43
- _version: number;
44
- _organization_id: Uuid;
45
- /** On a platform row only: the organization's custom fields (a real column may be named `custom`). */
46
- _custom?: Record<string, unknown>;
47
- [key: string]: unknown;
48
- }
49
- /** §0. What a write carries, keyed by `Column.key`; `_custom` on platform sources. */
50
- type Values = Record<string, unknown> & {
51
- _custom?: Record<string, unknown>;
52
- };
53
- type WhereOp = "eq" | "neq" | "lt" | "lte" | "gt" | "gte" | "contains" | "in" | "empty";
54
- interface WhereClause {
55
- column: string;
56
- op: WhereOp;
57
- value?: unknown;
58
- }
59
- type Lane = "all" | "mine" | "team" | "orgs" | "shared" | "public" | "system";
60
- /** §4. A question of one source. Every clause must hold. */
61
- interface Query {
62
- where?: WhereClause[];
63
- search?: string;
64
- sort?: {
65
- column: string;
66
- direction?: "asc" | "desc";
67
- }[];
68
- pageSize?: number;
69
- /** Default: the type's "Shown to by default" knob. A custom table has one lane: what row security shows. */
70
- lane?: Lane;
71
- /** A filter, never a lock. Default "all". */
72
- org?: Uuid | "all";
73
- }
74
- /** §4. One page; `cursor` is null on the last one. */
75
- interface Page {
76
- rows: Row[];
77
- total: number | null;
78
- cursor: string | null;
79
- }
80
- interface DataSource {
81
- alias: string;
82
- label: string;
83
- kind: "table" | "entity";
84
- canCreate: boolean;
85
- canUpdate: boolean;
86
- }
87
- /** The one event stream a source has: these ids moved — re-read only them. `null`: cannot tell which. */
88
- interface RowsEvent {
89
- ids: Uuid[] | null;
90
- /** The table's columns moved (one added, retired or changed): re-read `columns()` too. */
91
- shape?: true;
92
- }
93
- type DataPortEventName = `rows:${string}`;
94
- /** §4. The host's data port, scoped to ONE mounted Applet's aliases. Every call answers, never throws. */
95
- interface DataPort {
96
- sources(): Promise<RecordsResult<DataSource[]>>;
97
- columns(alias: string): Promise<RecordsResult<Column[]>>;
98
- list(alias: string, q: Query, cursor?: string): Promise<RecordsResult<Page>>;
99
- get(alias: string, id: Uuid): Promise<RecordsResult<Row | null>>;
100
- create(alias: string, values: Values): Promise<RecordsResult<Row>>;
101
- update(alias: string, id: Uuid, patch: Values, baseVersion: number): Promise<RecordsResult<Row>>;
102
- archive(alias: string, id: Uuid): Promise<RecordsResult<void>>;
103
- restore(alias: string, id: Uuid): Promise<RecordsResult<void>>;
104
- }
105
- /**
106
- * The frame's side of the §1 event stream `rows:<alias>` (the AppletHost's `host.events`). The listener
107
- * stays in the frame; only the event payload `{ids, shape?}` crosses the channel.
108
- */
109
- interface DataEvents {
110
- on(event: DataPortEventName, listener: (event: RowsEvent) => void): () => void;
111
- }
112
- /**
113
- * The HOST's DataPort (contracts amendment 2.2): the port plus the producer of its event streams.
114
- * `subscribe` never crosses the frame/host channel — the AppletHost turns it into `rows:<alias>`.
115
- */
116
- interface HostDataPort extends DataPort {
117
- subscribe(event: DataPortEventName, listener: (event: RowsEvent) => void): () => void;
118
- }
119
- /** An alias as the Applet record declares it: one table plus its organization (an entity token is phase B). */
120
- interface TableAlias {
121
- kind: "table";
122
- tableId: Uuid;
123
- organizationId: Uuid;
124
- /** Shown in `sources()`; the table's own name when left out. */
125
- label?: string;
126
- }
127
- /**
128
- * An alias bound to one PLATFORM entity type (contacts, projects, tasks…), served by `@ai-matrx/entity-data`'s port.
129
- * `organizationId` is an assumed organization FILTER for its lists, never a lock; writes carry the active organization.
130
- */
131
- interface EntityAlias {
132
- kind: "entity";
133
- /** The type's token in `platform.entity_types` (`party`, `project`, `task`, …). */
134
- token: string;
135
- organizationId?: Uuid;
136
- label?: string;
137
- }
138
- /** Every alias an Applet record can declare. A host routes each kind to the port that serves it. */
139
- type AnyAlias = TableAlias | EntityAlias;
140
- /** What the table port takes (it serves `table` aliases only). */
141
- type AliasBinding = TableAlias;
1
+ import { C as Column, Q as Query, A as AliasBinding, H as HostDataPort } from '../types-BKYEeFt4.cjs';
2
+ export { a as AnyAlias, b as CUSTOM_ROW_TOKEN, D as DataEvents, c as DataPort, d as DataPortEventName, e as DataSource, E as EntityAlias, f as EntityRef, L as Lane, P as Page, R as Row, g as RowsEvent, T as TableAlias, V as Values, W as WhereClause, h as WhereOp } from '../types-BKYEeFt4.cjs';
3
+ import { R as RecordsClient } from '../client-Cn3odIIB.cjs';
4
+ import { b as Field } from '../field-CCY1rG9l.cjs';
5
+ import { U as Uuid, R as RecordsResult, r as RecordPageSort, q as ReadRow } from '../record-BwCf9wKW.cjs';
6
+ import { R as RuleExpression } from '../rule-wHI5B0Ka.cjs';
7
+ import '../relation-8vAWCa67.cjs';
8
+ import '../ports-s0D2jvqn.cjs';
9
+ import '../table-kind-DzctQ7dO.cjs';
10
+ import '../subscription-CdoI-UaB.cjs';
11
+ import '../portal-DRdmZ-xv.cjs';
142
12
 
143
13
  interface TableShape {
144
14
  columns: Column[];
@@ -173,4 +43,4 @@ interface CreateTableDataPortOptions {
173
43
  }
174
44
  declare function createTableDataPort({ client, aliases }: CreateTableDataPortOptions): HostDataPort;
175
45
 
176
- export { type AliasBinding, type AnyAlias, CUSTOM_ROW_TOKEN, type Column, type CreateTableDataPortOptions, DATA_PAGE_CEILING, DATA_PAGE_DEFAULT, type DataEvents, type DataPort, type DataPortEventName, type DataSource, type EntityAlias, type EntityRef, type HostDataPort, type Lane, type Page, type Query, type Row, type RowsEvent, type TableAlias, type TableShape, Uuid, type Values, type VersionedReadRow, type WhereClause, type WhereOp, columnTypeOf, compileSort, compileWhere, containsPattern, createTableDataPort, readTableShape };
46
+ export { AliasBinding, Column, type CreateTableDataPortOptions, DATA_PAGE_CEILING, DATA_PAGE_DEFAULT, HostDataPort, Query, type TableShape, Uuid, type VersionedReadRow, columnTypeOf, compileSort, compileWhere, containsPattern, createTableDataPort, readTableShape };
@@ -1,144 +1,14 @@
1
- import { bP as EntityRefWithWords } from '../table-kind-xKxTHtrV.js';
2
- import { U as Uuid, i as RecordsResult, o as RecordPageSort, n as ReadRow } from '../record-DpB2QgAZ.js';
3
- import { R as RecordsClient } from '../client-E0VQ0NPO.js';
4
- import { b as Field } from '../field-BPABOJ2Y.js';
5
- import { u as RuleExpression } from '../subscription-D7KQBHXN.js';
6
- import '../ports-TMWX-t9l.js';
7
-
8
- /** §0. A link to any thing: `{token, id, label}`. A custom row's token is `record`. Every link reads as `EntityRef[]`. */
9
- type EntityRef = EntityRefWithWords;
10
- /** The token a custom table's row carries (platform.entity_types maps `record` → `custom.record`). */
11
- declare const CUSTOM_ROW_TOKEN = "record";
12
- /** §0. One column, read live — never from a generated file. */
13
- interface Column {
14
- /** The store's stable field key — never derived from the label. No platform key starts with "_". */
15
- key: string;
16
- label: string;
17
- /** The store's word for what the value is: text, number, date, datetime, boolean, list, relation, formula, … */
18
- type: string;
19
- origin: "platform" | "custom";
20
- required: boolean;
21
- /** For a choice column: the words a person picks from (what a cell reads as and a write takes). */
22
- choices?: string[];
23
- /** For a link column: what it may point at (a custom table's id, or entity tokens). */
24
- linksTo?: string[];
25
- /**
26
- * For a link column: the alias, in the SAME port, that serves the table it points at — so a form can list
27
- * the linked rows to pick from. Absent when no source of this Applet serves that table.
28
- */
29
- linksToSource?: string;
30
- /**
31
- * The store's own answer to "does this column hold more than one value" (`custom.field.multi`). A choice
32
- * column's type is `list` whether it takes one word or many — only this tells them apart (Status, one
33
- * value, drew as four switches and the store refused the list it sent: social planner, 2026-10-08).
34
- */
35
- multi?: boolean;
36
- /** The column a row is named by (the table's `title_field`) — what a link to the row reads as. */
37
- title?: boolean;
38
- readOnly: boolean;
39
- }
40
- /** §0. One row, keyed by `Column.key`. Underscore keys are the runtime's own. */
41
- interface Row {
42
- _id: Uuid;
43
- _version: number;
44
- _organization_id: Uuid;
45
- /** On a platform row only: the organization's custom fields (a real column may be named `custom`). */
46
- _custom?: Record<string, unknown>;
47
- [key: string]: unknown;
48
- }
49
- /** §0. What a write carries, keyed by `Column.key`; `_custom` on platform sources. */
50
- type Values = Record<string, unknown> & {
51
- _custom?: Record<string, unknown>;
52
- };
53
- type WhereOp = "eq" | "neq" | "lt" | "lte" | "gt" | "gte" | "contains" | "in" | "empty";
54
- interface WhereClause {
55
- column: string;
56
- op: WhereOp;
57
- value?: unknown;
58
- }
59
- type Lane = "all" | "mine" | "team" | "orgs" | "shared" | "public" | "system";
60
- /** §4. A question of one source. Every clause must hold. */
61
- interface Query {
62
- where?: WhereClause[];
63
- search?: string;
64
- sort?: {
65
- column: string;
66
- direction?: "asc" | "desc";
67
- }[];
68
- pageSize?: number;
69
- /** Default: the type's "Shown to by default" knob. A custom table has one lane: what row security shows. */
70
- lane?: Lane;
71
- /** A filter, never a lock. Default "all". */
72
- org?: Uuid | "all";
73
- }
74
- /** §4. One page; `cursor` is null on the last one. */
75
- interface Page {
76
- rows: Row[];
77
- total: number | null;
78
- cursor: string | null;
79
- }
80
- interface DataSource {
81
- alias: string;
82
- label: string;
83
- kind: "table" | "entity";
84
- canCreate: boolean;
85
- canUpdate: boolean;
86
- }
87
- /** The one event stream a source has: these ids moved — re-read only them. `null`: cannot tell which. */
88
- interface RowsEvent {
89
- ids: Uuid[] | null;
90
- /** The table's columns moved (one added, retired or changed): re-read `columns()` too. */
91
- shape?: true;
92
- }
93
- type DataPortEventName = `rows:${string}`;
94
- /** §4. The host's data port, scoped to ONE mounted Applet's aliases. Every call answers, never throws. */
95
- interface DataPort {
96
- sources(): Promise<RecordsResult<DataSource[]>>;
97
- columns(alias: string): Promise<RecordsResult<Column[]>>;
98
- list(alias: string, q: Query, cursor?: string): Promise<RecordsResult<Page>>;
99
- get(alias: string, id: Uuid): Promise<RecordsResult<Row | null>>;
100
- create(alias: string, values: Values): Promise<RecordsResult<Row>>;
101
- update(alias: string, id: Uuid, patch: Values, baseVersion: number): Promise<RecordsResult<Row>>;
102
- archive(alias: string, id: Uuid): Promise<RecordsResult<void>>;
103
- restore(alias: string, id: Uuid): Promise<RecordsResult<void>>;
104
- }
105
- /**
106
- * The frame's side of the §1 event stream `rows:<alias>` (the AppletHost's `host.events`). The listener
107
- * stays in the frame; only the event payload `{ids, shape?}` crosses the channel.
108
- */
109
- interface DataEvents {
110
- on(event: DataPortEventName, listener: (event: RowsEvent) => void): () => void;
111
- }
112
- /**
113
- * The HOST's DataPort (contracts amendment 2.2): the port plus the producer of its event streams.
114
- * `subscribe` never crosses the frame/host channel — the AppletHost turns it into `rows:<alias>`.
115
- */
116
- interface HostDataPort extends DataPort {
117
- subscribe(event: DataPortEventName, listener: (event: RowsEvent) => void): () => void;
118
- }
119
- /** An alias as the Applet record declares it: one table plus its organization (an entity token is phase B). */
120
- interface TableAlias {
121
- kind: "table";
122
- tableId: Uuid;
123
- organizationId: Uuid;
124
- /** Shown in `sources()`; the table's own name when left out. */
125
- label?: string;
126
- }
127
- /**
128
- * An alias bound to one PLATFORM entity type (contacts, projects, tasks…), served by `@ai-matrx/entity-data`'s port.
129
- * `organizationId` is an assumed organization FILTER for its lists, never a lock; writes carry the active organization.
130
- */
131
- interface EntityAlias {
132
- kind: "entity";
133
- /** The type's token in `platform.entity_types` (`party`, `project`, `task`, …). */
134
- token: string;
135
- organizationId?: Uuid;
136
- label?: string;
137
- }
138
- /** Every alias an Applet record can declare. A host routes each kind to the port that serves it. */
139
- type AnyAlias = TableAlias | EntityAlias;
140
- /** What the table port takes (it serves `table` aliases only). */
141
- type AliasBinding = TableAlias;
1
+ import { C as Column, Q as Query, A as AliasBinding, H as HostDataPort } from '../types-cpKY7Pjb.js';
2
+ export { a as AnyAlias, b as CUSTOM_ROW_TOKEN, D as DataEvents, c as DataPort, d as DataPortEventName, e as DataSource, E as EntityAlias, f as EntityRef, L as Lane, P as Page, R as Row, g as RowsEvent, T as TableAlias, V as Values, W as WhereClause, h as WhereOp } from '../types-cpKY7Pjb.js';
3
+ import { R as RecordsClient } from '../client-Dzd8gtAo.js';
4
+ import { b as Field } from '../field-enufS5ry.js';
5
+ import { U as Uuid, R as RecordsResult, r as RecordPageSort, q as ReadRow } from '../record-BwCf9wKW.js';
6
+ import { R as RuleExpression } from '../rule-D9yNiorf.js';
7
+ import '../relation-eLMgv_dV.js';
8
+ import '../ports-BeOgjwYl.js';
9
+ import '../table-kind-i3lZJa3f.js';
10
+ import '../subscription-BynsG1K6.js';
11
+ import '../portal-or_f7BkT.js';
142
12
 
143
13
  interface TableShape {
144
14
  columns: Column[];
@@ -173,4 +43,4 @@ interface CreateTableDataPortOptions {
173
43
  }
174
44
  declare function createTableDataPort({ client, aliases }: CreateTableDataPortOptions): HostDataPort;
175
45
 
176
- export { type AliasBinding, type AnyAlias, CUSTOM_ROW_TOKEN, type Column, type CreateTableDataPortOptions, DATA_PAGE_CEILING, DATA_PAGE_DEFAULT, type DataEvents, type DataPort, type DataPortEventName, type DataSource, type EntityAlias, type EntityRef, type HostDataPort, type Lane, type Page, type Query, type Row, type RowsEvent, type TableAlias, type TableShape, Uuid, type Values, type VersionedReadRow, type WhereClause, type WhereOp, columnTypeOf, compileSort, compileWhere, containsPattern, createTableDataPort, readTableShape };
46
+ export { AliasBinding, Column, type CreateTableDataPortOptions, DATA_PAGE_CEILING, DATA_PAGE_DEFAULT, HostDataPort, Query, type TableShape, Uuid, type VersionedReadRow, columnTypeOf, compileSort, compileWhere, containsPattern, createTableDataPort, readTableShape };
@@ -290,9 +290,18 @@ function stableFilterKey(filter) {
290
290
  return `{${parts.join(",")}}`;
291
291
  }
292
292
  function liftWithheld(rows) {
293
+ let shared;
294
+ for (const row of rows) {
295
+ const m = (row.measures ?? {})["_withheld"];
296
+ if (m !== void 0 && m !== null && typeof m === "object") {
297
+ shared = m;
298
+ break;
299
+ }
300
+ }
293
301
  return rows.map((row) => {
294
302
  const measures = row.measures ?? {};
295
- const marker = measures["_withheld"];
303
+ const own = measures["_withheld"];
304
+ const marker = own !== void 0 && own !== null && typeof own === "object" ? own : shared;
296
305
  const rowCount = row.row_count ?? 0;
297
306
  if (marker === void 0 || marker === null || typeof marker !== "object") {
298
307
  return rowCount === row.row_count ? row : { ...row, row_count: rowCount };
@@ -3222,24 +3231,27 @@ function createRecordsClient(given) {
3222
3231
  if (!pass.ok) return pass;
3223
3232
  return carryOnCopy(pass.data, onProgress);
3224
3233
  },
3225
- async recordRead({ record_id, withComputed = false, organization_id }) {
3234
+ async recordRead({ record_id, withComputed = false, withVersion = false, organization_id }) {
3226
3235
  if (organization_id && organization_id !== org) {
3227
- return clientFor(organization_id).recordRead({ record_id, withComputed, organization_id });
3236
+ return clientFor(organization_id).recordRead({ record_id, withComputed, withVersion, organization_id });
3228
3237
  }
3229
3238
  if (readOrgs(organization_id).length > 1) {
3230
3239
  return openInOwnOrg(
3231
3240
  record_id,
3232
3241
  organization_id,
3233
- (sub) => sub.recordRead({ record_id, withComputed, organization_id: sub.config.organizationId }),
3242
+ (sub) => sub.recordRead({ record_id, withComputed, withVersion, organization_id: sub.config.organizationId }),
3234
3243
  () => true
3235
3244
  );
3236
3245
  }
3237
- const door = await callDoor(
3238
- DOORS.readRecord,
3239
- { p_organization_id: org, p_record_id: record_id },
3240
- "recordRead"
3241
- );
3246
+ const [door, header] = await Promise.all([
3247
+ callDoor(DOORS.readRecord, { p_organization_id: org, p_record_id: record_id }, "recordRead"),
3248
+ // A version that cannot be read never takes the record away: it comes back as null.
3249
+ withVersion ? callDoor(DOORS.recordHeaders, { p_organization_id: org, p_ids: [record_id] }, "recordRead.version").catch(
3250
+ () => null
3251
+ ) : Promise.resolve(null)
3252
+ ]);
3242
3253
  if (!door.ok) return err(door.error);
3254
+ const version = header && header.ok ? header.data?.find((h) => h.id === record_id)?.version ?? null : null;
3243
3255
  const { document, hidden } = unfold(door.data);
3244
3256
  let computed = [];
3245
3257
  let computedUnavailable = null;
@@ -3252,7 +3264,7 @@ function createRecordsClient(given) {
3252
3264
  if (provenance.ok) computed = provenance.data ?? [];
3253
3265
  else computedUnavailable = provenance.error;
3254
3266
  }
3255
- return ok({ record_id, document, hidden, computed, computedUnavailable });
3267
+ return ok({ record_id, document, hidden, computed, computedUnavailable, ...withVersion ? { version } : {} });
3256
3268
  },
3257
3269
  async listByIds({ table_id, ids }) {
3258
3270
  if (ids.length === 0) return ok([]);