@ai-matrx/records 0.99.31 → 0.99.33
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 +21 -0
- package/dist/{client-Dthx26hr.d.ts → client-CSfkP7Xf.d.ts} +11 -80
- package/dist/{client-B7KEs9hi.d.cts → client-jKf1Z-kp.d.cts} +11 -80
- package/dist/core/index.cjs +149 -105
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +18 -359
- package/dist/core/index.d.ts +18 -359
- package/dist/core/index.js +149 -105
- package/dist/core/index.js.map +1 -1
- package/dist/data/index.cjs +280 -236
- package/dist/data/index.cjs.map +1 -1
- package/dist/data/index.d.cts +12 -11
- package/dist/data/index.d.ts +12 -11
- package/dist/data/index.js +280 -236
- package/dist/data/index.js.map +1 -1
- package/dist/{declareTable-CvBu5dTJ.d.ts → declareTable-0emxEewn.d.ts} +3 -3
- package/dist/{declareTable-enQs2N0E.d.cts → declareTable-800bwUn3.d.cts} +3 -3
- package/dist/door-call/index.cjs +1287 -0
- package/dist/door-call/index.cjs.map +1 -0
- package/dist/door-call/index.d.cts +20 -0
- package/dist/door-call/index.d.ts +20 -0
- package/dist/door-call/index.js +1264 -0
- package/dist/door-call/index.js.map +1 -0
- package/dist/{doors-KbjyhBW-.d.cts → doors-BgjRUdxw.d.cts} +14 -2
- package/dist/{doors-C2-sFvAk.d.ts → doors-D7_jEKtg.d.ts} +14 -2
- package/dist/entity/index.d.cts +7 -7
- package/dist/entity/index.d.ts +7 -7
- package/dist/{field-ppX29ddi.d.cts → field-B8loYt-A.d.cts} +1 -1
- package/dist/{field-BHlhq24W.d.ts → field-DaE90BZ7.d.ts} +1 -1
- package/dist/forms/index.d.cts +3 -3
- package/dist/forms/index.d.ts +3 -3
- package/dist/index.d.cts +14 -13
- package/dist/index.d.ts +14 -13
- package/dist/memory/index.d.cts +7 -7
- package/dist/memory/index.d.ts +7 -7
- package/dist/{objectOrganization-Cu73SBxH.d.cts → objectOrganization-B5YFGVUB.d.cts} +2 -2
- package/dist/{objectOrganization-DtR3lWG2.d.ts → objectOrganization-DozoVIxS.d.ts} +2 -2
- package/dist/pickListDoors-C-_eAEGL.d.cts +135 -0
- package/dist/pickListDoors-DgWVnNRI.d.ts +135 -0
- package/dist/{port-Bk7TG0aE.d.ts → port-D6wepPvr.d.ts} +3 -3
- package/dist/{port-rqQEGhew.d.cts → port-O-UdH1HS.d.cts} +3 -3
- package/dist/{portal-DmxuUr2f.d.ts → portal-CAssJHRZ.d.ts} +1 -1
- package/dist/{portal-ffH13fsE.d.cts → portal-L_mN8l9P.d.cts} +1 -1
- package/dist/{ports-BCNNghmf.d.ts → ports-CmmvR8OI.d.ts} +2 -2
- package/dist/{ports-iATV-A2v.d.cts → ports-alv3bgKY.d.cts} +2 -2
- package/dist/questions/index.d.cts +10 -9
- package/dist/questions/index.d.ts +10 -9
- package/dist/react/index.cjs +363 -319
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +37 -22
- package/dist/react/index.d.ts +37 -22
- package/dist/react/index.js +363 -319
- package/dist/react/index.js.map +1 -1
- package/dist/realtime/index.d.cts +3 -3
- package/dist/realtime/index.d.ts +3 -3
- package/dist/{record-C8q21jjB.d.cts → record-CTgSgWe3.d.cts} +1 -1
- package/dist/{record-C8q21jjB.d.ts → record-CTgSgWe3.d.ts} +1 -1
- package/dist/{relation-Bwp8iuei.d.cts → relation-BjjjXyqn.d.cts} +2 -2
- package/dist/{relation-Bsjwkn6N.d.ts → relation-T4biacnz.d.ts} +2 -2
- package/dist/results/index.cjs +245 -0
- package/dist/results/index.cjs.map +1 -0
- package/dist/results/index.d.cts +24 -0
- package/dist/results/index.d.ts +24 -0
- package/dist/results/index.js +222 -0
- package/dist/results/index.js.map +1 -0
- package/dist/{rule-BQwUtKk5.d.cts → rule-49jO7lN-.d.cts} +1 -1
- package/dist/{rule-cGqclk_0.d.ts → rule-DzNj0QvN.d.ts} +1 -1
- package/dist/scopes/index.cjs +7 -0
- package/dist/scopes/index.cjs.map +1 -1
- package/dist/scopes/index.d.cts +3 -3
- package/dist/scopes/index.d.ts +3 -3
- package/dist/scopes/index.js +7 -0
- package/dist/scopes/index.js.map +1 -1
- package/dist/search/index.d.cts +1 -1
- package/dist/search/index.d.ts +1 -1
- package/dist/setup/index.cjs +289 -245
- package/dist/setup/index.cjs.map +1 -1
- package/dist/setup/index.d.cts +13 -12
- package/dist/setup/index.d.ts +13 -12
- package/dist/setup/index.js +289 -245
- package/dist/setup/index.js.map +1 -1
- package/dist/{subscription-eNzL9scc.d.ts → subscription-Bp1RSb6p.d.ts} +2 -2
- package/dist/{subscription-Ba8RKtPA.d.cts → subscription-CuaGi3lC.d.cts} +2 -2
- package/dist/table-logic-BPquabNN.d.ts +328 -0
- package/dist/table-logic-CTh6lwaq.d.cts +328 -0
- package/dist/templates/index.d.cts +10 -10
- package/dist/templates/index.d.ts +10 -10
- package/dist/typed-table/index.cjs +280 -236
- package/dist/typed-table/index.cjs.map +1 -1
- package/dist/typed-table/index.d.cts +11 -10
- package/dist/typed-table/index.d.ts +11 -10
- package/dist/typed-table/index.js +280 -236
- package/dist/typed-table/index.js.map +1 -1
- package/dist/{types-C4XCuv8O.d.cts → types-B54BeQzf.d.cts} +2 -2
- package/dist/{types-BlzdL4Vd.d.cts → types-BWfL38XJ.d.cts} +2 -2
- package/dist/{types-BBR2NGqj.d.ts → types-BZcYXFK3.d.ts} +2 -2
- package/dist/{types-EKwXJfxY.d.cts → types-Bztv0-pH.d.cts} +2 -2
- package/dist/{types-CmkHpvll.d.ts → types-CjGuR5ks.d.ts} +2 -2
- package/dist/{types-CrkzINrb.d.ts → types-bN7dG2ji.d.ts} +2 -2
- package/dist/use-cases/index.d.cts +5 -5
- package/dist/use-cases/index.d.ts +5 -5
- package/dist/{validate-BKeBAVSi.d.cts → validate-8VBa2xIU.d.cts} +1 -1
- package/dist/{validate-BB6DWgCP.d.ts → validate-xBnply7J.d.ts} +1 -1
- package/dist/views/index.d.cts +10 -9
- package/dist/views/index.d.ts +10 -9
- package/package.json +24 -4
package/dist/data/index.d.cts
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
import { C as Column, Q as Query, A as AliasBinding, H as HostDataPort } from '../types-
|
|
2
|
-
export { a as AnyAlias, b as CUSTOM_ROW_TOKEN, D as DataEvents, c as DataPort, d as DataPortEventName, e as DataSource, E as EntityAlias, f as EntityRef, L as Lane, P as Page, R as Row, g as RowsEvent, T as TableAlias, V as Values, W as WhereClause, h as WhereOp } from '../types-
|
|
3
|
-
import { R as RecordsClient } from '../client-
|
|
4
|
-
import { F as Field } from '../field-
|
|
5
|
-
import { U as Uuid, R as RecordsResult, k as RecordPageSort, l as ReadRow } from '../record-
|
|
6
|
-
import { R as RuleExpression } from '../rule-
|
|
7
|
-
import '../relation-
|
|
8
|
-
import '../ports-
|
|
9
|
-
import '../subscription-
|
|
10
|
-
import '../doors-
|
|
11
|
-
import '../
|
|
1
|
+
import { C as Column, Q as Query, A as AliasBinding, H as HostDataPort } from '../types-B54BeQzf.cjs';
|
|
2
|
+
export { a as AnyAlias, b as CUSTOM_ROW_TOKEN, D as DataEvents, c as DataPort, d as DataPortEventName, e as DataSource, E as EntityAlias, f as EntityRef, L as Lane, P as Page, R as Row, g as RowsEvent, T as TableAlias, V as Values, W as WhereClause, h as WhereOp } from '../types-B54BeQzf.cjs';
|
|
3
|
+
import { R as RecordsClient } from '../client-jKf1Z-kp.cjs';
|
|
4
|
+
import { F as Field } from '../field-B8loYt-A.cjs';
|
|
5
|
+
import { U as Uuid, R as RecordsResult, k as RecordPageSort, l as ReadRow } from '../record-CTgSgWe3.cjs';
|
|
6
|
+
import { R as RuleExpression } from '../rule-49jO7lN-.cjs';
|
|
7
|
+
import '../relation-BjjjXyqn.cjs';
|
|
8
|
+
import '../ports-alv3bgKY.cjs';
|
|
9
|
+
import '../subscription-CuaGi3lC.cjs';
|
|
10
|
+
import '../doors-BgjRUdxw.cjs';
|
|
11
|
+
import '../pickListDoors-C-_eAEGL.cjs';
|
|
12
|
+
import '../portal-L_mN8l9P.cjs';
|
|
12
13
|
import '../table-kind/index.cjs';
|
|
13
14
|
|
|
14
15
|
interface TableShape {
|
package/dist/data/index.d.ts
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
import { C as Column, Q as Query, A as AliasBinding, H as HostDataPort } from '../types-
|
|
2
|
-
export { a as AnyAlias, b as CUSTOM_ROW_TOKEN, D as DataEvents, c as DataPort, d as DataPortEventName, e as DataSource, E as EntityAlias, f as EntityRef, L as Lane, P as Page, R as Row, g as RowsEvent, T as TableAlias, V as Values, W as WhereClause, h as WhereOp } from '../types-
|
|
3
|
-
import { R as RecordsClient } from '../client-
|
|
4
|
-
import { F as Field } from '../field-
|
|
5
|
-
import { U as Uuid, R as RecordsResult, k as RecordPageSort, l as ReadRow } from '../record-
|
|
6
|
-
import { R as RuleExpression } from '../rule-
|
|
7
|
-
import '../relation-
|
|
8
|
-
import '../ports-
|
|
9
|
-
import '../subscription-
|
|
10
|
-
import '../doors-
|
|
11
|
-
import '../
|
|
1
|
+
import { C as Column, Q as Query, A as AliasBinding, H as HostDataPort } from '../types-bN7dG2ji.js';
|
|
2
|
+
export { a as AnyAlias, b as CUSTOM_ROW_TOKEN, D as DataEvents, c as DataPort, d as DataPortEventName, e as DataSource, E as EntityAlias, f as EntityRef, L as Lane, P as Page, R as Row, g as RowsEvent, T as TableAlias, V as Values, W as WhereClause, h as WhereOp } from '../types-bN7dG2ji.js';
|
|
3
|
+
import { R as RecordsClient } from '../client-CSfkP7Xf.js';
|
|
4
|
+
import { F as Field } from '../field-DaE90BZ7.js';
|
|
5
|
+
import { U as Uuid, R as RecordsResult, k as RecordPageSort, l as ReadRow } from '../record-CTgSgWe3.js';
|
|
6
|
+
import { R as RuleExpression } from '../rule-DzNj0QvN.js';
|
|
7
|
+
import '../relation-T4biacnz.js';
|
|
8
|
+
import '../ports-CmmvR8OI.js';
|
|
9
|
+
import '../subscription-Bp1RSb6p.js';
|
|
10
|
+
import '../doors-D7_jEKtg.js';
|
|
11
|
+
import '../pickListDoors-DgWVnNRI.js';
|
|
12
|
+
import '../portal-CAssJHRZ.js';
|
|
12
13
|
import '../table-kind/index.js';
|
|
13
14
|
|
|
14
15
|
interface TableShape {
|
package/dist/data/index.js
CHANGED
|
@@ -235,137 +235,6 @@ function isWritingDoor(door) {
|
|
|
235
235
|
return /(_declare|_set(_|$)|_update|_write|_delete|_restore|_archive|_upsert|_reparent|_change|_duplicate|_move|_decide|_run$|_submit|_publish|_import_|_start$|_complete|_sign$|_add$|_retire|_propose|_promote|_land$|_pin$|_mute|_snooze|_unsnooze|_clear|_unclear|_revoke|_issue|_bind|_unbind|_apply|_backfill|_sync$|_decorate|_designate|_ensure|^migrate_|^set_table_|^home_add|^capture_|^claim_|^record_stage|^anon_|^io_import_|^io_comment_resolve|^enrich_(declare|land|pin)|^field_(declare|duplicate|propose|restore|retire|update)|^table_(declare|ensure|from_example|move|sync)|^value_restore|^relation_own)/.test(door);
|
|
236
236
|
}
|
|
237
237
|
|
|
238
|
-
// src/core/recordChanges.ts
|
|
239
|
-
import { globalSlot } from "@ai-matrx/kit/global-slot";
|
|
240
|
-
var listeners = globalSlot("ai-matrx.records.record-change-listeners", () => /* @__PURE__ */ new Set());
|
|
241
|
-
function announceRecordChanged(recordId) {
|
|
242
|
-
for (const listener of [...listeners]) {
|
|
243
|
-
try {
|
|
244
|
-
listener(recordId);
|
|
245
|
-
} catch (thrown) {
|
|
246
|
-
console.error("[@ai-matrx/records] a record-change listener threw", thrown);
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
var removed = globalSlot("ai-matrx.records.removed-records", () => /* @__PURE__ */ new Set());
|
|
251
|
-
function markRecordRemoved(recordId) {
|
|
252
|
-
removed.add(recordId);
|
|
253
|
-
}
|
|
254
|
-
function markRecordRestored(recordId) {
|
|
255
|
-
removed.delete(recordId);
|
|
256
|
-
}
|
|
257
|
-
function onRecordChanged(listener) {
|
|
258
|
-
listeners.add(listener);
|
|
259
|
-
return () => listeners.delete(listener);
|
|
260
|
-
}
|
|
261
|
-
var tableListeners = globalSlot("ai-matrx.records.table-structure-listeners", () => /* @__PURE__ */ new Set());
|
|
262
|
-
function announceTableStructureChanged(tableId) {
|
|
263
|
-
for (const listener of [...tableListeners]) {
|
|
264
|
-
try {
|
|
265
|
-
listener(tableId);
|
|
266
|
-
} catch (thrown) {
|
|
267
|
-
console.error("[@ai-matrx/records] a table-structure listener threw", thrown);
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
// src/archive.ts
|
|
273
|
-
var DEFAULT_ARCHIVE_LANE = "org";
|
|
274
|
-
|
|
275
|
-
// src/aggregate.ts
|
|
276
|
-
function isRuleFilter(filter) {
|
|
277
|
-
if (!filter || typeof filter !== "object" || Array.isArray(filter)) return false;
|
|
278
|
-
const node = filter;
|
|
279
|
-
return typeof node.op === "string" && Array.isArray(node.args);
|
|
280
|
-
}
|
|
281
|
-
function stableFilterKey(filter) {
|
|
282
|
-
if (!filter) return "{}";
|
|
283
|
-
if (isRuleFilter(filter)) return JSON.stringify(filter);
|
|
284
|
-
const keys = Object.keys(filter).sort();
|
|
285
|
-
if (keys.length === 0) return "{}";
|
|
286
|
-
const parts = keys.map((key) => {
|
|
287
|
-
const value = filter[key];
|
|
288
|
-
if (value !== null && typeof value === "object") {
|
|
289
|
-
const window = value;
|
|
290
|
-
return `${JSON.stringify(key)}:{"from":${JSON.stringify(window.from ?? null)},"to":${JSON.stringify(window.to ?? null)}}`;
|
|
291
|
-
}
|
|
292
|
-
return `${JSON.stringify(key)}:${JSON.stringify(value ?? null)}`;
|
|
293
|
-
});
|
|
294
|
-
return `{${parts.join(",")}}`;
|
|
295
|
-
}
|
|
296
|
-
function liftWithheld(rows) {
|
|
297
|
-
let shared;
|
|
298
|
-
for (const row of rows) {
|
|
299
|
-
const m = (row.measures ?? {})["_withheld"];
|
|
300
|
-
if (m !== void 0 && m !== null && typeof m === "object") {
|
|
301
|
-
shared = m;
|
|
302
|
-
break;
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
|
-
return rows.map((row) => {
|
|
306
|
-
const measures = row.measures ?? {};
|
|
307
|
-
const own = measures["_withheld"];
|
|
308
|
-
const marker = own !== void 0 && own !== null && typeof own === "object" ? own : shared;
|
|
309
|
-
const rowCount = row.row_count ?? 0;
|
|
310
|
-
if (marker === void 0 || marker === null || typeof marker !== "object") {
|
|
311
|
-
return rowCount === row.row_count ? row : { ...row, row_count: rowCount };
|
|
312
|
-
}
|
|
313
|
-
const { _withheld: _drop, ...rest } = measures;
|
|
314
|
-
const withheld = {};
|
|
315
|
-
for (const [name, raw] of Object.entries(marker)) {
|
|
316
|
-
const m = raw ?? {};
|
|
317
|
-
withheld[name] = {
|
|
318
|
-
reason: m.withheld?.reason ?? null,
|
|
319
|
-
needs: m.withheld?.needs ?? null,
|
|
320
|
-
or: m.withheld?.or ?? null,
|
|
321
|
-
...m.says ? { says: m.says } : {},
|
|
322
|
-
...m.label ? { label: m.label } : {},
|
|
323
|
-
...m.field_key ? { field_key: m.field_key } : {}
|
|
324
|
-
};
|
|
325
|
-
}
|
|
326
|
-
return { ...row, measures: rest, withheld, row_count: rowCount };
|
|
327
|
-
});
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
// src/record.ts
|
|
331
|
-
function isLockedStub(row) {
|
|
332
|
-
if (!row) return false;
|
|
333
|
-
if (row.level !== null && row.level !== void 0) return false;
|
|
334
|
-
const doc = row.document;
|
|
335
|
-
if (!doc || typeof doc !== "object") return false;
|
|
336
|
-
const keys = Object.keys(doc);
|
|
337
|
-
if (keys.length === 0 || keys.length > 3) return false;
|
|
338
|
-
const d = doc;
|
|
339
|
-
return d["exists"] === true && keys.every((k) => k === "id" || k === "exists" || k === "submitted_at");
|
|
340
|
-
}
|
|
341
|
-
function splitLockedRows(rows) {
|
|
342
|
-
const open = [];
|
|
343
|
-
let locked = 0;
|
|
344
|
-
for (const row of rows) {
|
|
345
|
-
if (isLockedStub(row)) locked += 1;
|
|
346
|
-
else open.push(row);
|
|
347
|
-
}
|
|
348
|
-
return { rows: open, locked };
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
// src/subscription.ts
|
|
352
|
-
function callersTimeZone() {
|
|
353
|
-
try {
|
|
354
|
-
return Intl.DateTimeFormat().resolvedOptions().timeZone || null;
|
|
355
|
-
} catch {
|
|
356
|
-
return null;
|
|
357
|
-
}
|
|
358
|
-
}
|
|
359
|
-
function withCallersClock(spec, zone = callersTimeZone()) {
|
|
360
|
-
if (!zone || spec.quiet_hours?.tz) return spec;
|
|
361
|
-
return { ...spec, quiet_hours: { ...spec.quiet_hours ?? {}, tz: zone } };
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
// src/rowLabel.ts
|
|
365
|
-
function clearsRowLabel(formula) {
|
|
366
|
-
return formula == null || formula.trim() === "";
|
|
367
|
-
}
|
|
368
|
-
|
|
369
238
|
// src/results.ts
|
|
370
239
|
var ok = (data) => ({ ok: true, data });
|
|
371
240
|
var err = (error) => ({ ok: false, error });
|
|
@@ -536,6 +405,230 @@ function mapPgError(error, where) {
|
|
|
536
405
|
return mapped;
|
|
537
406
|
}
|
|
538
407
|
|
|
408
|
+
// src/core/doorCall.ts
|
|
409
|
+
var DEFAULT_DOOR_SCHEMA = "custom";
|
|
410
|
+
function canonicalArgs(value) {
|
|
411
|
+
return JSON.stringify(
|
|
412
|
+
value,
|
|
413
|
+
(_key, held) => held && typeof held === "object" && !Array.isArray(held) ? Object.fromEntries(Object.keys(held).sort().map((k) => [k, held[k]])) : held
|
|
414
|
+
);
|
|
415
|
+
}
|
|
416
|
+
var A_PERSONS_REFUSAL = /* @__PURE__ */ new Set([
|
|
417
|
+
"refused_by_rule",
|
|
418
|
+
"stale_write",
|
|
419
|
+
"invalid_argument",
|
|
420
|
+
"already_exists",
|
|
421
|
+
"missing_reference"
|
|
422
|
+
]);
|
|
423
|
+
function isAPersonsRefusal(code) {
|
|
424
|
+
return A_PERSONS_REFUSAL.has(code);
|
|
425
|
+
}
|
|
426
|
+
function recordsErrorSink(onError) {
|
|
427
|
+
return onError ?? ((e) => {
|
|
428
|
+
const line = `[@ai-matrx/records] ${e.where}: ${e.code} \u2014 ${e.message}${e.hint ? ` (${e.hint})` : ""}`;
|
|
429
|
+
if (isAPersonsRefusal(e.code)) console.info(line);
|
|
430
|
+
else console.error(line);
|
|
431
|
+
});
|
|
432
|
+
}
|
|
433
|
+
function doorAbsentRefusal(name, owedBy) {
|
|
434
|
+
return {
|
|
435
|
+
code: "door_absent",
|
|
436
|
+
message: `The record store has no door \`custom.${name}\` yet, so this call was not made. Nothing was read and nothing was written.`,
|
|
437
|
+
hint: owedBy ? `That door is ${owedBy}. Until it lands, this call refuses rather than guessing: an empty answer here would read like "there is nothing", which is a different sentence.` : `No lane in the build book claims this door. Either the name is wrong, or the door was removed from the store and this package has not been regenerated \u2014 run \`pnpm records:generate\`.`
|
|
438
|
+
};
|
|
439
|
+
}
|
|
440
|
+
function primedDoorAnswer(door, args) {
|
|
441
|
+
const look = LOOK_WRITES[door];
|
|
442
|
+
if (look) {
|
|
443
|
+
dropPrimedDoorAnswers(look);
|
|
444
|
+
return null;
|
|
445
|
+
}
|
|
446
|
+
if (isWritingDoor(door)) {
|
|
447
|
+
dropPrimedDoorAnswers();
|
|
448
|
+
return null;
|
|
449
|
+
}
|
|
450
|
+
return takePrimedDoorAnswer(`${door}|${canonicalArgs(args)}`);
|
|
451
|
+
}
|
|
452
|
+
function createDoorCall(options) {
|
|
453
|
+
const { dataSource, doorReady: doorReady2, held, wrote } = options;
|
|
454
|
+
const schema = options.schema ?? DEFAULT_DOOR_SCHEMA;
|
|
455
|
+
const scream = recordsErrorSink(options.onError);
|
|
456
|
+
const absent = options.absent ?? ((door) => doorAbsentRefusal(door));
|
|
457
|
+
const readsInFlight = /* @__PURE__ */ new Map();
|
|
458
|
+
const say = (refusal2, where) => scream({ code: refusal2.code, message: refusal2.message, ...refusal2.hint ? { hint: refusal2.hint } : {}, where });
|
|
459
|
+
return async function callDoor(door, args, where, opts) {
|
|
460
|
+
const primed = primedDoorAnswer(door, args);
|
|
461
|
+
if (primed) return ok(primed.data);
|
|
462
|
+
if (held) {
|
|
463
|
+
const bundled = await held(door, args);
|
|
464
|
+
if (bundled) return ok(bundled.data);
|
|
465
|
+
}
|
|
466
|
+
if (doorReady2 && !doorReady2(door)) {
|
|
467
|
+
const refusal2 = absent(door);
|
|
468
|
+
say(refusal2, where);
|
|
469
|
+
return err(refusal2);
|
|
470
|
+
}
|
|
471
|
+
const flightKey = isWritingDoor(door) ? null : `${door}|${canonicalArgs(args)}`;
|
|
472
|
+
const flying = flightKey ? readsInFlight.get(flightKey) : void 0;
|
|
473
|
+
const response = await (flying ?? (() => {
|
|
474
|
+
const call = Promise.resolve(dataSource.rpc(`${door}`, args, { schema }));
|
|
475
|
+
if (flightKey) {
|
|
476
|
+
readsInFlight.set(flightKey, call);
|
|
477
|
+
const forget = () => {
|
|
478
|
+
if (readsInFlight.get(flightKey) === call) readsInFlight.delete(flightKey);
|
|
479
|
+
};
|
|
480
|
+
call.then(forget, forget);
|
|
481
|
+
}
|
|
482
|
+
return call;
|
|
483
|
+
})());
|
|
484
|
+
if (response.error) {
|
|
485
|
+
const code = response.error.code;
|
|
486
|
+
const refusal2 = !doorReady2 && (code === "PGRST202" || code === "42883") ? absent(door) : mapPgError(response.error, where);
|
|
487
|
+
if (opts?.quiet) console.info(`[@ai-matrx/records] ${where}: ${refusal2.code} - ${refusal2.message}`);
|
|
488
|
+
else say(refusal2, where);
|
|
489
|
+
return err(refusal2);
|
|
490
|
+
}
|
|
491
|
+
if (isWritingDoor(door) || LOOK_WRITES[door]) {
|
|
492
|
+
const tableId = args["p_table_id"];
|
|
493
|
+
wrote?.(door, args);
|
|
494
|
+
forgetPrimedTablePageBundlesOf(typeof tableId === "string" ? tableId : null);
|
|
495
|
+
dropPrimedDoorAnswers(LOOK_WRITES[door]);
|
|
496
|
+
}
|
|
497
|
+
return ok(response.data);
|
|
498
|
+
};
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
// src/core/recordChanges.ts
|
|
502
|
+
import { globalSlot } from "@ai-matrx/kit/global-slot";
|
|
503
|
+
var listeners = globalSlot("ai-matrx.records.record-change-listeners", () => /* @__PURE__ */ new Set());
|
|
504
|
+
function announceRecordChanged(recordId) {
|
|
505
|
+
for (const listener of [...listeners]) {
|
|
506
|
+
try {
|
|
507
|
+
listener(recordId);
|
|
508
|
+
} catch (thrown) {
|
|
509
|
+
console.error("[@ai-matrx/records] a record-change listener threw", thrown);
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
var removed = globalSlot("ai-matrx.records.removed-records", () => /* @__PURE__ */ new Set());
|
|
514
|
+
function markRecordRemoved(recordId) {
|
|
515
|
+
removed.add(recordId);
|
|
516
|
+
}
|
|
517
|
+
function markRecordRestored(recordId) {
|
|
518
|
+
removed.delete(recordId);
|
|
519
|
+
}
|
|
520
|
+
function onRecordChanged(listener) {
|
|
521
|
+
listeners.add(listener);
|
|
522
|
+
return () => listeners.delete(listener);
|
|
523
|
+
}
|
|
524
|
+
var tableListeners = globalSlot("ai-matrx.records.table-structure-listeners", () => /* @__PURE__ */ new Set());
|
|
525
|
+
function announceTableStructureChanged(tableId) {
|
|
526
|
+
for (const listener of [...tableListeners]) {
|
|
527
|
+
try {
|
|
528
|
+
listener(tableId);
|
|
529
|
+
} catch (thrown) {
|
|
530
|
+
console.error("[@ai-matrx/records] a table-structure listener threw", thrown);
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
// src/archive.ts
|
|
536
|
+
var DEFAULT_ARCHIVE_LANE = "org";
|
|
537
|
+
|
|
538
|
+
// src/aggregate.ts
|
|
539
|
+
function isRuleFilter(filter) {
|
|
540
|
+
if (!filter || typeof filter !== "object" || Array.isArray(filter)) return false;
|
|
541
|
+
const node = filter;
|
|
542
|
+
return typeof node.op === "string" && Array.isArray(node.args);
|
|
543
|
+
}
|
|
544
|
+
function stableFilterKey(filter) {
|
|
545
|
+
if (!filter) return "{}";
|
|
546
|
+
if (isRuleFilter(filter)) return JSON.stringify(filter);
|
|
547
|
+
const keys = Object.keys(filter).sort();
|
|
548
|
+
if (keys.length === 0) return "{}";
|
|
549
|
+
const parts = keys.map((key) => {
|
|
550
|
+
const value = filter[key];
|
|
551
|
+
if (value !== null && typeof value === "object") {
|
|
552
|
+
const window = value;
|
|
553
|
+
return `${JSON.stringify(key)}:{"from":${JSON.stringify(window.from ?? null)},"to":${JSON.stringify(window.to ?? null)}}`;
|
|
554
|
+
}
|
|
555
|
+
return `${JSON.stringify(key)}:${JSON.stringify(value ?? null)}`;
|
|
556
|
+
});
|
|
557
|
+
return `{${parts.join(",")}}`;
|
|
558
|
+
}
|
|
559
|
+
function liftWithheld(rows) {
|
|
560
|
+
let shared;
|
|
561
|
+
for (const row of rows) {
|
|
562
|
+
const m = (row.measures ?? {})["_withheld"];
|
|
563
|
+
if (m !== void 0 && m !== null && typeof m === "object") {
|
|
564
|
+
shared = m;
|
|
565
|
+
break;
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
return rows.map((row) => {
|
|
569
|
+
const measures = row.measures ?? {};
|
|
570
|
+
const own = measures["_withheld"];
|
|
571
|
+
const marker = own !== void 0 && own !== null && typeof own === "object" ? own : shared;
|
|
572
|
+
const rowCount = row.row_count ?? 0;
|
|
573
|
+
if (marker === void 0 || marker === null || typeof marker !== "object") {
|
|
574
|
+
return rowCount === row.row_count ? row : { ...row, row_count: rowCount };
|
|
575
|
+
}
|
|
576
|
+
const { _withheld: _drop, ...rest } = measures;
|
|
577
|
+
const withheld = {};
|
|
578
|
+
for (const [name, raw] of Object.entries(marker)) {
|
|
579
|
+
const m = raw ?? {};
|
|
580
|
+
withheld[name] = {
|
|
581
|
+
reason: m.withheld?.reason ?? null,
|
|
582
|
+
needs: m.withheld?.needs ?? null,
|
|
583
|
+
or: m.withheld?.or ?? null,
|
|
584
|
+
...m.says ? { says: m.says } : {},
|
|
585
|
+
...m.label ? { label: m.label } : {},
|
|
586
|
+
...m.field_key ? { field_key: m.field_key } : {}
|
|
587
|
+
};
|
|
588
|
+
}
|
|
589
|
+
return { ...row, measures: rest, withheld, row_count: rowCount };
|
|
590
|
+
});
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
// src/record.ts
|
|
594
|
+
function isLockedStub(row) {
|
|
595
|
+
if (!row) return false;
|
|
596
|
+
if (row.level !== null && row.level !== void 0) return false;
|
|
597
|
+
const doc = row.document;
|
|
598
|
+
if (!doc || typeof doc !== "object") return false;
|
|
599
|
+
const keys = Object.keys(doc);
|
|
600
|
+
if (keys.length === 0 || keys.length > 3) return false;
|
|
601
|
+
const d = doc;
|
|
602
|
+
return d["exists"] === true && keys.every((k) => k === "id" || k === "exists" || k === "submitted_at");
|
|
603
|
+
}
|
|
604
|
+
function splitLockedRows(rows) {
|
|
605
|
+
const open = [];
|
|
606
|
+
let locked = 0;
|
|
607
|
+
for (const row of rows) {
|
|
608
|
+
if (isLockedStub(row)) locked += 1;
|
|
609
|
+
else open.push(row);
|
|
610
|
+
}
|
|
611
|
+
return { rows: open, locked };
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
// src/subscription.ts
|
|
615
|
+
function callersTimeZone() {
|
|
616
|
+
try {
|
|
617
|
+
return Intl.DateTimeFormat().resolvedOptions().timeZone || null;
|
|
618
|
+
} catch {
|
|
619
|
+
return null;
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
function withCallersClock(spec, zone = callersTimeZone()) {
|
|
623
|
+
if (!zone || spec.quiet_hours?.tz) return spec;
|
|
624
|
+
return { ...spec, quiet_hours: { ...spec.quiet_hours ?? {}, tz: zone } };
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
// src/rowLabel.ts
|
|
628
|
+
function clearsRowLabel(formula) {
|
|
629
|
+
return formula == null || formula.trim() === "";
|
|
630
|
+
}
|
|
631
|
+
|
|
539
632
|
// src/relation.ts
|
|
540
633
|
import { isUuidShape as isUuidShape3 } from "@ai-matrx/kit/uuid";
|
|
541
634
|
function isRefLike(value) {
|
|
@@ -1341,11 +1434,51 @@ function createScopeDoors(call) {
|
|
|
1341
1434
|
source_type: String(envelope.data?.source_type ?? cell.source_type ?? "ai_enriched")
|
|
1342
1435
|
}
|
|
1343
1436
|
};
|
|
1437
|
+
},
|
|
1438
|
+
tableProvision({ organization_id, item_id, scope_id, home_id }) {
|
|
1439
|
+
return call(
|
|
1440
|
+
"scope_table_provision",
|
|
1441
|
+
{ p_organization_id: organization_id, p_item_id: item_id, p_scope_id: scope_id, p_home_id: home_id ?? null },
|
|
1442
|
+
"scopeTableProvision"
|
|
1443
|
+
);
|
|
1344
1444
|
}
|
|
1345
1445
|
};
|
|
1346
1446
|
return doors;
|
|
1347
1447
|
}
|
|
1348
1448
|
|
|
1449
|
+
// src/core/pickListDoors.ts
|
|
1450
|
+
var PICK_LIST_DOORS = {
|
|
1451
|
+
pickListGet: "pick_list_get",
|
|
1452
|
+
pickListForSelection: "pick_list_for_selection",
|
|
1453
|
+
pickListUpdate: "pick_list_update"
|
|
1454
|
+
};
|
|
1455
|
+
function createPickListDoors(callDoor) {
|
|
1456
|
+
return {
|
|
1457
|
+
async pickListGet({ list_id }) {
|
|
1458
|
+
return callDoor(PICK_LIST_DOORS.pickListGet, { p_list_id: list_id }, "pickListGet");
|
|
1459
|
+
},
|
|
1460
|
+
async pickListForSelection({ list_id }) {
|
|
1461
|
+
return callDoor(
|
|
1462
|
+
PICK_LIST_DOORS.pickListForSelection,
|
|
1463
|
+
{ p_list_id: list_id },
|
|
1464
|
+
"pickListForSelection"
|
|
1465
|
+
);
|
|
1466
|
+
},
|
|
1467
|
+
async pickListUpdate({ list_id, list_name, description, items }) {
|
|
1468
|
+
return callDoor(
|
|
1469
|
+
PICK_LIST_DOORS.pickListUpdate,
|
|
1470
|
+
{
|
|
1471
|
+
p_list_id: list_id,
|
|
1472
|
+
p_list_name: list_name ?? null,
|
|
1473
|
+
p_description: description ?? null,
|
|
1474
|
+
p_items: items ? [...items] : null
|
|
1475
|
+
},
|
|
1476
|
+
"pickListUpdate"
|
|
1477
|
+
);
|
|
1478
|
+
}
|
|
1479
|
+
};
|
|
1480
|
+
}
|
|
1481
|
+
|
|
1349
1482
|
// src/placement.ts
|
|
1350
1483
|
function countOf(value) {
|
|
1351
1484
|
return typeof value === "number" && Number.isFinite(value) ? value : 0;
|
|
@@ -2665,12 +2798,7 @@ function doorReady(config, name) {
|
|
|
2665
2798
|
return DOOR_NAMES.has(name) || Boolean(config?.knownDoors?.includes(name));
|
|
2666
2799
|
}
|
|
2667
2800
|
function doorAbsent(name) {
|
|
2668
|
-
|
|
2669
|
-
return {
|
|
2670
|
-
code: "door_absent",
|
|
2671
|
-
message: `The record store has no door \`custom.${name}\` yet, so this call was not made. Nothing was read and nothing was written.`,
|
|
2672
|
-
hint: owed ? `That door is ${owed}. Until it lands, this call refuses rather than guessing: an empty answer here would read like "there is nothing", which is a different sentence.` : `No lane in the build book claims this door. Either the name is wrong, or the door was removed from the store and this package has not been regenerated \u2014 run \`pnpm records:generate\`.`
|
|
2673
|
-
};
|
|
2801
|
+
return doorAbsentRefusal(name, OWED_BY[name]);
|
|
2674
2802
|
}
|
|
2675
2803
|
var DOORS = {
|
|
2676
2804
|
// THE READ DOOR (DOOR-1). Every read of a record's values goes through these
|
|
@@ -3450,29 +3578,6 @@ function intersectIds(sets) {
|
|
|
3450
3578
|
|
|
3451
3579
|
// src/core/client.ts
|
|
3452
3580
|
var DEFAULT_SCHEMA = "custom";
|
|
3453
|
-
function canonicalArgs(value) {
|
|
3454
|
-
return JSON.stringify(
|
|
3455
|
-
value,
|
|
3456
|
-
(_key, held) => held && typeof held === "object" && !Array.isArray(held) ? Object.fromEntries(Object.keys(held).sort().map((k) => [k, held[k]])) : held
|
|
3457
|
-
);
|
|
3458
|
-
}
|
|
3459
|
-
var A_PERSONS_REFUSAL = /* @__PURE__ */ new Set([
|
|
3460
|
-
"refused_by_rule",
|
|
3461
|
-
"stale_write",
|
|
3462
|
-
"invalid_argument",
|
|
3463
|
-
"already_exists",
|
|
3464
|
-
"missing_reference"
|
|
3465
|
-
]);
|
|
3466
|
-
function isAPersonsRefusal(code) {
|
|
3467
|
-
return A_PERSONS_REFUSAL.has(code);
|
|
3468
|
-
}
|
|
3469
|
-
function sink(config) {
|
|
3470
|
-
return config.onError ?? ((e) => {
|
|
3471
|
-
const line = `[@ai-matrx/records] ${e.where}: ${e.code} \u2014 ${e.message}${e.hint ? ` (${e.hint})` : ""}`;
|
|
3472
|
-
if (isAPersonsRefusal(e.code)) console.info(line);
|
|
3473
|
-
else console.error(line);
|
|
3474
|
-
});
|
|
3475
|
-
}
|
|
3476
3581
|
var TABLE_LIST_PAGE = 500;
|
|
3477
3582
|
var TABLE_ARCHIVE_PASS = 20;
|
|
3478
3583
|
var TABLE_RESTORE_PASS = 20;
|
|
@@ -3485,7 +3590,7 @@ function createRecordsClient(given) {
|
|
|
3485
3590
|
const org = config.organizationId;
|
|
3486
3591
|
const ledger = config.opLedger ?? defaultOpLedger;
|
|
3487
3592
|
const mintOp = () => ledger.mint();
|
|
3488
|
-
const scream =
|
|
3593
|
+
const scream = recordsErrorSink(config.onError);
|
|
3489
3594
|
const BUNDLE_TTL_MS = 1e4;
|
|
3490
3595
|
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"]);
|
|
3491
3596
|
const bundleParts = /* @__PURE__ */ new Map();
|
|
@@ -3627,56 +3732,20 @@ function createRecordsClient(given) {
|
|
|
3627
3732
|
bundleAsked.delete(tableId);
|
|
3628
3733
|
for (const key of [...bundleParts.keys()]) if (key.includes(tableId)) bundleParts.delete(key);
|
|
3629
3734
|
}
|
|
3630
|
-
|
|
3631
|
-
|
|
3632
|
-
|
|
3633
|
-
|
|
3634
|
-
|
|
3635
|
-
|
|
3636
|
-
|
|
3637
|
-
|
|
3638
|
-
|
|
3639
|
-
}
|
|
3640
|
-
return takePrimedDoorAnswer(`${door}|${canonicalArgs(args)}`);
|
|
3641
|
-
}
|
|
3642
|
-
const readsInFlight = /* @__PURE__ */ new Map();
|
|
3643
|
-
async function callDoor(door, args, where, opts) {
|
|
3644
|
-
const primed = primedFor(door, args);
|
|
3645
|
-
if (primed) return ok(primed.data);
|
|
3646
|
-
const bundled = await fromBundle(door, args);
|
|
3647
|
-
if (bundled) return ok(bundled.data);
|
|
3648
|
-
if (!doorReady(config, door)) {
|
|
3649
|
-
const refusal2 = doorAbsent(door);
|
|
3650
|
-
scream({ code: refusal2.code, message: refusal2.message, ...refusal2.hint ? { hint: refusal2.hint } : {}, where });
|
|
3651
|
-
return err(refusal2);
|
|
3652
|
-
}
|
|
3653
|
-
const flightKey = isWritingDoor(door) ? null : `${door}|${canonicalArgs(args)}`;
|
|
3654
|
-
const flying = flightKey ? readsInFlight.get(flightKey) : void 0;
|
|
3655
|
-
const response = await (flying ?? (() => {
|
|
3656
|
-
const call = Promise.resolve(config.dataSource.rpc(`${door}`, args, { schema }));
|
|
3657
|
-
if (flightKey) {
|
|
3658
|
-
readsInFlight.set(flightKey, call);
|
|
3659
|
-
const forget = () => {
|
|
3660
|
-
if (readsInFlight.get(flightKey) === call) readsInFlight.delete(flightKey);
|
|
3661
|
-
};
|
|
3662
|
-
call.then(forget, forget);
|
|
3663
|
-
}
|
|
3664
|
-
return call;
|
|
3665
|
-
})());
|
|
3666
|
-
if (response.error) {
|
|
3667
|
-
const refusal2 = mapPgError(response.error, where);
|
|
3668
|
-
if (opts?.quiet) console.info(`[@ai-matrx/records] ${where}: ${refusal2.code} - ${refusal2.message}`);
|
|
3669
|
-
else scream({ code: refusal2.code, message: refusal2.message, ...refusal2.hint ? { hint: refusal2.hint } : {}, where });
|
|
3670
|
-
return err(refusal2);
|
|
3671
|
-
}
|
|
3672
|
-
if (isWritingDoor(door) || LOOK_WRITES[door]) {
|
|
3735
|
+
const primedFor = primedDoorAnswer;
|
|
3736
|
+
const callDoor = createDoorCall({
|
|
3737
|
+
dataSource: config.dataSource,
|
|
3738
|
+
schema,
|
|
3739
|
+
onError: scream,
|
|
3740
|
+
doorReady: (door) => doorReady(config, door),
|
|
3741
|
+
absent: doorAbsent,
|
|
3742
|
+
held: fromBundle,
|
|
3743
|
+
wrote: (_door, args) => {
|
|
3673
3744
|
const tableId = args["p_table_id"];
|
|
3674
3745
|
bundleDrop(typeof tableId === "string" ? tableId : null);
|
|
3675
|
-
forgetPrimedTablePageBundlesOf(typeof tableId === "string" ? tableId : null);
|
|
3676
|
-
dropPrimedDoorAnswers(LOOK_WRITES[door]);
|
|
3677
3746
|
}
|
|
3678
|
-
|
|
3679
|
-
|
|
3747
|
+
});
|
|
3748
|
+
const scopes = createScopeDoors(callDoor);
|
|
3680
3749
|
function structureMoved(tableId, result) {
|
|
3681
3750
|
if (result.ok) {
|
|
3682
3751
|
bundleDrop(tableId);
|
|
@@ -3875,7 +3944,7 @@ function createRecordsClient(given) {
|
|
|
3875
3944
|
const unavailableReason = (error) => `${error.message}${error.hint ? ` ${error.hint}` : ""}`;
|
|
3876
3945
|
const client = {
|
|
3877
3946
|
config,
|
|
3878
|
-
scopes
|
|
3947
|
+
scopes,
|
|
3879
3948
|
async recordWrite({ table_id, data }) {
|
|
3880
3949
|
const result = await callDoor(
|
|
3881
3950
|
DOORS.recordWrite,
|
|
@@ -4574,28 +4643,7 @@ function createRecordsClient(given) {
|
|
|
4574
4643
|
"fieldOptions"
|
|
4575
4644
|
);
|
|
4576
4645
|
},
|
|
4577
|
-
|
|
4578
|
-
return callDoor(DOORS.pickListGet, { p_list_id: list_id }, "pickListGet");
|
|
4579
|
-
},
|
|
4580
|
-
async pickListForSelection({ list_id }) {
|
|
4581
|
-
return callDoor(
|
|
4582
|
-
DOORS.pickListForSelection,
|
|
4583
|
-
{ p_list_id: list_id },
|
|
4584
|
-
"pickListForSelection"
|
|
4585
|
-
);
|
|
4586
|
-
},
|
|
4587
|
-
async pickListUpdate({ list_id, list_name, description, items }) {
|
|
4588
|
-
return callDoor(
|
|
4589
|
-
DOORS.pickListUpdate,
|
|
4590
|
-
{
|
|
4591
|
-
p_list_id: list_id,
|
|
4592
|
-
p_list_name: list_name ?? null,
|
|
4593
|
-
p_description: description ?? null,
|
|
4594
|
-
p_items: items ? [...items] : null
|
|
4595
|
-
},
|
|
4596
|
-
"pickListUpdate"
|
|
4597
|
-
);
|
|
4598
|
-
},
|
|
4646
|
+
...createPickListDoors(callDoor),
|
|
4599
4647
|
async fieldChoiceUsage({ field_id }) {
|
|
4600
4648
|
const result = await callDoor(
|
|
4601
4649
|
DOORS.fieldChoiceUsage,
|
|
@@ -7129,11 +7177,7 @@ function createRecordsClient(given) {
|
|
|
7129
7177
|
);
|
|
7130
7178
|
},
|
|
7131
7179
|
async scopeTableProvision({ home_id, item_id, scope_id }) {
|
|
7132
|
-
return
|
|
7133
|
-
DOORS.scopeTableProvision,
|
|
7134
|
-
{ p_organization_id: org, p_item_id: item_id, p_scope_id: scope_id, p_home_id: home_id ?? null },
|
|
7135
|
-
"scopeTableProvision"
|
|
7136
|
-
);
|
|
7180
|
+
return scopes.tableProvision({ organization_id: org, item_id, scope_id, home_id: home_id ?? null });
|
|
7137
7181
|
},
|
|
7138
7182
|
async tableRowCounts({ table_ids }) {
|
|
7139
7183
|
return callDoor(
|