@ai-matrx/records 0.57.0 → 0.57.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.
@@ -2243,6 +2243,7 @@ __export(react_exports, {
2243
2243
  VALUE_ALTERNATE_KEYS: () => VALUE_ALTERNATE_KEYS,
2244
2244
  VALUE_ENVELOPE_KEYS: () => VALUE_ENVELOPE_KEYS,
2245
2245
  actionRefusals: () => actionRefusals,
2246
+ allowsOtherValues: () => allowsOtherValues,
2246
2247
  archivedByLine: () => archivedByLine,
2247
2248
  archivedWhen: () => archivedWhen,
2248
2249
  asPermissionLevel: () => asPermissionLevel,
@@ -2303,6 +2304,7 @@ __export(react_exports, {
2303
2304
  useMyLevels: () => useMyLevels,
2304
2305
  useOptionalRecordsClient: () => useOptionalRecordsClient,
2305
2306
  useRecord: () => useRecord,
2307
+ useRecordChangeRevision: () => useRecordChangeRevision,
2306
2308
  useRecordMutation: () => useRecordMutation,
2307
2309
  useRecords: () => useRecords,
2308
2310
  useRecordsActor: () => useRecordsActor,
@@ -5032,6 +5034,22 @@ function staleWriteDetail(error) {
5032
5034
  };
5033
5035
  }
5034
5036
 
5037
+ // src/core/recordChanges.ts
5038
+ var listeners = /* @__PURE__ */ new Set();
5039
+ function announceRecordChanged(recordId) {
5040
+ for (const listener of [...listeners]) {
5041
+ try {
5042
+ listener(recordId);
5043
+ } catch (thrown) {
5044
+ console.error("[@ai-matrx/records] a record-change listener threw", thrown);
5045
+ }
5046
+ }
5047
+ }
5048
+ function onRecordChanged(listener) {
5049
+ listeners.add(listener);
5050
+ return () => listeners.delete(listener);
5051
+ }
5052
+
5035
5053
  // src/core/query.ts
5036
5054
  var DEFAULT_PAGE_SIZE = 50;
5037
5055
  function planQuery(query) {
@@ -5073,12 +5091,22 @@ function intersectIds(sets) {
5073
5091
 
5074
5092
  // src/core/client.ts
5075
5093
  var DEFAULT_SCHEMA = "custom";
5094
+ var A_PERSONS_REFUSAL = /* @__PURE__ */ new Set([
5095
+ "refused_by_rule",
5096
+ "stale_write",
5097
+ "invalid_argument",
5098
+ "already_exists",
5099
+ "missing_reference"
5100
+ ]);
5101
+ function isAPersonsRefusal(code) {
5102
+ return A_PERSONS_REFUSAL.has(code);
5103
+ }
5076
5104
  function sink(config) {
5077
- return config.onError ?? ((e) => (
5078
- // The defined degradation, stated: loud, with the store's own words, and
5079
- // naming where it happened. Never silence.
5080
- console.error(`[@ai-matrx/records] ${e.where}: ${e.code} \u2014 ${e.message}${e.hint ? ` (${e.hint})` : ""}`)
5081
- ));
5105
+ return config.onError ?? ((e) => {
5106
+ const line = `[@ai-matrx/records] ${e.where}: ${e.code} \u2014 ${e.message}${e.hint ? ` (${e.hint})` : ""}`;
5107
+ if (isAPersonsRefusal(e.code)) console.info(line);
5108
+ else console.error(line);
5109
+ });
5082
5110
  }
5083
5111
  function createRecordsClient(config) {
5084
5112
  const schema = config.schema ?? DEFAULT_SCHEMA;
@@ -5185,21 +5213,26 @@ function createRecordsClient(config) {
5185
5213
  },
5186
5214
  "recordUpdate"
5187
5215
  );
5216
+ if (result.ok) announceRecordChanged(record_id);
5188
5217
  return result;
5189
5218
  },
5190
5219
  async recordDelete({ record_id }) {
5191
- return callDoor(
5220
+ const result = await callDoor(
5192
5221
  DOORS.recordDelete,
5193
5222
  { p_organization_id: org, p_record_id: record_id },
5194
5223
  "recordDelete"
5195
5224
  );
5225
+ if (result.ok) announceRecordChanged(record_id);
5226
+ return result;
5196
5227
  },
5197
5228
  async recordRestore({ record_id }) {
5198
- return callDoor(
5229
+ const result = await callDoor(
5199
5230
  DOORS.recordRestore,
5200
5231
  { p_organization_id: org, p_record_id: record_id },
5201
5232
  "recordRestore"
5202
5233
  );
5234
+ if (result.ok) announceRecordChanged(record_id);
5235
+ return result;
5203
5236
  },
5204
5237
  async tableArchive({ table_id, chunk, includeTable }) {
5205
5238
  return callDoor(
@@ -5249,6 +5282,24 @@ function createRecordsClient(config) {
5249
5282
  })
5250
5283
  );
5251
5284
  },
5285
+ async tableArchived({ table_id }) {
5286
+ const kernel = await callDoor(DOORS.tableKernelId, {}, "tableArchived.kernel");
5287
+ if (!kernel.ok) return err(kernel.error);
5288
+ const PAGE = 200;
5289
+ for (let page = 0; page < 25; page += 1) {
5290
+ const answered = await this.listArchived({
5291
+ table_id: kernel.data,
5292
+ lane: "org",
5293
+ limit: PAGE,
5294
+ offset: page * PAGE
5295
+ });
5296
+ if (!answered.ok) return err(answered.error);
5297
+ const hit = answered.data.rows.find((row) => row.id === table_id);
5298
+ if (hit) return ok(hit);
5299
+ if (answered.data.total !== null) return ok(null);
5300
+ }
5301
+ return ok(null);
5302
+ },
5252
5303
  async listArchived({ table_id, lane = DEFAULT_ARCHIVE_LANE, limit = 50, offset = 0 }) {
5253
5304
  const door = await callDoor(
5254
5305
  DOORS.readRecordsArchived,
@@ -5450,9 +5501,11 @@ function createRecordsClient(config) {
5450
5501
  );
5451
5502
  },
5452
5503
  async fieldDeclare({ table_id, spec }) {
5504
+ const { allow_other, ...rest } = spec;
5505
+ const p_spec = allow_other === void 0 ? rest : { ...rest, config: { ...rest.config ?? {}, allow_other } };
5453
5506
  return callDoor(
5454
5507
  DOORS.fieldDeclare,
5455
- { p_organization_id: org, p_table_id: table_id, p_spec: spec },
5508
+ { p_organization_id: org, p_table_id: table_id, p_spec },
5456
5509
  "fieldDeclare"
5457
5510
  );
5458
5511
  },
@@ -6420,14 +6473,16 @@ function createRecordsClient(config) {
6420
6473
  );
6421
6474
  },
6422
6475
  async restoreVersion({ record_id, version }) {
6423
- return callDoor(
6476
+ const result = await callDoor(
6424
6477
  DOORS.restoreVersion,
6425
6478
  { p_organization_id: org, p_record_id: record_id, p_version: version },
6426
6479
  "restoreVersion"
6427
6480
  );
6481
+ if (result.ok) announceRecordChanged(record_id);
6482
+ return result;
6428
6483
  },
6429
6484
  async valueRestore({ record_id, field_key, version }) {
6430
- return callDoor(
6485
+ const answered = await callDoor(
6431
6486
  DOORS.valueRestore,
6432
6487
  {
6433
6488
  p_organization_id: org,
@@ -6437,6 +6492,8 @@ function createRecordsClient(config) {
6437
6492
  },
6438
6493
  "valueRestore"
6439
6494
  );
6495
+ if (answered.ok) announceRecordChanged(record_id);
6496
+ return answered;
6440
6497
  },
6441
6498
  async commentThread({ record_id, include_resolved }) {
6442
6499
  return callDoor(
@@ -7363,13 +7420,24 @@ function useRecords(tableId, options = {}) {
7363
7420
  const liveReason = realtime ? tableId ? "Live: changes to this table re-read through the read door." : "Not live: no table selected." : "Not live: this host bound no realtime port, so this list updates when you reload it.";
7364
7421
  return { ...base, live, liveReason };
7365
7422
  }
7423
+ function useRecordChangeRevision(recordId) {
7424
+ const [revision, setRevision] = (0, import_react2.useState)(0);
7425
+ (0, import_react2.useEffect)(() => {
7426
+ if (!recordId) return;
7427
+ return onRecordChanged((changed) => {
7428
+ if (changed === recordId) setRevision((n) => n + 1);
7429
+ });
7430
+ }, [recordId]);
7431
+ return revision;
7432
+ }
7366
7433
  function useRecord(recordId, withComputed = false) {
7434
+ const changed = useRecordChangeRevision(recordId);
7367
7435
  return useAsync(
7368
7436
  async (client) => {
7369
7437
  if (!recordId) return { ok: true, data: null };
7370
7438
  return client.recordRead({ record_id: recordId, withComputed });
7371
7439
  },
7372
- [recordId, withComputed]
7440
+ [recordId, withComputed, changed]
7373
7441
  );
7374
7442
  }
7375
7443
  function useRecordMutation() {
@@ -7715,6 +7783,11 @@ var OVERRIDE_POLICIES = [
7715
7783
  var FRESHNESS = ["live", "cached", "snapshot"];
7716
7784
  var TABLE_DISPLAYS = ["list", "grid", "board", "calendar", "timeline"];
7717
7785
 
7786
+ // src/field.ts
7787
+ function allowsOtherValues(field) {
7788
+ return field.type === "list" && field.config?.["allow_other"] === true;
7789
+ }
7790
+
7718
7791
  // src/choice.ts
7719
7792
  var UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
7720
7793
  function optionKey(option) {