@ai-matrx/records 0.58.9 → 0.58.12
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 +48 -1
- package/dist/core/index.cjs +67 -19
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +54 -7
- package/dist/core/index.d.ts +54 -7
- package/dist/core/index.js +67 -19
- package/dist/core/index.js.map +1 -1
- package/dist/index.cjs +2 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +10 -2
- package/dist/index.d.ts +10 -2
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/react/index.cjs +2 -1
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +13 -1
- package/dist/react/index.d.ts +13 -1
- package/dist/react/index.js +2 -1
- package/dist/react/index.js.map +1 -1
- package/dist/{types-CCwTeJvm.d.cts → types-BeDeDL6g.d.cts} +5 -1
- package/dist/{types-CCwTeJvm.d.ts → types-BeDeDL6g.d.ts} +5 -1
- package/dist/use-cases/index.cjs.map +1 -1
- package/dist/use-cases/index.d.cts +2 -2
- package/dist/use-cases/index.d.ts +2 -2
- package/dist/use-cases/index.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,12 +1,59 @@
|
|
|
1
1
|
# Changelog — @ai-matrx/records
|
|
2
2
|
|
|
3
|
+
## 0.58.12 (2026-09-25)
|
|
4
|
+
|
|
5
|
+
### Lane DECLARE-ENTITY-REF (2026-09-25)
|
|
6
|
+
|
|
7
|
+
* **Every column word reaches the door as `type`.** `declareTable` / `addFields` / `fieldDeclarationFor`
|
|
8
|
+
mapped `text` / `long_text` / `number` synonyms to `plain` and sent EVERY other word as
|
|
9
|
+
`parity_type` — but `custom._field_document_for` accepts `parity_type` only for the fourteen parity
|
|
10
|
+
types, while its `type` arm resolves them all. So eight words were refused ("There is no field type
|
|
11
|
+
called …"): `entity_reference`, `relation`, `signature`, `autonumber`, `created_time`,
|
|
12
|
+
`modified_time`, `list`, `boolean`. The word is now sent as `type`, unmapped (multiline text still
|
|
13
|
+
becomes `long_text`), and `NewFieldSpec.allowedTypes` carries an entity reference's kinds as
|
|
14
|
+
`allowed_types`. Guard: `every-declarable-word-reaches-the-door-as-its-word.test.ts` holds the
|
|
15
|
+
door's rule against every word it resolves. Proven live: a table with an
|
|
16
|
+
`entity_reference → ai_model` column declared as admin, a record written with
|
|
17
|
+
`{token: "ai_model", id}`, one `platform.associations` row answered.
|
|
18
|
+
**Consumer action:** a caller that put `allowed_types` in `config` may keep it (the door reads both)
|
|
19
|
+
or move it to `allowedTypes`; nothing else changes.
|
|
20
|
+
|
|
21
|
+
## 0.58.11 (2026-09-25 — published by PUBLISH-SWEEP-6)
|
|
22
|
+
|
|
23
|
+
0.58.10 was tagged but never reached npm: its publish gate (`real-doors.test.ts`, "no signed-out caller
|
|
24
|
+
reaches the store") counted `custom._older_table_copy_refusal(uuid)`, an anonymous door lane
|
|
25
|
+
WHERE-LIVES-SWITCH declared in `platform.client_callable_door`. The gate now counts only UNDECLARED
|
|
26
|
+
anon grants and also asserts anon holds no USAGE on schema `custom`. Everything under 0.58.10 below
|
|
27
|
+
ships here.
|
|
28
|
+
|
|
29
|
+
## 0.58.10 (2026-09-25 — tagged by PUBLISH-SWEEP-5; never published, see 0.58.11)
|
|
30
|
+
|
|
31
|
+
Carries S5-PRIME-2's decision hold (`WorkInboxItem.undo_seconds` / `undo_refusal`, `3e2c93da3c`; registry
|
|
32
|
+
689 doors), which records-ui 0.85.12 reads, so it publishes first. ORDER-FILTER shipped in 0.58.9 (below).
|
|
33
|
+
|
|
34
|
+
### Lane MOVER-BIG-VALUES (2026-09-25)
|
|
35
|
+
|
|
36
|
+
* **A value kept as a file** (`core/wholeValue.ts`): a value over the organization's ceiling for one
|
|
37
|
+
value is kept as a file and the cell holds its first 1000 characters, its envelope pointing at a
|
|
38
|
+
`whole_value_in_file` provenance entry. `wholeValueOf(document, key)` / `wholeValueOfRead(value)`
|
|
39
|
+
recognise it; `withWholeValues(rows, readFileText)` makes an export write the file's whole content;
|
|
40
|
+
`cellText` never passes the words off as the whole value (it says where the rest is).
|
|
41
|
+
|
|
42
|
+
### Lane S5-PRIME-2, VERIFIER-20 (2026-09-25)
|
|
43
|
+
|
|
44
|
+
* **`WorkInboxItem.undo_seconds` / `undo_refusal`** (uichamp_s5c, applied to production
|
|
45
|
+
2026-09-25): how long a decision on the row is held with Undo — the organization's
|
|
46
|
+
`custom/decision_undo_seconds` (default 5) for a pending approval or proposal, 0 with the store's
|
|
47
|
+
sentence when a run already waits on the answer, null for work and closed rows. Registry
|
|
48
|
+
regenerated (689 doors).
|
|
49
|
+
|
|
3
50
|
## 0.58.9
|
|
4
51
|
|
|
5
52
|
Automatic changed-only republish (docs/metadata drift since the last tag — see
|
|
6
53
|
`git diff npm/records/v0.58.8..npm/records/v0.58.9 -- apps/shared/records`).
|
|
7
54
|
No source changes intended and no consumer action required.
|
|
8
55
|
|
|
9
|
-
|
|
56
|
+
### Lane ORDER-FILTER (2026-09-25)
|
|
10
57
|
|
|
11
58
|
* **The order door takes the view's filter.** `readInViewOrder({ view_id, filter, limit, offset })`
|
|
12
59
|
now takes `filter` (`StoreFilter`: the flat map or a nested Rule — the view's own `where`, or a
|
package/dist/core/index.cjs
CHANGED
|
@@ -2247,6 +2247,7 @@ __export(core_exports, {
|
|
|
2247
2247
|
TABLE_TYPES: () => TABLE_TYPES,
|
|
2248
2248
|
VALUE_ALTERNATE_KEYS: () => VALUE_ALTERNATE_KEYS,
|
|
2249
2249
|
VALUE_ENVELOPE_KEYS: () => VALUE_ENVELOPE_KEYS,
|
|
2250
|
+
WHOLE_VALUE_SOURCE_KIND: () => WHOLE_VALUE_SOURCE_KIND,
|
|
2250
2251
|
actionRefusals: () => actionRefusals,
|
|
2251
2252
|
addFields: () => addFields,
|
|
2252
2253
|
allowsOtherValues: () => allowsOtherValues,
|
|
@@ -2343,9 +2344,14 @@ __export(core_exports, {
|
|
|
2343
2344
|
supabaseDataSource: () => supabaseDataSource,
|
|
2344
2345
|
toAoa: () => toAoa,
|
|
2345
2346
|
tokenFor: () => tokenFor,
|
|
2347
|
+
wholeValueNotRead: () => wholeValueNotRead,
|
|
2348
|
+
wholeValueOf: () => wholeValueOf,
|
|
2349
|
+
wholeValueOfRead: () => wholeValueOfRead,
|
|
2350
|
+
wholeValueSize: () => wholeValueSize,
|
|
2346
2351
|
withRowCounts: () => withRowCounts,
|
|
2347
2352
|
withTableFacts: () => withTableFacts,
|
|
2348
|
-
withTablePlacement: () => withTablePlacement
|
|
2353
|
+
withTablePlacement: () => withTablePlacement,
|
|
2354
|
+
withWholeValues: () => withWholeValues
|
|
2349
2355
|
});
|
|
2350
2356
|
module.exports = __toCommonJS(core_exports);
|
|
2351
2357
|
|
|
@@ -4401,7 +4407,7 @@ var STORE_DOORS = [
|
|
|
4401
4407
|
{ name: "work_assignment_fields", args: "p_options_table_id uuid DEFAULT NULL::uuid", returns: "TABLE(key text, label text, spec jsonb)", security: "invoker" },
|
|
4402
4408
|
{ name: "work_decide_many", args: "p_organization_id uuid, p_decisions jsonb", returns: "jsonb", security: "definer" },
|
|
4403
4409
|
{ name: "work_has_assignment", args: "p_organization_id uuid, p_table_id uuid", returns: "boolean", security: "definer" },
|
|
4404
|
-
{ name: "work_inbox", args: "p_organization_id uuid, p_limit integer DEFAULT 50, p_offset integer DEFAULT 0, p_include_decided boolean DEFAULT false, p_view text DEFAULT 'inbox'::text", returns: "TABLE(item_id uuid, kind text, origin text, title text, subject_id uuid, subject_kind text, summary text, state text, due_on timestamp with time zone, due_state text, actionable boolean, requested_by uuid, requested_by_name text, at timestamp with time zone, table_id uuid, table_name text, decided_by uuid, decided_by_name text, decided_at timestamp with time zone, outcome text, snoozed_until timestamp with time zone, cleared_at timestamp with time zone, snoozed_count integer, cleared_count integer)", security: "definer" },
|
|
4410
|
+
{ name: "work_inbox", args: "p_organization_id uuid, p_limit integer DEFAULT 50, p_offset integer DEFAULT 0, p_include_decided boolean DEFAULT false, p_view text DEFAULT 'inbox'::text", returns: "TABLE(item_id uuid, kind text, origin text, title text, subject_id uuid, subject_kind text, summary text, state text, due_on timestamp with time zone, due_state text, actionable boolean, requested_by uuid, requested_by_name text, at timestamp with time zone, table_id uuid, table_name text, decided_by uuid, decided_by_name text, decided_at timestamp with time zone, outcome text, snoozed_until timestamp with time zone, cleared_at timestamp with time zone, snoozed_count integer, cleared_count integer, undo_seconds integer, undo_refusal text)", security: "definer" },
|
|
4405
4411
|
{ name: "work_instantiation_shape", args: "p_organization_id uuid, p_instantiation_id uuid", returns: "jsonb", security: "definer" },
|
|
4406
4412
|
{ name: "work_list", args: "p_organization_id uuid, p_flavour text DEFAULT 'mine'::text, p_include_finished boolean DEFAULT false, p_limit integer DEFAULT 100, p_offset integer DEFAULT 0", returns: "TABLE(record_id uuid, table_id uuid, table_name text, title text, assignee_id uuid, assignee_name text, assignee_user_id uuid, due_on timestamp with time zone, due_state text, status text, terminal boolean, assigned_by uuid, updated_at timestamp with time zone)", security: "definer" },
|
|
4407
4413
|
{ name: "work_person", args: "p_organization_id uuid, p_user_id uuid, p_create boolean DEFAULT true", returns: "uuid", security: "definer" },
|
|
@@ -4445,6 +4451,7 @@ var STORE_KNOBS = [
|
|
|
4445
4451
|
{ key: "containment_depth_ceiling", value: "16", type: "integer" },
|
|
4446
4452
|
{ key: "context_copy_following", value: "true", type: "boolean" },
|
|
4447
4453
|
{ key: "cross_organization_links", value: "false", type: "boolean" },
|
|
4454
|
+
{ key: "decision_undo_seconds", value: "5", type: "integer" },
|
|
4448
4455
|
{ key: "decoration_rules_max", value: "50", type: "integer" },
|
|
4449
4456
|
{ key: "decorations_max_bytes", value: "262144", type: "integer" },
|
|
4450
4457
|
{ key: "document_letterhead", value: "{}", type: "json" },
|
|
@@ -8552,7 +8559,8 @@ function fieldDeclarationFor(field) {
|
|
|
8552
8559
|
...field.options ? { options: field.options } : {},
|
|
8553
8560
|
...field.relationTarget ? { relation_target: field.relationTarget } : {},
|
|
8554
8561
|
...field.unit ? { unit: field.unit } : {},
|
|
8555
|
-
...field.kind ? { kind: field.kind } : {}
|
|
8562
|
+
...field.kind ? { kind: field.kind } : {},
|
|
8563
|
+
...field.allowedTypes ? { allowed_types: field.allowedTypes } : {}
|
|
8556
8564
|
};
|
|
8557
8565
|
}
|
|
8558
8566
|
async function declareTable(client, spec) {
|
|
@@ -8619,25 +8627,12 @@ async function addFields(client, tableId, fields) {
|
|
|
8619
8627
|
}
|
|
8620
8628
|
return { ok: true, data: tableId };
|
|
8621
8629
|
}
|
|
8622
|
-
var PLAIN_WORDS = {
|
|
8623
|
-
text: "text",
|
|
8624
|
-
string: "text",
|
|
8625
|
-
long_text: "long_text",
|
|
8626
|
-
longtext: "long_text",
|
|
8627
|
-
paragraph: "long_text",
|
|
8628
|
-
number: "number",
|
|
8629
|
-
range: "number",
|
|
8630
|
-
integer: "number",
|
|
8631
|
-
decimal: "number",
|
|
8632
|
-
float: "number"
|
|
8633
|
-
};
|
|
8634
8630
|
function declaredType(field) {
|
|
8635
8631
|
const word = (field.type ?? "text").toLowerCase();
|
|
8636
|
-
|
|
8637
|
-
|
|
8638
|
-
return { plain: plain === "text" && field.config?.["multiline"] === true ? "long_text" : plain };
|
|
8632
|
+
if ((word === "text" || word === "string") && field.config?.["multiline"] === true) {
|
|
8633
|
+
return { type: "long_text" };
|
|
8639
8634
|
}
|
|
8640
|
-
return {
|
|
8635
|
+
return { type: word };
|
|
8641
8636
|
}
|
|
8642
8637
|
|
|
8643
8638
|
// src/core/supabase.ts
|
|
@@ -9032,6 +9027,57 @@ function predictWriteRefusals(args) {
|
|
|
9032
9027
|
return found;
|
|
9033
9028
|
}
|
|
9034
9029
|
|
|
9030
|
+
// src/core/wholeValue.ts
|
|
9031
|
+
var WHOLE_VALUE_SOURCE_KIND = "whole_value_in_file";
|
|
9032
|
+
function asPointer(source) {
|
|
9033
|
+
if (!source || typeof source !== "object") return null;
|
|
9034
|
+
const s = source;
|
|
9035
|
+
if (s.kind !== WHOLE_VALUE_SOURCE_KIND || typeof s.file_id !== "string" || !s.file_id) return null;
|
|
9036
|
+
return s;
|
|
9037
|
+
}
|
|
9038
|
+
function wholeValueOf(document, key) {
|
|
9039
|
+
if (!document) return null;
|
|
9040
|
+
const envelope = (document._values ?? {})[key];
|
|
9041
|
+
const pointer = envelope?.src;
|
|
9042
|
+
if (typeof pointer !== "string") return null;
|
|
9043
|
+
return asPointer((document._sources ?? {})[pointer]);
|
|
9044
|
+
}
|
|
9045
|
+
function wholeValueOfRead(value) {
|
|
9046
|
+
return asPointer(value?.source ?? null);
|
|
9047
|
+
}
|
|
9048
|
+
function wholeValueSize(pointer) {
|
|
9049
|
+
const kb = pointer.bytes / 1024;
|
|
9050
|
+
return kb >= 1024 ? `${(kb / 1024).toFixed(1)} MB` : `${Math.round(kb)} KB`;
|
|
9051
|
+
}
|
|
9052
|
+
function wholeValueNotRead(words, pointer, why) {
|
|
9053
|
+
return `${words}\u2026 [This is the start of a ${wholeValueSize(pointer)} text kept as file ${pointer.file_id}` + (why ? `; it could not be read for this export: ${why}` : "") + "]";
|
|
9054
|
+
}
|
|
9055
|
+
async function withWholeValues(rows, read) {
|
|
9056
|
+
const texts = /* @__PURE__ */ new Map();
|
|
9057
|
+
const out = [];
|
|
9058
|
+
for (const row of rows) {
|
|
9059
|
+
const next = { ...row };
|
|
9060
|
+
for (const [key, value] of Object.entries(row)) {
|
|
9061
|
+
const pointer = wholeValueOfRead(value);
|
|
9062
|
+
if (!pointer || !value) continue;
|
|
9063
|
+
const words = typeof value.value === "string" ? value.value : "";
|
|
9064
|
+
if (!read) {
|
|
9065
|
+
next[key] = { ...value, value: wholeValueNotRead(words, pointer, "this screen has no way to read files"), source: null };
|
|
9066
|
+
continue;
|
|
9067
|
+
}
|
|
9068
|
+
if (!texts.has(pointer.file_id)) texts.set(pointer.file_id, read(pointer.file_id));
|
|
9069
|
+
try {
|
|
9070
|
+
next[key] = { ...value, value: await texts.get(pointer.file_id), source: null };
|
|
9071
|
+
} catch (thrown) {
|
|
9072
|
+
const why = thrown instanceof Error ? thrown.message : String(thrown);
|
|
9073
|
+
next[key] = { ...value, value: wholeValueNotRead(words, pointer, why), source: null };
|
|
9074
|
+
}
|
|
9075
|
+
}
|
|
9076
|
+
out.push(next);
|
|
9077
|
+
}
|
|
9078
|
+
return out;
|
|
9079
|
+
}
|
|
9080
|
+
|
|
9035
9081
|
// src/core/io.ts
|
|
9036
9082
|
var escape = (value) => /[",\n\r]/.test(value) ? `"${value.replace(/"/g, '""')}"` : value;
|
|
9037
9083
|
function cellText(value) {
|
|
@@ -9039,6 +9085,8 @@ function cellText(value) {
|
|
|
9039
9085
|
if (value.absent_reason) return `(${value.absent_reason})`;
|
|
9040
9086
|
const raw = value.value;
|
|
9041
9087
|
if (raw === null || raw === void 0) return "";
|
|
9088
|
+
const pointer = wholeValueOfRead(value);
|
|
9089
|
+
if (pointer && typeof raw === "string") return wholeValueNotRead(raw, pointer);
|
|
9042
9090
|
if (typeof raw === "string") return raw;
|
|
9043
9091
|
return JSON.stringify(raw);
|
|
9044
9092
|
}
|