@ai-matrx/content-ir-react 0.18.1 → 0.19.1
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 +30 -0
- package/dist/directives.cjs +97 -47
- 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 +95 -45
- package/dist/directives.js.map +1 -1
- package/dist/index.cjs +99 -49
- 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 +97 -47
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +94 -47
- package/dist/react.cjs.map +1 -1
- package/dist/react.js +92 -45
- package/dist/react.js.map +1 -1
- package/package.json +3 -3
package/dist/react.js
CHANGED
|
@@ -94,7 +94,7 @@ import { looksLikeDirectiveHead, tryDecodeDirectiveContent } from "@ai-matrx/con
|
|
|
94
94
|
import { directiveDisplay } from "@ai-matrx/content-ir";
|
|
95
95
|
|
|
96
96
|
// directives/ApplyDirectiveButton.tsx
|
|
97
|
-
import { useEffect, useRef, useState, useSyncExternalStore as
|
|
97
|
+
import { useEffect as useEffect2, useRef, useState as useState2, useSyncExternalStore as useSyncExternalStore3 } from "react";
|
|
98
98
|
import { nounLabel } from "@ai-matrx/content-ir";
|
|
99
99
|
|
|
100
100
|
// directives/item-changes.ts
|
|
@@ -170,6 +170,73 @@ function itemChanges(item, current, options = {}) {
|
|
|
170
170
|
return out;
|
|
171
171
|
}
|
|
172
172
|
|
|
173
|
+
// directives/record-values.ts
|
|
174
|
+
import { useEffect, useState, useSyncExternalStore as useSyncExternalStore2 } from "react";
|
|
175
|
+
var STORE_SLOT = /* @__PURE__ */ Symbol.for("@ai-matrx/content-ir-react/record-revisions");
|
|
176
|
+
function revisionStore() {
|
|
177
|
+
const slots = globalThis;
|
|
178
|
+
let store = slots[STORE_SLOT];
|
|
179
|
+
if (!store) {
|
|
180
|
+
store = { revisions: /* @__PURE__ */ new Map(), listeners: /* @__PURE__ */ new Set() };
|
|
181
|
+
slots[STORE_SLOT] = store;
|
|
182
|
+
}
|
|
183
|
+
return store;
|
|
184
|
+
}
|
|
185
|
+
var { revisions, listeners } = revisionStore();
|
|
186
|
+
function recordRevision(id) {
|
|
187
|
+
return revisions.get(id) ?? 0;
|
|
188
|
+
}
|
|
189
|
+
function noteRecordChanged(id) {
|
|
190
|
+
if (!id) return;
|
|
191
|
+
revisions.set(id, recordRevision(id) + 1);
|
|
192
|
+
for (const listener of listeners) listener();
|
|
193
|
+
}
|
|
194
|
+
function subscribeRevisions(listener) {
|
|
195
|
+
listeners.add(listener);
|
|
196
|
+
return () => {
|
|
197
|
+
listeners.delete(listener);
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
function useRecordRevision(id) {
|
|
201
|
+
return useSyncExternalStore2(
|
|
202
|
+
subscribeRevisions,
|
|
203
|
+
() => recordRevision(id),
|
|
204
|
+
() => 0
|
|
205
|
+
);
|
|
206
|
+
}
|
|
207
|
+
function useRecordValues(read, ref) {
|
|
208
|
+
const revision = useRecordRevision(ref?.id ?? "");
|
|
209
|
+
const key = ref && read ? `${ref.noun}:${ref.id}#${revision}` : "";
|
|
210
|
+
const [result, setResult] = useState({
|
|
211
|
+
key: "",
|
|
212
|
+
values: null,
|
|
213
|
+
status: "idle"
|
|
214
|
+
});
|
|
215
|
+
useEffect(() => {
|
|
216
|
+
if (!key || !read) return;
|
|
217
|
+
const split = key.indexOf(":");
|
|
218
|
+
const target = {
|
|
219
|
+
noun: key.slice(0, split),
|
|
220
|
+
id: key.slice(split + 1, key.lastIndexOf("#"))
|
|
221
|
+
};
|
|
222
|
+
let live = true;
|
|
223
|
+
setResult({ key, values: null, status: "loading" });
|
|
224
|
+
read(target).then((values) => {
|
|
225
|
+
if (!live) return;
|
|
226
|
+
setResult({ key, values, status: values ? "ready" : "unavailable" });
|
|
227
|
+
}).catch(() => {
|
|
228
|
+
if (!live) return;
|
|
229
|
+
setResult({ key, values: null, status: "unavailable" });
|
|
230
|
+
});
|
|
231
|
+
return () => {
|
|
232
|
+
live = false;
|
|
233
|
+
};
|
|
234
|
+
}, [key, read]);
|
|
235
|
+
if (!key) return { values: null, status: "idle" };
|
|
236
|
+
if (result.key !== key) return { values: null, status: "loading" };
|
|
237
|
+
return { values: result.values, status: result.status };
|
|
238
|
+
}
|
|
239
|
+
|
|
173
240
|
// directives/failure-words.ts
|
|
174
241
|
var PAST = {
|
|
175
242
|
create: "created",
|
|
@@ -289,6 +356,13 @@ function classIcon(directiveClass, noun) {
|
|
|
289
356
|
|
|
290
357
|
// directives/ApplyDirectiveButton.tsx
|
|
291
358
|
import { jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
359
|
+
function announceChangedRecords(directive, items) {
|
|
360
|
+
if (!TARGETING_CLASSES.has(directive.directiveClass)) return;
|
|
361
|
+
for (const item of items) {
|
|
362
|
+
const id = itemRecordId(item);
|
|
363
|
+
if (id) noteRecordChanged(id);
|
|
364
|
+
}
|
|
365
|
+
}
|
|
292
366
|
var applyOutcomes = /* @__PURE__ */ new WeakMap();
|
|
293
367
|
var EMPTY_AUTHORITY = {};
|
|
294
368
|
var outcomeListeners = /* @__PURE__ */ new Set();
|
|
@@ -311,7 +385,7 @@ function subscribeOutcomes(listener) {
|
|
|
311
385
|
};
|
|
312
386
|
}
|
|
313
387
|
function useApplyOutcome(host, identity) {
|
|
314
|
-
return
|
|
388
|
+
return useSyncExternalStore3(
|
|
315
389
|
subscribeOutcomes,
|
|
316
390
|
() => applyOutcomes.get(host)?.get(identity) ?? null,
|
|
317
391
|
() => null
|
|
@@ -336,12 +410,12 @@ function ApplyDirectiveButton({
|
|
|
336
410
|
const items = directive.items;
|
|
337
411
|
const readsLedger = readsApplyLedger(host, directive);
|
|
338
412
|
const initial = readsLedger ? { status: "checking" } : { status: "idle" };
|
|
339
|
-
const [state, setState] =
|
|
340
|
-
const [elapsed, setElapsed] =
|
|
341
|
-
const [askingAgain, setAskingAgain] =
|
|
413
|
+
const [state, setState] = useState2(initial);
|
|
414
|
+
const [elapsed, setElapsed] = useState2(0);
|
|
415
|
+
const [askingAgain, setAskingAgain] = useState2(false);
|
|
342
416
|
const startedAt = useRef(null);
|
|
343
417
|
const identity = JSON.stringify([directive.slug, items, conversationId ?? null]);
|
|
344
|
-
const [stateFor, setStateFor] =
|
|
418
|
+
const [stateFor, setStateFor] = useState2(identity);
|
|
345
419
|
if (stateFor !== identity) {
|
|
346
420
|
setStateFor(identity);
|
|
347
421
|
setState(initial);
|
|
@@ -351,14 +425,14 @@ function ApplyDirectiveButton({
|
|
|
351
425
|
const shared = useApplyOutcome(host.confirm ?? EMPTY_AUTHORITY, identity);
|
|
352
426
|
const view = state.status === "asking" || !shared ? state : shared;
|
|
353
427
|
const currentIdentity = useRef(identity);
|
|
354
|
-
|
|
428
|
+
useEffect2(() => {
|
|
355
429
|
currentIdentity.current = identity;
|
|
356
430
|
}, [identity]);
|
|
357
431
|
const nounText = nounLabel(directive.noun, host.nouns);
|
|
358
432
|
const shellKey = readsLedger ? JSON.stringify([directive.slug, items, conversationId ?? null]) : "";
|
|
359
433
|
const read = host.applyState;
|
|
360
434
|
const report = host.reportError;
|
|
361
|
-
|
|
435
|
+
useEffect2(() => {
|
|
362
436
|
if (!shellKey || !read) return;
|
|
363
437
|
const [slug, shellItems, inConversation] = JSON.parse(shellKey);
|
|
364
438
|
const shell = { __kind: slug, items: shellItems };
|
|
@@ -406,14 +480,14 @@ function ApplyDirectiveButton({
|
|
|
406
480
|
const appliedClean = view.status === "applied" && view.failed === 0 ? view : null;
|
|
407
481
|
const appliedBefore = appliedClean ? appliedClean.before : null;
|
|
408
482
|
const phaseKey = view.status === "checking" || view.status === "finishing" ? "pending" : appliedClean ? `applied:${JSON.stringify(appliedBefore)}` : "open";
|
|
409
|
-
|
|
483
|
+
useEffect2(() => {
|
|
410
484
|
if (!onPhase) return;
|
|
411
485
|
if (phaseKey === "pending") onPhase({ phase: "pending" });
|
|
412
486
|
else if (phaseKey === "open") onPhase({ phase: "open" });
|
|
413
487
|
else onPhase({ phase: "applied", before: appliedBefore });
|
|
414
488
|
}, [phaseKey, onPhase, appliedBefore]);
|
|
415
489
|
const applyingSince = view.status === "applying" ? view.startedAt : null;
|
|
416
|
-
|
|
490
|
+
useEffect2(() => {
|
|
417
491
|
if (applyingSince === null) return;
|
|
418
492
|
startedAt.current = applyingSince;
|
|
419
493
|
const id = setInterval(
|
|
@@ -465,7 +539,13 @@ function ApplyDirectiveButton({
|
|
|
465
539
|
const shell = { __kind: directive.slug, items };
|
|
466
540
|
if (conversationId) shell.conversationId = conversationId;
|
|
467
541
|
if (again) shell.force = true;
|
|
468
|
-
|
|
542
|
+
let result;
|
|
543
|
+
try {
|
|
544
|
+
result = await confirm(shell);
|
|
545
|
+
} finally {
|
|
546
|
+
announceChangedRecords(directive, items);
|
|
547
|
+
}
|
|
548
|
+
for (const record of result.records ?? []) noteRecordChanged(record.id);
|
|
469
549
|
publishOutcome(confirm, askedFor, {
|
|
470
550
|
status: "applied",
|
|
471
551
|
applied: result.applied,
|
|
@@ -626,7 +706,7 @@ function FailureNotice({
|
|
|
626
706
|
words,
|
|
627
707
|
raw
|
|
628
708
|
}) {
|
|
629
|
-
const [open, setOpen] =
|
|
709
|
+
const [open, setOpen] = useState2(false);
|
|
630
710
|
const detail = raw?.trim() ?? "";
|
|
631
711
|
return /* @__PURE__ */ jsxs2("span", { className: "flex min-w-0 flex-col gap-0.5", "data-apply-failure": true, children: [
|
|
632
712
|
/* @__PURE__ */ jsxs2("span", { className: "min-w-0", children: [
|
|
@@ -747,39 +827,6 @@ import {
|
|
|
747
827
|
nounLabel as nounLabel2,
|
|
748
828
|
nounTitleColumn
|
|
749
829
|
} from "@ai-matrx/content-ir";
|
|
750
|
-
|
|
751
|
-
// directives/record-values.ts
|
|
752
|
-
import { useEffect as useEffect2, useState as useState2 } from "react";
|
|
753
|
-
function useRecordValues(read, ref) {
|
|
754
|
-
const key = ref && read ? `${ref.noun}:${ref.id}` : "";
|
|
755
|
-
const [result, setResult] = useState2({
|
|
756
|
-
key: "",
|
|
757
|
-
values: null,
|
|
758
|
-
status: "idle"
|
|
759
|
-
});
|
|
760
|
-
useEffect2(() => {
|
|
761
|
-
if (!key || !read) return;
|
|
762
|
-
const split = key.indexOf(":");
|
|
763
|
-
const target = { noun: key.slice(0, split), id: key.slice(split + 1) };
|
|
764
|
-
let live = true;
|
|
765
|
-
setResult({ key, values: null, status: "loading" });
|
|
766
|
-
read(target).then((values) => {
|
|
767
|
-
if (!live) return;
|
|
768
|
-
setResult({ key, values, status: values ? "ready" : "unavailable" });
|
|
769
|
-
}).catch(() => {
|
|
770
|
-
if (!live) return;
|
|
771
|
-
setResult({ key, values: null, status: "unavailable" });
|
|
772
|
-
});
|
|
773
|
-
return () => {
|
|
774
|
-
live = false;
|
|
775
|
-
};
|
|
776
|
-
}, [key, read]);
|
|
777
|
-
if (!key) return { values: null, status: "idle" };
|
|
778
|
-
if (result.key !== key) return { values: null, status: "loading" };
|
|
779
|
-
return { values: result.values, status: result.status };
|
|
780
|
-
}
|
|
781
|
-
|
|
782
|
-
// directives/SideEffectDirectiveCard.tsx
|
|
783
830
|
import { Fragment, jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
784
831
|
var ROWS_BEFORE_FOLD = 3;
|
|
785
832
|
function ItemRow({
|