@ai-matrx/records 0.76.4 → 0.76.6

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.
@@ -43083,11 +43083,12 @@ function createTableDataPort({ client, aliases }) {
43083
43083
  }
43084
43084
 
43085
43085
  // src/data/react.tsx
43086
- import { createContext as createContext3, createElement as createElement3, useContext as useContext3, useEffect as useEffect5, useMemo as useMemo3 } from "react";
43086
+ import { createContext as createContext3, createElement as createElement3, useContext as useContext3, useEffect as useEffect5, useMemo as useMemo3, useRef as useRef4 } from "react";
43087
43087
  import {
43088
43088
  QueryClient as QueryClientClass,
43089
43089
  QueryClientContext,
43090
43090
  QueryClientProvider,
43091
+ hashKey,
43091
43092
  useInfiniteQuery,
43092
43093
  useQuery
43093
43094
  } from "@tanstack/react-query";
@@ -43158,7 +43159,64 @@ function forEachRowsEntry(qc, portKey, alias, fn) {
43158
43159
  if (next && next !== data) qc.setQueryData(key, next);
43159
43160
  }
43160
43161
  }
43162
+ var LANDED_MS = 3e4;
43163
+ var LANDED_KEY = /* @__PURE__ */ Symbol.for("@ai-matrx/records/data-landed");
43164
+ function landedHome(qc) {
43165
+ const holder = qc;
43166
+ let home = holder[LANDED_KEY];
43167
+ if (!home) {
43168
+ const made = { byAlias: /* @__PURE__ */ new Map(), unsubscribe: () => {
43169
+ } };
43170
+ made.unsubscribe = qc.getQueryCache().subscribe((event) => {
43171
+ if (event.type !== "updated" || event.action.type !== "success") return;
43172
+ const key = event.query.queryKey;
43173
+ if (key[0] !== RECORDS_QUERY_ROOT || key[1] !== "data" || key[3] !== "alias" || key[5] !== "rows") return;
43174
+ const portKey = String(key[2]);
43175
+ const alias = String(key[4]);
43176
+ const landed = made.byAlias.get(`${portKey}${alias}`);
43177
+ if (!landed || landed.size === 0) return;
43178
+ reapplyLanded(qc, event.query.queryKey, landed);
43179
+ });
43180
+ holder[LANDED_KEY] = made;
43181
+ home = made;
43182
+ }
43183
+ return home;
43184
+ }
43185
+ function remember(qc, portKey, alias, id, row) {
43186
+ const home = landedHome(qc);
43187
+ const key = `${portKey}${alias}`;
43188
+ let landed = home.byAlias.get(key);
43189
+ if (!landed) home.byAlias.set(key, landed = /* @__PURE__ */ new Map());
43190
+ const now = Date.now();
43191
+ for (const [oldId, entry] of landed) if (now - entry.at > LANDED_MS) landed.delete(oldId);
43192
+ landed.set(id, { row, at: now });
43193
+ }
43194
+ function reapplyLanded(qc, key, landed) {
43195
+ const data = qc.getQueryData(key);
43196
+ if (!data) return;
43197
+ const now = Date.now();
43198
+ let changed = false;
43199
+ const pages = data.pages.map((page2) => {
43200
+ let rows = null;
43201
+ page2.rows.forEach((r, i) => {
43202
+ const entry = landed.get(r._id);
43203
+ if (!entry || now - entry.at > LANDED_MS) return;
43204
+ if (entry.row === null) {
43205
+ rows ??= page2.rows.slice();
43206
+ rows[i] = null;
43207
+ } else if (entry.row._version > r._version) {
43208
+ rows ??= page2.rows.slice();
43209
+ rows[i] = entry.row;
43210
+ }
43211
+ });
43212
+ if (!rows) return page2;
43213
+ changed = true;
43214
+ return { ...page2, rows: rows.filter((r) => r !== null) };
43215
+ });
43216
+ if (changed) qc.setQueryData(key, { ...data, pages });
43217
+ }
43161
43218
  function patchRow(qc, portKey, alias, row, options = {}) {
43219
+ if (options.fromStore) remember(qc, portKey, alias, row._id, row);
43162
43220
  let held = false;
43163
43221
  forEachRowsEntry(qc, portKey, alias, (_key, data) => {
43164
43222
  let changed = false;
@@ -43179,7 +43237,8 @@ function patchRow(qc, portKey, alias, row, options = {}) {
43179
43237
  if (options.force || !current || current._version <= row._version) qc.setQueryData(rowKey, row);
43180
43238
  return held;
43181
43239
  }
43182
- function dropRow(qc, portKey, alias, id) {
43240
+ function dropRow(qc, portKey, alias, id, options = {}) {
43241
+ if (options.fromStore) remember(qc, portKey, alias, id, null);
43183
43242
  forEachRowsEntry(qc, portKey, alias, (_key, data) => {
43184
43243
  let changed = false;
43185
43244
  const pages = data.pages.map((page2) => {
@@ -43229,8 +43288,52 @@ async function sourceKind(qc, port, portKey, alias) {
43229
43288
  return null;
43230
43289
  }
43231
43290
  }
43291
+ var DEFERRED_KEY = /* @__PURE__ */ Symbol.for("@ai-matrx/records/data-deferred-rereads");
43292
+ var OWED_KEY = /* @__PURE__ */ Symbol.for("@ai-matrx/records/data-owed-pages");
43293
+ function owedPages(qc) {
43294
+ const holder = qc;
43295
+ return holder[OWED_KEY] ??= /* @__PURE__ */ new Map();
43296
+ }
43297
+ function owedPage(qc, hash) {
43298
+ const owed = owedPages(qc).get(hash);
43299
+ if (!owed) return null;
43300
+ const query = qc.getQueryCache().get(hash);
43301
+ const data = query?.state.data;
43302
+ const last = data?.pages[data.pages.length - 1];
43303
+ if (!query || query.state.status === "error" || !data || data.pages.length >= owed.pages || !last?.cursor) {
43304
+ owedPages(qc).delete(hash);
43305
+ return null;
43306
+ }
43307
+ return owed;
43308
+ }
43309
+ function rereadList(qc, key) {
43310
+ const query = qc.getQueryCache().find({ queryKey: key, exact: true });
43311
+ if (!query || query.state.fetchStatus !== "fetching" && !owedPage(qc, query.queryHash)) {
43312
+ void qc.invalidateQueries({ queryKey: key, exact: true });
43313
+ return;
43314
+ }
43315
+ const holder = qc;
43316
+ const waiting = holder[DEFERRED_KEY] ??= /* @__PURE__ */ new Set();
43317
+ if (waiting.has(query.queryHash)) return;
43318
+ waiting.add(query.queryHash);
43319
+ const settle = () => {
43320
+ if (query.state.fetchStatus === "fetching") return;
43321
+ const owed = owedPage(qc, query.queryHash);
43322
+ if (owed) {
43323
+ owed.fetchNext();
43324
+ return;
43325
+ }
43326
+ stop();
43327
+ waiting.delete(query.queryHash);
43328
+ void qc.invalidateQueries({ queryKey: key, exact: true });
43329
+ };
43330
+ const stop = qc.getQueryCache().subscribe((event) => {
43331
+ if (event.query === query) settle();
43332
+ });
43333
+ settle();
43334
+ }
43232
43335
  function rereadOrCount(qc, key, data, count) {
43233
- if (data.pages.length <= REREAD_PAGES_MAX) void qc.invalidateQueries({ queryKey: key, exact: true });
43336
+ if (data.pages.length <= REREAD_PAGES_MAX) rereadList(qc, key);
43234
43337
  else qc.setQueryData(key, { ...data, newer: (data.newer ?? 0) + count });
43235
43338
  }
43236
43339
  function placeUnseen(qc, portKey, alias, rows, kind) {
@@ -43255,8 +43358,8 @@ async function rereadIds(qc, port, portKey, alias, ids) {
43255
43358
  for (const [id, answer] of answers) {
43256
43359
  if (!answer.ok) continue;
43257
43360
  if (answer.data === null) {
43258
- dropRow(qc, portKey, alias, id);
43259
- } else if (!patchRow(qc, portKey, alias, answer.data)) {
43361
+ dropRow(qc, portKey, alias, id, { fromStore: true });
43362
+ } else if (!patchRow(qc, portKey, alias, answer.data, { fromStore: true })) {
43260
43363
  unseen.push(answer.data);
43261
43364
  }
43262
43365
  }
@@ -43265,10 +43368,10 @@ async function rereadIds(qc, port, portKey, alias, ids) {
43265
43368
  function rereadUnknown(qc, portKey, alias) {
43266
43369
  for (const [key, data] of qc.getQueriesData({ queryKey: dataKeys.rowsPrefix(portKey, alias) })) {
43267
43370
  if (!data || data.pages.length === 0) {
43268
- void qc.invalidateQueries({ queryKey: key, exact: true });
43371
+ rereadList(qc, key);
43269
43372
  continue;
43270
43373
  }
43271
- if (data.pages.length <= REREAD_PAGES_MAX) void qc.invalidateQueries({ queryKey: key, exact: true });
43374
+ if (data.pages.length <= REREAD_PAGES_MAX) rereadList(qc, key);
43272
43375
  else qc.setQueryData(key, { ...data, newer: Math.max(data.newer ?? 0, 1) });
43273
43376
  }
43274
43377
  void qc.invalidateQueries({ queryKey: [...dataKeys.alias(portKey, alias), "row"] });
@@ -43348,9 +43451,10 @@ function useDataRows(alias, query = {}, scope) {
43348
43451
  const { port, portKey } = useDataPort(scope);
43349
43452
  const qc = useRecordsQueryClient();
43350
43453
  useLive(alias, scope);
43454
+ const rowsKey = dataKeys.rows(portKey, alias, query);
43351
43455
  const q = useInfiniteQuery(
43352
43456
  {
43353
- queryKey: dataKeys.rows(portKey, alias, query),
43457
+ queryKey: rowsKey,
43354
43458
  queryFn: async ({ pageParam }) => unwrap(await port.list(alias, query, pageParam ?? void 0)),
43355
43459
  initialPageParam: null,
43356
43460
  getNextPageParam: (last) => last.cursor ?? void 0,
@@ -43370,6 +43474,20 @@ function useDataRows(alias, query = {}, scope) {
43370
43474
  }
43371
43475
  return out;
43372
43476
  }, [q.data]);
43477
+ const want = useRef4({ key: "", pages: 0 });
43478
+ const keyHash = hashKey(rowsKey);
43479
+ const loaded = q.data?.pages.length ?? 0;
43480
+ const { isFetching, hasNextPage, isFetchNextPageError, fetchNextPage } = q;
43481
+ useEffect5(() => {
43482
+ const w = want.current;
43483
+ if (w.key !== keyHash || isFetching || loaded >= w.pages) return;
43484
+ if (!hasNextPage || isFetchNextPageError) {
43485
+ want.current = { key: keyHash, pages: 0 };
43486
+ owedPages(qc).delete(keyHash);
43487
+ return;
43488
+ }
43489
+ void fetchNextPage({ cancelRefetch: false });
43490
+ }, [qc, keyHash, isFetching, loaded, hasNextPage, isFetchNextPageError, fetchNextPage]);
43373
43491
  return {
43374
43492
  rows,
43375
43493
  total: q.data?.pages[0]?.total ?? null,
@@ -43378,7 +43496,10 @@ function useDataRows(alias, query = {}, scope) {
43378
43496
  hasMore: Boolean(q.hasNextPage),
43379
43497
  error: asRecordsError(q.error),
43380
43498
  loadMore: () => {
43381
- if (q.hasNextPage && !q.isFetchingNextPage) void q.fetchNextPage();
43499
+ if (!q.hasNextPage || q.isFetchingNextPage) return;
43500
+ want.current = { key: keyHash, pages: loaded + 1 };
43501
+ owedPages(qc).set(keyHash, { pages: loaded + 1, fetchNext: () => void q.fetchNextPage({ cancelRefetch: false }) });
43502
+ if (!q.isFetching) void q.fetchNextPage({ cancelRefetch: false });
43382
43503
  },
43383
43504
  newer: q.data?.newer ?? 0,
43384
43505
  refresh: () => void q.refetch()
@@ -43436,7 +43557,7 @@ function useDataMutations(alias, scope) {
43436
43557
  if (before) patchRow(qc, portKey, alias, drawPatch(before, patch), { force: true });
43437
43558
  const answer = await port.update(alias, id, patch, baseVersion);
43438
43559
  if (answer.ok) {
43439
- patchRow(qc, portKey, alias, answer.data, { force: true });
43560
+ patchRow(qc, portKey, alias, answer.data, { force: true, fromStore: true });
43440
43561
  return answer;
43441
43562
  }
43442
43563
  if (before) patchRow(qc, portKey, alias, before, { force: true });