@ai-matrx/records 0.58.19 → 0.58.21

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,20 @@
1
1
  # Changelog — @ai-matrx/records
2
2
 
3
+ ## 0.58.21
4
+
5
+ Automatic changed-only republish (docs/metadata drift since the last tag — see
6
+ `git diff npm/records/v0.58.20..npm/records/v0.58.21 -- apps/shared/records`).
7
+ No source changes intended and no consumer action required.
8
+
9
+ ## 0.58.20 (2026-09-26 — cut by the automatic republish; carries lane data-tables-grid-overhaul, merge tranche 6k)
10
+
11
+ * **`useRecordPage(tableId, { pageSize, page, filter, search, sort, viewId })`** (`/react`) — one page
12
+ through `client.listPage` (`custom.read_records_page`): the store sorts, searches, filters and
13
+ counts; `total` is the matching set this reader may see. Realtime-aware exactly like
14
+ `useRecords`: a notice re-reads only the ids it names and patches them into the page (a row the
15
+ page does not hold costs one page read). `tableId: null` reads nothing. The realtime half is one
16
+ shared helper for both hooks. New types `UseRecordPageOptions`, `UseRecordPageState`.
17
+
3
18
  ## 0.58.19
4
19
 
5
20
  Automatic changed-only republish (docs/metadata drift since the last tag — see
@@ -2328,6 +2328,7 @@ __export(react_exports, {
2328
2328
  useRecord: () => useRecord,
2329
2329
  useRecordChangeRevision: () => useRecordChangeRevision,
2330
2330
  useRecordMutation: () => useRecordMutation,
2331
+ useRecordPage: () => useRecordPage,
2331
2332
  useRecords: () => useRecords,
2332
2333
  useRecordsActor: () => useRecordsActor,
2333
2334
  useRecordsClient: () => useRecordsClient,
@@ -8122,26 +8123,8 @@ function useFields(tableId, recordType) {
8122
8123
  tableId ? `fields:${tableId}:${recordType ?? ""}:${revision}` : null
8123
8124
  );
8124
8125
  }
8125
- function useRecords(tableId, options = {}) {
8126
+ function useLiveRows(tableId, base) {
8126
8127
  const client = useRecordsClient();
8127
- const pageSize = options.pageSize ?? 50;
8128
- const page = options.page ?? 0;
8129
- const filterKey = stableFilterKey(options.filter);
8130
- const base = useAsync(
8131
- async (c) => {
8132
- if (!tableId) return { ok: true, data: { rows: [], total: null } };
8133
- return c.list({
8134
- table_id: tableId,
8135
- ...filterKey === "{}" ? {} : { filter: options.filter },
8136
- limit: pageSize,
8137
- offset: page * pageSize
8138
- });
8139
- },
8140
- // The QUESTION, not the object: a parent that rebuilds `{status: "Cancelled"}`
8141
- // on every render must not re-read the page on every render, and a parent
8142
- // that changes the question must re-read on the first one.
8143
- [tableId, pageSize, page, filterKey]
8144
- );
8145
8128
  const realtime = client.config.realtime;
8146
8129
  const { reload, setData } = base;
8147
8130
  (0, import_react2.useEffect)(() => {
@@ -8188,6 +8171,54 @@ function useRecords(tableId, options = {}) {
8188
8171
  }, [realtime, tableId, client, reload, setData, base.data]);
8189
8172
  const live = Boolean(realtime && tableId);
8190
8173
  const liveReason = realtime ? tableId ? "Live: changes to this table re-read through the read door." : "Not live: no table selected." : "Not live: this host bound no realtime port, so this list updates when you reload it.";
8174
+ return { live, liveReason };
8175
+ }
8176
+ function useRecords(tableId, options = {}) {
8177
+ const pageSize = options.pageSize ?? 50;
8178
+ const page = options.page ?? 0;
8179
+ const filterKey = stableFilterKey(options.filter);
8180
+ const base = useAsync(
8181
+ async (c) => {
8182
+ if (!tableId) return { ok: true, data: { rows: [], total: null } };
8183
+ return c.list({
8184
+ table_id: tableId,
8185
+ ...filterKey === "{}" ? {} : { filter: options.filter },
8186
+ limit: pageSize,
8187
+ offset: page * pageSize
8188
+ });
8189
+ },
8190
+ // The QUESTION, not the object: a parent that rebuilds `{status: "Cancelled"}`
8191
+ // on every render must not re-read the page on every render, and a parent
8192
+ // that changes the question must re-read on the first one.
8193
+ [tableId, pageSize, page, filterKey]
8194
+ );
8195
+ const { live, liveReason } = useLiveRows(tableId, base);
8196
+ return { ...base, live, liveReason };
8197
+ }
8198
+ function useRecordPage(tableId, options = {}) {
8199
+ const pageSize = options.pageSize ?? 50;
8200
+ const page = options.page ?? 0;
8201
+ const filterKey = stableFilterKey(options.filter);
8202
+ const search = options.search && options.search.trim() !== "" ? options.search.trim() : null;
8203
+ const sortKey = JSON.stringify(options.sort ?? []);
8204
+ const viewId = options.viewId ?? null;
8205
+ const base = useAsync(
8206
+ async (c) => {
8207
+ if (!tableId) return { ok: true, data: { rows: [], total: null } };
8208
+ const answered = await c.listPage({
8209
+ table_id: tableId,
8210
+ ...filterKey === "{}" ? {} : { filter: options.filter },
8211
+ search,
8212
+ sort: JSON.parse(sortKey),
8213
+ view_id: viewId,
8214
+ limit: pageSize,
8215
+ offset: page * pageSize
8216
+ });
8217
+ return answered.ok ? { ok: true, data: { rows: answered.data.rows, total: answered.data.total } } : answered;
8218
+ },
8219
+ [tableId, pageSize, page, filterKey, search, sortKey, viewId]
8220
+ );
8221
+ const { live, liveReason } = useLiveRows(tableId, base);
8191
8222
  return { ...base, live, liveReason };
8192
8223
  }
8193
8224
  function useRecordChangeRevision(recordId) {