@ai-matrx/records 0.99.32 → 0.99.34
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 +16 -1
- package/dist/{client-CrwedBYU.d.ts → client-CSfkP7Xf.d.ts} +5 -74
- package/dist/{client-D1EwyWfh.d.cts → client-jKf1Z-kp.d.cts} +5 -74
- package/dist/core/index.cjs +149 -105
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +9 -331
- package/dist/core/index.d.ts +9 -331
- 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 +3 -2
- package/dist/data/index.d.ts +3 -2
- package/dist/data/index.js +280 -236
- package/dist/data/index.js.map +1 -1
- package/dist/{declareTable-CC5rTTIA.d.ts → declareTable-0emxEewn.d.ts} +1 -1
- package/dist/{declareTable-BIIt0Wqt.d.cts → declareTable-800bwUn3.d.cts} +1 -1
- 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-D1yAs0a0.d.cts → doors-BgjRUdxw.d.cts} +13 -1
- package/dist/{doors-D2z3kH2i.d.ts → doors-D7_jEKtg.d.ts} +13 -1
- package/dist/index.d.cts +5 -4
- package/dist/index.d.ts +5 -4
- package/dist/{objectOrganization-DazBoDAq.d.cts → objectOrganization-B5YFGVUB.d.cts} +1 -1
- package/dist/{objectOrganization-D1ox3gUx.d.ts → objectOrganization-DozoVIxS.d.ts} +1 -1
- package/dist/pickListDoors-C-_eAEGL.d.cts +135 -0
- package/dist/pickListDoors-DgWVnNRI.d.ts +135 -0
- package/dist/questions/index.d.cts +3 -2
- package/dist/questions/index.d.ts +3 -2
- 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/scopes/index.cjs +7 -0
- package/dist/scopes/index.cjs.map +1 -1
- package/dist/scopes/index.d.cts +2 -2
- package/dist/scopes/index.d.ts +2 -2
- package/dist/scopes/index.js +7 -0
- package/dist/scopes/index.js.map +1 -1
- package/dist/setup/index.cjs +289 -245
- package/dist/setup/index.cjs.map +1 -1
- package/dist/setup/index.d.cts +4 -3
- package/dist/setup/index.d.ts +4 -3
- package/dist/setup/index.js +289 -245
- package/dist/setup/index.js.map +1 -1
- package/dist/table-logic-BPquabNN.d.ts +328 -0
- package/dist/table-logic-CTh6lwaq.d.cts +328 -0
- package/dist/typed-table/index.cjs +280 -236
- package/dist/typed-table/index.cjs.map +1 -1
- package/dist/typed-table/index.d.cts +4 -3
- package/dist/typed-table/index.d.ts +4 -3
- package/dist/typed-table/index.js +280 -236
- package/dist/typed-table/index.js.map +1 -1
- package/dist/views/index.d.cts +3 -2
- package/dist/views/index.d.ts +3 -2
- package/package.json +13 -3
package/dist/data/index.cjs
CHANGED
|
@@ -279,137 +279,6 @@ function isWritingDoor(door) {
|
|
|
279
279
|
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);
|
|
280
280
|
}
|
|
281
281
|
|
|
282
|
-
// src/core/recordChanges.ts
|
|
283
|
-
var import_global_slot = require("@ai-matrx/kit/global-slot");
|
|
284
|
-
var listeners = (0, import_global_slot.globalSlot)("ai-matrx.records.record-change-listeners", () => /* @__PURE__ */ new Set());
|
|
285
|
-
function announceRecordChanged(recordId) {
|
|
286
|
-
for (const listener of [...listeners]) {
|
|
287
|
-
try {
|
|
288
|
-
listener(recordId);
|
|
289
|
-
} catch (thrown) {
|
|
290
|
-
console.error("[@ai-matrx/records] a record-change listener threw", thrown);
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
}
|
|
294
|
-
var removed = (0, import_global_slot.globalSlot)("ai-matrx.records.removed-records", () => /* @__PURE__ */ new Set());
|
|
295
|
-
function markRecordRemoved(recordId) {
|
|
296
|
-
removed.add(recordId);
|
|
297
|
-
}
|
|
298
|
-
function markRecordRestored(recordId) {
|
|
299
|
-
removed.delete(recordId);
|
|
300
|
-
}
|
|
301
|
-
function onRecordChanged(listener) {
|
|
302
|
-
listeners.add(listener);
|
|
303
|
-
return () => listeners.delete(listener);
|
|
304
|
-
}
|
|
305
|
-
var tableListeners = (0, import_global_slot.globalSlot)("ai-matrx.records.table-structure-listeners", () => /* @__PURE__ */ new Set());
|
|
306
|
-
function announceTableStructureChanged(tableId) {
|
|
307
|
-
for (const listener of [...tableListeners]) {
|
|
308
|
-
try {
|
|
309
|
-
listener(tableId);
|
|
310
|
-
} catch (thrown) {
|
|
311
|
-
console.error("[@ai-matrx/records] a table-structure listener threw", thrown);
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
// src/archive.ts
|
|
317
|
-
var DEFAULT_ARCHIVE_LANE = "org";
|
|
318
|
-
|
|
319
|
-
// src/aggregate.ts
|
|
320
|
-
function isRuleFilter(filter) {
|
|
321
|
-
if (!filter || typeof filter !== "object" || Array.isArray(filter)) return false;
|
|
322
|
-
const node = filter;
|
|
323
|
-
return typeof node.op === "string" && Array.isArray(node.args);
|
|
324
|
-
}
|
|
325
|
-
function stableFilterKey(filter) {
|
|
326
|
-
if (!filter) return "{}";
|
|
327
|
-
if (isRuleFilter(filter)) return JSON.stringify(filter);
|
|
328
|
-
const keys = Object.keys(filter).sort();
|
|
329
|
-
if (keys.length === 0) return "{}";
|
|
330
|
-
const parts = keys.map((key) => {
|
|
331
|
-
const value = filter[key];
|
|
332
|
-
if (value !== null && typeof value === "object") {
|
|
333
|
-
const window = value;
|
|
334
|
-
return `${JSON.stringify(key)}:{"from":${JSON.stringify(window.from ?? null)},"to":${JSON.stringify(window.to ?? null)}}`;
|
|
335
|
-
}
|
|
336
|
-
return `${JSON.stringify(key)}:${JSON.stringify(value ?? null)}`;
|
|
337
|
-
});
|
|
338
|
-
return `{${parts.join(",")}}`;
|
|
339
|
-
}
|
|
340
|
-
function liftWithheld(rows) {
|
|
341
|
-
let shared;
|
|
342
|
-
for (const row of rows) {
|
|
343
|
-
const m = (row.measures ?? {})["_withheld"];
|
|
344
|
-
if (m !== void 0 && m !== null && typeof m === "object") {
|
|
345
|
-
shared = m;
|
|
346
|
-
break;
|
|
347
|
-
}
|
|
348
|
-
}
|
|
349
|
-
return rows.map((row) => {
|
|
350
|
-
const measures = row.measures ?? {};
|
|
351
|
-
const own = measures["_withheld"];
|
|
352
|
-
const marker = own !== void 0 && own !== null && typeof own === "object" ? own : shared;
|
|
353
|
-
const rowCount = row.row_count ?? 0;
|
|
354
|
-
if (marker === void 0 || marker === null || typeof marker !== "object") {
|
|
355
|
-
return rowCount === row.row_count ? row : { ...row, row_count: rowCount };
|
|
356
|
-
}
|
|
357
|
-
const { _withheld: _drop, ...rest } = measures;
|
|
358
|
-
const withheld = {};
|
|
359
|
-
for (const [name, raw] of Object.entries(marker)) {
|
|
360
|
-
const m = raw ?? {};
|
|
361
|
-
withheld[name] = {
|
|
362
|
-
reason: m.withheld?.reason ?? null,
|
|
363
|
-
needs: m.withheld?.needs ?? null,
|
|
364
|
-
or: m.withheld?.or ?? null,
|
|
365
|
-
...m.says ? { says: m.says } : {},
|
|
366
|
-
...m.label ? { label: m.label } : {},
|
|
367
|
-
...m.field_key ? { field_key: m.field_key } : {}
|
|
368
|
-
};
|
|
369
|
-
}
|
|
370
|
-
return { ...row, measures: rest, withheld, row_count: rowCount };
|
|
371
|
-
});
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
// src/record.ts
|
|
375
|
-
function isLockedStub(row) {
|
|
376
|
-
if (!row) return false;
|
|
377
|
-
if (row.level !== null && row.level !== void 0) return false;
|
|
378
|
-
const doc = row.document;
|
|
379
|
-
if (!doc || typeof doc !== "object") return false;
|
|
380
|
-
const keys = Object.keys(doc);
|
|
381
|
-
if (keys.length === 0 || keys.length > 3) return false;
|
|
382
|
-
const d = doc;
|
|
383
|
-
return d["exists"] === true && keys.every((k) => k === "id" || k === "exists" || k === "submitted_at");
|
|
384
|
-
}
|
|
385
|
-
function splitLockedRows(rows) {
|
|
386
|
-
const open = [];
|
|
387
|
-
let locked = 0;
|
|
388
|
-
for (const row of rows) {
|
|
389
|
-
if (isLockedStub(row)) locked += 1;
|
|
390
|
-
else open.push(row);
|
|
391
|
-
}
|
|
392
|
-
return { rows: open, locked };
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
// src/subscription.ts
|
|
396
|
-
function callersTimeZone() {
|
|
397
|
-
try {
|
|
398
|
-
return Intl.DateTimeFormat().resolvedOptions().timeZone || null;
|
|
399
|
-
} catch {
|
|
400
|
-
return null;
|
|
401
|
-
}
|
|
402
|
-
}
|
|
403
|
-
function withCallersClock(spec, zone = callersTimeZone()) {
|
|
404
|
-
if (!zone || spec.quiet_hours?.tz) return spec;
|
|
405
|
-
return { ...spec, quiet_hours: { ...spec.quiet_hours ?? {}, tz: zone } };
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
// src/rowLabel.ts
|
|
409
|
-
function clearsRowLabel(formula) {
|
|
410
|
-
return formula == null || formula.trim() === "";
|
|
411
|
-
}
|
|
412
|
-
|
|
413
282
|
// src/results.ts
|
|
414
283
|
var ok = (data) => ({ ok: true, data });
|
|
415
284
|
var err = (error) => ({ ok: false, error });
|
|
@@ -580,6 +449,230 @@ function mapPgError(error, where) {
|
|
|
580
449
|
return mapped;
|
|
581
450
|
}
|
|
582
451
|
|
|
452
|
+
// src/core/doorCall.ts
|
|
453
|
+
var DEFAULT_DOOR_SCHEMA = "custom";
|
|
454
|
+
function canonicalArgs(value) {
|
|
455
|
+
return JSON.stringify(
|
|
456
|
+
value,
|
|
457
|
+
(_key, held) => held && typeof held === "object" && !Array.isArray(held) ? Object.fromEntries(Object.keys(held).sort().map((k) => [k, held[k]])) : held
|
|
458
|
+
);
|
|
459
|
+
}
|
|
460
|
+
var A_PERSONS_REFUSAL = /* @__PURE__ */ new Set([
|
|
461
|
+
"refused_by_rule",
|
|
462
|
+
"stale_write",
|
|
463
|
+
"invalid_argument",
|
|
464
|
+
"already_exists",
|
|
465
|
+
"missing_reference"
|
|
466
|
+
]);
|
|
467
|
+
function isAPersonsRefusal(code) {
|
|
468
|
+
return A_PERSONS_REFUSAL.has(code);
|
|
469
|
+
}
|
|
470
|
+
function recordsErrorSink(onError) {
|
|
471
|
+
return onError ?? ((e) => {
|
|
472
|
+
const line = `[@ai-matrx/records] ${e.where}: ${e.code} \u2014 ${e.message}${e.hint ? ` (${e.hint})` : ""}`;
|
|
473
|
+
if (isAPersonsRefusal(e.code)) console.info(line);
|
|
474
|
+
else console.error(line);
|
|
475
|
+
});
|
|
476
|
+
}
|
|
477
|
+
function doorAbsentRefusal(name, owedBy) {
|
|
478
|
+
return {
|
|
479
|
+
code: "door_absent",
|
|
480
|
+
message: `The record store has no door \`custom.${name}\` yet, so this call was not made. Nothing was read and nothing was written.`,
|
|
481
|
+
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\`.`
|
|
482
|
+
};
|
|
483
|
+
}
|
|
484
|
+
function primedDoorAnswer(door, args) {
|
|
485
|
+
const look = LOOK_WRITES[door];
|
|
486
|
+
if (look) {
|
|
487
|
+
dropPrimedDoorAnswers(look);
|
|
488
|
+
return null;
|
|
489
|
+
}
|
|
490
|
+
if (isWritingDoor(door)) {
|
|
491
|
+
dropPrimedDoorAnswers();
|
|
492
|
+
return null;
|
|
493
|
+
}
|
|
494
|
+
return takePrimedDoorAnswer(`${door}|${canonicalArgs(args)}`);
|
|
495
|
+
}
|
|
496
|
+
function createDoorCall(options) {
|
|
497
|
+
const { dataSource, doorReady: doorReady2, held, wrote } = options;
|
|
498
|
+
const schema = options.schema ?? DEFAULT_DOOR_SCHEMA;
|
|
499
|
+
const scream = recordsErrorSink(options.onError);
|
|
500
|
+
const absent = options.absent ?? ((door) => doorAbsentRefusal(door));
|
|
501
|
+
const readsInFlight = /* @__PURE__ */ new Map();
|
|
502
|
+
const say = (refusal2, where) => scream({ code: refusal2.code, message: refusal2.message, ...refusal2.hint ? { hint: refusal2.hint } : {}, where });
|
|
503
|
+
return async function callDoor(door, args, where, opts) {
|
|
504
|
+
const primed = primedDoorAnswer(door, args);
|
|
505
|
+
if (primed) return ok(primed.data);
|
|
506
|
+
if (held) {
|
|
507
|
+
const bundled = await held(door, args);
|
|
508
|
+
if (bundled) return ok(bundled.data);
|
|
509
|
+
}
|
|
510
|
+
if (doorReady2 && !doorReady2(door)) {
|
|
511
|
+
const refusal2 = absent(door);
|
|
512
|
+
say(refusal2, where);
|
|
513
|
+
return err(refusal2);
|
|
514
|
+
}
|
|
515
|
+
const flightKey = isWritingDoor(door) ? null : `${door}|${canonicalArgs(args)}`;
|
|
516
|
+
const flying = flightKey ? readsInFlight.get(flightKey) : void 0;
|
|
517
|
+
const response = await (flying ?? (() => {
|
|
518
|
+
const call = Promise.resolve(dataSource.rpc(`${door}`, args, { schema }));
|
|
519
|
+
if (flightKey) {
|
|
520
|
+
readsInFlight.set(flightKey, call);
|
|
521
|
+
const forget = () => {
|
|
522
|
+
if (readsInFlight.get(flightKey) === call) readsInFlight.delete(flightKey);
|
|
523
|
+
};
|
|
524
|
+
call.then(forget, forget);
|
|
525
|
+
}
|
|
526
|
+
return call;
|
|
527
|
+
})());
|
|
528
|
+
if (response.error) {
|
|
529
|
+
const code = response.error.code;
|
|
530
|
+
const refusal2 = !doorReady2 && (code === "PGRST202" || code === "42883") ? absent(door) : mapPgError(response.error, where);
|
|
531
|
+
if (opts?.quiet) console.info(`[@ai-matrx/records] ${where}: ${refusal2.code} - ${refusal2.message}`);
|
|
532
|
+
else say(refusal2, where);
|
|
533
|
+
return err(refusal2);
|
|
534
|
+
}
|
|
535
|
+
if (isWritingDoor(door) || LOOK_WRITES[door]) {
|
|
536
|
+
const tableId = args["p_table_id"];
|
|
537
|
+
wrote?.(door, args);
|
|
538
|
+
forgetPrimedTablePageBundlesOf(typeof tableId === "string" ? tableId : null);
|
|
539
|
+
dropPrimedDoorAnswers(LOOK_WRITES[door]);
|
|
540
|
+
}
|
|
541
|
+
return ok(response.data);
|
|
542
|
+
};
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
// src/core/recordChanges.ts
|
|
546
|
+
var import_global_slot = require("@ai-matrx/kit/global-slot");
|
|
547
|
+
var listeners = (0, import_global_slot.globalSlot)("ai-matrx.records.record-change-listeners", () => /* @__PURE__ */ new Set());
|
|
548
|
+
function announceRecordChanged(recordId) {
|
|
549
|
+
for (const listener of [...listeners]) {
|
|
550
|
+
try {
|
|
551
|
+
listener(recordId);
|
|
552
|
+
} catch (thrown) {
|
|
553
|
+
console.error("[@ai-matrx/records] a record-change listener threw", thrown);
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
var removed = (0, import_global_slot.globalSlot)("ai-matrx.records.removed-records", () => /* @__PURE__ */ new Set());
|
|
558
|
+
function markRecordRemoved(recordId) {
|
|
559
|
+
removed.add(recordId);
|
|
560
|
+
}
|
|
561
|
+
function markRecordRestored(recordId) {
|
|
562
|
+
removed.delete(recordId);
|
|
563
|
+
}
|
|
564
|
+
function onRecordChanged(listener) {
|
|
565
|
+
listeners.add(listener);
|
|
566
|
+
return () => listeners.delete(listener);
|
|
567
|
+
}
|
|
568
|
+
var tableListeners = (0, import_global_slot.globalSlot)("ai-matrx.records.table-structure-listeners", () => /* @__PURE__ */ new Set());
|
|
569
|
+
function announceTableStructureChanged(tableId) {
|
|
570
|
+
for (const listener of [...tableListeners]) {
|
|
571
|
+
try {
|
|
572
|
+
listener(tableId);
|
|
573
|
+
} catch (thrown) {
|
|
574
|
+
console.error("[@ai-matrx/records] a table-structure listener threw", thrown);
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
// src/archive.ts
|
|
580
|
+
var DEFAULT_ARCHIVE_LANE = "org";
|
|
581
|
+
|
|
582
|
+
// src/aggregate.ts
|
|
583
|
+
function isRuleFilter(filter) {
|
|
584
|
+
if (!filter || typeof filter !== "object" || Array.isArray(filter)) return false;
|
|
585
|
+
const node = filter;
|
|
586
|
+
return typeof node.op === "string" && Array.isArray(node.args);
|
|
587
|
+
}
|
|
588
|
+
function stableFilterKey(filter) {
|
|
589
|
+
if (!filter) return "{}";
|
|
590
|
+
if (isRuleFilter(filter)) return JSON.stringify(filter);
|
|
591
|
+
const keys = Object.keys(filter).sort();
|
|
592
|
+
if (keys.length === 0) return "{}";
|
|
593
|
+
const parts = keys.map((key) => {
|
|
594
|
+
const value = filter[key];
|
|
595
|
+
if (value !== null && typeof value === "object") {
|
|
596
|
+
const window = value;
|
|
597
|
+
return `${JSON.stringify(key)}:{"from":${JSON.stringify(window.from ?? null)},"to":${JSON.stringify(window.to ?? null)}}`;
|
|
598
|
+
}
|
|
599
|
+
return `${JSON.stringify(key)}:${JSON.stringify(value ?? null)}`;
|
|
600
|
+
});
|
|
601
|
+
return `{${parts.join(",")}}`;
|
|
602
|
+
}
|
|
603
|
+
function liftWithheld(rows) {
|
|
604
|
+
let shared;
|
|
605
|
+
for (const row of rows) {
|
|
606
|
+
const m = (row.measures ?? {})["_withheld"];
|
|
607
|
+
if (m !== void 0 && m !== null && typeof m === "object") {
|
|
608
|
+
shared = m;
|
|
609
|
+
break;
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
return rows.map((row) => {
|
|
613
|
+
const measures = row.measures ?? {};
|
|
614
|
+
const own = measures["_withheld"];
|
|
615
|
+
const marker = own !== void 0 && own !== null && typeof own === "object" ? own : shared;
|
|
616
|
+
const rowCount = row.row_count ?? 0;
|
|
617
|
+
if (marker === void 0 || marker === null || typeof marker !== "object") {
|
|
618
|
+
return rowCount === row.row_count ? row : { ...row, row_count: rowCount };
|
|
619
|
+
}
|
|
620
|
+
const { _withheld: _drop, ...rest } = measures;
|
|
621
|
+
const withheld = {};
|
|
622
|
+
for (const [name, raw] of Object.entries(marker)) {
|
|
623
|
+
const m = raw ?? {};
|
|
624
|
+
withheld[name] = {
|
|
625
|
+
reason: m.withheld?.reason ?? null,
|
|
626
|
+
needs: m.withheld?.needs ?? null,
|
|
627
|
+
or: m.withheld?.or ?? null,
|
|
628
|
+
...m.says ? { says: m.says } : {},
|
|
629
|
+
...m.label ? { label: m.label } : {},
|
|
630
|
+
...m.field_key ? { field_key: m.field_key } : {}
|
|
631
|
+
};
|
|
632
|
+
}
|
|
633
|
+
return { ...row, measures: rest, withheld, row_count: rowCount };
|
|
634
|
+
});
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
// src/record.ts
|
|
638
|
+
function isLockedStub(row) {
|
|
639
|
+
if (!row) return false;
|
|
640
|
+
if (row.level !== null && row.level !== void 0) return false;
|
|
641
|
+
const doc = row.document;
|
|
642
|
+
if (!doc || typeof doc !== "object") return false;
|
|
643
|
+
const keys = Object.keys(doc);
|
|
644
|
+
if (keys.length === 0 || keys.length > 3) return false;
|
|
645
|
+
const d = doc;
|
|
646
|
+
return d["exists"] === true && keys.every((k) => k === "id" || k === "exists" || k === "submitted_at");
|
|
647
|
+
}
|
|
648
|
+
function splitLockedRows(rows) {
|
|
649
|
+
const open = [];
|
|
650
|
+
let locked = 0;
|
|
651
|
+
for (const row of rows) {
|
|
652
|
+
if (isLockedStub(row)) locked += 1;
|
|
653
|
+
else open.push(row);
|
|
654
|
+
}
|
|
655
|
+
return { rows: open, locked };
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
// src/subscription.ts
|
|
659
|
+
function callersTimeZone() {
|
|
660
|
+
try {
|
|
661
|
+
return Intl.DateTimeFormat().resolvedOptions().timeZone || null;
|
|
662
|
+
} catch {
|
|
663
|
+
return null;
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
function withCallersClock(spec, zone = callersTimeZone()) {
|
|
667
|
+
if (!zone || spec.quiet_hours?.tz) return spec;
|
|
668
|
+
return { ...spec, quiet_hours: { ...spec.quiet_hours ?? {}, tz: zone } };
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
// src/rowLabel.ts
|
|
672
|
+
function clearsRowLabel(formula) {
|
|
673
|
+
return formula == null || formula.trim() === "";
|
|
674
|
+
}
|
|
675
|
+
|
|
583
676
|
// src/relation.ts
|
|
584
677
|
var import_uuid3 = require("@ai-matrx/kit/uuid");
|
|
585
678
|
function isRefLike(value) {
|
|
@@ -1385,11 +1478,51 @@ function createScopeDoors(call) {
|
|
|
1385
1478
|
source_type: String(envelope.data?.source_type ?? cell.source_type ?? "ai_enriched")
|
|
1386
1479
|
}
|
|
1387
1480
|
};
|
|
1481
|
+
},
|
|
1482
|
+
tableProvision({ organization_id, item_id, scope_id, home_id }) {
|
|
1483
|
+
return call(
|
|
1484
|
+
"scope_table_provision",
|
|
1485
|
+
{ p_organization_id: organization_id, p_item_id: item_id, p_scope_id: scope_id, p_home_id: home_id ?? null },
|
|
1486
|
+
"scopeTableProvision"
|
|
1487
|
+
);
|
|
1388
1488
|
}
|
|
1389
1489
|
};
|
|
1390
1490
|
return doors;
|
|
1391
1491
|
}
|
|
1392
1492
|
|
|
1493
|
+
// src/core/pickListDoors.ts
|
|
1494
|
+
var PICK_LIST_DOORS = {
|
|
1495
|
+
pickListGet: "pick_list_get",
|
|
1496
|
+
pickListForSelection: "pick_list_for_selection",
|
|
1497
|
+
pickListUpdate: "pick_list_update"
|
|
1498
|
+
};
|
|
1499
|
+
function createPickListDoors(callDoor) {
|
|
1500
|
+
return {
|
|
1501
|
+
async pickListGet({ list_id }) {
|
|
1502
|
+
return callDoor(PICK_LIST_DOORS.pickListGet, { p_list_id: list_id }, "pickListGet");
|
|
1503
|
+
},
|
|
1504
|
+
async pickListForSelection({ list_id }) {
|
|
1505
|
+
return callDoor(
|
|
1506
|
+
PICK_LIST_DOORS.pickListForSelection,
|
|
1507
|
+
{ p_list_id: list_id },
|
|
1508
|
+
"pickListForSelection"
|
|
1509
|
+
);
|
|
1510
|
+
},
|
|
1511
|
+
async pickListUpdate({ list_id, list_name, description, items }) {
|
|
1512
|
+
return callDoor(
|
|
1513
|
+
PICK_LIST_DOORS.pickListUpdate,
|
|
1514
|
+
{
|
|
1515
|
+
p_list_id: list_id,
|
|
1516
|
+
p_list_name: list_name ?? null,
|
|
1517
|
+
p_description: description ?? null,
|
|
1518
|
+
p_items: items ? [...items] : null
|
|
1519
|
+
},
|
|
1520
|
+
"pickListUpdate"
|
|
1521
|
+
);
|
|
1522
|
+
}
|
|
1523
|
+
};
|
|
1524
|
+
}
|
|
1525
|
+
|
|
1393
1526
|
// src/placement.ts
|
|
1394
1527
|
function countOf(value) {
|
|
1395
1528
|
return typeof value === "number" && Number.isFinite(value) ? value : 0;
|
|
@@ -2709,12 +2842,7 @@ function doorReady(config, name) {
|
|
|
2709
2842
|
return DOOR_NAMES.has(name) || Boolean(config?.knownDoors?.includes(name));
|
|
2710
2843
|
}
|
|
2711
2844
|
function doorAbsent(name) {
|
|
2712
|
-
|
|
2713
|
-
return {
|
|
2714
|
-
code: "door_absent",
|
|
2715
|
-
message: `The record store has no door \`custom.${name}\` yet, so this call was not made. Nothing was read and nothing was written.`,
|
|
2716
|
-
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\`.`
|
|
2717
|
-
};
|
|
2845
|
+
return doorAbsentRefusal(name, OWED_BY[name]);
|
|
2718
2846
|
}
|
|
2719
2847
|
var DOORS = {
|
|
2720
2848
|
// THE READ DOOR (DOOR-1). Every read of a record's values goes through these
|
|
@@ -3494,29 +3622,6 @@ function intersectIds(sets) {
|
|
|
3494
3622
|
|
|
3495
3623
|
// src/core/client.ts
|
|
3496
3624
|
var DEFAULT_SCHEMA = "custom";
|
|
3497
|
-
function canonicalArgs(value) {
|
|
3498
|
-
return JSON.stringify(
|
|
3499
|
-
value,
|
|
3500
|
-
(_key, held) => held && typeof held === "object" && !Array.isArray(held) ? Object.fromEntries(Object.keys(held).sort().map((k) => [k, held[k]])) : held
|
|
3501
|
-
);
|
|
3502
|
-
}
|
|
3503
|
-
var A_PERSONS_REFUSAL = /* @__PURE__ */ new Set([
|
|
3504
|
-
"refused_by_rule",
|
|
3505
|
-
"stale_write",
|
|
3506
|
-
"invalid_argument",
|
|
3507
|
-
"already_exists",
|
|
3508
|
-
"missing_reference"
|
|
3509
|
-
]);
|
|
3510
|
-
function isAPersonsRefusal(code) {
|
|
3511
|
-
return A_PERSONS_REFUSAL.has(code);
|
|
3512
|
-
}
|
|
3513
|
-
function sink(config) {
|
|
3514
|
-
return config.onError ?? ((e) => {
|
|
3515
|
-
const line = `[@ai-matrx/records] ${e.where}: ${e.code} \u2014 ${e.message}${e.hint ? ` (${e.hint})` : ""}`;
|
|
3516
|
-
if (isAPersonsRefusal(e.code)) console.info(line);
|
|
3517
|
-
else console.error(line);
|
|
3518
|
-
});
|
|
3519
|
-
}
|
|
3520
3625
|
var TABLE_LIST_PAGE = 500;
|
|
3521
3626
|
var TABLE_ARCHIVE_PASS = 20;
|
|
3522
3627
|
var TABLE_RESTORE_PASS = 20;
|
|
@@ -3529,7 +3634,7 @@ function createRecordsClient(given) {
|
|
|
3529
3634
|
const org = config.organizationId;
|
|
3530
3635
|
const ledger = config.opLedger ?? defaultOpLedger;
|
|
3531
3636
|
const mintOp = () => ledger.mint();
|
|
3532
|
-
const scream =
|
|
3637
|
+
const scream = recordsErrorSink(config.onError);
|
|
3533
3638
|
const BUNDLE_TTL_MS = 1e4;
|
|
3534
3639
|
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"]);
|
|
3535
3640
|
const bundleParts = /* @__PURE__ */ new Map();
|
|
@@ -3671,56 +3776,20 @@ function createRecordsClient(given) {
|
|
|
3671
3776
|
bundleAsked.delete(tableId);
|
|
3672
3777
|
for (const key of [...bundleParts.keys()]) if (key.includes(tableId)) bundleParts.delete(key);
|
|
3673
3778
|
}
|
|
3674
|
-
|
|
3675
|
-
|
|
3676
|
-
|
|
3677
|
-
|
|
3678
|
-
|
|
3679
|
-
|
|
3680
|
-
|
|
3681
|
-
|
|
3682
|
-
|
|
3683
|
-
}
|
|
3684
|
-
return takePrimedDoorAnswer(`${door}|${canonicalArgs(args)}`);
|
|
3685
|
-
}
|
|
3686
|
-
const readsInFlight = /* @__PURE__ */ new Map();
|
|
3687
|
-
async function callDoor(door, args, where, opts) {
|
|
3688
|
-
const primed = primedFor(door, args);
|
|
3689
|
-
if (primed) return ok(primed.data);
|
|
3690
|
-
const bundled = await fromBundle(door, args);
|
|
3691
|
-
if (bundled) return ok(bundled.data);
|
|
3692
|
-
if (!doorReady(config, door)) {
|
|
3693
|
-
const refusal2 = doorAbsent(door);
|
|
3694
|
-
scream({ code: refusal2.code, message: refusal2.message, ...refusal2.hint ? { hint: refusal2.hint } : {}, where });
|
|
3695
|
-
return err(refusal2);
|
|
3696
|
-
}
|
|
3697
|
-
const flightKey = isWritingDoor(door) ? null : `${door}|${canonicalArgs(args)}`;
|
|
3698
|
-
const flying = flightKey ? readsInFlight.get(flightKey) : void 0;
|
|
3699
|
-
const response = await (flying ?? (() => {
|
|
3700
|
-
const call = Promise.resolve(config.dataSource.rpc(`${door}`, args, { schema }));
|
|
3701
|
-
if (flightKey) {
|
|
3702
|
-
readsInFlight.set(flightKey, call);
|
|
3703
|
-
const forget = () => {
|
|
3704
|
-
if (readsInFlight.get(flightKey) === call) readsInFlight.delete(flightKey);
|
|
3705
|
-
};
|
|
3706
|
-
call.then(forget, forget);
|
|
3707
|
-
}
|
|
3708
|
-
return call;
|
|
3709
|
-
})());
|
|
3710
|
-
if (response.error) {
|
|
3711
|
-
const refusal2 = mapPgError(response.error, where);
|
|
3712
|
-
if (opts?.quiet) console.info(`[@ai-matrx/records] ${where}: ${refusal2.code} - ${refusal2.message}`);
|
|
3713
|
-
else scream({ code: refusal2.code, message: refusal2.message, ...refusal2.hint ? { hint: refusal2.hint } : {}, where });
|
|
3714
|
-
return err(refusal2);
|
|
3715
|
-
}
|
|
3716
|
-
if (isWritingDoor(door) || LOOK_WRITES[door]) {
|
|
3779
|
+
const primedFor = primedDoorAnswer;
|
|
3780
|
+
const callDoor = createDoorCall({
|
|
3781
|
+
dataSource: config.dataSource,
|
|
3782
|
+
schema,
|
|
3783
|
+
onError: scream,
|
|
3784
|
+
doorReady: (door) => doorReady(config, door),
|
|
3785
|
+
absent: doorAbsent,
|
|
3786
|
+
held: fromBundle,
|
|
3787
|
+
wrote: (_door, args) => {
|
|
3717
3788
|
const tableId = args["p_table_id"];
|
|
3718
3789
|
bundleDrop(typeof tableId === "string" ? tableId : null);
|
|
3719
|
-
forgetPrimedTablePageBundlesOf(typeof tableId === "string" ? tableId : null);
|
|
3720
|
-
dropPrimedDoorAnswers(LOOK_WRITES[door]);
|
|
3721
3790
|
}
|
|
3722
|
-
|
|
3723
|
-
|
|
3791
|
+
});
|
|
3792
|
+
const scopes = createScopeDoors(callDoor);
|
|
3724
3793
|
function structureMoved(tableId, result) {
|
|
3725
3794
|
if (result.ok) {
|
|
3726
3795
|
bundleDrop(tableId);
|
|
@@ -3919,7 +3988,7 @@ function createRecordsClient(given) {
|
|
|
3919
3988
|
const unavailableReason = (error) => `${error.message}${error.hint ? ` ${error.hint}` : ""}`;
|
|
3920
3989
|
const client = {
|
|
3921
3990
|
config,
|
|
3922
|
-
scopes
|
|
3991
|
+
scopes,
|
|
3923
3992
|
async recordWrite({ table_id, data }) {
|
|
3924
3993
|
const result = await callDoor(
|
|
3925
3994
|
DOORS.recordWrite,
|
|
@@ -4618,28 +4687,7 @@ function createRecordsClient(given) {
|
|
|
4618
4687
|
"fieldOptions"
|
|
4619
4688
|
);
|
|
4620
4689
|
},
|
|
4621
|
-
|
|
4622
|
-
return callDoor(DOORS.pickListGet, { p_list_id: list_id }, "pickListGet");
|
|
4623
|
-
},
|
|
4624
|
-
async pickListForSelection({ list_id }) {
|
|
4625
|
-
return callDoor(
|
|
4626
|
-
DOORS.pickListForSelection,
|
|
4627
|
-
{ p_list_id: list_id },
|
|
4628
|
-
"pickListForSelection"
|
|
4629
|
-
);
|
|
4630
|
-
},
|
|
4631
|
-
async pickListUpdate({ list_id, list_name, description, items }) {
|
|
4632
|
-
return callDoor(
|
|
4633
|
-
DOORS.pickListUpdate,
|
|
4634
|
-
{
|
|
4635
|
-
p_list_id: list_id,
|
|
4636
|
-
p_list_name: list_name ?? null,
|
|
4637
|
-
p_description: description ?? null,
|
|
4638
|
-
p_items: items ? [...items] : null
|
|
4639
|
-
},
|
|
4640
|
-
"pickListUpdate"
|
|
4641
|
-
);
|
|
4642
|
-
},
|
|
4690
|
+
...createPickListDoors(callDoor),
|
|
4643
4691
|
async fieldChoiceUsage({ field_id }) {
|
|
4644
4692
|
const result = await callDoor(
|
|
4645
4693
|
DOORS.fieldChoiceUsage,
|
|
@@ -7173,11 +7221,7 @@ function createRecordsClient(given) {
|
|
|
7173
7221
|
);
|
|
7174
7222
|
},
|
|
7175
7223
|
async scopeTableProvision({ home_id, item_id, scope_id }) {
|
|
7176
|
-
return
|
|
7177
|
-
DOORS.scopeTableProvision,
|
|
7178
|
-
{ p_organization_id: org, p_item_id: item_id, p_scope_id: scope_id, p_home_id: home_id ?? null },
|
|
7179
|
-
"scopeTableProvision"
|
|
7180
|
-
);
|
|
7224
|
+
return scopes.tableProvision({ organization_id: org, item_id, scope_id, home_id: home_id ?? null });
|
|
7181
7225
|
},
|
|
7182
7226
|
async tableRowCounts({ table_ids }) {
|
|
7183
7227
|
return callDoor(
|