@ai-matrx/content-ir-react 0.17.0 → 0.18.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/CHANGELOG.md +28 -0
- package/README.md +1 -1
- package/dist/{component-resolution.types-DLO2w-0n.d.cts → component-resolution.types-DY4pGymy.d.cts} +1 -1
- package/dist/{component-resolution.types-DLO2w-0n.d.ts → component-resolution.types-DY4pGymy.d.ts} +1 -1
- package/dist/{component-resolution.types-C1MzCf2s.d.cts → component-resolution.types-DwKSF64x.d.cts} +1 -1
- package/dist/{component-resolution.types-C1MzCf2s.d.ts → component-resolution.types-DwKSF64x.d.ts} +1 -1
- package/dist/db-component.d.cts +1 -1
- package/dist/db-component.d.ts +1 -1
- package/dist/{directive-host-BOML4BQ7.d.cts → directive-host-Bw2_PrgL.d.cts} +14 -0
- package/dist/{directive-host-BOML4BQ7.d.ts → directive-host-Bw2_PrgL.d.ts} +14 -0
- package/dist/directives.cjs +56 -17
- package/dist/directives.cjs.map +1 -1
- package/dist/directives.d.cts +33 -5
- package/dist/directives.d.ts +33 -5
- package/dist/directives.js +56 -17
- package/dist/directives.js.map +1 -1
- package/dist/{host-types-Dxzs0C3f.d.cts → host-types-YP_l_Q_t.d.cts} +2 -2
- package/dist/{host-types-uKO1zZo3.d.ts → host-types-eSjFmXyF.d.ts} +2 -2
- package/dist/host.cjs.map +1 -1
- package/dist/host.d.cts +4 -4
- package/dist/host.d.ts +4 -4
- package/dist/host.js.map +1 -1
- package/dist/index.cjs +56 -17
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +36 -8
- package/dist/index.d.ts +36 -8
- package/dist/index.js +56 -17
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +55 -17
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +4 -4
- package/dist/react.d.ts +4 -4
- package/dist/react.js +55 -17
- package/dist/react.js.map +1 -1
- package/dist/resolver.d.cts +2 -2
- package/dist/resolver.d.ts +2 -2
- package/dist/{route-CfKxIEdj.d.ts → route-CtYw2cTN.d.ts} +16 -2
- package/dist/{route-DjGv9skd.d.cts → route-KoRMp3Qn.d.cts} +16 -2
- package/dist/route.cjs.map +1 -1
- package/dist/route.d.cts +2 -2
- package/dist/route.d.ts +2 -2
- package/dist/route.js.map +1 -1
- package/package.json +3 -3
package/dist/react.d.cts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { c as KindDefinitionSource, C as ContentIrHost } from './host-types-
|
|
2
|
-
import { d as ComponentResolutionSource } from './component-resolution.types-
|
|
1
|
+
import { c as KindDefinitionSource, C as ContentIrHost } from './host-types-YP_l_Q_t.cjs';
|
|
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-
|
|
6
|
+
import './directive-host-Bw2_PrgL.cjs';
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* The two registries this hook watches. Passed explicitly by a host whose
|
|
@@ -87,7 +87,7 @@ declare function KindInstanceRender(props: KindInstanceRenderProps): react.JSX.E
|
|
|
87
87
|
/**
|
|
88
88
|
* The safety net + the "still arriving" affordance for a provisional kind
|
|
89
89
|
* render (streaming partial kinds — see `route/partial-kind-route.ts` and
|
|
90
|
-
* `common-docs/systems/content-ir
|
|
90
|
+
* `common-docs/systems/architecture/content-ir/STREAMING_PARTIAL_KINDS.md`).
|
|
91
91
|
*
|
|
92
92
|
* TWO JOBS
|
|
93
93
|
* --------
|
package/dist/react.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { c as KindDefinitionSource, C as ContentIrHost } from './host-types-
|
|
2
|
-
import { d as ComponentResolutionSource } from './component-resolution.types-
|
|
1
|
+
import { c as KindDefinitionSource, C as ContentIrHost } from './host-types-eSjFmXyF.js';
|
|
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-
|
|
6
|
+
import './directive-host-Bw2_PrgL.js';
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* The two registries this hook watches. Passed explicitly by a host whose
|
|
@@ -87,7 +87,7 @@ declare function KindInstanceRender(props: KindInstanceRenderProps): react.JSX.E
|
|
|
87
87
|
/**
|
|
88
88
|
* The safety net + the "still arriving" affordance for a provisional kind
|
|
89
89
|
* render (streaming partial kinds — see `route/partial-kind-route.ts` and
|
|
90
|
-
* `common-docs/systems/content-ir
|
|
90
|
+
* `common-docs/systems/architecture/content-ir/STREAMING_PARTIAL_KINDS.md`).
|
|
91
91
|
*
|
|
92
92
|
* TWO JOBS
|
|
93
93
|
* --------
|
package/dist/react.js
CHANGED
|
@@ -291,17 +291,22 @@ function classIcon(directiveClass, noun) {
|
|
|
291
291
|
import { jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
292
292
|
var FINISH_POLL_MS = 2e3;
|
|
293
293
|
var FINISH_POLLS_MAX = 30;
|
|
294
|
+
function readsApplyLedger(host, directive) {
|
|
295
|
+
return !!host.applyState && !!host.confirm && directive.parsed.executes && directive.items.length > 0;
|
|
296
|
+
}
|
|
294
297
|
function ApplyDirectiveButton({
|
|
295
298
|
directive,
|
|
296
299
|
label = "Apply",
|
|
297
300
|
itemCount,
|
|
298
|
-
onApplied
|
|
301
|
+
onApplied,
|
|
302
|
+
onPhase,
|
|
303
|
+
nothingToChange = false
|
|
299
304
|
}) {
|
|
300
305
|
const host = useDirectiveHost();
|
|
301
306
|
const scope = useDirectiveScope();
|
|
302
307
|
const conversationId = scope.conversationId || void 0;
|
|
303
308
|
const items = directive.items;
|
|
304
|
-
const readsLedger =
|
|
309
|
+
const readsLedger = readsApplyLedger(host, directive);
|
|
305
310
|
const initial = readsLedger ? { status: "checking" } : { status: "idle" };
|
|
306
311
|
const [state, setState] = useState(initial);
|
|
307
312
|
const [elapsed, setElapsed] = useState(0);
|
|
@@ -342,7 +347,8 @@ function ApplyDirectiveButton({
|
|
|
342
347
|
failed: 0,
|
|
343
348
|
message: answer.message?.trim() ? answer.message.trim() : null,
|
|
344
349
|
records: answer.records ?? [],
|
|
345
|
-
copies: Math.max(1, answer.copies ?? 1)
|
|
350
|
+
copies: Math.max(1, answer.copies ?? 1),
|
|
351
|
+
before: answer.before ?? null
|
|
346
352
|
} : prev
|
|
347
353
|
);
|
|
348
354
|
} else if (answer.state === "in_flight" && polls < FINISH_POLLS_MAX) {
|
|
@@ -367,6 +373,15 @@ function ApplyDirectiveButton({
|
|
|
367
373
|
if (timer) clearTimeout(timer);
|
|
368
374
|
};
|
|
369
375
|
}, [shellKey, read, report]);
|
|
376
|
+
const appliedClean = state.status === "applied" && state.failed === 0 ? state : null;
|
|
377
|
+
const appliedBefore = appliedClean ? appliedClean.before : null;
|
|
378
|
+
const phaseKey = state.status === "checking" || state.status === "finishing" ? "pending" : appliedClean ? `applied:${JSON.stringify(appliedBefore)}` : "open";
|
|
379
|
+
useEffect(() => {
|
|
380
|
+
if (!onPhase) return;
|
|
381
|
+
if (phaseKey === "pending") onPhase({ phase: "pending" });
|
|
382
|
+
else if (phaseKey === "open") onPhase({ phase: "open" });
|
|
383
|
+
else onPhase({ phase: "applied", before: appliedBefore });
|
|
384
|
+
}, [phaseKey, onPhase, appliedBefore]);
|
|
370
385
|
useEffect(() => {
|
|
371
386
|
if (state.status !== "applying") return;
|
|
372
387
|
startedAt.current = Date.now();
|
|
@@ -381,7 +396,7 @@ function ApplyDirectiveButton({
|
|
|
381
396
|
if (!confirm) return null;
|
|
382
397
|
async function handleApply(again = false) {
|
|
383
398
|
if (!confirm) return;
|
|
384
|
-
const
|
|
399
|
+
const prior = state;
|
|
385
400
|
const askedFor = identity;
|
|
386
401
|
const stillHere = () => currentIdentity.current === askedFor;
|
|
387
402
|
const priorCopies = state.status === "applied" ? state.copies : 0;
|
|
@@ -408,7 +423,7 @@ function ApplyDirectiveButton({
|
|
|
408
423
|
if (!stillHere()) return;
|
|
409
424
|
setAskingAgain(false);
|
|
410
425
|
if (!ok) {
|
|
411
|
-
setState(again ?
|
|
426
|
+
setState(again ? prior : { status: "idle" });
|
|
412
427
|
return;
|
|
413
428
|
}
|
|
414
429
|
}
|
|
@@ -427,7 +442,10 @@ function ApplyDirectiveButton({
|
|
|
427
442
|
message: result.message?.trim() ? result.message.trim() : null,
|
|
428
443
|
records: result.records ?? [],
|
|
429
444
|
// "Run again" made one more; a first apply (or a replay of one) is one.
|
|
430
|
-
copies: again ? Math.max(1, priorCopies) + 1 : Math.max(1, priorCopies)
|
|
445
|
+
copies: again ? Math.max(1, priorCopies) + 1 : Math.max(1, priorCopies),
|
|
446
|
+
// "Run again" wrote the same values over themselves; what the FIRST
|
|
447
|
+
// apply replaced is still the change this block made.
|
|
448
|
+
before: again && prior.status === "applied" && prior.before ? prior.before : result.before ?? null
|
|
431
449
|
});
|
|
432
450
|
onApplied?.();
|
|
433
451
|
} catch (error) {
|
|
@@ -529,15 +547,18 @@ function ApplyDirectiveButton({
|
|
|
529
547
|
);
|
|
530
548
|
}
|
|
531
549
|
const destructive = directive.directiveClass === "delete";
|
|
550
|
+
const muted = nothingToChange && state.status === "idle";
|
|
532
551
|
return /* @__PURE__ */ jsxs2("span", { className: "inline-flex items-center gap-2", children: [
|
|
552
|
+
muted ? /* @__PURE__ */ jsx4("span", { className: "text-xs text-muted-foreground", "data-apply-nothing": "", children: "Nothing to change" }) : null,
|
|
533
553
|
/* @__PURE__ */ jsxs2(
|
|
534
554
|
"button",
|
|
535
555
|
{
|
|
536
556
|
type: "button",
|
|
537
557
|
onClick: () => void handleApply(),
|
|
538
558
|
disabled: state.status === "applying" || state.status === "asking" || items.length === 0,
|
|
539
|
-
"data-apply-tone": destructive ? "destructive" : "default",
|
|
540
|
-
|
|
559
|
+
"data-apply-tone": muted ? "muted" : destructive ? "destructive" : "default",
|
|
560
|
+
title: muted ? "It sets no fields, so applying it changes nothing." : void 0,
|
|
561
|
+
className: `inline-flex items-center gap-1 rounded-md border px-2 py-1 text-xs font-medium disabled:opacity-50 ${muted ? "border-border/60 bg-background text-muted-foreground hover:bg-accent" : destructive ? "border-destructive/50 bg-background text-destructive hover:bg-destructive/10" : "border-border bg-background hover:bg-accent"}`,
|
|
541
562
|
children: [
|
|
542
563
|
state.status === "applying" ? /* @__PURE__ */ jsx4(LoaderIcon, { className: "h-3.5 w-3.5 animate-spin" }) : /* @__PURE__ */ jsx4(PlayIcon, { className: "h-3.5 w-3.5" }),
|
|
543
564
|
state.status === "applying" ? `Applying${itemCount ? ` ${itemCount} ${itemCount === 1 ? "item" : "items"}` : ""}\u2026${elapsed ? ` ${elapsed}s` : ""}` : label
|
|
@@ -735,12 +756,13 @@ function ItemRow({
|
|
|
735
756
|
directive,
|
|
736
757
|
item,
|
|
737
758
|
index,
|
|
738
|
-
total
|
|
759
|
+
total,
|
|
760
|
+
phase
|
|
739
761
|
}) {
|
|
740
762
|
const host = useDirectiveHost();
|
|
741
763
|
const recordId = TARGETING_CLASSES.has(directive.directiveClass) ? itemRecordId(item) : null;
|
|
742
764
|
if (recordId) {
|
|
743
|
-
return /* @__PURE__ */ jsx7(TargetRow, { directive, item, recordId });
|
|
765
|
+
return /* @__PURE__ */ jsx7(TargetRow, { directive, item, recordId, index, phase });
|
|
744
766
|
}
|
|
745
767
|
const titleColumn = nounTitleColumn(directive.noun, host.nouns);
|
|
746
768
|
const title = itemTitle(item, titleColumn, index, total);
|
|
@@ -827,16 +849,20 @@ function DirectiveChangeList({
|
|
|
827
849
|
function TargetRow({
|
|
828
850
|
directive,
|
|
829
851
|
item,
|
|
830
|
-
recordId
|
|
852
|
+
recordId,
|
|
853
|
+
index,
|
|
854
|
+
phase
|
|
831
855
|
}) {
|
|
832
856
|
const host = useDirectiveHost();
|
|
833
857
|
const fallback = recordFallbackName(nounLabel2(directive.noun, host.nouns), recordId);
|
|
834
858
|
const isUpdate = directive.directiveClass === "update";
|
|
835
|
-
const
|
|
836
|
-
|
|
837
|
-
|
|
859
|
+
const readsLive = isUpdate && phase.phase === "open";
|
|
860
|
+
const live = useRecordValues(
|
|
861
|
+
readsLive ? host.readRecord : void 0,
|
|
862
|
+
readsLive ? { noun: directive.noun, id: recordId } : null
|
|
838
863
|
);
|
|
839
|
-
const
|
|
864
|
+
const compareTo = phase.phase === "applied" ? phase.before?.[index] ?? null : readsLive ? live.values : null;
|
|
865
|
+
const changes = isUpdate ? itemChanges(item, compareTo, { titleColumn: nounTitleColumn(directive.noun, host.nouns) }) : [];
|
|
840
866
|
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 });
|
|
841
867
|
return /* @__PURE__ */ jsxs5("div", { className: "py-1 text-xs", "data-directive-target": recordId, children: [
|
|
842
868
|
/* @__PURE__ */ jsxs5("div", { className: "flex min-w-0 items-center gap-2", children: [
|
|
@@ -853,6 +879,10 @@ function SideEffectDirectiveCard({ directive }) {
|
|
|
853
879
|
const total = items.length;
|
|
854
880
|
const display = directiveDisplay3(directive.directiveClass, directive.noun, host.nouns);
|
|
855
881
|
const Icon = classIcon(directive.directiveClass, directive.noun);
|
|
882
|
+
const [phase, setPhase] = useState3(
|
|
883
|
+
() => readsApplyLedger(host, directive) ? { phase: "pending" } : { phase: "open" }
|
|
884
|
+
);
|
|
885
|
+
const nothingToChange = directive.directiveClass === "update" && total > 0 && items.every((item) => itemChanges(item).length === 0);
|
|
856
886
|
const shown = expanded ? items : items.slice(0, ROWS_BEFORE_FOLD);
|
|
857
887
|
const hidden = total - shown.length;
|
|
858
888
|
return /* @__PURE__ */ jsxs5("div", { className: "my-3 rounded-md border border-border bg-card px-2.5 py-1.5", "data-directive": directive.slug, children: [
|
|
@@ -867,13 +897,21 @@ function SideEffectDirectiveCard({ directive }) {
|
|
|
867
897
|
] }),
|
|
868
898
|
/* @__PURE__ */ jsxs5("div", { className: "ml-auto flex items-center gap-1", children: [
|
|
869
899
|
host.renderCopy?.({ label: display.title, value: directive.shell, size: "icon" }),
|
|
870
|
-
/* @__PURE__ */ jsx7(
|
|
900
|
+
/* @__PURE__ */ jsx7(
|
|
901
|
+
ApplyDirectiveButton,
|
|
902
|
+
{
|
|
903
|
+
directive,
|
|
904
|
+
itemCount: total,
|
|
905
|
+
onPhase: setPhase,
|
|
906
|
+
nothingToChange
|
|
907
|
+
}
|
|
908
|
+
)
|
|
871
909
|
] })
|
|
872
910
|
] }),
|
|
873
911
|
total === 0 ? (
|
|
874
912
|
// Stated, never silent: an empty batch is a real (and suspicious) state.
|
|
875
913
|
/* @__PURE__ */ jsx7("p", { className: "mt-1 text-xs text-muted-foreground", children: "No items \u2014 nothing would be written." })
|
|
876
|
-
) : /* @__PURE__ */ jsx7("div", { className: "mt-0.5 divide-y divide-border/60", children: shown.map((item, i) => /* @__PURE__ */ jsx7(ItemRow, { directive, item, index: i, total }, i)) }),
|
|
914
|
+
) : /* @__PURE__ */ jsx7("div", { className: "mt-0.5 divide-y divide-border/60", children: shown.map((item, i) => /* @__PURE__ */ jsx7(ItemRow, { directive, item, index: i, total, phase }, i)) }),
|
|
877
915
|
hidden > 0 || expanded ? /* @__PURE__ */ jsxs5(
|
|
878
916
|
"button",
|
|
879
917
|
{
|