@ai-matrx/records 0.58.0 → 0.58.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 +6 -0
- package/dist/core/index.cjs +108 -3
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +26 -3
- package/dist/core/index.d.ts +26 -3
- package/dist/core/index.js +108 -3
- package/dist/core/index.js.map +1 -1
- package/dist/index.cjs +66 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +61 -1
- package/dist/index.d.ts +61 -1
- package/dist/index.js +66 -3
- package/dist/index.js.map +1 -1
- package/dist/react/index.cjs +158 -53
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +82 -1
- package/dist/react/index.d.ts +82 -1
- package/dist/react/index.js +158 -53
- package/dist/react/index.js.map +1 -1
- package/package.json +1 -1
package/dist/react/index.cjs
CHANGED
|
@@ -2289,12 +2289,15 @@ __export(react_exports, {
|
|
|
2289
2289
|
memoryStore: () => memoryStore,
|
|
2290
2290
|
mintClientKey: () => mintClientKey,
|
|
2291
2291
|
mintOpId: () => mintOpId,
|
|
2292
|
+
moveConsequence: () => moveConsequence,
|
|
2292
2293
|
moveInOrder: () => moveInOrder,
|
|
2293
2294
|
offeredAsContext: () => offeredAsContext,
|
|
2294
2295
|
ok: () => ok,
|
|
2295
2296
|
openCaptureQueue: () => openCaptureQueue,
|
|
2296
2297
|
optionKey: () => optionKey,
|
|
2297
2298
|
optionLabel: () => optionLabel,
|
|
2299
|
+
parseTableHome: () => parseTableHome,
|
|
2300
|
+
parseTableMoved: () => parseTableMoved,
|
|
2298
2301
|
portalArchiveConsequence: () => portalArchiveConsequence,
|
|
2299
2302
|
portalConfirmLine: () => portalConfirmLine,
|
|
2300
2303
|
portalPath: () => portalPath,
|
|
@@ -2441,6 +2444,116 @@ function rememberedOpCount() {
|
|
|
2441
2444
|
return ours.size;
|
|
2442
2445
|
}
|
|
2443
2446
|
|
|
2447
|
+
// src/placement.ts
|
|
2448
|
+
function keptOutOfSight(placement) {
|
|
2449
|
+
return placement?.kept_by_the_app === true;
|
|
2450
|
+
}
|
|
2451
|
+
function offeredAsContext(placement) {
|
|
2452
|
+
return placement?.offered_as_context === true;
|
|
2453
|
+
}
|
|
2454
|
+
function withTablePlacement(tables, facts) {
|
|
2455
|
+
if (!facts) return [...tables];
|
|
2456
|
+
const byId = new Map(facts.map((f) => [f.table_id, f]));
|
|
2457
|
+
return tables.map((table) => {
|
|
2458
|
+
const fact = byId.get(table.id);
|
|
2459
|
+
if (!fact || fact.kept_by_the_app === void 0) return table;
|
|
2460
|
+
return {
|
|
2461
|
+
...table,
|
|
2462
|
+
kept_by_the_app: fact.kept_by_the_app,
|
|
2463
|
+
kept_for: fact.kept_for ?? null,
|
|
2464
|
+
offered_as_context: fact.offered_as_context ?? false,
|
|
2465
|
+
keeper_group: fact.keeper_group ?? null,
|
|
2466
|
+
keeper_says: fact.keeper_says ?? null,
|
|
2467
|
+
used_in_kind: fact.used_in_kind ?? null,
|
|
2468
|
+
used_in_id: fact.used_in_id ?? null,
|
|
2469
|
+
used_in_table_id: fact.used_in_table_id ?? null
|
|
2470
|
+
};
|
|
2471
|
+
});
|
|
2472
|
+
}
|
|
2473
|
+
function keptGroups(tables) {
|
|
2474
|
+
const out = [];
|
|
2475
|
+
const at = /* @__PURE__ */ new Map();
|
|
2476
|
+
for (const table of tables) {
|
|
2477
|
+
if (!keptOutOfSight(table)) continue;
|
|
2478
|
+
const group = table.keeper_group?.trim() || "Kept by the app";
|
|
2479
|
+
let i = at.get(group);
|
|
2480
|
+
if (i === void 0) {
|
|
2481
|
+
i = out.length;
|
|
2482
|
+
at.set(group, i);
|
|
2483
|
+
out.push({ group, tables: [] });
|
|
2484
|
+
}
|
|
2485
|
+
out[i].tables.push(table);
|
|
2486
|
+
}
|
|
2487
|
+
return out;
|
|
2488
|
+
}
|
|
2489
|
+
function keptTableHref(fact, hrefs) {
|
|
2490
|
+
if (fact.used_in_kind === "scope" && fact.used_in_id) return hrefs.scope(fact.used_in_id);
|
|
2491
|
+
if (fact.used_in_kind === "table" && (fact.used_in_table_id || fact.used_in_id)) {
|
|
2492
|
+
return hrefs.table(fact.used_in_table_id || fact.used_in_id);
|
|
2493
|
+
}
|
|
2494
|
+
return hrefs.table(fact.table_id);
|
|
2495
|
+
}
|
|
2496
|
+
function countOf(value) {
|
|
2497
|
+
return typeof value === "number" && Number.isFinite(value) ? value : 0;
|
|
2498
|
+
}
|
|
2499
|
+
function wordsOf(value) {
|
|
2500
|
+
return typeof value === "string" && value.length > 0 ? value : null;
|
|
2501
|
+
}
|
|
2502
|
+
function parseTableHome(raw) {
|
|
2503
|
+
if (!raw || typeof raw !== "object") return null;
|
|
2504
|
+
const row = raw;
|
|
2505
|
+
const table = row.table;
|
|
2506
|
+
const org = row.organization;
|
|
2507
|
+
if (!table || !org || !wordsOf(table.id) || !wordsOf(org.id) || !wordsOf(org.name)) return null;
|
|
2508
|
+
const carries = row.carries ?? {};
|
|
2509
|
+
const destinations = Array.isArray(row.destinations) ? row.destinations : [];
|
|
2510
|
+
return {
|
|
2511
|
+
table: { id: String(table.id), name: wordsOf(table.name) ?? "This table", version: countOf(table.version) },
|
|
2512
|
+
organization: { id: String(org.id), name: String(org.name) },
|
|
2513
|
+
mayMove: row.may_move === true,
|
|
2514
|
+
whyNot: wordsOf(row.why_not),
|
|
2515
|
+
heldBy: Array.isArray(row.held_by) ? row.held_by.filter((s) => typeof s === "string") : [],
|
|
2516
|
+
destinations: destinations.filter((d) => !!d && typeof d === "object" && !!wordsOf(d.id)).map((d) => ({
|
|
2517
|
+
id: String(d.id),
|
|
2518
|
+
name: wordsOf(d.name) ?? "An organization",
|
|
2519
|
+
role: wordsOf(d.role) ?? "member",
|
|
2520
|
+
ok: d.ok === true,
|
|
2521
|
+
why: wordsOf(d.why)
|
|
2522
|
+
})),
|
|
2523
|
+
carries: {
|
|
2524
|
+
fields: countOf(carries.fields),
|
|
2525
|
+
records: countOf(carries.records),
|
|
2526
|
+
inTrash: countOf(carries.in_trash),
|
|
2527
|
+
choiceLists: countOf(carries.choice_lists),
|
|
2528
|
+
withIt: countOf(carries.with_it),
|
|
2529
|
+
tablesInside: countOf(carries.tables_inside),
|
|
2530
|
+
linksAcross: countOf(carries.links_across)
|
|
2531
|
+
}
|
|
2532
|
+
};
|
|
2533
|
+
}
|
|
2534
|
+
function parseTableMoved(raw) {
|
|
2535
|
+
const row = raw ?? {};
|
|
2536
|
+
const to = row.to ?? {};
|
|
2537
|
+
const from = row.from ?? {};
|
|
2538
|
+
const table = row.table ?? {};
|
|
2539
|
+
if (row.moved !== true || !wordsOf(to.id)) return null;
|
|
2540
|
+
return {
|
|
2541
|
+
to: { id: String(to.id), name: wordsOf(to.name) ?? "the new organization" },
|
|
2542
|
+
from: { id: wordsOf(from.id) ?? "", name: wordsOf(from.name) ?? "its old organization" },
|
|
2543
|
+
tableName: wordsOf(table.name) ?? "The table"
|
|
2544
|
+
};
|
|
2545
|
+
}
|
|
2546
|
+
function plural(n, one, many) {
|
|
2547
|
+
return `${n} ${n === 1 ? one : many}`;
|
|
2548
|
+
}
|
|
2549
|
+
function moveConsequence(home, to) {
|
|
2550
|
+
const c = home.carries;
|
|
2551
|
+
const parts = [plural(c.fields, "column", "columns"), plural(c.records, "row", "rows")];
|
|
2552
|
+
if (c.inTrash > 0) parts.push(`${c.inTrash} in the trash`);
|
|
2553
|
+
const extra = c.choiceLists + c.withIt;
|
|
2554
|
+
return `${home.table.name} moves to ${to.name} with its ${parts.join(", ")}` + (c.tablesInside > 0 ? `, the ${plural(c.tablesInside, "table", "tables")} that live${c.tablesInside === 1 ? "s" : ""} inside it or its rows (with their own rows)` : "") + (extra > 0 ? `, and ${plural(extra, "thing", "things")} built only on it (choice lists, rules, dashboards, templates)` : "") + `, its comments, forms, saved views and history. ` + (c.linksAcross > 0 ? `${plural(c.linksAcross, "link", "links")} to rows that stay in ${home.organization.name} keep${c.linksAcross === 1 ? "s" : ""} pointing there, across the two organizations. ` : "") + `People who see it only because they are in ${home.organization.name} stop seeing it; people it was shared with by name keep it. You can move it back from the same place.`;
|
|
2555
|
+
}
|
|
2556
|
+
|
|
2444
2557
|
// src/level.ts
|
|
2445
2558
|
var PERMISSION_LEVELS = [
|
|
2446
2559
|
"viewer",
|
|
@@ -4449,6 +4562,8 @@ var ENTITY_TOKENS = [
|
|
|
4449
4562
|
|
|
4450
4563
|
// src/core/doors.ts
|
|
4451
4564
|
var OWED_BY = {
|
|
4565
|
+
table_home: "SC-1' \u2014 matrx-frontend migrations/campaign/sc1p_a_table_says_where_it_lives_and_its_owner_can_move_it.sql (and its grant file), applied by the chair",
|
|
4566
|
+
table_move: "SC-1' / SC-1-TAILS \u2014 sc1p_a_table_says_where_it_lives_and_its_owner_can_move_it.sql, then sc1t_a_table_moves_with_the_tables_inside_it.sql, applied by the chair",
|
|
4452
4567
|
metadata_search: "W5-SRV / W5-AGENT \u2014 the agent surface's eight verbs",
|
|
4453
4568
|
record_aggregate: "W5-SRV / W5-AGENT \u2014 `record_aggregate` is one of the eight verbs",
|
|
4454
4569
|
field_propose: "W5-AGENT \u2014 AGT-4/AGT-8, the proposal and its approvers",
|
|
@@ -4774,6 +4889,12 @@ var DOORS = {
|
|
|
4774
4889
|
// ask, under the same wall and visibility gate as `portals` itself.
|
|
4775
4890
|
portalTables: "portal_tables",
|
|
4776
4891
|
tableFacts: "table_facts",
|
|
4892
|
+
// WHERE A TABLE LIVES, AND MOVING IT (SC-1' / SC-1-TAILS). `table_home` answers only when the
|
|
4893
|
+
// caller may open the Table (custom.where_id_opens) and names its organization FROM THE TABLE;
|
|
4894
|
+
// `table_move` moves it into another organization the caller belongs to, with every Table
|
|
4895
|
+
// inside it, or refuses with one sentence.
|
|
4896
|
+
tableHome: "table_home",
|
|
4897
|
+
tableMove: "table_move",
|
|
4777
4898
|
portalCard: "portal_card",
|
|
4778
4899
|
portalDeclare: "portal_declare",
|
|
4779
4900
|
portalInvite: "portal_invite",
|
|
@@ -5417,6 +5538,40 @@ function createRecordsClient(config) {
|
|
|
5417
5538
|
if (!doorExists(DOORS.tableFacts)) return ok(null);
|
|
5418
5539
|
return callDoor(DOORS.tableFacts, { p_organization_id: org }, "tableFacts");
|
|
5419
5540
|
},
|
|
5541
|
+
async tableHome({ table_id }) {
|
|
5542
|
+
const answered = await callDoor(DOORS.tableHome, { p_table_id: table_id }, "tableHome");
|
|
5543
|
+
if (!answered.ok) return answered;
|
|
5544
|
+
if (answered.data === null || answered.data === void 0) return ok(null);
|
|
5545
|
+
const home = parseTableHome(answered.data);
|
|
5546
|
+
if (!home) {
|
|
5547
|
+
const refusal = {
|
|
5548
|
+
code: "not_supported",
|
|
5549
|
+
message: "The record store answered where this table lives in a shape this client cannot read, so nothing is claimed about it.",
|
|
5550
|
+
hint: "Regenerate @ai-matrx/records against the store (pnpm records:generate) \u2014 the door and this client disagree."
|
|
5551
|
+
};
|
|
5552
|
+
scream({ code: refusal.code, message: refusal.message, ...refusal.hint ? { hint: refusal.hint } : {}, where: "tableHome" });
|
|
5553
|
+
return err(refusal);
|
|
5554
|
+
}
|
|
5555
|
+
return ok(home);
|
|
5556
|
+
},
|
|
5557
|
+
async tableMove({ table_id, to_organization_id, expected_version }) {
|
|
5558
|
+
const answered = await callDoor(
|
|
5559
|
+
DOORS.tableMove,
|
|
5560
|
+
{ p_table_id: table_id, p_to_organization_id: to_organization_id, p_expected_version: expected_version ?? null },
|
|
5561
|
+
"tableMove"
|
|
5562
|
+
);
|
|
5563
|
+
if (!answered.ok) return answered;
|
|
5564
|
+
const moved = parseTableMoved(answered.data);
|
|
5565
|
+
if (!moved) {
|
|
5566
|
+
const refusal = {
|
|
5567
|
+
code: "not_supported",
|
|
5568
|
+
message: "The record store answered the move in a shape this client cannot read. Look where the table lives before trying again."
|
|
5569
|
+
};
|
|
5570
|
+
scream({ code: refusal.code, message: refusal.message, where: "tableMove" });
|
|
5571
|
+
return err(refusal);
|
|
5572
|
+
}
|
|
5573
|
+
return ok(moved);
|
|
5574
|
+
},
|
|
5420
5575
|
async tableArchived({ table_id }) {
|
|
5421
5576
|
const kernel = await callDoor(DOORS.tableKernelId, {}, "tableArchived.kernel");
|
|
5422
5577
|
if (!kernel.ok) return err(kernel.error);
|
|
@@ -8440,56 +8595,6 @@ function emptyPortalArchiveLine() {
|
|
|
8440
8595
|
return "No portal of this organization has been archived. A portal you put away waits here until somebody restores it, and nothing is ever destroyed.";
|
|
8441
8596
|
}
|
|
8442
8597
|
|
|
8443
|
-
// src/placement.ts
|
|
8444
|
-
function keptOutOfSight(placement) {
|
|
8445
|
-
return placement?.kept_by_the_app === true;
|
|
8446
|
-
}
|
|
8447
|
-
function offeredAsContext(placement) {
|
|
8448
|
-
return placement?.offered_as_context === true;
|
|
8449
|
-
}
|
|
8450
|
-
function withTablePlacement(tables, facts) {
|
|
8451
|
-
if (!facts) return [...tables];
|
|
8452
|
-
const byId = new Map(facts.map((f) => [f.table_id, f]));
|
|
8453
|
-
return tables.map((table) => {
|
|
8454
|
-
const fact = byId.get(table.id);
|
|
8455
|
-
if (!fact || fact.kept_by_the_app === void 0) return table;
|
|
8456
|
-
return {
|
|
8457
|
-
...table,
|
|
8458
|
-
kept_by_the_app: fact.kept_by_the_app,
|
|
8459
|
-
kept_for: fact.kept_for ?? null,
|
|
8460
|
-
offered_as_context: fact.offered_as_context ?? false,
|
|
8461
|
-
keeper_group: fact.keeper_group ?? null,
|
|
8462
|
-
keeper_says: fact.keeper_says ?? null,
|
|
8463
|
-
used_in_kind: fact.used_in_kind ?? null,
|
|
8464
|
-
used_in_id: fact.used_in_id ?? null,
|
|
8465
|
-
used_in_table_id: fact.used_in_table_id ?? null
|
|
8466
|
-
};
|
|
8467
|
-
});
|
|
8468
|
-
}
|
|
8469
|
-
function keptGroups(tables) {
|
|
8470
|
-
const out = [];
|
|
8471
|
-
const at = /* @__PURE__ */ new Map();
|
|
8472
|
-
for (const table of tables) {
|
|
8473
|
-
if (!keptOutOfSight(table)) continue;
|
|
8474
|
-
const group = table.keeper_group?.trim() || "Kept by the app";
|
|
8475
|
-
let i = at.get(group);
|
|
8476
|
-
if (i === void 0) {
|
|
8477
|
-
i = out.length;
|
|
8478
|
-
at.set(group, i);
|
|
8479
|
-
out.push({ group, tables: [] });
|
|
8480
|
-
}
|
|
8481
|
-
out[i].tables.push(table);
|
|
8482
|
-
}
|
|
8483
|
-
return out;
|
|
8484
|
-
}
|
|
8485
|
-
function keptTableHref(fact, hrefs) {
|
|
8486
|
-
if (fact.used_in_kind === "scope" && fact.used_in_id) return hrefs.scope(fact.used_in_id);
|
|
8487
|
-
if (fact.used_in_kind === "table" && (fact.used_in_table_id || fact.used_in_id)) {
|
|
8488
|
-
return hrefs.table(fact.used_in_table_id || fact.used_in_id);
|
|
8489
|
-
}
|
|
8490
|
-
return hrefs.table(fact.table_id);
|
|
8491
|
-
}
|
|
8492
|
-
|
|
8493
8598
|
// src/capture-queue.ts
|
|
8494
8599
|
var DB_NAME = "matrx-capture";
|
|
8495
8600
|
var DB_VERSION = 1;
|
|
@@ -8558,7 +8663,7 @@ function memoryStore() {
|
|
|
8558
8663
|
setMeta: async (key, value) => void meta.set(key, value)
|
|
8559
8664
|
};
|
|
8560
8665
|
}
|
|
8561
|
-
function
|
|
8666
|
+
function countOf2(items) {
|
|
8562
8667
|
const c = { waiting: 0, sending: 0, refused: 0, landed: 0 };
|
|
8563
8668
|
for (const i of items) c[i.state] += 1;
|
|
8564
8669
|
return c;
|
|
@@ -8575,7 +8680,7 @@ function openCaptureQueue(opts) {
|
|
|
8575
8680
|
const announce = async () => {
|
|
8576
8681
|
if (!opts.onChange) return;
|
|
8577
8682
|
const items = await store.all();
|
|
8578
|
-
opts.onChange(
|
|
8683
|
+
opts.onChange(countOf2(items), items);
|
|
8579
8684
|
};
|
|
8580
8685
|
const oldestFirst = (items) => items.slice().sort((a, b) => a.captured_at.localeCompare(b.captured_at));
|
|
8581
8686
|
const queue = {
|
|
@@ -8604,7 +8709,7 @@ function openCaptureQueue(opts) {
|
|
|
8604
8709
|
return key;
|
|
8605
8710
|
},
|
|
8606
8711
|
list: () => store.all().then(oldestFirst),
|
|
8607
|
-
counts: () => store.all().then(
|
|
8712
|
+
counts: () => store.all().then(countOf2),
|
|
8608
8713
|
async sync() {
|
|
8609
8714
|
if (syncing) return syncing;
|
|
8610
8715
|
syncing = (async () => {
|