@ai-matrx/content-ir-react 0.19.0 → 0.20.0

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/dist/react.d.cts CHANGED
@@ -1,9 +1,9 @@
1
- import { c as KindDefinitionSource, C as ContentIrHost } from './host-types-YP_l_Q_t.cjs';
1
+ import { c as KindDefinitionSource, C as ContentIrHost } from './host-types-Cn2lf8q3.cjs';
2
2
  import { d as ComponentResolutionSource } from './component-resolution.types-DwKSF64x.cjs';
3
3
  import * as react from 'react';
4
4
  import react__default, { ReactNode } from 'react';
5
5
  import '@ai-matrx/content-ir';
6
- import './directive-host-Bw2_PrgL.cjs';
6
+ import './directive-host-B1hcjJxS.cjs';
7
7
 
8
8
  /**
9
9
  * The two registries this hook watches. Passed explicitly by a host whose
package/dist/react.d.ts CHANGED
@@ -1,9 +1,9 @@
1
- import { c as KindDefinitionSource, C as ContentIrHost } from './host-types-eSjFmXyF.js';
1
+ import { c as KindDefinitionSource, C as ContentIrHost } from './host-types-BOWu99zI.js';
2
2
  import { d as ComponentResolutionSource } from './component-resolution.types-DwKSF64x.js';
3
3
  import * as react from 'react';
4
4
  import react__default, { ReactNode } from 'react';
5
5
  import '@ai-matrx/content-ir';
6
- import './directive-host-Bw2_PrgL.js';
6
+ import './directive-host-B1hcjJxS.js';
7
7
 
8
8
  /**
9
9
  * The two registries this hook watches. Passed explicitly by a host whose
package/dist/react.js CHANGED
@@ -99,9 +99,10 @@ import { nounLabel } from "@ai-matrx/content-ir";
99
99
 
100
100
  // directives/item-changes.ts
101
101
  import { isUuidShape } from "@ai-matrx/kit/uuid";
102
+ import { humanizeIdentifier } from "@ai-matrx/kit/text-case";
102
103
  var TARGETING_CLASSES = /* @__PURE__ */ new Set(["update", "delete"]);
103
104
  var NOT_A_CHANGE = /* @__PURE__ */ new Set(["__kind", "id"]);
104
- var CHANGE_VALUE_MAX = 60;
105
+ var CHANGE_VALUE_MAX = 280;
105
106
  function itemRecordId(item) {
106
107
  const id = item.id;
107
108
  if (typeof id === "string" && id.trim()) return id.trim();
@@ -109,18 +110,24 @@ function itemRecordId(item) {
109
110
  return null;
110
111
  }
111
112
  function fieldLabel(key) {
112
- const spaced = key.replace(/_/g, " ").trim();
113
- return spaced.charAt(0).toUpperCase() + spaced.slice(1);
113
+ return humanizeIdentifier(key) || key;
114
114
  }
115
+ function directiveFieldLabel(key, titleColumn) {
116
+ return titleColumn && key === titleColumn ? "Title" : fieldLabel(key);
117
+ }
118
+ var EMPTY_VALUE_WORD = "None";
115
119
  function recordFallbackName(nounLabel3, id) {
116
120
  const short = isUuidShape(id) ? id.slice(0, 8) : id.length > 12 ? `${id.slice(0, 12)}\u2026` : id;
117
121
  return `${nounLabel3} ${short}`;
118
122
  }
119
- function describeValue(value) {
120
- if (value === null || value === void 0) return { value: "cleared", full: "cleared", clears: true };
123
+ var EMPTY = { value: EMPTY_VALUE_WORD, full: EMPTY_VALUE_WORD, clears: true };
124
+ function describeValue(value, word) {
125
+ if (value === null || value === void 0) return EMPTY;
121
126
  if (typeof value === "string") {
122
127
  const trimmed = value.trim();
123
- if (!trimmed) return { value: "cleared", full: "cleared", clears: true };
128
+ if (!trimmed) return EMPTY;
129
+ const named = word?.(trimmed) ?? null;
130
+ if (named) return { value: named, full: named, clears: false };
124
131
  const oneLine = trimmed.replace(/\s+/g, " ");
125
132
  const shown = oneLine.length > CHANGE_VALUE_MAX ? `${oneLine.slice(0, CHANGE_VALUE_MAX - 1)}\u2026` : oneLine;
126
133
  return { value: shown, full: trimmed, clears: false };
@@ -130,11 +137,11 @@ function describeValue(value) {
130
137
  }
131
138
  if (Array.isArray(value)) {
132
139
  const n2 = value.length;
133
- const text2 = n2 === 0 ? "cleared" : `${n2} ${n2 === 1 ? "entry" : "entries"}`;
140
+ const text2 = n2 === 0 ? EMPTY_VALUE_WORD : `${n2} ${n2 === 1 ? "entry" : "entries"}`;
134
141
  return { value: text2, full: safeJson(value), clears: n2 === 0 };
135
142
  }
136
143
  const n = Object.keys(value).length;
137
- const text = n === 0 ? "cleared" : `${n} ${n === 1 ? "field" : "fields"}`;
144
+ const text = n === 0 ? EMPTY_VALUE_WORD : `${n} ${n === 1 ? "field" : "fields"}`;
138
145
  return { value: text, full: safeJson(value), clears: n === 0 };
139
146
  }
140
147
  function safeJson(value) {
@@ -159,10 +166,12 @@ function itemChanges(item, current, options = {}) {
159
166
  const titleColumn = options.titleColumn ?? null;
160
167
  for (const [key, raw] of Object.entries(item)) {
161
168
  if (NOT_A_CHANGE.has(key)) continue;
162
- const label = key === titleColumn ? "Title" : fieldLabel(key);
163
- const change = { key, label, ...describeValue(raw) };
169
+ const label = directiveFieldLabel(key, titleColumn);
170
+ const valueWord = options.valueWord;
171
+ const word = key === titleColumn || !valueWord ? void 0 : (v) => valueWord(key, v);
172
+ const change = { key, label, ...describeValue(raw, word) };
164
173
  if (current && Object.prototype.hasOwnProperty.call(current, key)) {
165
- change.before = describeValue(current[key]);
174
+ change.before = describeValue(current[key], word);
166
175
  change.same = sameValue(current[key], raw);
167
176
  }
168
177
  out.push(change);
@@ -172,8 +181,17 @@ function itemChanges(item, current, options = {}) {
172
181
 
173
182
  // directives/record-values.ts
174
183
  import { useEffect, useState, useSyncExternalStore as useSyncExternalStore2 } from "react";
175
- var revisions = /* @__PURE__ */ new Map();
176
- var listeners = /* @__PURE__ */ new Set();
184
+ var STORE_SLOT = /* @__PURE__ */ Symbol.for("@ai-matrx/content-ir-react/record-revisions");
185
+ function revisionStore() {
186
+ const slots = globalThis;
187
+ let store = slots[STORE_SLOT];
188
+ if (!store) {
189
+ store = { revisions: /* @__PURE__ */ new Map(), listeners: /* @__PURE__ */ new Set() };
190
+ slots[STORE_SLOT] = store;
191
+ }
192
+ return store;
193
+ }
194
+ var { revisions, listeners } = revisionStore();
177
195
  function recordRevision(id) {
178
196
  return revisions.get(id) ?? 0;
179
197
  }
@@ -819,6 +837,14 @@ import {
819
837
  nounTitleColumn
820
838
  } from "@ai-matrx/content-ir";
821
839
  import { Fragment, jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
840
+ function directiveValueWord(host, noun) {
841
+ const valueLabel = host.valueLabel;
842
+ return valueLabel ? (field, value) => valueLabel({ noun, field, value }) : null;
843
+ }
844
+ function omitKey(item, key) {
845
+ const { [key]: _omitted, ...rest } = item;
846
+ return rest;
847
+ }
822
848
  var ROWS_BEFORE_FOLD = 3;
823
849
  function ItemRow({
824
850
  directive,
@@ -835,16 +861,21 @@ function ItemRow({
835
861
  const titleColumn = nounTitleColumn(directive.noun, host.nouns);
836
862
  const title = itemTitle(item, titleColumn, index, total);
837
863
  const subtitle = itemSubtitle(item);
838
- const facts = itemFacts(item);
864
+ const valueWord = directiveValueWord(host, directive.noun);
865
+ const facts = itemFacts(titleColumn ? omitKey(item, titleColumn) : item).map((fact) => ({
866
+ ...fact,
867
+ label: directiveFieldLabel(fact.key, titleColumn),
868
+ value: valueWord?.(fact.key, fact.value) ?? fact.value
869
+ }));
839
870
  const kind = host.itemKind?.(directive.slug) ?? null;
840
871
  const display = directiveDisplay3(directive.directiveClass, directive.noun, host.nouns);
841
872
  const openItem = host.openItem;
842
873
  const body = /* @__PURE__ */ jsxs5(Fragment, { children: [
843
874
  /* @__PURE__ */ jsx7("span", { className: "min-w-0 shrink-0 truncate font-medium text-foreground", children: title }),
844
- /* @__PURE__ */ jsx7("span", { className: "hidden min-w-0 flex-1 items-baseline gap-2 overflow-hidden sm:flex", children: facts.map((fact) => /* @__PURE__ */ jsxs5("span", { className: "truncate text-[11px] text-muted-foreground", children: [
845
- fact.value,
875
+ /* @__PURE__ */ jsx7("span", { className: "hidden min-w-0 flex-1 items-baseline gap-2 overflow-hidden sm:flex", children: facts.map((fact) => /* @__PURE__ */ jsxs5("span", { className: "truncate text-[11px] text-muted-foreground", "data-item-fact": fact.key, children: [
876
+ fact.label,
846
877
  " ",
847
- fact.label
878
+ /* @__PURE__ */ jsx7("span", { className: "text-foreground/80", children: fact.value })
848
879
  ] }, fact.key)) }),
849
880
  subtitle && facts.length === 0 ? /* @__PURE__ */ jsx7("span", { className: "hidden truncate text-[11px] text-muted-foreground sm:inline", children: subtitle }) : null,
850
881
  openItem ? /* @__PURE__ */ jsx7(MaximizeIcon, { className: "ml-auto h-3 w-3 shrink-0 text-muted-foreground" }) : null
@@ -879,35 +910,36 @@ function DirectiveChangeList({
879
910
  if (changes.length === 0) {
880
911
  return /* @__PURE__ */ jsx7("p", { className: `text-[11px] text-muted-foreground${className ? ` ${className}` : ""}`, children: "Sets no fields \u2014 nothing would change." });
881
912
  }
882
- return /* @__PURE__ */ jsx7("ul", { className: `space-y-0.5${className ? ` ${className}` : ""}`, "data-directive-changes": "", children: changes.map((change) => {
913
+ return /* @__PURE__ */ jsx7("ul", { className: `@container space-y-1${className ? ` ${className}` : ""}`, "data-directive-changes": "", children: changes.map((change) => {
883
914
  const before = change.before && !change.same ? change.before : null;
884
- const was = before ? before.clears ? "empty" : before.value : null;
885
915
  return /* @__PURE__ */ jsxs5(
886
916
  "li",
887
917
  {
888
- className: "flex min-w-0 items-baseline gap-1.5 text-[11px]",
889
- title: before ? `${change.label}: ${before.clears ? "empty" : before.full} \u2192 ${change.full}` : `${change.label} \u2192 ${change.full}`,
918
+ className: "flex min-w-0 flex-col text-[11px] @xs:flex-row @xs:flex-wrap @xs:items-baseline @xs:gap-x-1.5",
919
+ title: before ? `${change.label}: ${before.full} \u2192 ${change.full}` : `${change.label} \u2192 ${change.full}`,
890
920
  "data-change-key": change.key,
891
921
  children: [
892
922
  /* @__PURE__ */ jsx7("span", { className: "shrink-0 text-muted-foreground", children: change.label }),
893
- was !== null ? /* @__PURE__ */ jsx7(
923
+ before ? /* @__PURE__ */ jsx7(
894
924
  "span",
895
925
  {
896
- className: "min-w-0 max-w-[40%] shrink truncate text-muted-foreground line-through",
926
+ className: "min-w-0 text-muted-foreground line-through [overflow-wrap:anywhere]",
897
927
  "data-change-before": "",
898
- children: was
928
+ children: before.value
899
929
  }
900
930
  ) : null,
901
- /* @__PURE__ */ jsx7("span", { "aria-hidden": true, className: "shrink-0 text-muted-foreground", children: "\u2192" }),
902
- /* @__PURE__ */ jsx7(
903
- "span",
904
- {
905
- className: `min-w-0 truncate ${change.clears ? "italic text-muted-foreground" : "text-foreground"}`,
906
- "data-change-after": "",
907
- children: change.value
908
- }
909
- ),
910
- change.same ? /* @__PURE__ */ jsx7("span", { className: "shrink-0 text-muted-foreground", children: "(no change)" }) : null
931
+ /* @__PURE__ */ jsxs5("span", { className: "flex min-w-0 items-baseline gap-1.5", children: [
932
+ /* @__PURE__ */ jsx7("span", { "aria-hidden": true, className: "shrink-0 text-muted-foreground", children: "\u2192" }),
933
+ /* @__PURE__ */ jsx7(
934
+ "span",
935
+ {
936
+ className: `min-w-0 [overflow-wrap:anywhere] ${change.clears ? "italic text-muted-foreground" : "text-foreground"}`,
937
+ "data-change-after": "",
938
+ children: change.value
939
+ }
940
+ ),
941
+ change.same ? /* @__PURE__ */ jsx7("span", { className: "shrink-0 text-muted-foreground", children: "(no change)" }) : null
942
+ ] })
911
943
  ]
912
944
  },
913
945
  change.key
@@ -930,7 +962,10 @@ function TargetRow({
930
962
  readsLive ? { noun: directive.noun, id: recordId } : null
931
963
  );
932
964
  const compareTo = phase.phase === "applied" ? phase.before?.[index] ?? null : readsLive ? live.values : null;
933
- const changes = isUpdate ? itemChanges(item, compareTo, { titleColumn: nounTitleColumn(directive.noun, host.nouns) }) : [];
965
+ const changes = isUpdate ? itemChanges(item, compareTo, {
966
+ titleColumn: nounTitleColumn(directive.noun, host.nouns),
967
+ valueWord: directiveValueWord(host, directive.noun)
968
+ }) : [];
934
969
  const name = host.renderRecord ? host.renderRecord({ noun: directive.noun, id: recordId, fallback, context: "row" }) : /* @__PURE__ */ jsx7("span", { className: "truncate font-medium text-foreground", children: fallback });
935
970
  return /* @__PURE__ */ jsxs5("div", { className: "py-1 text-xs", "data-directive-target": recordId, children: [
936
971
  /* @__PURE__ */ jsxs5("div", { className: "flex min-w-0 items-center gap-2", children: [