@ai-matrx/records-ui 0.110.4 → 0.110.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.
package/dist/index.cjs CHANGED
@@ -1702,12 +1702,33 @@ function inColumnWords(error, fields) {
1702
1702
 
1703
1703
  // src/askOnce.ts
1704
1704
  var asked = /* @__PURE__ */ new WeakMap();
1705
- function askOnce(client, key, ask, freshMs) {
1705
+ var byPerson = /* @__PURE__ */ new WeakMap();
1706
+ function heldFor(client) {
1707
+ const config = client.config;
1708
+ const source = config?.dataSource;
1709
+ if (source && typeof source === "object" && config?.actor) {
1710
+ const who = [config.actor.actor ?? "-", config.actor.user_id ?? "-", config.actor.on_behalf_of ?? "-"].join("|");
1711
+ let persons = byPerson.get(source);
1712
+ if (!persons) {
1713
+ persons = /* @__PURE__ */ new Map();
1714
+ byPerson.set(source, persons);
1715
+ }
1716
+ let held2 = persons.get(who);
1717
+ if (!held2) {
1718
+ held2 = /* @__PURE__ */ new Map();
1719
+ persons.set(who, held2);
1720
+ }
1721
+ return held2;
1722
+ }
1706
1723
  let held = asked.get(client);
1707
1724
  if (!held) {
1708
1725
  held = /* @__PURE__ */ new Map();
1709
1726
  asked.set(client, held);
1710
1727
  }
1728
+ return held;
1729
+ }
1730
+ function askOnce(client, key, ask, freshMs) {
1731
+ const held = heldFor(client);
1711
1732
  const now = Date.now();
1712
1733
  const kept = held.get(key);
1713
1734
  if (kept && now - kept.at <= freshMs) return kept.answer;
@@ -1725,8 +1746,7 @@ function askOnce(client, key, ask, freshMs) {
1725
1746
  return answer;
1726
1747
  }
1727
1748
  function forgetAsked(client, prefix) {
1728
- const held = asked.get(client);
1729
- if (!held) return;
1749
+ const held = heldFor(client);
1730
1750
  for (const key of [...held.keys()]) if (key.startsWith(prefix)) held.delete(key);
1731
1751
  }
1732
1752
  var FIELD_OPTIONS_FRESH_MS = 2e3;
@@ -3382,6 +3402,12 @@ function asRefusal(thrown, sentence2, remedy, code = "internal") {
3382
3402
  return refusalFromThrown(thrown, sentence2, remedy, code);
3383
3403
  }
3384
3404
 
3405
+ // src/rowVersion.ts
3406
+ function ownVersion(row) {
3407
+ const v = row.version;
3408
+ return typeof v === "number" ? v : null;
3409
+ }
3410
+
3385
3411
  // src/recordVersions.ts
3386
3412
  var STALE_MOVE_LABEL = "Changed by someone else";
3387
3413
  var VERSION_UNREAD_LABEL = "Could not check for changes";
@@ -3398,10 +3424,6 @@ function isVersionUnread(error) {
3398
3424
  function isChangedElsewhere(error) {
3399
3425
  return error?.code === "stale_write";
3400
3426
  }
3401
- function ownVersion(row) {
3402
- const v = row.version;
3403
- return typeof v === "number" ? v : null;
3404
- }
3405
3427
  function signatureOf(row) {
3406
3428
  const own3 = ownVersion(row);
3407
3429
  if (own3 !== null) return `v${own3}`;
@@ -3411,6 +3433,7 @@ function signatureOf(row) {
3411
3433
  return String(Math.random());
3412
3434
  }
3413
3435
  }
3436
+ var HEADERS_SHARED_MS = 3e3;
3414
3437
  function useRecordVersions(client, rows, mayRead) {
3415
3438
  const versions = (0, import_react13.useRef)(/* @__PURE__ */ new Map());
3416
3439
  const drawn = (0, import_react13.useRef)(/* @__PURE__ */ new Map());
@@ -3428,7 +3451,7 @@ function useRecordVersions(client, rows, mayRead) {
3428
3451
  unread.current.delete(id);
3429
3452
  };
3430
3453
  const readHeaders = (0, import_react13.useCallback)(
3431
- (toRead) => {
3454
+ (toRead, shared = false) => {
3432
3455
  if (toRead.length === 0) return;
3433
3456
  generation.current += 1;
3434
3457
  const gen = generation.current;
@@ -3436,7 +3459,8 @@ function useRecordVersions(client, rows, mayRead) {
3436
3459
  versions.current.delete(id);
3437
3460
  unread.current.add(id);
3438
3461
  };
3439
- const read = client.recordHeaders({ ids: toRead }).then(
3462
+ const asking = shared ? askOnce(client, `record_headers:${toRead.join(",")}`, () => client.recordHeaders({ ids: toRead }), HEADERS_SHARED_MS) : client.recordHeaders({ ids: toRead });
3463
+ const read = asking.then(
3440
3464
  (res) => {
3441
3465
  const found = /* @__PURE__ */ new Set();
3442
3466
  if (res.ok) {
@@ -3469,7 +3493,7 @@ function useRecordVersions(client, rows, mayRead) {
3469
3493
  if (own3 !== null) raise(row.id, own3);
3470
3494
  else toRead.push(row.id);
3471
3495
  }
3472
- readHeaders(toRead);
3496
+ readHeaders(toRead, true);
3473
3497
  }, [readHeaders, key]);
3474
3498
  const refresh = (0, import_react13.useCallback)((ids) => readHeaders([...ids]), [readHeaders]);
3475
3499
  const seen = (0, import_react13.useCallback)(async (id) => {
@@ -7439,6 +7463,21 @@ var import_react40 = require("react");
7439
7463
 
7440
7464
  // src/firstPage.ts
7441
7465
  var import_core6 = require("@ai-matrx/records/core");
7466
+ var import_uuid4 = require("@ai-matrx/kit/uuid");
7467
+
7468
+ // src/groupReads.ts
7469
+ function groupedPageSort(fields, groupKey, sort) {
7470
+ if (!groupKey) return sort;
7471
+ const field2 = fields.find((f) => f.key === groupKey);
7472
+ if (!field2) return sort;
7473
+ return [{ field: groupKey, direction: "asc", as: sortAsFor(field2) }, ...sort.filter((s) => s.field !== groupKey)];
7474
+ }
7475
+ function chosenEntries(chosen) {
7476
+ return JSON.parse(JSON.stringify(Object.entries(chosen).sort())).filter(([, op2]) => op2 in MEASURE_LABEL);
7477
+ }
7478
+ function groupFactMeasures(chosen) {
7479
+ return [{ op: "count" }, ...chosenEntries(chosen).filter(([, op2]) => op2 !== "count").map(([key, op2]) => ({ op: op2, key }))];
7480
+ }
7442
7481
 
7443
7482
  // src/viewKeys.ts
7444
7483
  var STORE_KEEPS_TIMELINE = true;
@@ -22469,12 +22508,6 @@ function groupValueKey(value) {
22469
22508
  if (Array.isArray(value)) return value.length === 0 ? "" : JSON.stringify(value);
22470
22509
  return typeof value === "object" ? JSON.stringify(value) : String(value);
22471
22510
  }
22472
- function groupedPageSort(fields, groupKey, sort) {
22473
- if (!groupKey) return sort;
22474
- const field2 = fields.find((f) => f.key === groupKey);
22475
- if (!field2) return sort;
22476
- return [{ field: groupKey, direction: "asc", as: sortAsFor(field2) }, ...sort.filter((s) => s.field !== groupKey)];
22477
- }
22478
22511
  function useGroupFacts(args) {
22479
22512
  const client = (0, import_react112.useRecordsClient)();
22480
22513
  const { tableId, groupKey, version } = args;
@@ -22490,10 +22523,7 @@ function useGroupFacts(args) {
22490
22523
  const entries = JSON.parse(chosenKey);
22491
22524
  const asked3 = JSON.parse(filterKey);
22492
22525
  const filter = Object.keys(asked3).length > 0 ? asked3 : void 0;
22493
- const measures = [
22494
- { op: "count" },
22495
- ...entries.filter(([, op2]) => op2 !== "count").map(([key, op2]) => ({ op: op2, key }))
22496
- ];
22526
+ const measures = groupFactMeasures(Object.fromEntries(entries));
22497
22527
  let cancelled = false;
22498
22528
  void client.recordAggregate({ table_id: tableId, groupBy: [groupKey], measures, limit: 1e3, ...filter ? { filter } : {} }).then((answered) => {
22499
22529
  if (cancelled) return;
@@ -49919,7 +49949,7 @@ function useSlotScroll(slot) {
49919
49949
  }
49920
49950
 
49921
49951
  // src/TablePage.tsx
49922
- var import_uuid4 = require("@ai-matrx/kit/uuid");
49952
+ var import_uuid5 = require("@ai-matrx/kit/uuid");
49923
49953
  var import_jsx_runtime158 = require("react/jsx-runtime");
49924
49954
  var RAIL_TITLE = {
49925
49955
  settings: "Table settings",
@@ -50141,7 +50171,7 @@ function openingView(activeView, activeDashboardId) {
50141
50171
  }
50142
50172
  function savedViewFromParam(activeView) {
50143
50173
  const word = typeof activeView === "string" ? activeView.trim() : "";
50144
- return (0, import_uuid4.isUuidShape)(word) ? word.toLowerCase() : null;
50174
+ return (0, import_uuid5.isUuidShape)(word) ? word.toLowerCase() : null;
50145
50175
  }
50146
50176
  function addressForView(view, layout) {
50147
50177
  return view && !view.isDefault ? view.id : layout;
@@ -50966,7 +50996,7 @@ function TablePage({
50966
50996
  QuestionPanel,
50967
50997
  {
50968
50998
  tableId,
50969
- activeQuestionId: questionsFromLink && activeItemId && (0, import_uuid4.isUuidShape)(activeItemId) ? activeItemId : null,
50999
+ activeQuestionId: questionsFromLink && activeItemId && (0, import_uuid5.isUuidShape)(activeItemId) ? activeItemId : null,
50970
51000
  draft: questionDraft
50971
51001
  }
50972
51002
  ) : main === "archived" ? (
@@ -51299,15 +51329,13 @@ function EntityChartBlock({ source, kind, by, measure, title, where, organizatio
51299
51329
  const question = entityChartQuestion({ by, measure, where, organization });
51300
51330
  const measures = [m.op === "count" ? { op: "count" } : { op: m.op, key: m.of }];
51301
51331
  const base = { title: title ?? "", kind, measures, group_by: by ? [by] : [] };
51302
- const seeded = (0, import_react287.useSeededAnswer)(`entity-chart:${ask}`, (c) => c.drillAsk({ source, question }));
51303
- const [block, setBlock] = (0, import_react286.useState)(() => seeded ? blockOfAnswer({ ok: true, data: seeded }, base, by) : null);
51304
- const firstRead = (0, import_react286.useRef)(true);
51332
+ const seeded = (0, import_react287.useSeededAnswerAt)(`entity-chart:${ask}`, (c) => c.drillAsk({ source, question }));
51333
+ const [block, setBlock] = (0, import_react286.useState)(() => seeded ? blockOfAnswer({ ok: true, data: seeded.data }, base, by) : null);
51334
+ const seededFor = (0, import_react286.useRef)(seeded ? { ask: `${ask}|${kind}|${title ?? ""}`, at: seeded.at } : null);
51305
51335
  (0, import_react286.useEffect)(() => {
51306
- if (firstRead.current && seeded) {
51307
- firstRead.current = false;
51308
- return;
51309
- }
51310
- firstRead.current = false;
51336
+ const held = seededFor.current;
51337
+ if (held && held.ask === `${ask}|${kind}|${title ?? ""}` && Date.now() - held.at < import_react287.SEED_FRESH_MS) return;
51338
+ seededFor.current = null;
51311
51339
  let cancelled = false;
51312
51340
  void client.drillAsk({ source, question }).then((answer) => {
51313
51341
  if (cancelled) return;