@ai-matrx/records 0.77.2 → 0.78.0
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 +15 -0
- package/dist/app-table/index.cjs +94 -5
- package/dist/app-table/index.cjs.map +1 -1
- package/dist/app-table/index.d.cts +7 -7
- package/dist/app-table/index.d.ts +7 -7
- package/dist/app-table/index.js +94 -5
- package/dist/app-table/index.js.map +1 -1
- package/dist/{client-DZ3UcU4_.d.cts → client-BExNR0TK.d.cts} +5 -5
- package/dist/{client-ZIxyAOdh.d.ts → client-Byn_UthM.d.ts} +5 -5
- package/dist/core/index.cjs +98 -7
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +11 -11
- package/dist/core/index.d.ts +11 -11
- package/dist/core/index.js +98 -7
- package/dist/core/index.js.map +1 -1
- package/dist/data/index.cjs +90 -1
- package/dist/data/index.cjs.map +1 -1
- package/dist/data/index.d.cts +6 -6
- package/dist/data/index.d.ts +6 -6
- package/dist/data/index.js +90 -1
- package/dist/data/index.js.map +1 -1
- package/dist/{declareTable-BYZdFrt5.d.cts → declareTable-CgrEusy8.d.cts} +4 -4
- package/dist/{declareTable-DGSJMqGx.d.ts → declareTable-DWOh53eK.d.ts} +4 -4
- package/dist/{field-D7I9yck6.d.ts → field-B2bvpqcE.d.ts} +1 -1
- package/dist/{field-BTW7h7Wh.d.cts → field-t9aefszx.d.cts} +1 -1
- package/dist/index.cjs +6 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +7 -7
- package/dist/index.d.ts +7 -7
- package/dist/index.js +6 -2
- package/dist/index.js.map +1 -1
- package/dist/memory/index.cjs +6 -1
- package/dist/memory/index.cjs.map +1 -1
- package/dist/memory/index.d.cts +6 -6
- package/dist/memory/index.d.ts +6 -6
- package/dist/memory/index.js +6 -1
- package/dist/memory/index.js.map +1 -1
- package/dist/{ports-CaYEF1dG.d.ts → ports-Ch4Ym0tj.d.ts} +7 -1
- package/dist/{ports-PpvsH1cQ.d.cts → ports-Cjl-IjFa.d.cts} +7 -1
- package/dist/react/index.cjs +98 -7
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +16 -0
- package/dist/react/index.d.ts +16 -0
- package/dist/react/index.js +98 -7
- package/dist/react/index.js.map +1 -1
- package/dist/realtime/index.d.cts +2 -2
- package/dist/realtime/index.d.ts +2 -2
- package/dist/{record-B7iwye2k.d.cts → record-Ba1F1CNS.d.cts} +10 -0
- package/dist/{record-B7iwye2k.d.ts → record-Ba1F1CNS.d.ts} +10 -0
- package/dist/{subscription-BWaRPLyo.d.ts → subscription-CccP6N93.d.ts} +1 -1
- package/dist/{subscription-Br30ZwIt.d.cts → subscription-DGCrwwSR.d.cts} +1 -1
- package/dist/{table-kind-Da21ZLdJ.d.ts → table-kind-BMWi8G37.d.ts} +3 -3
- package/dist/{table-kind-HAQ6WNxZ.d.cts → table-kind-BoelIMjr.d.cts} +3 -3
- package/dist/templates/index.cjs +6 -2
- package/dist/templates/index.cjs.map +1 -1
- package/dist/templates/index.d.cts +9 -9
- package/dist/templates/index.d.ts +9 -9
- package/dist/templates/index.js +6 -2
- package/dist/templates/index.js.map +1 -1
- package/dist/{types-DrJLOqVi.d.ts → types-CiHdoATO.d.ts} +2 -2
- package/dist/{types-DWZ5_3by.d.ts → types-CtyMwJvy.d.ts} +2 -2
- package/dist/{types-DYoWzHwJ.d.cts → types-D-Mhiodh.d.cts} +2 -2
- package/dist/{types-LvxsZ6Zv.d.cts → types-euaQwxnB.d.cts} +2 -2
- package/dist/use-cases/index.cjs.map +1 -1
- package/dist/use-cases/index.d.cts +5 -5
- package/dist/use-cases/index.d.ts +5 -5
- package/dist/use-cases/index.js.map +1 -1
- package/dist/{validate-j0WQoC3C.d.ts → validate-B-p3YPgA.d.ts} +1 -1
- package/dist/{validate-CRdXE73G.d.cts → validate-COvMcv8z.d.cts} +1 -1
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
# Changelog — @ai-matrx/records
|
|
2
2
|
|
|
3
|
+
## 0.78.0
|
|
4
|
+
|
|
5
|
+
PAGE-BUNDLE: a table page opens in one call. `custom.table_page_bundle` answers, in one round trip, the table row, fields, views, look, change actions, decorations, row actions, reverse columns, grid layout, the caller's level and recent imports. The client hands each part to the caller that asks that door with the same arguments (once, within 10 s), so every mapping, mask and refusal is unchanged; a refusing part, a missing door or a failed bundle is a miss and the door is asked itself.
|
|
6
|
+
|
|
7
|
+
- `RecordsDataSource.opensInOneCall` (optional): set by `supabaseDataSource`; a source without it (tests, replays) never asks the bundle.
|
|
8
|
+
- `store.generated.ts` regenerated from the live catalogue.
|
|
9
|
+
|
|
10
|
+
**Consumer action:** none. Measured on production as admin: 12 parts identical to their doors; ~0.2-0.6 s for the bundle against ~1.5-2.2 s for the doors one after another (`pnpm perf:bundle` in matrx-frontend).
|
|
11
|
+
|
|
12
|
+
## 0.77.3
|
|
13
|
+
|
|
14
|
+
UUID checks in app-table graduation, landing outcomes and template validation use `@ai-matrx/kit/uuid` `isUuidShape`; table-kind slugs use `isLowercaseUuidShape` (the same lower-case contract the local regex had). Scripts' console lines format sizes, durations and cost through kit. Package-twins collapse.
|
|
15
|
+
|
|
16
|
+
Consumer action: none.
|
|
17
|
+
|
|
3
18
|
## 0.77.2
|
|
4
19
|
|
|
5
20
|
Automatic changed-only republish (docs/metadata drift since the last tag — see
|
package/dist/app-table/index.cjs
CHANGED
|
@@ -56,6 +56,7 @@ __export(app_table_exports, {
|
|
|
56
56
|
module.exports = __toCommonJS(app_table_exports);
|
|
57
57
|
|
|
58
58
|
// src/app-table/graduate.ts
|
|
59
|
+
var import_uuid = require("@ai-matrx/kit/uuid");
|
|
59
60
|
var TO_CUSTOM_FIELDS = "custom_fields";
|
|
60
61
|
var TO_ASSOCIATION = "association";
|
|
61
62
|
var GRADUATION_BASE_COLUMNS = [
|
|
@@ -115,10 +116,9 @@ function graduationProblems(fields, graduation) {
|
|
|
115
116
|
}
|
|
116
117
|
return problems;
|
|
117
118
|
}
|
|
118
|
-
var UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
119
119
|
function idsOf(value) {
|
|
120
120
|
const list = Array.isArray(value) ? value : value === null || value === void 0 ? [] : [value];
|
|
121
|
-
return list.filter((v) => typeof v === "string" &&
|
|
121
|
+
return list.filter((v) => typeof v === "string" && (0, import_uuid.isUuidShape)(v));
|
|
122
122
|
}
|
|
123
123
|
function graduatedRow(fields, graduation, snapshot) {
|
|
124
124
|
const row = {
|
|
@@ -649,7 +649,7 @@ function mapPgError(error, where) {
|
|
|
649
649
|
}
|
|
650
650
|
|
|
651
651
|
// src/relation.ts
|
|
652
|
-
var
|
|
652
|
+
var import_uuid2 = require("@ai-matrx/kit/uuid");
|
|
653
653
|
var REVERSE_LINKS_RECORDS_PER_CALL = 200;
|
|
654
654
|
function sourceArchivedOf(value) {
|
|
655
655
|
if (!value || typeof value !== "object" || Array.isArray(value)) return null;
|
|
@@ -692,7 +692,7 @@ function mintOpId() {
|
|
|
692
692
|
}
|
|
693
693
|
|
|
694
694
|
// src/choice.ts
|
|
695
|
-
var
|
|
695
|
+
var import_uuid3 = require("@ai-matrx/kit/uuid");
|
|
696
696
|
var CHOICE_NUDGES = ["ask", "always_add", "never_add"];
|
|
697
697
|
function asChoiceNudge(value) {
|
|
698
698
|
return typeof value === "string" && CHOICE_NUDGES.includes(value) ? value : "ask";
|
|
@@ -1131,6 +1131,7 @@ var STORE_DOORS = [
|
|
|
1131
1131
|
{ name: "data_home", args: "p_organization_id uuid DEFAULT NULL::uuid, p_search text DEFAULT NULL::text, p_include_app_tables boolean DEFAULT false", returns: "jsonb", security: "definer" },
|
|
1132
1132
|
{ name: "data_home_changed_by", args: "p_asks jsonb", returns: "TABLE(organization_id uuid, id uuid, at timestamp with time zone, who text)", security: "definer" },
|
|
1133
1133
|
{ name: "data_home_items", args: "p_organization_id uuid DEFAULT NULL::uuid", returns: "TABLE(kind text, organization_id uuid, organization_name text, item_id uuid, table_id uuid, table_name text, item_row jsonb)", security: "definer" },
|
|
1134
|
+
{ name: "data_home_slim", args: "p_organization_id uuid DEFAULT NULL::uuid, p_search text DEFAULT NULL::text, p_include_app_tables boolean DEFAULT false", returns: "jsonb", security: "invoker" },
|
|
1134
1135
|
{ name: "data_home_tables", args: "p_organization_id uuid DEFAULT NULL::uuid", returns: "TABLE(table_id uuid, table_name text, organization_id uuid, organization_name text, member boolean, visibility text, updated_at timestamp with time zone, mine boolean, shared_with_me boolean, kept_by_the_app boolean, kind text, team boolean, system boolean, created_by uuid)", security: "definer" },
|
|
1135
1136
|
{ name: "data_home_tables", args: "p_organization_id uuid, p_include_app_tables boolean", returns: "TABLE(table_id uuid, table_name text, organization_id uuid, organization_name text, member boolean, visibility text, updated_at timestamp with time zone, mine boolean, shared_with_me boolean, kept_by_the_app boolean, kind text, team boolean, system boolean, created_by uuid)", security: "invoker" },
|
|
1136
1137
|
{ name: "declared_conversation", args: "", returns: "uuid", security: "invoker" },
|
|
@@ -1711,6 +1712,7 @@ var STORE_DOORS = [
|
|
|
1711
1712
|
{ name: "table_list_everywhere", args: "p_organization_id uuid DEFAULT NULL::uuid", returns: "jsonb", security: "definer" },
|
|
1712
1713
|
{ name: "table_list_everywhere", args: "p_organization_id uuid, p_include_app_tables boolean", returns: "jsonb", security: "invoker" },
|
|
1713
1714
|
{ name: "table_move", args: "p_table_id uuid, p_to_organization_id uuid, p_expected_version integer DEFAULT NULL::integer", returns: "jsonb", security: "definer" },
|
|
1715
|
+
{ name: "table_page_bundle", args: "p_organization_id uuid, p_table_id uuid, p_view_id uuid DEFAULT NULL::uuid", returns: "jsonb", security: "invoker" },
|
|
1714
1716
|
{ name: "table_placement", args: "p_organization_id uuid, p_table_id uuid, p_data jsonb, p_is_kernel boolean DEFAULT false", returns: "jsonb", security: "invoker" },
|
|
1715
1717
|
{ name: "table_record_ceiling", args: "", returns: "integer", security: "invoker" },
|
|
1716
1718
|
{ name: "table_record_ceiling", args: "p_organization_id uuid", returns: "integer", security: "invoker" },
|
|
@@ -2571,6 +2573,8 @@ function supabaseDataSource(client) {
|
|
|
2571
2573
|
const supabase = client;
|
|
2572
2574
|
const hasSchema = typeof supabase.schema === "function";
|
|
2573
2575
|
const bound = {
|
|
2576
|
+
// PAGE-BUNDLE: the real adapter opens a table page with one `custom.table_page_bundle` call.
|
|
2577
|
+
opensInOneCall: true,
|
|
2574
2578
|
rpc(fn, args, options) {
|
|
2575
2579
|
if (!hasSchema) {
|
|
2576
2580
|
return Promise.resolve(
|
|
@@ -2693,6 +2697,12 @@ function intersectIds(sets) {
|
|
|
2693
2697
|
|
|
2694
2698
|
// src/core/client.ts
|
|
2695
2699
|
var DEFAULT_SCHEMA = "custom";
|
|
2700
|
+
function canonicalArgs(value) {
|
|
2701
|
+
return JSON.stringify(
|
|
2702
|
+
value,
|
|
2703
|
+
(_key, held) => held && typeof held === "object" && !Array.isArray(held) ? Object.fromEntries(Object.keys(held).sort().map((k) => [k, held[k]])) : held
|
|
2704
|
+
);
|
|
2705
|
+
}
|
|
2696
2706
|
var A_PERSONS_REFUSAL = /* @__PURE__ */ new Set([
|
|
2697
2707
|
"refused_by_rule",
|
|
2698
2708
|
"stale_write",
|
|
@@ -2721,7 +2731,83 @@ function createRecordsClient(given) {
|
|
|
2721
2731
|
const schema = config.schema ?? DEFAULT_SCHEMA;
|
|
2722
2732
|
const org = config.organizationId;
|
|
2723
2733
|
const scream = sink(config);
|
|
2734
|
+
const BUNDLE_TTL_MS = 1e4;
|
|
2735
|
+
const BUNDLE_OPENERS = /* @__PURE__ */ new Set(["applicable_fields", "views", "view_look_read", "table_decorations", "row_actions", "reverse_columns", "record_change_actions", "grid_layout", "io_imports"]);
|
|
2736
|
+
const bundleParts = /* @__PURE__ */ new Map();
|
|
2737
|
+
const bundleFlights = /* @__PURE__ */ new Map();
|
|
2738
|
+
const bundleAsked = /* @__PURE__ */ new Map();
|
|
2739
|
+
let bundleKernel = null;
|
|
2740
|
+
const bundleKey = (door, args) => `${door}|${canonicalArgs(args)}`;
|
|
2741
|
+
function bundleTableOf(door, args) {
|
|
2742
|
+
const t = args["p_table_id"];
|
|
2743
|
+
if (door === "read_records_by_ids") {
|
|
2744
|
+
const ids = args["p_record_ids"];
|
|
2745
|
+
return typeof t === "string" && t === bundleKernel && Array.isArray(ids) && ids.length === 1 && typeof ids[0] === "string" ? ids[0] : null;
|
|
2746
|
+
}
|
|
2747
|
+
if (door === "my_levels") {
|
|
2748
|
+
const ids = args["p_ids"];
|
|
2749
|
+
return args["p_type"] === "record" && Array.isArray(ids) && ids.length === 1 && typeof ids[0] === "string" ? ids[0] : null;
|
|
2750
|
+
}
|
|
2751
|
+
return typeof t === "string" ? t : null;
|
|
2752
|
+
}
|
|
2753
|
+
async function fillBundle(tableId, viewId) {
|
|
2754
|
+
try {
|
|
2755
|
+
const response = await config.dataSource.rpc(
|
|
2756
|
+
"table_page_bundle",
|
|
2757
|
+
{ p_organization_id: org, p_table_id: tableId, p_view_id: typeof viewId === "string" ? viewId : null },
|
|
2758
|
+
{ schema }
|
|
2759
|
+
);
|
|
2760
|
+
const answer = response.data;
|
|
2761
|
+
if (response.error || !answer || !Array.isArray(answer.parts)) return;
|
|
2762
|
+
const now = Date.now();
|
|
2763
|
+
for (const part of answer.parts) {
|
|
2764
|
+
if (part.error !== void 0 || part.data === void 0) continue;
|
|
2765
|
+
if (part.door === "table_kernel_id" && typeof part.data === "string") bundleKernel = part.data;
|
|
2766
|
+
bundleParts.set(bundleKey(part.door, part.args), { data: part.data, at: now });
|
|
2767
|
+
}
|
|
2768
|
+
} catch {
|
|
2769
|
+
}
|
|
2770
|
+
}
|
|
2771
|
+
async function fromBundle(door, args) {
|
|
2772
|
+
if (!config.dataSource.opensInOneCall || !doorReady(config, "table_page_bundle")) return null;
|
|
2773
|
+
const tableId = bundleTableOf(door, args);
|
|
2774
|
+
if (tableId) {
|
|
2775
|
+
const asked = bundleAsked.get(tableId);
|
|
2776
|
+
const fresh = asked !== void 0 && Date.now() - asked < BUNDLE_TTL_MS;
|
|
2777
|
+
if (!fresh && BUNDLE_OPENERS.has(door)) {
|
|
2778
|
+
bundleAsked.set(tableId, Date.now());
|
|
2779
|
+
const flight2 = fillBundle(tableId, door === "grid_layout" ? args["p_view_id"] : null).finally(() => bundleFlights.delete(tableId));
|
|
2780
|
+
bundleFlights.set(tableId, flight2);
|
|
2781
|
+
}
|
|
2782
|
+
const flight = bundleFlights.get(tableId);
|
|
2783
|
+
if (flight) await flight;
|
|
2784
|
+
} else if (door === "table_kernel_id") {
|
|
2785
|
+
if (bundleKernel === null) {
|
|
2786
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
2787
|
+
await Promise.all([...bundleFlights.values()]);
|
|
2788
|
+
}
|
|
2789
|
+
return bundleKernel === null ? null : { data: bundleKernel };
|
|
2790
|
+
} else {
|
|
2791
|
+
return null;
|
|
2792
|
+
}
|
|
2793
|
+
const key = bundleKey(door, args);
|
|
2794
|
+
const held = bundleParts.get(key);
|
|
2795
|
+
if (!held) return null;
|
|
2796
|
+
bundleParts.delete(key);
|
|
2797
|
+
return Date.now() - held.at < BUNDLE_TTL_MS ? { data: held.data } : null;
|
|
2798
|
+
}
|
|
2799
|
+
function bundleDrop(tableId) {
|
|
2800
|
+
if (tableId === null) {
|
|
2801
|
+
bundleParts.clear();
|
|
2802
|
+
bundleAsked.clear();
|
|
2803
|
+
return;
|
|
2804
|
+
}
|
|
2805
|
+
bundleAsked.delete(tableId);
|
|
2806
|
+
for (const key of [...bundleParts.keys()]) if (key.includes(tableId)) bundleParts.delete(key);
|
|
2807
|
+
}
|
|
2724
2808
|
async function callDoor(door, args, where) {
|
|
2809
|
+
const bundled = await fromBundle(door, args);
|
|
2810
|
+
if (bundled) return ok(bundled.data);
|
|
2725
2811
|
if (!doorReady(config, door)) {
|
|
2726
2812
|
const refusal2 = doorAbsent(door);
|
|
2727
2813
|
scream({ code: refusal2.code, message: refusal2.message, ...refusal2.hint ? { hint: refusal2.hint } : {}, where });
|
|
@@ -2736,7 +2822,10 @@ function createRecordsClient(given) {
|
|
|
2736
2822
|
return ok(response.data);
|
|
2737
2823
|
}
|
|
2738
2824
|
function structureMoved(tableId, result) {
|
|
2739
|
-
if (result.ok)
|
|
2825
|
+
if (result.ok) {
|
|
2826
|
+
bundleDrop(tableId);
|
|
2827
|
+
announceTableStructureChanged(tableId);
|
|
2828
|
+
}
|
|
2740
2829
|
return result;
|
|
2741
2830
|
}
|
|
2742
2831
|
async function owedDoor(door, args, where) {
|