@ai-matrx/content-ir-react 0.18.0 → 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/CHANGELOG.md +31 -0
- package/dist/directives.cjs +150 -79
- package/dist/directives.cjs.map +1 -1
- package/dist/directives.d.cts +10 -1
- package/dist/directives.d.ts +10 -1
- package/dist/directives.js +148 -77
- package/dist/directives.js.map +1 -1
- package/dist/index.cjs +152 -81
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +10 -1
- package/dist/index.d.ts +10 -1
- package/dist/index.js +150 -79
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +147 -79
- package/dist/react.cjs.map +1 -1
- package/dist/react.js +145 -77
- package/dist/react.js.map +1 -1
- package/package.json +1 -1
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
|
|
272
|
-
if (
|
|
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 } 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,41 @@ 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
|
+
}
|
|
1019
|
+
var applyOutcomes = /* @__PURE__ */ new WeakMap();
|
|
1020
|
+
var EMPTY_AUTHORITY = {};
|
|
1021
|
+
var outcomeListeners = /* @__PURE__ */ new Set();
|
|
1022
|
+
function outcomesOf(host) {
|
|
1023
|
+
let held = applyOutcomes.get(host);
|
|
1024
|
+
if (!held) {
|
|
1025
|
+
held = /* @__PURE__ */ new Map();
|
|
1026
|
+
applyOutcomes.set(host, held);
|
|
1027
|
+
}
|
|
1028
|
+
return held;
|
|
1029
|
+
}
|
|
1030
|
+
function publishOutcome(host, identity, outcome) {
|
|
1031
|
+
outcomesOf(host).set(identity, outcome);
|
|
1032
|
+
for (const listener of outcomeListeners) listener();
|
|
1033
|
+
}
|
|
1034
|
+
function subscribeOutcomes(listener) {
|
|
1035
|
+
outcomeListeners.add(listener);
|
|
1036
|
+
return () => {
|
|
1037
|
+
outcomeListeners.delete(listener);
|
|
1038
|
+
};
|
|
1039
|
+
}
|
|
1040
|
+
function useApplyOutcome(host, identity) {
|
|
1041
|
+
return useSyncExternalStore3(
|
|
1042
|
+
subscribeOutcomes,
|
|
1043
|
+
() => applyOutcomes.get(host)?.get(identity) ?? null,
|
|
1044
|
+
() => null
|
|
1045
|
+
);
|
|
1046
|
+
}
|
|
954
1047
|
var FINISH_POLL_MS = 2e3;
|
|
955
1048
|
var FINISH_POLLS_MAX = 30;
|
|
956
1049
|
function readsApplyLedger(host, directive) {
|
|
@@ -970,27 +1063,29 @@ function ApplyDirectiveButton({
|
|
|
970
1063
|
const items = directive.items;
|
|
971
1064
|
const readsLedger = readsApplyLedger(host, directive);
|
|
972
1065
|
const initial = readsLedger ? { status: "checking" } : { status: "idle" };
|
|
973
|
-
const [state, setState] =
|
|
974
|
-
const [elapsed, setElapsed] =
|
|
975
|
-
const [askingAgain, setAskingAgain] =
|
|
1066
|
+
const [state, setState] = useState2(initial);
|
|
1067
|
+
const [elapsed, setElapsed] = useState2(0);
|
|
1068
|
+
const [askingAgain, setAskingAgain] = useState2(false);
|
|
976
1069
|
const startedAt = useRef(null);
|
|
977
1070
|
const identity = JSON.stringify([directive.slug, items, conversationId ?? null]);
|
|
978
|
-
const [stateFor, setStateFor] =
|
|
1071
|
+
const [stateFor, setStateFor] = useState2(identity);
|
|
979
1072
|
if (stateFor !== identity) {
|
|
980
1073
|
setStateFor(identity);
|
|
981
1074
|
setState(initial);
|
|
982
1075
|
setAskingAgain(false);
|
|
983
1076
|
setElapsed(0);
|
|
984
1077
|
}
|
|
1078
|
+
const shared = useApplyOutcome(host.confirm ?? EMPTY_AUTHORITY, identity);
|
|
1079
|
+
const view = state.status === "asking" || !shared ? state : shared;
|
|
985
1080
|
const currentIdentity = useRef(identity);
|
|
986
|
-
|
|
1081
|
+
useEffect2(() => {
|
|
987
1082
|
currentIdentity.current = identity;
|
|
988
1083
|
}, [identity]);
|
|
989
1084
|
const nounText = nounLabel(directive.noun, host.nouns);
|
|
990
1085
|
const shellKey = readsLedger ? JSON.stringify([directive.slug, items, conversationId ?? null]) : "";
|
|
991
1086
|
const read = host.applyState;
|
|
992
1087
|
const report = host.reportError;
|
|
993
|
-
|
|
1088
|
+
useEffect2(() => {
|
|
994
1089
|
if (!shellKey || !read) return;
|
|
995
1090
|
const [slug, shellItems, inConversation] = JSON.parse(shellKey);
|
|
996
1091
|
const shell = { __kind: slug, items: shellItems };
|
|
@@ -1035,33 +1130,34 @@ function ApplyDirectiveButton({
|
|
|
1035
1130
|
if (timer) clearTimeout(timer);
|
|
1036
1131
|
};
|
|
1037
1132
|
}, [shellKey, read, report]);
|
|
1038
|
-
const appliedClean =
|
|
1133
|
+
const appliedClean = view.status === "applied" && view.failed === 0 ? view : null;
|
|
1039
1134
|
const appliedBefore = appliedClean ? appliedClean.before : null;
|
|
1040
|
-
const phaseKey =
|
|
1041
|
-
|
|
1135
|
+
const phaseKey = view.status === "checking" || view.status === "finishing" ? "pending" : appliedClean ? `applied:${JSON.stringify(appliedBefore)}` : "open";
|
|
1136
|
+
useEffect2(() => {
|
|
1042
1137
|
if (!onPhase) return;
|
|
1043
1138
|
if (phaseKey === "pending") onPhase({ phase: "pending" });
|
|
1044
1139
|
else if (phaseKey === "open") onPhase({ phase: "open" });
|
|
1045
1140
|
else onPhase({ phase: "applied", before: appliedBefore });
|
|
1046
1141
|
}, [phaseKey, onPhase, appliedBefore]);
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1142
|
+
const applyingSince = view.status === "applying" ? view.startedAt : null;
|
|
1143
|
+
useEffect2(() => {
|
|
1144
|
+
if (applyingSince === null) return;
|
|
1145
|
+
startedAt.current = applyingSince;
|
|
1050
1146
|
const id = setInterval(
|
|
1051
1147
|
() => setElapsed(Math.round((Date.now() - (startedAt.current ?? 0)) / 1e3)),
|
|
1052
1148
|
1e3
|
|
1053
1149
|
);
|
|
1054
1150
|
return () => clearInterval(id);
|
|
1055
|
-
}, [
|
|
1151
|
+
}, [applyingSince]);
|
|
1056
1152
|
if (!directive.parsed.executes) return null;
|
|
1057
1153
|
const confirm = host.confirm;
|
|
1058
1154
|
if (!confirm) return null;
|
|
1059
1155
|
async function handleApply(again = false) {
|
|
1060
1156
|
if (!confirm) return;
|
|
1061
|
-
const prior =
|
|
1157
|
+
const prior = view;
|
|
1062
1158
|
const askedFor = identity;
|
|
1063
1159
|
const stillHere = () => currentIdentity.current === askedFor;
|
|
1064
|
-
const priorCopies =
|
|
1160
|
+
const priorCopies = view.status === "applied" ? view.copies : 0;
|
|
1065
1161
|
if (host.ask) {
|
|
1066
1162
|
if (again) setAskingAgain(true);
|
|
1067
1163
|
else setState({ status: "asking" });
|
|
@@ -1090,14 +1186,20 @@ function ApplyDirectiveButton({
|
|
|
1090
1186
|
}
|
|
1091
1187
|
}
|
|
1092
1188
|
setElapsed(0);
|
|
1093
|
-
setState({ status: "
|
|
1189
|
+
setState((prev) => prev.status === "asking" ? { status: "idle" } : prev);
|
|
1190
|
+
publishOutcome(confirm, askedFor, { status: "applying", startedAt: Date.now() });
|
|
1094
1191
|
try {
|
|
1095
1192
|
const shell = { __kind: directive.slug, items };
|
|
1096
1193
|
if (conversationId) shell.conversationId = conversationId;
|
|
1097
1194
|
if (again) shell.force = true;
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
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);
|
|
1202
|
+
publishOutcome(confirm, askedFor, {
|
|
1101
1203
|
status: "applied",
|
|
1102
1204
|
applied: result.applied,
|
|
1103
1205
|
failed: result.failed,
|
|
@@ -1109,20 +1211,19 @@ function ApplyDirectiveButton({
|
|
|
1109
1211
|
// apply replaced is still the change this block made.
|
|
1110
1212
|
before: again && prior.status === "applied" && prior.before ? prior.before : result.before ?? null
|
|
1111
1213
|
});
|
|
1112
|
-
onApplied?.();
|
|
1214
|
+
if (stillHere()) onApplied?.();
|
|
1113
1215
|
} catch (error) {
|
|
1114
|
-
|
|
1115
|
-
setState({
|
|
1216
|
+
publishOutcome(confirm, askedFor, {
|
|
1116
1217
|
status: "error",
|
|
1117
1218
|
message: error instanceof Error && error.message ? error.message : "That couldn't be applied just now. Please try again."
|
|
1118
1219
|
});
|
|
1119
1220
|
}
|
|
1120
1221
|
}
|
|
1121
|
-
if (
|
|
1122
|
-
const bad =
|
|
1222
|
+
if (view.status === "applied") {
|
|
1223
|
+
const bad = view.failed > 0;
|
|
1123
1224
|
const trashed = directive.directiveClass === "delete";
|
|
1124
1225
|
const label2 = nounText;
|
|
1125
|
-
const records = host.renderRecord ?
|
|
1226
|
+
const records = host.renderRecord ? view.records : [];
|
|
1126
1227
|
return /* @__PURE__ */ jsxs2(
|
|
1127
1228
|
"span",
|
|
1128
1229
|
{
|
|
@@ -1136,26 +1237,26 @@ function ApplyDirectiveButton({
|
|
|
1136
1237
|
{
|
|
1137
1238
|
words: failureWords(
|
|
1138
1239
|
{
|
|
1139
|
-
raw:
|
|
1240
|
+
raw: view.message ?? `${view.failed} failed`,
|
|
1140
1241
|
directiveClass: directive.directiveClass,
|
|
1141
1242
|
noun: directive.noun,
|
|
1142
1243
|
nounLabel: nounText,
|
|
1143
|
-
failed:
|
|
1144
|
-
total:
|
|
1244
|
+
failed: view.failed,
|
|
1245
|
+
total: view.applied + view.failed
|
|
1145
1246
|
},
|
|
1146
1247
|
host.explainFailure
|
|
1147
1248
|
),
|
|
1148
|
-
raw:
|
|
1249
|
+
raw: view.message
|
|
1149
1250
|
}
|
|
1150
|
-
) : /* @__PURE__ */ jsx4("span", { className: "min-w-0", children:
|
|
1251
|
+
) : /* @__PURE__ */ jsx4("span", { className: "min-w-0", children: view.message ?? `Applied ${view.applied}` })
|
|
1151
1252
|
] }),
|
|
1152
|
-
|
|
1253
|
+
view.copies > 1 ? /* @__PURE__ */ jsx4(
|
|
1153
1254
|
"span",
|
|
1154
1255
|
{
|
|
1155
1256
|
className: "shrink-0 text-muted-foreground",
|
|
1156
|
-
"data-apply-copies":
|
|
1257
|
+
"data-apply-copies": view.copies,
|
|
1157
1258
|
title: records.length > 0 ? directive.directiveClass === "create" ? "Links to the latest copy." : "Links to the latest run." : void 0,
|
|
1158
|
-
children: directive.directiveClass === "create" ? `${
|
|
1259
|
+
children: directive.directiveClass === "create" ? `${view.copies} copies` : `Ran ${view.copies} times`
|
|
1159
1260
|
}
|
|
1160
1261
|
) : null,
|
|
1161
1262
|
records.map((record) => /* @__PURE__ */ jsx4("span", { className: "inline-flex min-w-0 items-center", children: host.renderRecord?.({
|
|
@@ -1182,7 +1283,7 @@ function ApplyDirectiveButton({
|
|
|
1182
1283
|
}
|
|
1183
1284
|
);
|
|
1184
1285
|
}
|
|
1185
|
-
if (
|
|
1286
|
+
if (view.status === "checking") {
|
|
1186
1287
|
return /* @__PURE__ */ jsx4(
|
|
1187
1288
|
"span",
|
|
1188
1289
|
{
|
|
@@ -1194,7 +1295,7 @@ function ApplyDirectiveButton({
|
|
|
1194
1295
|
}
|
|
1195
1296
|
);
|
|
1196
1297
|
}
|
|
1197
|
-
if (
|
|
1298
|
+
if (view.status === "finishing") {
|
|
1198
1299
|
return /* @__PURE__ */ jsxs2(
|
|
1199
1300
|
"span",
|
|
1200
1301
|
{
|
|
@@ -1209,7 +1310,7 @@ function ApplyDirectiveButton({
|
|
|
1209
1310
|
);
|
|
1210
1311
|
}
|
|
1211
1312
|
const destructive = directive.directiveClass === "delete";
|
|
1212
|
-
const muted = nothingToChange &&
|
|
1313
|
+
const muted = nothingToChange && view.status === "idle";
|
|
1213
1314
|
return /* @__PURE__ */ jsxs2("span", { className: "inline-flex items-center gap-2", children: [
|
|
1214
1315
|
muted ? /* @__PURE__ */ jsx4("span", { className: "text-xs text-muted-foreground", "data-apply-nothing": "", children: "Nothing to change" }) : null,
|
|
1215
1316
|
/* @__PURE__ */ jsxs2(
|
|
@@ -1217,17 +1318,17 @@ function ApplyDirectiveButton({
|
|
|
1217
1318
|
{
|
|
1218
1319
|
type: "button",
|
|
1219
1320
|
onClick: () => void handleApply(),
|
|
1220
|
-
disabled:
|
|
1321
|
+
disabled: view.status === "applying" || view.status === "asking" || items.length === 0,
|
|
1221
1322
|
"data-apply-tone": muted ? "muted" : destructive ? "destructive" : "default",
|
|
1222
1323
|
title: muted ? "It sets no fields, so applying it changes nothing." : void 0,
|
|
1223
1324
|
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"}`,
|
|
1224
1325
|
children: [
|
|
1225
|
-
|
|
1226
|
-
|
|
1326
|
+
view.status === "applying" ? /* @__PURE__ */ jsx4(LoaderIcon, { className: "h-3.5 w-3.5 animate-spin" }) : /* @__PURE__ */ jsx4(PlayIcon, { className: "h-3.5 w-3.5" }),
|
|
1327
|
+
view.status === "applying" ? `Applying${itemCount ? ` ${itemCount} ${itemCount === 1 ? "item" : "items"}` : ""}\u2026${elapsed ? ` ${elapsed}s` : ""}` : label
|
|
1227
1328
|
]
|
|
1228
1329
|
}
|
|
1229
1330
|
),
|
|
1230
|
-
|
|
1331
|
+
view.status === "error" ? /* @__PURE__ */ jsxs2(
|
|
1231
1332
|
"span",
|
|
1232
1333
|
{
|
|
1233
1334
|
className: "inline-flex max-w-sm items-start gap-1 text-xs text-destructive",
|
|
@@ -1239,14 +1340,14 @@ function ApplyDirectiveButton({
|
|
|
1239
1340
|
{
|
|
1240
1341
|
words: failureWords(
|
|
1241
1342
|
{
|
|
1242
|
-
raw:
|
|
1343
|
+
raw: view.message,
|
|
1243
1344
|
directiveClass: directive.directiveClass,
|
|
1244
1345
|
noun: directive.noun,
|
|
1245
1346
|
nounLabel: nounText
|
|
1246
1347
|
},
|
|
1247
1348
|
host.explainFailure
|
|
1248
1349
|
),
|
|
1249
|
-
raw:
|
|
1350
|
+
raw: view.message
|
|
1250
1351
|
}
|
|
1251
1352
|
)
|
|
1252
1353
|
]
|
|
@@ -1258,7 +1359,7 @@ function FailureNotice({
|
|
|
1258
1359
|
words,
|
|
1259
1360
|
raw
|
|
1260
1361
|
}) {
|
|
1261
|
-
const [open, setOpen] =
|
|
1362
|
+
const [open, setOpen] = useState2(false);
|
|
1262
1363
|
const detail = raw?.trim() ?? "";
|
|
1263
1364
|
return /* @__PURE__ */ jsxs2("span", { className: "flex min-w-0 flex-col gap-0.5", "data-apply-failure": true, children: [
|
|
1264
1365
|
/* @__PURE__ */ jsxs2("span", { className: "min-w-0", children: [
|
|
@@ -1387,39 +1488,6 @@ import {
|
|
|
1387
1488
|
nounLabel as nounLabel2,
|
|
1388
1489
|
nounTitleColumn
|
|
1389
1490
|
} from "@ai-matrx/content-ir";
|
|
1390
|
-
|
|
1391
|
-
// directives/record-values.ts
|
|
1392
|
-
import { useEffect as useEffect2, useState as useState2 } from "react";
|
|
1393
|
-
function useRecordValues(read, ref) {
|
|
1394
|
-
const key = ref && read ? `${ref.noun}:${ref.id}` : "";
|
|
1395
|
-
const [result, setResult] = useState2({
|
|
1396
|
-
key: "",
|
|
1397
|
-
values: null,
|
|
1398
|
-
status: "idle"
|
|
1399
|
-
});
|
|
1400
|
-
useEffect2(() => {
|
|
1401
|
-
if (!key || !read) return;
|
|
1402
|
-
const split = key.indexOf(":");
|
|
1403
|
-
const target = { noun: key.slice(0, split), id: key.slice(split + 1) };
|
|
1404
|
-
let live = true;
|
|
1405
|
-
setResult({ key, values: null, status: "loading" });
|
|
1406
|
-
read(target).then((values) => {
|
|
1407
|
-
if (!live) return;
|
|
1408
|
-
setResult({ key, values, status: values ? "ready" : "unavailable" });
|
|
1409
|
-
}).catch(() => {
|
|
1410
|
-
if (!live) return;
|
|
1411
|
-
setResult({ key, values: null, status: "unavailable" });
|
|
1412
|
-
});
|
|
1413
|
-
return () => {
|
|
1414
|
-
live = false;
|
|
1415
|
-
};
|
|
1416
|
-
}, [key, read]);
|
|
1417
|
-
if (!key) return { values: null, status: "idle" };
|
|
1418
|
-
if (result.key !== key) return { values: null, status: "loading" };
|
|
1419
|
-
return { values: result.values, status: result.status };
|
|
1420
|
-
}
|
|
1421
|
-
|
|
1422
|
-
// directives/SideEffectDirectiveCard.tsx
|
|
1423
1491
|
import { Fragment, jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
1424
1492
|
var ROWS_BEFORE_FOLD = 3;
|
|
1425
1493
|
function ItemRow({
|
|
@@ -2107,10 +2175,12 @@ export {
|
|
|
2107
2175
|
kindIsRoutable,
|
|
2108
2176
|
kindServerDataFromStoredValue,
|
|
2109
2177
|
markKindPartialUnsafe,
|
|
2178
|
+
noteRecordChanged,
|
|
2110
2179
|
provisionalDirectiveSlug,
|
|
2111
2180
|
readIrRouteMarker,
|
|
2112
2181
|
readsApplyLedger,
|
|
2113
2182
|
recordFallbackName,
|
|
2183
|
+
recordRevision,
|
|
2114
2184
|
registerDirectiveRenderer,
|
|
2115
2185
|
resetDirectiveRenderers,
|
|
2116
2186
|
resetPartialUnsafeKinds,
|
|
@@ -2125,6 +2195,7 @@ export {
|
|
|
2125
2195
|
useDirectiveHost,
|
|
2126
2196
|
useDirectiveScope,
|
|
2127
2197
|
useKindRouteEnv,
|
|
2198
|
+
useRecordRevision,
|
|
2128
2199
|
useRecordValues
|
|
2129
2200
|
};
|
|
2130
2201
|
//# sourceMappingURL=index.js.map
|