@ai-matrx/records 0.80.4 → 0.80.8

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 (71) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/README.md +19 -0
  3. package/dist/app-table/index.cjs +88 -23
  4. package/dist/app-table/index.cjs.map +1 -1
  5. package/dist/app-table/index.d.cts +7 -7
  6. package/dist/app-table/index.d.ts +7 -7
  7. package/dist/app-table/index.js +88 -23
  8. package/dist/app-table/index.js.map +1 -1
  9. package/dist/{client-CB_Klj1P.d.ts → client-D1LTezMZ.d.ts} +5 -5
  10. package/dist/{client-D0yGEof4.d.cts → client-DLIKeBWF.d.cts} +5 -5
  11. package/dist/core/index.cjs +97 -31
  12. package/dist/core/index.cjs.map +1 -1
  13. package/dist/core/index.d.cts +21 -12
  14. package/dist/core/index.d.ts +21 -12
  15. package/dist/core/index.js +97 -31
  16. package/dist/core/index.js.map +1 -1
  17. package/dist/data/index.cjs +88 -23
  18. package/dist/data/index.cjs.map +1 -1
  19. package/dist/data/index.d.cts +6 -6
  20. package/dist/data/index.d.ts +6 -6
  21. package/dist/data/index.js +88 -23
  22. package/dist/data/index.js.map +1 -1
  23. package/dist/{declareTable-l7ktxN6p.d.cts → declareTable-02uao-5n.d.cts} +4 -4
  24. package/dist/{declareTable-DoYVueVF.d.ts → declareTable-C5FlIS0z.d.ts} +4 -4
  25. package/dist/{field-6UtYgFeu.d.ts → field-BIJiFPc0.d.ts} +1 -1
  26. package/dist/{field-DpJR_5Pe.d.cts → field-snQG2jMq.d.cts} +1 -1
  27. package/dist/index.cjs +2 -0
  28. package/dist/index.cjs.map +1 -1
  29. package/dist/index.d.cts +7 -7
  30. package/dist/index.d.ts +7 -7
  31. package/dist/index.js +2 -0
  32. package/dist/index.js.map +1 -1
  33. package/dist/memory/index.cjs +1 -0
  34. package/dist/memory/index.cjs.map +1 -1
  35. package/dist/memory/index.d.cts +6 -6
  36. package/dist/memory/index.d.ts +6 -6
  37. package/dist/memory/index.js +1 -0
  38. package/dist/memory/index.js.map +1 -1
  39. package/dist/{ports-CiEYhwi5.d.ts → ports-Y5gLbCXe.d.ts} +1 -1
  40. package/dist/{ports-CE7umTp-.d.cts → ports-y1QNfM80.d.cts} +1 -1
  41. package/dist/react/index.cjs +89 -27
  42. package/dist/react/index.cjs.map +1 -1
  43. package/dist/react/index.d.cts +6 -1
  44. package/dist/react/index.d.ts +6 -1
  45. package/dist/react/index.js +89 -27
  46. package/dist/react/index.js.map +1 -1
  47. package/dist/realtime/index.d.cts +2 -2
  48. package/dist/realtime/index.d.ts +2 -2
  49. package/dist/{record-CvqV8wyO.d.cts → record-1yDCn169.d.cts} +6 -1
  50. package/dist/{record-CvqV8wyO.d.ts → record-1yDCn169.d.ts} +6 -1
  51. package/dist/{subscription-CC0kgkwa.d.cts → subscription-B_WaT-kr.d.cts} +1 -1
  52. package/dist/{subscription-DjkuDMcX.d.ts → subscription-CUok1vAm.d.ts} +1 -1
  53. package/dist/{table-kind-FMYq3nCr.d.ts → table-kind-COmkYYkc.d.ts} +3 -3
  54. package/dist/{table-kind-DHpMEOHd.d.cts → table-kind-LodkBhCZ.d.cts} +3 -3
  55. package/dist/templates/index.cjs +3 -2
  56. package/dist/templates/index.cjs.map +1 -1
  57. package/dist/templates/index.d.cts +9 -9
  58. package/dist/templates/index.d.ts +9 -9
  59. package/dist/templates/index.js +3 -2
  60. package/dist/templates/index.js.map +1 -1
  61. package/dist/{types-DuceX7js.d.cts → types-BJGTxu3Y.d.cts} +2 -2
  62. package/dist/{types-BbCZJh1C.d.ts → types-C5-AaPa6.d.ts} +2 -2
  63. package/dist/{types-B4LF3sFx.d.ts → types-CU_Tn2Np.d.ts} +2 -2
  64. package/dist/{types-Flsf_KU5.d.cts → types-yBZLtxrZ.d.cts} +2 -2
  65. package/dist/use-cases/index.cjs.map +1 -1
  66. package/dist/use-cases/index.d.cts +5 -5
  67. package/dist/use-cases/index.d.ts +5 -5
  68. package/dist/use-cases/index.js.map +1 -1
  69. package/dist/{validate-EvZGkD96.d.cts → validate-CE6qpJIb.d.cts} +1 -1
  70. package/dist/{validate-DyVwSD74.d.ts → validate-Rz9djP6H.d.ts} +1 -1
  71. package/package.json +1 -1
@@ -238,6 +238,32 @@ function takePrimedTablePageBundle(organizationId, tableId, viewId) {
238
238
  return Date.now() - held.at < PRIMED_TTL_MS ? held.answer : null;
239
239
  }
240
240
 
241
+ // src/core/recordChanges.ts
242
+ var listeners = /* @__PURE__ */ new Set();
243
+ function announceRecordChanged(recordId) {
244
+ for (const listener of [...listeners]) {
245
+ try {
246
+ listener(recordId);
247
+ } catch (thrown) {
248
+ console.error("[@ai-matrx/records] a record-change listener threw", thrown);
249
+ }
250
+ }
251
+ }
252
+ function onRecordChanged(listener) {
253
+ listeners.add(listener);
254
+ return () => listeners.delete(listener);
255
+ }
256
+ var tableListeners = /* @__PURE__ */ new Set();
257
+ function announceTableStructureChanged(tableId) {
258
+ for (const listener of [...tableListeners]) {
259
+ try {
260
+ listener(tableId);
261
+ } catch (thrown) {
262
+ console.error("[@ai-matrx/records] a table-structure listener threw", thrown);
263
+ }
264
+ }
265
+ }
266
+
241
267
  // src/archive.ts
242
268
  var DEFAULT_ARCHIVE_LANE = "org";
243
269
 
@@ -1393,6 +1419,7 @@ var STORE_DOORS = [
1393
1419
  { name: "record_filter_sql", args: "p_organization_id uuid, p_table_id uuid, p_filter jsonb", returns: "text", security: "invoker" },
1394
1420
  { name: "record_headers", args: "p_organization_id uuid, p_ids uuid[]", returns: "TABLE(id uuid, table_id uuid, created_at timestamp with time zone, updated_at timestamp with time zone, version integer, deleted_at timestamp with time zone, mine boolean, created_by uuid)", security: "definer" },
1395
1421
  { name: "record_history", args: "p_organization_id uuid, p_record_id uuid, p_limit integer DEFAULT 200, p_offset integer DEFAULT 0", returns: "TABLE(version integer, occurred_at timestamp with time zone, operation text, operation_label text, actor jsonb, changes jsonb, migration_id uuid, undoable boolean)", security: "definer" },
1422
+ { name: "record_page_bundle", args: "p_organization_id uuid, p_record_id uuid", returns: "jsonb", security: "invoker" },
1396
1423
  { name: "record_platform_keys", args: "", returns: "text[]", security: "invoker" },
1397
1424
  { name: "record_relation_edges", args: "p_organization_id uuid, p_id uuid, p_table_id uuid, p_data_class text, p_data jsonb, p_deleted_at timestamp with time zone", returns: "TABLE(target_id uuid, edge_role text, field_id uuid, ord integer)", security: "invoker" },
1398
1425
  { name: "record_reparent", args: "p_organization_id uuid, p_record_id uuid, p_parent_id uuid", returns: "void", security: "definer" },
@@ -2490,28 +2517,6 @@ var DRILL_DOORS = {
2490
2517
  rows: "drill_rows"
2491
2518
  };
2492
2519
 
2493
- // src/core/recordChanges.ts
2494
- var listeners = /* @__PURE__ */ new Set();
2495
- function announceRecordChanged(recordId) {
2496
- for (const listener of [...listeners]) {
2497
- try {
2498
- listener(recordId);
2499
- } catch (thrown) {
2500
- console.error("[@ai-matrx/records] a record-change listener threw", thrown);
2501
- }
2502
- }
2503
- }
2504
- var tableListeners = /* @__PURE__ */ new Set();
2505
- function announceTableStructureChanged(tableId) {
2506
- for (const listener of [...tableListeners]) {
2507
- try {
2508
- listener(tableId);
2509
- } catch (thrown) {
2510
- console.error("[@ai-matrx/records] a table-structure listener threw", thrown);
2511
- }
2512
- }
2513
- }
2514
-
2515
2520
  // src/core/query.ts
2516
2521
  var DEFAULT_PAGE_SIZE = 50;
2517
2522
  function planQuery(query) {
@@ -2631,8 +2636,68 @@ function createRecordsClient(given) {
2631
2636
  } catch {
2632
2637
  }
2633
2638
  }
2639
+ const RECORD_OPENERS = /* @__PURE__ */ new Set(["read_record", "record_row_controls", "record_history", "comment_thread", "computed_provenance"]);
2640
+ const recordFlights = /* @__PURE__ */ new Map();
2641
+ const recordAsked = /* @__PURE__ */ new Map();
2642
+ let recordChangesHeard = false;
2643
+ function bundleRecordOf(door, args) {
2644
+ if (RECORD_OPENERS.has(door)) return typeof args["p_record_id"] === "string" ? args["p_record_id"] : null;
2645
+ const ids = args["p_ids"];
2646
+ const one = Array.isArray(ids) && ids.length === 1 && typeof ids[0] === "string" ? ids[0] : null;
2647
+ if (door === "record_headers") return one;
2648
+ if (door === "my_levels" && args["p_type"] === "record") return one;
2649
+ return null;
2650
+ }
2651
+ async function fillRecordBundle(recordId) {
2652
+ if (!recordChangesHeard) {
2653
+ recordChangesHeard = true;
2654
+ onRecordChanged((changed) => {
2655
+ recordAsked.delete(changed);
2656
+ for (const key of [...bundleParts.keys()]) if (key.includes(changed)) bundleParts.delete(key);
2657
+ });
2658
+ }
2659
+ try {
2660
+ const usable = (r) => r !== null && !r.error && r.data !== null && typeof r.data === "object" && Array.isArray(r.data.parts);
2661
+ const primedAnswer = takePrimedTablePageBundle(org, `record:${recordId}`, null);
2662
+ let response = primedAnswer ? await primedAnswer : null;
2663
+ if (!usable(response)) {
2664
+ response = await config.dataSource.rpc("record_page_bundle", { p_organization_id: org, p_record_id: recordId }, { schema });
2665
+ }
2666
+ if (!usable(response)) return;
2667
+ const now = Date.now();
2668
+ for (const part of response.data.parts) {
2669
+ if (part.error !== void 0 || part.data === void 0) continue;
2670
+ bundleParts.set(bundleKey(part.door, part.args), { data: part.data, at: now });
2671
+ }
2672
+ } catch {
2673
+ }
2674
+ }
2675
+ async function fromRecordBundle(door, args) {
2676
+ if (!doorReady(config, "record_page_bundle")) return void 0;
2677
+ const recordId = bundleRecordOf(door, args);
2678
+ if (!recordId) return void 0;
2679
+ const opener = RECORD_OPENERS.has(door);
2680
+ if (!opener && !recordFlights.has(recordId) && !recordAsked.has(recordId)) return void 0;
2681
+ const asked = recordAsked.get(recordId);
2682
+ const fresh = asked !== void 0 && Date.now() - asked < BUNDLE_TTL_MS;
2683
+ if (!fresh && opener) {
2684
+ recordAsked.set(recordId, Date.now());
2685
+ const flight2 = fillRecordBundle(recordId).finally(() => recordFlights.delete(recordId));
2686
+ recordFlights.set(recordId, flight2);
2687
+ }
2688
+ const flight = recordFlights.get(recordId);
2689
+ if (flight) await flight;
2690
+ const key = bundleKey(door, args);
2691
+ const held = bundleParts.get(key);
2692
+ if (!held) return opener ? null : void 0;
2693
+ bundleParts.delete(key);
2694
+ return Date.now() - held.at < BUNDLE_TTL_MS ? { data: held.data } : null;
2695
+ }
2634
2696
  async function fromBundle(door, args) {
2635
- if (!config.dataSource.opensInOneCall || !doorReady(config, "table_page_bundle")) return null;
2697
+ if (!config.dataSource.opensInOneCall) return null;
2698
+ const fromRecord = await fromRecordBundle(door, args);
2699
+ if (fromRecord !== void 0) return fromRecord;
2700
+ if (!doorReady(config, "table_page_bundle")) return null;
2636
2701
  const tableId = bundleTableOf(door, args);
2637
2702
  if (tableId) {
2638
2703
  const asked = bundleAsked.get(tableId);