@ai-matrx/content-ir-react 0.18.1 → 0.19.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/index.d.cts CHANGED
@@ -428,6 +428,15 @@ interface RecordValues {
428
428
  status: RecordValuesStatus;
429
429
  }
430
430
  type RecordReader = (ref: DirectiveRecordRef) => Promise<Record<string, unknown> | null>;
431
+ /** How many times this page has changed record `id` (0 = never). */
432
+ declare function recordRevision(id: string): number;
433
+ /**
434
+ * Record `id` just changed (an apply wrote it, or any other writer on the page).
435
+ * Every `useRecordValues` naming it reads it again.
436
+ */
437
+ declare function noteRecordChanged(id: string): void;
438
+ /** The live revision of record `id`, re-rendering when it changes. */
439
+ declare function useRecordRevision(id: string): number;
431
440
  declare function useRecordValues(read: RecordReader | undefined, ref: DirectiveRecordRef | null): RecordValues;
432
441
 
433
442
  /**
@@ -693,4 +702,4 @@ declare class DbKindComponentErrorBoundary extends react.Component<DbKindCompone
693
702
  render(): react.ReactNode;
694
703
  }
695
704
 
696
- export { ApplyDirectiveButton, type ApplyDirectiveButtonProps, CHANGE_VALUE_MAX, type ChangeValue, type CompiledDbKindComponent, ComponentResolution, ComponentResolutionSource, ContentIrErrorReporter, ContentIrHost, ContentIrRenderProvider, type ContentIrRenderProviderProps, type DbKindActionResult, type DbKindCompileResult, type DbKindComponentCache, type DbKindComponentCachePorts, type DbKindComponentCompiler, DbKindComponentErrorBoundary, type DbKindComponentErrorBoundaryProps, type DbKindComponentIncident, type DbKindComponentIncidentSink, type DbKindComponentIncidentType, type DbKindComponentRenderProps, DelegatedOutput, type DelegatedOutputProps, type DirectiveApplyPhase, DirectiveChangeList, DirectiveFailure, DirectiveFailureWords, DirectiveFallbackCard, type DirectiveFallbackCardProps, DirectiveProvisionalCard, type DirectiveProvisionalCardProps, DirectiveRecordRef, DirectiveRender, type DirectiveRenderProps, type DirectiveRenderer, type DirectiveRendererProps, GenericStructuredView, type GenericStructuredViewProps, type ItemChange, type ItemChangesOptions, type KindComponentUiOptions, KindDefinitionSource, KindInstanceRender, type KindInstanceRenderProps, KindRouteEnv, type KindVersionSources, NodeOutcomeView, type NodeOutcomeViewProps, ProvisionalKindBoundary, ProvisionalKindFrame, type RecordReader, type RecordValues, type RecordValuesStatus, type ResolveKindValue, type RunDbKindAction, RunResultView, type RunResultViewProps, SideEffectDirectiveCard, type SideEffectDirectiveCardProps, TARGETING_CLASSES, createDbKindComponentCache, defaultFailureWords, describeChangeValue, failureWords, fieldLabel, getDirectiveRenderer, isDbKindComponentBodyPending, isRecordValue, itemChanges, itemRecordId, kindIsRoutable, provisionalDirectiveSlug, readsApplyLedger, recordFallbackName, registerDirectiveRenderer, resetDirectiveRenderers, useContentIrHost, useContentIrHostOrNull, useContentIrKindVersion, useKindRouteEnv, useRecordValues };
705
+ export { ApplyDirectiveButton, type ApplyDirectiveButtonProps, CHANGE_VALUE_MAX, type ChangeValue, type CompiledDbKindComponent, ComponentResolution, ComponentResolutionSource, ContentIrErrorReporter, ContentIrHost, ContentIrRenderProvider, type ContentIrRenderProviderProps, type DbKindActionResult, type DbKindCompileResult, type DbKindComponentCache, type DbKindComponentCachePorts, type DbKindComponentCompiler, DbKindComponentErrorBoundary, type DbKindComponentErrorBoundaryProps, type DbKindComponentIncident, type DbKindComponentIncidentSink, type DbKindComponentIncidentType, type DbKindComponentRenderProps, DelegatedOutput, type DelegatedOutputProps, type DirectiveApplyPhase, DirectiveChangeList, DirectiveFailure, DirectiveFailureWords, DirectiveFallbackCard, type DirectiveFallbackCardProps, DirectiveProvisionalCard, type DirectiveProvisionalCardProps, DirectiveRecordRef, DirectiveRender, type DirectiveRenderProps, type DirectiveRenderer, type DirectiveRendererProps, GenericStructuredView, type GenericStructuredViewProps, type ItemChange, type ItemChangesOptions, type KindComponentUiOptions, KindDefinitionSource, KindInstanceRender, type KindInstanceRenderProps, KindRouteEnv, type KindVersionSources, NodeOutcomeView, type NodeOutcomeViewProps, ProvisionalKindBoundary, ProvisionalKindFrame, type RecordReader, type RecordValues, type RecordValuesStatus, type ResolveKindValue, type RunDbKindAction, RunResultView, type RunResultViewProps, SideEffectDirectiveCard, type SideEffectDirectiveCardProps, TARGETING_CLASSES, createDbKindComponentCache, defaultFailureWords, describeChangeValue, failureWords, fieldLabel, getDirectiveRenderer, isDbKindComponentBodyPending, isRecordValue, itemChanges, itemRecordId, kindIsRoutable, noteRecordChanged, provisionalDirectiveSlug, readsApplyLedger, recordFallbackName, recordRevision, registerDirectiveRenderer, resetDirectiveRenderers, useContentIrHost, useContentIrHostOrNull, useContentIrKindVersion, useKindRouteEnv, useRecordRevision, useRecordValues };
package/dist/index.d.ts CHANGED
@@ -428,6 +428,15 @@ interface RecordValues {
428
428
  status: RecordValuesStatus;
429
429
  }
430
430
  type RecordReader = (ref: DirectiveRecordRef) => Promise<Record<string, unknown> | null>;
431
+ /** How many times this page has changed record `id` (0 = never). */
432
+ declare function recordRevision(id: string): number;
433
+ /**
434
+ * Record `id` just changed (an apply wrote it, or any other writer on the page).
435
+ * Every `useRecordValues` naming it reads it again.
436
+ */
437
+ declare function noteRecordChanged(id: string): void;
438
+ /** The live revision of record `id`, re-rendering when it changes. */
439
+ declare function useRecordRevision(id: string): number;
431
440
  declare function useRecordValues(read: RecordReader | undefined, ref: DirectiveRecordRef | null): RecordValues;
432
441
 
433
442
  /**
@@ -693,4 +702,4 @@ declare class DbKindComponentErrorBoundary extends react.Component<DbKindCompone
693
702
  render(): react.ReactNode;
694
703
  }
695
704
 
696
- export { ApplyDirectiveButton, type ApplyDirectiveButtonProps, CHANGE_VALUE_MAX, type ChangeValue, type CompiledDbKindComponent, ComponentResolution, ComponentResolutionSource, ContentIrErrorReporter, ContentIrHost, ContentIrRenderProvider, type ContentIrRenderProviderProps, type DbKindActionResult, type DbKindCompileResult, type DbKindComponentCache, type DbKindComponentCachePorts, type DbKindComponentCompiler, DbKindComponentErrorBoundary, type DbKindComponentErrorBoundaryProps, type DbKindComponentIncident, type DbKindComponentIncidentSink, type DbKindComponentIncidentType, type DbKindComponentRenderProps, DelegatedOutput, type DelegatedOutputProps, type DirectiveApplyPhase, DirectiveChangeList, DirectiveFailure, DirectiveFailureWords, DirectiveFallbackCard, type DirectiveFallbackCardProps, DirectiveProvisionalCard, type DirectiveProvisionalCardProps, DirectiveRecordRef, DirectiveRender, type DirectiveRenderProps, type DirectiveRenderer, type DirectiveRendererProps, GenericStructuredView, type GenericStructuredViewProps, type ItemChange, type ItemChangesOptions, type KindComponentUiOptions, KindDefinitionSource, KindInstanceRender, type KindInstanceRenderProps, KindRouteEnv, type KindVersionSources, NodeOutcomeView, type NodeOutcomeViewProps, ProvisionalKindBoundary, ProvisionalKindFrame, type RecordReader, type RecordValues, type RecordValuesStatus, type ResolveKindValue, type RunDbKindAction, RunResultView, type RunResultViewProps, SideEffectDirectiveCard, type SideEffectDirectiveCardProps, TARGETING_CLASSES, createDbKindComponentCache, defaultFailureWords, describeChangeValue, failureWords, fieldLabel, getDirectiveRenderer, isDbKindComponentBodyPending, isRecordValue, itemChanges, itemRecordId, kindIsRoutable, provisionalDirectiveSlug, readsApplyLedger, recordFallbackName, registerDirectiveRenderer, resetDirectiveRenderers, useContentIrHost, useContentIrHostOrNull, useContentIrKindVersion, useKindRouteEnv, useRecordValues };
705
+ export { ApplyDirectiveButton, type ApplyDirectiveButtonProps, CHANGE_VALUE_MAX, type ChangeValue, type CompiledDbKindComponent, ComponentResolution, ComponentResolutionSource, ContentIrErrorReporter, ContentIrHost, ContentIrRenderProvider, type ContentIrRenderProviderProps, type DbKindActionResult, type DbKindCompileResult, type DbKindComponentCache, type DbKindComponentCachePorts, type DbKindComponentCompiler, DbKindComponentErrorBoundary, type DbKindComponentErrorBoundaryProps, type DbKindComponentIncident, type DbKindComponentIncidentSink, type DbKindComponentIncidentType, type DbKindComponentRenderProps, DelegatedOutput, type DelegatedOutputProps, type DirectiveApplyPhase, DirectiveChangeList, DirectiveFailure, DirectiveFailureWords, DirectiveFallbackCard, type DirectiveFallbackCardProps, DirectiveProvisionalCard, type DirectiveProvisionalCardProps, DirectiveRecordRef, DirectiveRender, type DirectiveRenderProps, type DirectiveRenderer, type DirectiveRendererProps, GenericStructuredView, type GenericStructuredViewProps, type ItemChange, type ItemChangesOptions, type KindComponentUiOptions, KindDefinitionSource, KindInstanceRender, type KindInstanceRenderProps, KindRouteEnv, type KindVersionSources, NodeOutcomeView, type NodeOutcomeViewProps, ProvisionalKindBoundary, ProvisionalKindFrame, type RecordReader, type RecordValues, type RecordValuesStatus, type ResolveKindValue, type RunDbKindAction, RunResultView, type RunResultViewProps, SideEffectDirectiveCard, type SideEffectDirectiveCardProps, TARGETING_CLASSES, createDbKindComponentCache, defaultFailureWords, describeChangeValue, failureWords, fieldLabel, getDirectiveRenderer, isDbKindComponentBodyPending, isRecordValue, itemChanges, itemRecordId, kindIsRoutable, noteRecordChanged, provisionalDirectiveSlug, readsApplyLedger, recordFallbackName, recordRevision, registerDirectiveRenderer, resetDirectiveRenderers, useContentIrHost, useContentIrHostOrNull, useContentIrKindVersion, useKindRouteEnv, useRecordRevision, useRecordValues };
package/dist/index.js CHANGED
@@ -268,8 +268,8 @@ var ComponentResolver = class {
268
268
  }
269
269
  bumpKind(kind) {
270
270
  this.kindVersions.set(kind, (this.kindVersions.get(kind) ?? 0) + 1);
271
- const listeners = this.kindListeners.get(kind);
272
- if (listeners) for (const listener of listeners) listener();
271
+ const listeners2 = this.kindListeners.get(kind);
272
+ if (listeners2) for (const listener of listeners2) listener();
273
273
  }
274
274
  notifyChanged() {
275
275
  this.version += 1;
@@ -753,7 +753,7 @@ import { looksLikeDirectiveHead, tryDecodeDirectiveContent } from "@ai-matrx/con
753
753
  import { directiveDisplay } from "@ai-matrx/content-ir";
754
754
 
755
755
  // directives/ApplyDirectiveButton.tsx
756
- import { useEffect, useRef, useState, useSyncExternalStore as useSyncExternalStore2 } from "react";
756
+ import { useEffect as useEffect2, useRef, useState as useState2, useSyncExternalStore as useSyncExternalStore3 } from "react";
757
757
  import { nounLabel } from "@ai-matrx/content-ir";
758
758
 
759
759
  // directives/item-changes.ts
@@ -832,6 +832,64 @@ function itemChanges(item, current, options = {}) {
832
832
  return out;
833
833
  }
834
834
 
835
+ // directives/record-values.ts
836
+ import { useEffect, useState, useSyncExternalStore as useSyncExternalStore2 } from "react";
837
+ var revisions = /* @__PURE__ */ new Map();
838
+ var listeners = /* @__PURE__ */ new Set();
839
+ function recordRevision(id) {
840
+ return revisions.get(id) ?? 0;
841
+ }
842
+ function noteRecordChanged(id) {
843
+ if (!id) return;
844
+ revisions.set(id, recordRevision(id) + 1);
845
+ for (const listener of listeners) listener();
846
+ }
847
+ function subscribeRevisions(listener) {
848
+ listeners.add(listener);
849
+ return () => {
850
+ listeners.delete(listener);
851
+ };
852
+ }
853
+ function useRecordRevision(id) {
854
+ return useSyncExternalStore2(
855
+ subscribeRevisions,
856
+ () => recordRevision(id),
857
+ () => 0
858
+ );
859
+ }
860
+ function useRecordValues(read, ref) {
861
+ const revision = useRecordRevision(ref?.id ?? "");
862
+ const key = ref && read ? `${ref.noun}:${ref.id}#${revision}` : "";
863
+ const [result, setResult] = useState({
864
+ key: "",
865
+ values: null,
866
+ status: "idle"
867
+ });
868
+ useEffect(() => {
869
+ if (!key || !read) return;
870
+ const split = key.indexOf(":");
871
+ const target = {
872
+ noun: key.slice(0, split),
873
+ id: key.slice(split + 1, key.lastIndexOf("#"))
874
+ };
875
+ let live = true;
876
+ setResult({ key, values: null, status: "loading" });
877
+ read(target).then((values) => {
878
+ if (!live) return;
879
+ setResult({ key, values, status: values ? "ready" : "unavailable" });
880
+ }).catch(() => {
881
+ if (!live) return;
882
+ setResult({ key, values: null, status: "unavailable" });
883
+ });
884
+ return () => {
885
+ live = false;
886
+ };
887
+ }, [key, read]);
888
+ if (!key) return { values: null, status: "idle" };
889
+ if (result.key !== key) return { values: null, status: "loading" };
890
+ return { values: result.values, status: result.status };
891
+ }
892
+
835
893
  // directives/failure-words.ts
836
894
  var PAST = {
837
895
  create: "created",
@@ -951,6 +1009,13 @@ function classIcon(directiveClass, noun) {
951
1009
 
952
1010
  // directives/ApplyDirectiveButton.tsx
953
1011
  import { jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
1012
+ function announceChangedRecords(directive, items) {
1013
+ if (!TARGETING_CLASSES.has(directive.directiveClass)) return;
1014
+ for (const item of items) {
1015
+ const id = itemRecordId(item);
1016
+ if (id) noteRecordChanged(id);
1017
+ }
1018
+ }
954
1019
  var applyOutcomes = /* @__PURE__ */ new WeakMap();
955
1020
  var EMPTY_AUTHORITY = {};
956
1021
  var outcomeListeners = /* @__PURE__ */ new Set();
@@ -973,7 +1038,7 @@ function subscribeOutcomes(listener) {
973
1038
  };
974
1039
  }
975
1040
  function useApplyOutcome(host, identity) {
976
- return useSyncExternalStore2(
1041
+ return useSyncExternalStore3(
977
1042
  subscribeOutcomes,
978
1043
  () => applyOutcomes.get(host)?.get(identity) ?? null,
979
1044
  () => null
@@ -998,12 +1063,12 @@ function ApplyDirectiveButton({
998
1063
  const items = directive.items;
999
1064
  const readsLedger = readsApplyLedger(host, directive);
1000
1065
  const initial = readsLedger ? { status: "checking" } : { status: "idle" };
1001
- const [state, setState] = useState(initial);
1002
- const [elapsed, setElapsed] = useState(0);
1003
- const [askingAgain, setAskingAgain] = useState(false);
1066
+ const [state, setState] = useState2(initial);
1067
+ const [elapsed, setElapsed] = useState2(0);
1068
+ const [askingAgain, setAskingAgain] = useState2(false);
1004
1069
  const startedAt = useRef(null);
1005
1070
  const identity = JSON.stringify([directive.slug, items, conversationId ?? null]);
1006
- const [stateFor, setStateFor] = useState(identity);
1071
+ const [stateFor, setStateFor] = useState2(identity);
1007
1072
  if (stateFor !== identity) {
1008
1073
  setStateFor(identity);
1009
1074
  setState(initial);
@@ -1013,14 +1078,14 @@ function ApplyDirectiveButton({
1013
1078
  const shared = useApplyOutcome(host.confirm ?? EMPTY_AUTHORITY, identity);
1014
1079
  const view = state.status === "asking" || !shared ? state : shared;
1015
1080
  const currentIdentity = useRef(identity);
1016
- useEffect(() => {
1081
+ useEffect2(() => {
1017
1082
  currentIdentity.current = identity;
1018
1083
  }, [identity]);
1019
1084
  const nounText = nounLabel(directive.noun, host.nouns);
1020
1085
  const shellKey = readsLedger ? JSON.stringify([directive.slug, items, conversationId ?? null]) : "";
1021
1086
  const read = host.applyState;
1022
1087
  const report = host.reportError;
1023
- useEffect(() => {
1088
+ useEffect2(() => {
1024
1089
  if (!shellKey || !read) return;
1025
1090
  const [slug, shellItems, inConversation] = JSON.parse(shellKey);
1026
1091
  const shell = { __kind: slug, items: shellItems };
@@ -1068,14 +1133,14 @@ function ApplyDirectiveButton({
1068
1133
  const appliedClean = view.status === "applied" && view.failed === 0 ? view : null;
1069
1134
  const appliedBefore = appliedClean ? appliedClean.before : null;
1070
1135
  const phaseKey = view.status === "checking" || view.status === "finishing" ? "pending" : appliedClean ? `applied:${JSON.stringify(appliedBefore)}` : "open";
1071
- useEffect(() => {
1136
+ useEffect2(() => {
1072
1137
  if (!onPhase) return;
1073
1138
  if (phaseKey === "pending") onPhase({ phase: "pending" });
1074
1139
  else if (phaseKey === "open") onPhase({ phase: "open" });
1075
1140
  else onPhase({ phase: "applied", before: appliedBefore });
1076
1141
  }, [phaseKey, onPhase, appliedBefore]);
1077
1142
  const applyingSince = view.status === "applying" ? view.startedAt : null;
1078
- useEffect(() => {
1143
+ useEffect2(() => {
1079
1144
  if (applyingSince === null) return;
1080
1145
  startedAt.current = applyingSince;
1081
1146
  const id = setInterval(
@@ -1127,7 +1192,13 @@ function ApplyDirectiveButton({
1127
1192
  const shell = { __kind: directive.slug, items };
1128
1193
  if (conversationId) shell.conversationId = conversationId;
1129
1194
  if (again) shell.force = true;
1130
- const result = await confirm(shell);
1195
+ let result;
1196
+ try {
1197
+ result = await confirm(shell);
1198
+ } finally {
1199
+ announceChangedRecords(directive, items);
1200
+ }
1201
+ for (const record of result.records ?? []) noteRecordChanged(record.id);
1131
1202
  publishOutcome(confirm, askedFor, {
1132
1203
  status: "applied",
1133
1204
  applied: result.applied,
@@ -1288,7 +1359,7 @@ function FailureNotice({
1288
1359
  words,
1289
1360
  raw
1290
1361
  }) {
1291
- const [open, setOpen] = useState(false);
1362
+ const [open, setOpen] = useState2(false);
1292
1363
  const detail = raw?.trim() ?? "";
1293
1364
  return /* @__PURE__ */ jsxs2("span", { className: "flex min-w-0 flex-col gap-0.5", "data-apply-failure": true, children: [
1294
1365
  /* @__PURE__ */ jsxs2("span", { className: "min-w-0", children: [
@@ -1417,39 +1488,6 @@ import {
1417
1488
  nounLabel as nounLabel2,
1418
1489
  nounTitleColumn
1419
1490
  } from "@ai-matrx/content-ir";
1420
-
1421
- // directives/record-values.ts
1422
- import { useEffect as useEffect2, useState as useState2 } from "react";
1423
- function useRecordValues(read, ref) {
1424
- const key = ref && read ? `${ref.noun}:${ref.id}` : "";
1425
- const [result, setResult] = useState2({
1426
- key: "",
1427
- values: null,
1428
- status: "idle"
1429
- });
1430
- useEffect2(() => {
1431
- if (!key || !read) return;
1432
- const split = key.indexOf(":");
1433
- const target = { noun: key.slice(0, split), id: key.slice(split + 1) };
1434
- let live = true;
1435
- setResult({ key, values: null, status: "loading" });
1436
- read(target).then((values) => {
1437
- if (!live) return;
1438
- setResult({ key, values, status: values ? "ready" : "unavailable" });
1439
- }).catch(() => {
1440
- if (!live) return;
1441
- setResult({ key, values: null, status: "unavailable" });
1442
- });
1443
- return () => {
1444
- live = false;
1445
- };
1446
- }, [key, read]);
1447
- if (!key) return { values: null, status: "idle" };
1448
- if (result.key !== key) return { values: null, status: "loading" };
1449
- return { values: result.values, status: result.status };
1450
- }
1451
-
1452
- // directives/SideEffectDirectiveCard.tsx
1453
1491
  import { Fragment, jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
1454
1492
  var ROWS_BEFORE_FOLD = 3;
1455
1493
  function ItemRow({
@@ -2137,10 +2175,12 @@ export {
2137
2175
  kindIsRoutable,
2138
2176
  kindServerDataFromStoredValue,
2139
2177
  markKindPartialUnsafe,
2178
+ noteRecordChanged,
2140
2179
  provisionalDirectiveSlug,
2141
2180
  readIrRouteMarker,
2142
2181
  readsApplyLedger,
2143
2182
  recordFallbackName,
2183
+ recordRevision,
2144
2184
  registerDirectiveRenderer,
2145
2185
  resetDirectiveRenderers,
2146
2186
  resetPartialUnsafeKinds,
@@ -2155,6 +2195,7 @@ export {
2155
2195
  useDirectiveHost,
2156
2196
  useDirectiveScope,
2157
2197
  useKindRouteEnv,
2198
+ useRecordRevision,
2158
2199
  useRecordValues
2159
2200
  };
2160
2201
  //# sourceMappingURL=index.js.map