@ai-matrx/records 0.80.8 → 0.81.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 +23 -0
- package/dist/app-table/index.cjs.map +1 -1
- package/dist/app-table/index.js.map +1 -1
- package/dist/core/index.cjs +74 -0
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +35 -1
- package/dist/core/index.d.ts +35 -1
- package/dist/core/index.js +74 -0
- package/dist/core/index.js.map +1 -1
- package/dist/data/index.cjs.map +1 -1
- package/dist/data/index.js.map +1 -1
- package/dist/memory/index.cjs.map +1 -1
- package/dist/memory/index.js.map +1 -1
- package/dist/react/index.cjs +268 -98
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +60 -1
- package/dist/react/index.d.ts +60 -1
- package/dist/react/index.js +206 -36
- package/dist/react/index.js.map +1 -1
- package/dist/templates/index.cjs +1 -1
- package/dist/templates/index.cjs.map +1 -1
- package/dist/templates/index.js +1 -1
- package/dist/templates/index.js.map +1 -1
- package/package.json +18 -3
package/dist/react/index.cjs
CHANGED
|
@@ -86,6 +86,8 @@ __export(react_exports, {
|
|
|
86
86
|
RULE_USES: () => RULE_USES,
|
|
87
87
|
RecordsHoldScope: () => RecordsHoldScope,
|
|
88
88
|
RecordsProvider: () => RecordsProvider,
|
|
89
|
+
RecordsSeedProvider: () => RecordsSeedProvider,
|
|
90
|
+
SEED_FRESH_MS: () => SEED_FRESH_MS,
|
|
89
91
|
SHOWN_TO_LABEL: () => SHOWN_TO_LABEL,
|
|
90
92
|
SHOWN_TO_VALUES: () => SHOWN_TO_VALUES,
|
|
91
93
|
SHOWN_TO_WHO_MAY_CHANGE: () => SHOWN_TO_WHO_MAY_CHANGE,
|
|
@@ -277,6 +279,7 @@ __export(react_exports, {
|
|
|
277
279
|
useReverseColumns: () => useReverseColumns,
|
|
278
280
|
useReverseLinks: () => useReverseLinks,
|
|
279
281
|
useRowActions: () => useRowActions,
|
|
282
|
+
useSeededAnswer: () => useSeededAnswer,
|
|
280
283
|
useStoreTable: () => useStoreTable,
|
|
281
284
|
useTable: () => useTable,
|
|
282
285
|
useTableArchive: () => useTableArchive,
|
|
@@ -300,6 +303,10 @@ function registry() {
|
|
|
300
303
|
return g[REGISTRY] ??= /* @__PURE__ */ new Map();
|
|
301
304
|
}
|
|
302
305
|
var primedKey = (organizationId, tableId, viewId) => `${organizationId}|${tableId}|${viewId ?? ""}`;
|
|
306
|
+
function primeTablePageBundle(input) {
|
|
307
|
+
const answer = Promise.resolve(input.answer).catch((thrown) => ({ data: null, error: thrown }));
|
|
308
|
+
registry().set(primedKey(input.organizationId, input.tableId, input.viewId), { answer, at: Date.now() });
|
|
309
|
+
}
|
|
303
310
|
function takePrimedTablePageBundle(organizationId, tableId, viewId) {
|
|
304
311
|
if (!organizationId) return null;
|
|
305
312
|
const key = primedKey(organizationId, tableId, viewId);
|
|
@@ -309,6 +316,9 @@ function takePrimedTablePageBundle(organizationId, tableId, viewId) {
|
|
|
309
316
|
primed.delete(key);
|
|
310
317
|
return Date.now() - held.at < PRIMED_TTL_MS ? held.answer : null;
|
|
311
318
|
}
|
|
319
|
+
function primeRecordPageBundle(input) {
|
|
320
|
+
primeTablePageBundle({ organizationId: input.organizationId, tableId: `record:${input.recordId}`, answer: input.answer });
|
|
321
|
+
}
|
|
312
322
|
|
|
313
323
|
// src/core/recordChanges.ts
|
|
314
324
|
var listeners = /* @__PURE__ */ new Set();
|
|
@@ -426,8 +436,8 @@ function liftWithheld(rows) {
|
|
|
426
436
|
}
|
|
427
437
|
|
|
428
438
|
// src/subscription.ts
|
|
429
|
-
function hasQuietHours(
|
|
430
|
-
return Boolean(
|
|
439
|
+
function hasQuietHours(quiet2) {
|
|
440
|
+
return Boolean(quiet2?.start && quiet2?.end);
|
|
431
441
|
}
|
|
432
442
|
function callersTimeZone() {
|
|
433
443
|
try {
|
|
@@ -7851,7 +7861,7 @@ function useRecordsActor() {
|
|
|
7851
7861
|
}
|
|
7852
7862
|
|
|
7853
7863
|
// src/react/hooks.ts
|
|
7854
|
-
var
|
|
7864
|
+
var import_react4 = require("react");
|
|
7855
7865
|
|
|
7856
7866
|
// src/react/dataCache.ts
|
|
7857
7867
|
var RECORDS_CACHE_GRACE_MS = 3e4;
|
|
@@ -8004,6 +8014,12 @@ function releaseEntry(handle) {
|
|
|
8004
8014
|
entry.refs = Math.max(0, entry.refs - 1);
|
|
8005
8015
|
if (entry.refs === 0) scheduleClose(entry);
|
|
8006
8016
|
}
|
|
8017
|
+
function seedEntry(handle, data, stale) {
|
|
8018
|
+
const entry = handle;
|
|
8019
|
+
if (entry.started || entry.snapshot.data !== null) return;
|
|
8020
|
+
entry.snapshot = { data, loading: false, error: null };
|
|
8021
|
+
entry.started = !stale;
|
|
8022
|
+
}
|
|
8007
8023
|
function openHold(holdKey) {
|
|
8008
8024
|
const holds = root().holds;
|
|
8009
8025
|
let hold = holds.get(holdKey);
|
|
@@ -8034,65 +8050,215 @@ function recordsCacheCounters() {
|
|
|
8034
8050
|
return { ...root().counters };
|
|
8035
8051
|
}
|
|
8036
8052
|
|
|
8037
|
-
// src/react/
|
|
8053
|
+
// src/react/seed.tsx
|
|
8038
8054
|
var import_react2 = require("react");
|
|
8039
|
-
|
|
8055
|
+
|
|
8056
|
+
// src/core/seed.ts
|
|
8057
|
+
var BUNDLE_DOORS = /* @__PURE__ */ new Set(["table_page_bundle", "record_page_bundle"]);
|
|
8058
|
+
function seedKey(door, args) {
|
|
8059
|
+
return `${door}|${canonicalArgs(args)}`;
|
|
8060
|
+
}
|
|
8061
|
+
function answersOf(door, args, data) {
|
|
8062
|
+
const out = [{ door, args, data }];
|
|
8063
|
+
if (!BUNDLE_DOORS.has(door) || !data || typeof data !== "object") return out;
|
|
8064
|
+
const parts = data.parts;
|
|
8065
|
+
if (!Array.isArray(parts)) return out;
|
|
8066
|
+
for (const part of parts) {
|
|
8067
|
+
if (part.error !== void 0 || part.data === void 0) continue;
|
|
8068
|
+
if (typeof part.door !== "string" || !part.args || typeof part.args !== "object") continue;
|
|
8069
|
+
out.push({ door: part.door, args: part.args, data: part.data });
|
|
8070
|
+
}
|
|
8071
|
+
return out;
|
|
8072
|
+
}
|
|
8073
|
+
function seedIndex(seed) {
|
|
8074
|
+
const index = /* @__PURE__ */ new Map();
|
|
8075
|
+
for (const a of seed.answers) {
|
|
8076
|
+
for (const spread of answersOf(a.door, a.args, a.data)) index.set(seedKey(spread.door, spread.args), spread.data);
|
|
8077
|
+
}
|
|
8078
|
+
return index;
|
|
8079
|
+
}
|
|
8080
|
+
var MISS = { code: "SEED_MISS", message: "Not in the page's seed.", details: null, hint: null };
|
|
8081
|
+
function missingQuery(onMiss) {
|
|
8082
|
+
const answer = () => {
|
|
8083
|
+
onMiss();
|
|
8084
|
+
return Promise.resolve({ data: null, error: MISS, count: null });
|
|
8085
|
+
};
|
|
8086
|
+
const chain = new Proxy(function() {
|
|
8087
|
+
}, {
|
|
8088
|
+
get(_target, prop) {
|
|
8089
|
+
if (prop === "then") return (ok2, bad) => answer().then(ok2, bad);
|
|
8090
|
+
return () => chain;
|
|
8091
|
+
},
|
|
8092
|
+
apply: () => chain
|
|
8093
|
+
});
|
|
8094
|
+
return { select: () => chain };
|
|
8095
|
+
}
|
|
8096
|
+
function seededDataSource(index) {
|
|
8097
|
+
let missed = false;
|
|
8098
|
+
const source = {
|
|
8099
|
+
rpc(fn, args) {
|
|
8100
|
+
const key = seedKey(fn, args);
|
|
8101
|
+
if (index.has(key)) return Promise.resolve({ data: index.get(key), error: null });
|
|
8102
|
+
missed = true;
|
|
8103
|
+
return Promise.resolve({ data: null, error: MISS });
|
|
8104
|
+
},
|
|
8105
|
+
schema: () => ({ from: () => missingQuery(() => missed = true) })
|
|
8106
|
+
};
|
|
8107
|
+
return { source, missed: () => missed };
|
|
8108
|
+
}
|
|
8109
|
+
|
|
8110
|
+
// src/react/seed.tsx
|
|
8111
|
+
var SEED_FRESH_MS = 3e4;
|
|
8112
|
+
var stores = /* @__PURE__ */ new WeakMap();
|
|
8113
|
+
var quiet = () => {
|
|
8114
|
+
};
|
|
8115
|
+
function storeFor(seed) {
|
|
8116
|
+
const held = stores.get(seed);
|
|
8117
|
+
if (held) return held;
|
|
8118
|
+
const index = seedIndex(seed);
|
|
8119
|
+
const runs = /* @__PURE__ */ new Map();
|
|
8120
|
+
const store = {
|
|
8121
|
+
live: true,
|
|
8122
|
+
run(slot, run, config) {
|
|
8123
|
+
const asked = runs.get(slot);
|
|
8124
|
+
if (asked) return asked;
|
|
8125
|
+
const { source, missed } = seededDataSource(index);
|
|
8126
|
+
const { realtime: _live, ...quietConfig } = config;
|
|
8127
|
+
const client = createRecordsClient({ ...quietConfig, dataSource: source, onError: quiet });
|
|
8128
|
+
const stale = typeof seed.at !== "number" || Date.now() - seed.at > SEED_FRESH_MS;
|
|
8129
|
+
const outcome = Promise.resolve().then(() => run(client)).then(
|
|
8130
|
+
(answer) => answer.ok && !missed() ? { seeded: true, data: answer.data, stale } : { seeded: false },
|
|
8131
|
+
() => ({ seeded: false })
|
|
8132
|
+
);
|
|
8133
|
+
runs.set(slot, outcome);
|
|
8134
|
+
return outcome;
|
|
8135
|
+
}
|
|
8136
|
+
};
|
|
8137
|
+
stores.set(seed, store);
|
|
8138
|
+
if (typeof window !== "undefined") {
|
|
8139
|
+
for (const a of seed.answers) {
|
|
8140
|
+
const org = a.args["p_organization_id"];
|
|
8141
|
+
if (typeof org !== "string") continue;
|
|
8142
|
+
if (a.door === "table_page_bundle" && typeof a.args["p_table_id"] === "string") {
|
|
8143
|
+
const view = a.args["p_view_id"];
|
|
8144
|
+
primeTablePageBundle({ organizationId: org, tableId: a.args["p_table_id"], viewId: typeof view === "string" ? view : null, answer: { data: a.data, error: null } });
|
|
8145
|
+
} else if (a.door === "record_page_bundle" && typeof a.args["p_record_id"] === "string") {
|
|
8146
|
+
primeRecordPageBundle({ organizationId: org, recordId: a.args["p_record_id"], answer: { data: a.data, error: null } });
|
|
8147
|
+
}
|
|
8148
|
+
}
|
|
8149
|
+
}
|
|
8150
|
+
return store;
|
|
8151
|
+
}
|
|
8152
|
+
var SeedContext = (0, import_react2.createContext)(null);
|
|
8153
|
+
function RecordsSeedProvider({ seed, children }) {
|
|
8154
|
+
const store = seed && Array.isArray(seed.answers) ? storeFor(seed) : null;
|
|
8155
|
+
(0, import_react2.useEffect)(() => {
|
|
8156
|
+
if (store) store.live = false;
|
|
8157
|
+
}, [store]);
|
|
8158
|
+
return (0, import_react2.createElement)(SeedContext.Provider, { value: store }, children);
|
|
8159
|
+
}
|
|
8160
|
+
function useSeedStore() {
|
|
8161
|
+
const store = (0, import_react2.useContext)(SeedContext);
|
|
8162
|
+
return store && store.live ? store : null;
|
|
8163
|
+
}
|
|
8164
|
+
|
|
8165
|
+
// src/react/hold.tsx
|
|
8166
|
+
var import_react3 = require("react");
|
|
8167
|
+
var HoldContext = (0, import_react3.createContext)(null);
|
|
8040
8168
|
function RecordsHoldScope({ holdKey, children }) {
|
|
8041
|
-
return (0,
|
|
8169
|
+
return (0, import_react3.createElement)(HoldContext.Provider, { value: holdKey }, children);
|
|
8042
8170
|
}
|
|
8043
8171
|
function useRecordsHold(holdKey) {
|
|
8044
|
-
(0,
|
|
8172
|
+
(0, import_react3.useEffect)(() => holdKey ? openHold(holdKey) : void 0, [holdKey]);
|
|
8045
8173
|
}
|
|
8046
8174
|
function useHoldKey() {
|
|
8047
|
-
return (0,
|
|
8175
|
+
return (0, import_react3.useContext)(HoldContext);
|
|
8176
|
+
}
|
|
8177
|
+
|
|
8178
|
+
// src/react/pageOrder.ts
|
|
8179
|
+
function pageOrderOf(sort, narrowed) {
|
|
8180
|
+
return { sortFields: (sort ?? []).map((key) => key.field), narrowed };
|
|
8181
|
+
}
|
|
8182
|
+
var same = (a, b) => {
|
|
8183
|
+
if (a === b) return true;
|
|
8184
|
+
if ((a === null || a === void 0 || a === "") && (b === null || b === void 0 || b === "")) return true;
|
|
8185
|
+
return JSON.stringify(a) === JSON.stringify(b);
|
|
8186
|
+
};
|
|
8187
|
+
function patchMovesRows(held, fresh, order) {
|
|
8188
|
+
if (order.sortFields.length === 0 && !order.narrowed) return false;
|
|
8189
|
+
for (const row of held) {
|
|
8190
|
+
const next = fresh.get(row.id);
|
|
8191
|
+
if (!next) continue;
|
|
8192
|
+
const was = row.document ?? {};
|
|
8193
|
+
const now = next.document ?? {};
|
|
8194
|
+
if (order.narrowed) {
|
|
8195
|
+
if (!same(was, now)) return true;
|
|
8196
|
+
continue;
|
|
8197
|
+
}
|
|
8198
|
+
for (const field2 of order.sortFields) if (!same(was[field2], now[field2])) return true;
|
|
8199
|
+
}
|
|
8200
|
+
return false;
|
|
8048
8201
|
}
|
|
8049
8202
|
|
|
8050
8203
|
// src/react/hooks.ts
|
|
8051
8204
|
function useAsync(run, key, live) {
|
|
8052
8205
|
const client = useRecordsClient();
|
|
8053
8206
|
const holdKey = useHoldKey();
|
|
8054
|
-
const slot = (0,
|
|
8055
|
-
const entry = (0,
|
|
8207
|
+
const slot = (0, import_react4.useId)();
|
|
8208
|
+
const entry = (0, import_react4.useMemo)(
|
|
8056
8209
|
() => typeof window === "undefined" ? serverEntry(run, client) : entryFor(client, key, run, live ?? null),
|
|
8057
8210
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
8058
8211
|
[client, key]
|
|
8059
8212
|
);
|
|
8060
8213
|
entry.run = run;
|
|
8061
8214
|
entry.client = client;
|
|
8062
|
-
const
|
|
8063
|
-
(
|
|
8215
|
+
const seed = useSeedStore();
|
|
8216
|
+
if (seed && entry.snapshot.data === null && !entry.snapshot.error && !entry.started) {
|
|
8217
|
+
const outcome = (0, import_react4.use)(seed.run(`${identityOf(client)}|${key}`, run, client.config));
|
|
8218
|
+
if (outcome.seeded) seedEntry(entry, outcome.data, outcome.stale);
|
|
8219
|
+
}
|
|
8220
|
+
const snapshot = (0, import_react4.useSyncExternalStore)(entry.subscribe, entry.getSnapshot, entry.getSnapshot);
|
|
8221
|
+
(0, import_react4.useEffect)(() => {
|
|
8064
8222
|
acquireEntry(entry);
|
|
8065
8223
|
return () => releaseEntry(entry);
|
|
8066
8224
|
}, [entry]);
|
|
8067
|
-
(0,
|
|
8225
|
+
(0, import_react4.useEffect)(() => {
|
|
8068
8226
|
if (holdKey) pinToHold(holdKey, slot, entry);
|
|
8069
8227
|
}, [holdKey, slot, entry]);
|
|
8070
|
-
const lastData = (0,
|
|
8228
|
+
const lastData = (0, import_react4.useRef)(null);
|
|
8071
8229
|
if (snapshot.data !== null) lastData.current = snapshot.data;
|
|
8072
8230
|
const shown = snapshot.data === null && snapshot.loading && !snapshot.error && lastData.current !== null ? { ...snapshot, data: lastData.current } : snapshot;
|
|
8073
|
-
const reload = (0,
|
|
8074
|
-
const setData = (0,
|
|
8231
|
+
const reload = (0, import_react4.useCallback)(() => entry.refetch(), [entry]);
|
|
8232
|
+
const setData = (0, import_react4.useCallback)((update) => entry.setData(update), [entry]);
|
|
8075
8233
|
return { ...shown, reload, setData };
|
|
8076
8234
|
}
|
|
8235
|
+
function useSeededAnswer(key, run) {
|
|
8236
|
+
const client = useRecordsClient();
|
|
8237
|
+
const seed = useSeedStore();
|
|
8238
|
+
if (!seed || key === null) return void 0;
|
|
8239
|
+
const outcome = (0, import_react4.use)(seed.run(`${identityOf(client)}|own:${key}`, run, client.config));
|
|
8240
|
+
return outcome.seeded ? outcome.data : void 0;
|
|
8241
|
+
}
|
|
8077
8242
|
function serverEntry(run, client) {
|
|
8078
|
-
const
|
|
8079
|
-
return {
|
|
8243
|
+
const entry = {
|
|
8080
8244
|
key: "server",
|
|
8081
|
-
snapshot,
|
|
8245
|
+
snapshot: { data: null, loading: true, error: null },
|
|
8082
8246
|
run,
|
|
8083
8247
|
client,
|
|
8084
8248
|
subscribe: () => () => {
|
|
8085
8249
|
},
|
|
8086
|
-
|
|
8250
|
+
// Read through the entry: a page seed may answer it during this render (`seedEntry`).
|
|
8251
|
+
getSnapshot: () => entry.snapshot,
|
|
8087
8252
|
refetch: () => {
|
|
8088
8253
|
},
|
|
8089
8254
|
setData: () => {
|
|
8090
8255
|
}
|
|
8091
8256
|
};
|
|
8257
|
+
return entry;
|
|
8092
8258
|
}
|
|
8093
8259
|
function useTable(tableId) {
|
|
8094
8260
|
const revision = useShapeRevision(tableId);
|
|
8095
|
-
(0,
|
|
8261
|
+
(0, import_react4.useEffect)(() => {
|
|
8096
8262
|
if (tableId) registerShapeInterest(tableId);
|
|
8097
8263
|
}, [tableId]);
|
|
8098
8264
|
return useAsync(
|
|
@@ -8149,12 +8315,12 @@ function subscribeToShape(listener) {
|
|
|
8149
8315
|
};
|
|
8150
8316
|
}
|
|
8151
8317
|
function useShapeRevision(tableId) {
|
|
8152
|
-
const read = (0,
|
|
8153
|
-
return (0,
|
|
8318
|
+
const read = (0, import_react4.useCallback)(() => tableId ? shapeRevisions.get(tableId) ?? 0 : 0, [tableId]);
|
|
8319
|
+
return (0, import_react4.useSyncExternalStore)(subscribeToShape, read, () => 0);
|
|
8154
8320
|
}
|
|
8155
8321
|
function useFields(tableId, recordType) {
|
|
8156
8322
|
const revision = useShapeRevision(tableId);
|
|
8157
|
-
(0,
|
|
8323
|
+
(0, import_react4.useEffect)(() => {
|
|
8158
8324
|
if (tableId) registerShapeInterest(tableId);
|
|
8159
8325
|
}, [tableId]);
|
|
8160
8326
|
return useAsync(
|
|
@@ -8179,7 +8345,7 @@ async function answerOrRefusal(ask, where) {
|
|
|
8179
8345
|
}
|
|
8180
8346
|
}
|
|
8181
8347
|
function useReverseColumns(tableId) {
|
|
8182
|
-
const revision = (0,
|
|
8348
|
+
const revision = (0, import_react4.useSyncExternalStore)(subscribeToShape, () => anyShapeRevision, () => 0);
|
|
8183
8349
|
return useAsync(
|
|
8184
8350
|
async (client) => {
|
|
8185
8351
|
if (!tableId || !doorReady(client.config, DOORS.reverseColumns)) return { ok: true, data: [] };
|
|
@@ -8189,8 +8355,8 @@ function useReverseColumns(tableId) {
|
|
|
8189
8355
|
);
|
|
8190
8356
|
}
|
|
8191
8357
|
function useReverseLinks(tableId, columns, recordIds, limit = 3, offset = 0) {
|
|
8192
|
-
const [writes, setWrites] = (0,
|
|
8193
|
-
(0,
|
|
8358
|
+
const [writes, setWrites] = (0, import_react4.useState)(0);
|
|
8359
|
+
(0, import_react4.useEffect)(() => onRecordChanged(() => setWrites((n) => n + 1)), []);
|
|
8194
8360
|
const idsKey = recordIds.join(",");
|
|
8195
8361
|
const columnsKey = columns.map((c) => c.source_field_id).join(",");
|
|
8196
8362
|
return useAsync(
|
|
@@ -8217,7 +8383,7 @@ function useReverseLinks(tableId, columns, recordIds, limit = 3, offset = 0) {
|
|
|
8217
8383
|
tableId ? `reverse-links:${tableId}:${columnsKey}:${limit}:${offset}:${idsKey}:${writes}` : "reverse-links:none"
|
|
8218
8384
|
);
|
|
8219
8385
|
}
|
|
8220
|
-
function liveRowsFor(tableId) {
|
|
8386
|
+
function liveRowsFor(tableId, order = { sortFields: [], narrowed: false }) {
|
|
8221
8387
|
return (entry) => {
|
|
8222
8388
|
const client = entry.client;
|
|
8223
8389
|
const realtime = client.config.realtime;
|
|
@@ -8236,6 +8402,10 @@ function liveRowsFor(tableId) {
|
|
|
8236
8402
|
entry.refetch();
|
|
8237
8403
|
return;
|
|
8238
8404
|
}
|
|
8405
|
+
if (patchMovesRows(held, fresh, order)) {
|
|
8406
|
+
entry.refetch();
|
|
8407
|
+
return;
|
|
8408
|
+
}
|
|
8239
8409
|
entry.setData(
|
|
8240
8410
|
(current) => current === null ? current : {
|
|
8241
8411
|
...current,
|
|
@@ -8285,7 +8455,7 @@ function liveStatus(client, tableId) {
|
|
|
8285
8455
|
return { live, liveReason };
|
|
8286
8456
|
}
|
|
8287
8457
|
function useKeptPage(tableId, base) {
|
|
8288
|
-
const lastGood = (0,
|
|
8458
|
+
const lastGood = (0, import_react4.useRef)(null);
|
|
8289
8459
|
if (base.data !== null && !base.error) lastGood.current = { tableId, data: base.data };
|
|
8290
8460
|
if (base.error && base.data === null && lastGood.current && lastGood.current.tableId === tableId) {
|
|
8291
8461
|
return { ...base, data: lastGood.current.data };
|
|
@@ -8302,7 +8472,7 @@ function sameRowAnswer(a, b) {
|
|
|
8302
8472
|
}
|
|
8303
8473
|
}
|
|
8304
8474
|
function useSharedRows(state) {
|
|
8305
|
-
const held = (0,
|
|
8475
|
+
const held = (0, import_react4.useRef)({
|
|
8306
8476
|
source: null,
|
|
8307
8477
|
shared: null,
|
|
8308
8478
|
byId: /* @__PURE__ */ new Map()
|
|
@@ -8343,7 +8513,7 @@ function useRecords(tableId, options = {}) {
|
|
|
8343
8513
|
// on every render must not re-read the page on every render, and a parent
|
|
8344
8514
|
// that changes the question must re-read on the first one.
|
|
8345
8515
|
`records:${tableId ?? "none"}:${pageSize}:${page2}:${filterKey}:s${shape}`,
|
|
8346
|
-
liveRowsFor(tableId)
|
|
8516
|
+
liveRowsFor(tableId, pageOrderOf(void 0, filterKey !== "{}"))
|
|
8347
8517
|
);
|
|
8348
8518
|
const { live, liveReason } = liveStatus(useRecordsClient(), tableId);
|
|
8349
8519
|
return { ...useSharedRows(useKeptPage(tableId, base)), live, liveReason };
|
|
@@ -8371,14 +8541,14 @@ function useRecordPage(tableId, options = {}) {
|
|
|
8371
8541
|
return answered.ok ? { ok: true, data: { rows: answered.data.rows, total: answered.data.total, sortIgnored: answered.data.sort_ignored ?? [] } } : answered;
|
|
8372
8542
|
},
|
|
8373
8543
|
`page:${tableId ?? "none"}:${pageSize}:${page2}:${filterKey}:${search ?? ""}:${sortKey}:${viewId ?? ""}:s${shape}`,
|
|
8374
|
-
liveRowsFor(tableId)
|
|
8544
|
+
liveRowsFor(tableId, pageOrderOf(options.sort, filterKey !== "{}" || search !== null))
|
|
8375
8545
|
);
|
|
8376
8546
|
const { live, liveReason } = liveStatus(useRecordsClient(), tableId);
|
|
8377
8547
|
return { ...useSharedRows(useKeptPage(tableId, base)), live, liveReason };
|
|
8378
8548
|
}
|
|
8379
8549
|
function useRecordChangeRevision(recordId) {
|
|
8380
|
-
const [revision, setRevision] = (0,
|
|
8381
|
-
(0,
|
|
8550
|
+
const [revision, setRevision] = (0, import_react4.useState)(0);
|
|
8551
|
+
(0, import_react4.useEffect)(() => {
|
|
8382
8552
|
if (!recordId) return;
|
|
8383
8553
|
return onRecordChanged((changed) => {
|
|
8384
8554
|
if (changed === recordId) setRevision((n) => n + 1);
|
|
@@ -8429,10 +8599,10 @@ function liveRecordFor(recordId, tableId) {
|
|
|
8429
8599
|
}
|
|
8430
8600
|
function useRecordMutation() {
|
|
8431
8601
|
const client = useRecordsClient();
|
|
8432
|
-
const [saving, setSaving] = (0,
|
|
8433
|
-
const [error, setError] = (0,
|
|
8434
|
-
const [conflict, setConflict] = (0,
|
|
8435
|
-
const run = (0,
|
|
8602
|
+
const [saving, setSaving] = (0, import_react4.useState)(false);
|
|
8603
|
+
const [error, setError] = (0, import_react4.useState)(null);
|
|
8604
|
+
const [conflict, setConflict] = (0, import_react4.useState)(null);
|
|
8605
|
+
const run = (0, import_react4.useCallback)(
|
|
8436
8606
|
async (recordId, call) => {
|
|
8437
8607
|
setSaving(true);
|
|
8438
8608
|
setError(null);
|
|
@@ -8451,7 +8621,7 @@ function useRecordMutation() {
|
|
|
8451
8621
|
},
|
|
8452
8622
|
[]
|
|
8453
8623
|
);
|
|
8454
|
-
return (0,
|
|
8624
|
+
return (0, import_react4.useMemo)(
|
|
8455
8625
|
() => ({
|
|
8456
8626
|
write: (args) => run(null, () => client.recordWrite({ table_id: args.table_id, data: args.data })),
|
|
8457
8627
|
update: (args) => run(
|
|
@@ -8480,15 +8650,15 @@ function useTableArchive(tableId, options) {
|
|
|
8480
8650
|
const client = useRecordsClient();
|
|
8481
8651
|
const chunk = options?.chunk ?? TABLE_ARCHIVE_PASS;
|
|
8482
8652
|
const includeTable = options?.includeTable ?? true;
|
|
8483
|
-
const [progress, setProgress] = (0,
|
|
8484
|
-
const [running, setRunning] = (0,
|
|
8485
|
-
const [passes, setPasses] = (0,
|
|
8486
|
-
const [error, setError] = (0,
|
|
8487
|
-
const [interrupted, setInterrupted] = (0,
|
|
8488
|
-
const [chunkInUse, setChunkInUse] = (0,
|
|
8489
|
-
const [slowedDown, setSlowedDown] = (0,
|
|
8490
|
-
const cut = (0,
|
|
8491
|
-
const preview = (0,
|
|
8653
|
+
const [progress, setProgress] = (0, import_react4.useState)(null);
|
|
8654
|
+
const [running, setRunning] = (0, import_react4.useState)(false);
|
|
8655
|
+
const [passes, setPasses] = (0, import_react4.useState)(0);
|
|
8656
|
+
const [error, setError] = (0, import_react4.useState)(null);
|
|
8657
|
+
const [interrupted, setInterrupted] = (0, import_react4.useState)(false);
|
|
8658
|
+
const [chunkInUse, setChunkInUse] = (0, import_react4.useState)(chunk);
|
|
8659
|
+
const [slowedDown, setSlowedDown] = (0, import_react4.useState)(false);
|
|
8660
|
+
const cut = (0, import_react4.useRef)(false);
|
|
8661
|
+
const preview = (0, import_react4.useCallback)(async () => {
|
|
8492
8662
|
setError(null);
|
|
8493
8663
|
const answered = await client.tableArchive({ table_id: tableId, chunk: 0, includeTable });
|
|
8494
8664
|
if (!answered.ok) {
|
|
@@ -8499,7 +8669,7 @@ function useTableArchive(tableId, options) {
|
|
|
8499
8669
|
if (answered.data.in_progress) setInterrupted(true);
|
|
8500
8670
|
return answered.data;
|
|
8501
8671
|
}, [client, tableId, includeTable]);
|
|
8502
|
-
const loop = (0,
|
|
8672
|
+
const loop = (0, import_react4.useCallback)(async () => {
|
|
8503
8673
|
cut.current = false;
|
|
8504
8674
|
setRunning(true);
|
|
8505
8675
|
setError(null);
|
|
@@ -8536,7 +8706,7 @@ function useTableArchive(tableId, options) {
|
|
|
8536
8706
|
setRunning(false);
|
|
8537
8707
|
}
|
|
8538
8708
|
}, [client, tableId, chunk, includeTable]);
|
|
8539
|
-
return (0,
|
|
8709
|
+
return (0, import_react4.useMemo)(
|
|
8540
8710
|
() => ({
|
|
8541
8711
|
progress,
|
|
8542
8712
|
running,
|
|
@@ -8581,11 +8751,11 @@ function useEntityBackLinks(token, recordId, options) {
|
|
|
8581
8751
|
}) : Promise.resolve({ ok: true, data: null }),
|
|
8582
8752
|
`entity-back-links:${scope}`
|
|
8583
8753
|
);
|
|
8584
|
-
const [more, setMore] = (0,
|
|
8754
|
+
const [more, setMore] = (0, import_react4.useState)({ scope, items: [], cursor: void 0, busy: false, error: null });
|
|
8585
8755
|
const current = more.scope === scope ? more : { scope, items: [], cursor: void 0, busy: false, error: null };
|
|
8586
8756
|
const firstAnswer = first.data;
|
|
8587
8757
|
const cursor = current.cursor === void 0 ? firstAnswer?.next_cursor ?? null : current.cursor;
|
|
8588
|
-
const loadMore = (0,
|
|
8758
|
+
const loadMore = (0, import_react4.useCallback)(async () => {
|
|
8589
8759
|
if (!asking || !cursor) return;
|
|
8590
8760
|
setMore({ ...current, busy: true, error: null });
|
|
8591
8761
|
const answered = await client.entityBackLinks({
|
|
@@ -8607,7 +8777,7 @@ function useEntityBackLinks(token, recordId, options) {
|
|
|
8607
8777
|
error: null
|
|
8608
8778
|
});
|
|
8609
8779
|
}, [client, asking?.token, asking?.recordId, asking?.organizationId, limit, cursor, current, scope]);
|
|
8610
|
-
const reload = (0,
|
|
8780
|
+
const reload = (0, import_react4.useCallback)(() => {
|
|
8611
8781
|
setMore({ scope, items: [], cursor: void 0, busy: false, error: null });
|
|
8612
8782
|
first.reload();
|
|
8613
8783
|
}, [first, scope]);
|
|
@@ -8643,9 +8813,9 @@ function useEntityFieldRights(token) {
|
|
|
8643
8813
|
}
|
|
8644
8814
|
function useEntityFieldMutation() {
|
|
8645
8815
|
const client = useRecordsClient();
|
|
8646
|
-
const [saving, setSaving] = (0,
|
|
8647
|
-
const [error, setError] = (0,
|
|
8648
|
-
const run = (0,
|
|
8816
|
+
const [saving, setSaving] = (0, import_react4.useState)(false);
|
|
8817
|
+
const [error, setError] = (0, import_react4.useState)(null);
|
|
8818
|
+
const run = (0, import_react4.useCallback)(
|
|
8649
8819
|
async (call, whenRefused) => {
|
|
8650
8820
|
setSaving(true);
|
|
8651
8821
|
setError(null);
|
|
@@ -8660,7 +8830,7 @@ function useEntityFieldMutation() {
|
|
|
8660
8830
|
},
|
|
8661
8831
|
[]
|
|
8662
8832
|
);
|
|
8663
|
-
return (0,
|
|
8833
|
+
return (0, import_react4.useMemo)(
|
|
8664
8834
|
() => ({
|
|
8665
8835
|
declare: (args) => run(() => client.entityFieldDeclare({ token: args.token, spec: args.spec }), null),
|
|
8666
8836
|
update: (args) => run(
|
|
@@ -8686,9 +8856,9 @@ function useEntityFieldMutation() {
|
|
|
8686
8856
|
}
|
|
8687
8857
|
function useFieldMutation() {
|
|
8688
8858
|
const client = useRecordsClient();
|
|
8689
|
-
const [saving, setSaving] = (0,
|
|
8690
|
-
const [error, setError] = (0,
|
|
8691
|
-
const run = (0,
|
|
8859
|
+
const [saving, setSaving] = (0, import_react4.useState)(false);
|
|
8860
|
+
const [error, setError] = (0, import_react4.useState)(null);
|
|
8861
|
+
const run = (0, import_react4.useCallback)(
|
|
8692
8862
|
async (call, whenRefused) => {
|
|
8693
8863
|
setSaving(true);
|
|
8694
8864
|
setError(null);
|
|
@@ -8703,14 +8873,14 @@ function useFieldMutation() {
|
|
|
8703
8873
|
},
|
|
8704
8874
|
[]
|
|
8705
8875
|
);
|
|
8706
|
-
const announce = (0,
|
|
8876
|
+
const announce = (0, import_react4.useCallback)((tableId) => {
|
|
8707
8877
|
if (tableId) {
|
|
8708
8878
|
tableShapeChanged(tableId);
|
|
8709
8879
|
return;
|
|
8710
8880
|
}
|
|
8711
8881
|
for (const id of [...shapeRevisions.keys()]) tableShapeChanged(id);
|
|
8712
8882
|
}, []);
|
|
8713
|
-
return (0,
|
|
8883
|
+
return (0, import_react4.useMemo)(
|
|
8714
8884
|
() => ({
|
|
8715
8885
|
declare: async (args) => {
|
|
8716
8886
|
const made = await run(
|
|
@@ -8747,9 +8917,9 @@ function useFieldMutation() {
|
|
|
8747
8917
|
}
|
|
8748
8918
|
function useMergeField(key, state) {
|
|
8749
8919
|
const client = useRecordsClient();
|
|
8750
|
-
const [resolution, setResolution] = (0,
|
|
8920
|
+
const [resolution, setResolution] = (0, import_react4.useState)(null);
|
|
8751
8921
|
const resolver = client.config.resolver;
|
|
8752
|
-
(0,
|
|
8922
|
+
(0, import_react4.useEffect)(() => {
|
|
8753
8923
|
if (!key) {
|
|
8754
8924
|
setResolution(null);
|
|
8755
8925
|
return;
|
|
@@ -8784,11 +8954,11 @@ function useMergeField(key, state) {
|
|
|
8784
8954
|
}
|
|
8785
8955
|
|
|
8786
8956
|
// src/react/entity-reference.ts
|
|
8787
|
-
var
|
|
8957
|
+
var import_react5 = require("react");
|
|
8788
8958
|
function useEntityReferenceKinds() {
|
|
8789
8959
|
const client = useRecordsClient();
|
|
8790
|
-
const [state, setState] = (0,
|
|
8791
|
-
(0,
|
|
8960
|
+
const [state, setState] = (0, import_react5.useState)({ data: null, loading: true, error: null });
|
|
8961
|
+
(0, import_react5.useEffect)(() => {
|
|
8792
8962
|
let live = true;
|
|
8793
8963
|
void entityReferenceKinds(client.config.dataSource).then((res) => {
|
|
8794
8964
|
if (!live) return;
|
|
@@ -8803,8 +8973,8 @@ function useEntityReferenceKinds() {
|
|
|
8803
8973
|
function useEntityReferenceWords(refs) {
|
|
8804
8974
|
const client = useRecordsClient();
|
|
8805
8975
|
const key = refs.map((r) => `${r.token}:${r.id}`).join(",");
|
|
8806
|
-
const [state, setState] = (0,
|
|
8807
|
-
(0,
|
|
8976
|
+
const [state, setState] = (0, import_react5.useState)({ data: null, loading: refs.length > 0, error: null });
|
|
8977
|
+
(0, import_react5.useEffect)(() => {
|
|
8808
8978
|
let live = true;
|
|
8809
8979
|
void entityReferenceWords(client.config.dataSource, client.config.organizationId, refs).then((res) => {
|
|
8810
8980
|
if (!live) return;
|
|
@@ -8819,8 +8989,8 @@ function useEntityReferenceWords(refs) {
|
|
|
8819
8989
|
function useEntityReferenceSearch(tokens, search, enabled = true) {
|
|
8820
8990
|
const client = useRecordsClient();
|
|
8821
8991
|
const key = `${tokens.join(",")}|${search.trim()}|${enabled ? 1 : 0}`;
|
|
8822
|
-
const [state, setState] = (0,
|
|
8823
|
-
(0,
|
|
8992
|
+
const [state, setState] = (0, import_react5.useState)({ data: null, loading: enabled && tokens.length > 0, error: null });
|
|
8993
|
+
(0, import_react5.useEffect)(() => {
|
|
8824
8994
|
if (!enabled || tokens.length === 0) {
|
|
8825
8995
|
setState({ data: [], loading: false, error: null });
|
|
8826
8996
|
return;
|
|
@@ -8842,7 +9012,7 @@ function useEntityReferenceSearch(tokens, search, enabled = true) {
|
|
|
8842
9012
|
}
|
|
8843
9013
|
|
|
8844
9014
|
// src/react/useAppTable.ts
|
|
8845
|
-
var
|
|
9015
|
+
var import_react6 = require("react");
|
|
8846
9016
|
|
|
8847
9017
|
// src/core/declareTable.ts
|
|
8848
9018
|
function tokenFor(name) {
|
|
@@ -9137,16 +9307,16 @@ function useAppTable(def, options = {}) {
|
|
|
9137
9307
|
const client = useRecordsClient();
|
|
9138
9308
|
const narrowed = options.organizationId ?? null;
|
|
9139
9309
|
const writeOrg = narrowed ?? client.config.organizationId;
|
|
9140
|
-
const [rows, setRows] = (0,
|
|
9141
|
-
const [total, setTotal] = (0,
|
|
9142
|
-
const [truncated, setTruncated] = (0,
|
|
9143
|
-
const [loading, setLoading] = (0,
|
|
9144
|
-
const [error, setError] = (0,
|
|
9145
|
-
const [status, setStatus] = (0,
|
|
9146
|
-
const [revision, setRevision] = (0,
|
|
9147
|
-
const rowsRef = (0,
|
|
9310
|
+
const [rows, setRows] = (0, import_react6.useState)([]);
|
|
9311
|
+
const [total, setTotal] = (0, import_react6.useState)(null);
|
|
9312
|
+
const [truncated, setTruncated] = (0, import_react6.useState)(false);
|
|
9313
|
+
const [loading, setLoading] = (0, import_react6.useState)(true);
|
|
9314
|
+
const [error, setError] = (0, import_react6.useState)(null);
|
|
9315
|
+
const [status, setStatus] = (0, import_react6.useState)(null);
|
|
9316
|
+
const [revision, setRevision] = (0, import_react6.useState)(0);
|
|
9317
|
+
const rowsRef = (0, import_react6.useRef)([]);
|
|
9148
9318
|
rowsRef.current = rows;
|
|
9149
|
-
(0,
|
|
9319
|
+
(0, import_react6.useEffect)(() => {
|
|
9150
9320
|
let live = true;
|
|
9151
9321
|
setLoading(true);
|
|
9152
9322
|
(async () => {
|
|
@@ -9178,8 +9348,8 @@ function useAppTable(def, options = {}) {
|
|
|
9178
9348
|
live = false;
|
|
9179
9349
|
};
|
|
9180
9350
|
}, [client, def.slug, def.kept_for, def.specHash, writeOrg, narrowed, revision]);
|
|
9181
|
-
const reload = (0,
|
|
9182
|
-
const upsert = (0,
|
|
9351
|
+
const reload = (0, import_react6.useCallback)(() => setRevision((n) => n + 1), []);
|
|
9352
|
+
const upsert = (0, import_react6.useCallback)(
|
|
9183
9353
|
async (data, upsertOptions = {}) => {
|
|
9184
9354
|
if (!writeOrg) {
|
|
9185
9355
|
return { ok: false, error: { code: "invalid_argument", message: `${def.name}: no organization to write to.` } };
|
|
@@ -9190,7 +9360,7 @@ function useAppTable(def, options = {}) {
|
|
|
9190
9360
|
},
|
|
9191
9361
|
[client, def, writeOrg, reload]
|
|
9192
9362
|
);
|
|
9193
|
-
const remove = (0,
|
|
9363
|
+
const remove = (0, import_react6.useCallback)(
|
|
9194
9364
|
async (rowId) => {
|
|
9195
9365
|
const org = rowsRef.current.find((r) => r._id === rowId)?._organizationId ?? writeOrg;
|
|
9196
9366
|
const answer = await removeAppRow(client, def, rowId, { organizationId: org });
|
|
@@ -9207,7 +9377,7 @@ function archivedTableOf(error) {
|
|
|
9207
9377
|
}
|
|
9208
9378
|
|
|
9209
9379
|
// src/react/useStoreTable.ts
|
|
9210
|
-
var
|
|
9380
|
+
var import_react8 = require("react");
|
|
9211
9381
|
|
|
9212
9382
|
// src/app-table/store-table.ts
|
|
9213
9383
|
function storeTable(def) {
|
|
@@ -10442,7 +10612,7 @@ function createTableDataPort({ client, aliases }) {
|
|
|
10442
10612
|
}
|
|
10443
10613
|
|
|
10444
10614
|
// src/data/react.tsx
|
|
10445
|
-
var
|
|
10615
|
+
var import_react7 = require("react");
|
|
10446
10616
|
var import_react_query = require("@tanstack/react-query");
|
|
10447
10617
|
var RECORDS_QUERY_ROOT = "@ai-matrx/records";
|
|
10448
10618
|
var DATA_LIVE_GRACE_MS = 3e4;
|
|
@@ -10489,13 +10659,13 @@ function retryable(failureCount, thrown) {
|
|
|
10489
10659
|
const code = thrown instanceof DataRefusal ? thrown.error.code : "unreachable";
|
|
10490
10660
|
return (code === "unreachable" || code === "timed_out") && failureCount < 2;
|
|
10491
10661
|
}
|
|
10492
|
-
var DataPortContext = (0,
|
|
10662
|
+
var DataPortContext = (0, import_react7.createContext)(null);
|
|
10493
10663
|
function hostEvents(port) {
|
|
10494
10664
|
return { on: (event, listener) => port.subscribe(event, listener) };
|
|
10495
10665
|
}
|
|
10496
10666
|
var warnedNotLive = false;
|
|
10497
10667
|
function useDataPort(scope) {
|
|
10498
|
-
const held = (0,
|
|
10668
|
+
const held = (0, import_react7.useContext)(DataPortContext);
|
|
10499
10669
|
if (scope) return scope;
|
|
10500
10670
|
if (!held) {
|
|
10501
10671
|
throw new Error(
|
|
@@ -10781,7 +10951,7 @@ function acquireLive(qc, port, events, portKey, alias) {
|
|
|
10781
10951
|
}
|
|
10782
10952
|
var FALLBACK_KEY = /* @__PURE__ */ Symbol.for("@ai-matrx/records/data-query-client");
|
|
10783
10953
|
function useRecordsQueryClient() {
|
|
10784
|
-
const provided = (0,
|
|
10954
|
+
const provided = (0, import_react7.useContext)(import_react_query.QueryClientContext);
|
|
10785
10955
|
if (provided) return provided;
|
|
10786
10956
|
const g = globalThis;
|
|
10787
10957
|
let held = g[FALLBACK_KEY];
|
|
@@ -10794,7 +10964,7 @@ function useRecordsQueryClient() {
|
|
|
10794
10964
|
function useLive(alias, scope) {
|
|
10795
10965
|
const qc = useRecordsQueryClient();
|
|
10796
10966
|
const { port, portKey, events } = useDataPort(scope);
|
|
10797
|
-
(0,
|
|
10967
|
+
(0, import_react7.useEffect)(() => {
|
|
10798
10968
|
if (!alias) return;
|
|
10799
10969
|
return acquireLive(qc, port, events, portKey, alias);
|
|
10800
10970
|
}, [qc, port, events, portKey, alias]);
|
|
@@ -10814,7 +10984,7 @@ function useDataRows(alias, query = {}, scope) {
|
|
|
10814
10984
|
},
|
|
10815
10985
|
qc
|
|
10816
10986
|
);
|
|
10817
|
-
const rows = (0,
|
|
10987
|
+
const rows = (0, import_react7.useMemo)(() => {
|
|
10818
10988
|
const seen = /* @__PURE__ */ new Set();
|
|
10819
10989
|
const out = [];
|
|
10820
10990
|
for (const page2 of q.data?.pages ?? []) {
|
|
@@ -10826,11 +10996,11 @@ function useDataRows(alias, query = {}, scope) {
|
|
|
10826
10996
|
}
|
|
10827
10997
|
return out;
|
|
10828
10998
|
}, [q.data]);
|
|
10829
|
-
const want = (0,
|
|
10999
|
+
const want = (0, import_react7.useRef)({ key: "", pages: 0 });
|
|
10830
11000
|
const keyHash = (0, import_react_query.hashKey)(rowsKey);
|
|
10831
11001
|
const loaded = q.data?.pages.length ?? 0;
|
|
10832
11002
|
const { isFetching, hasNextPage, isFetchNextPageError, fetchNextPage } = q;
|
|
10833
|
-
(0,
|
|
11003
|
+
(0, import_react7.useEffect)(() => {
|
|
10834
11004
|
const w = want.current;
|
|
10835
11005
|
if (w.key !== keyHash || isFetching || loaded >= w.pages) return;
|
|
10836
11006
|
if (!hasNextPage || isFetchNextPageError) {
|
|
@@ -10870,7 +11040,7 @@ function drawPatch(before, patch) {
|
|
|
10870
11040
|
function useDataMutations(alias, scope) {
|
|
10871
11041
|
const qc = useRecordsQueryClient();
|
|
10872
11042
|
const { port, portKey } = useDataPort(scope);
|
|
10873
|
-
return (0,
|
|
11043
|
+
return (0, import_react7.useMemo)(() => {
|
|
10874
11044
|
const snapshotRows = () => qc.getQueriesData({ queryKey: dataKeys.rowsPrefix(portKey, alias) });
|
|
10875
11045
|
const putBack = (snap) => {
|
|
10876
11046
|
for (const [key, data] of snap) qc.setQueryData(key, data);
|
|
@@ -10972,7 +11142,7 @@ function toNamed(table, row) {
|
|
|
10972
11142
|
function useStoreTable(table, options = {}) {
|
|
10973
11143
|
const client = useRecordsClient();
|
|
10974
11144
|
const alias = table.id;
|
|
10975
|
-
const scope = (0,
|
|
11145
|
+
const scope = (0, import_react8.useMemo)(
|
|
10976
11146
|
() => {
|
|
10977
11147
|
const port = createTableDataPort({ client, aliases: { [alias]: { kind: "table", tableId: table.id, organizationId: table.organizationId, label: table.name } } });
|
|
10978
11148
|
return { port, events: hostEvents(port), portKey: `store-table|${client.config.organizationId ?? "-"}|${client.config.actor.user_id ?? "-"}` };
|
|
@@ -10980,7 +11150,7 @@ function useStoreTable(table, options = {}) {
|
|
|
10980
11150
|
[client, alias, table.id, table.organizationId, table.name]
|
|
10981
11151
|
);
|
|
10982
11152
|
const asked = JSON.stringify(options);
|
|
10983
|
-
const built = (0,
|
|
11153
|
+
const built = (0, import_react8.useMemo)(() => {
|
|
10984
11154
|
const where = [];
|
|
10985
11155
|
for (const [name, value] of Object.entries(options.where ?? {})) {
|
|
10986
11156
|
const column = table.columns[name];
|
|
@@ -11007,10 +11177,10 @@ function useStoreTable(table, options = {}) {
|
|
|
11007
11177
|
const limit = Math.min(options.limit ?? STORE_ROWS_CEILING, STORE_ROWS_CEILING);
|
|
11008
11178
|
const read = useDataRows(alias, built.ok ? built.data : { pageSize: 1 }, scope);
|
|
11009
11179
|
const write = useDataMutations(alias, scope);
|
|
11010
|
-
(0,
|
|
11180
|
+
(0, import_react8.useEffect)(() => {
|
|
11011
11181
|
if (built.ok && read.hasMore && !read.loadingMore && !read.loading && !read.error && read.rows.length < limit) read.loadMore();
|
|
11012
11182
|
}, [built.ok, read.hasMore, read.loadingMore, read.loading, read.error, read.rows.length, limit, read]);
|
|
11013
|
-
const rows = (0,
|
|
11183
|
+
const rows = (0, import_react8.useMemo)(() => read.rows.slice(0, limit).filter((r) => r["_pending"] !== true).map((r) => toNamed(table, r)), [read.rows, limit, table]);
|
|
11014
11184
|
const total = built.ok ? read.total : null;
|
|
11015
11185
|
return {
|
|
11016
11186
|
rows: built.ok ? rows : [],
|