@ai-matrx/content-ir-react 0.18.0 → 0.18.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 +13 -0
- package/dist/directives.cjs +63 -33
- package/dist/directives.cjs.map +1 -1
- package/dist/directives.js +64 -34
- package/dist/directives.js.map +1 -1
- package/dist/index.cjs +63 -33
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +64 -34
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +63 -33
- package/dist/react.cjs.map +1 -1
- package/dist/react.js +64 -34
- package/dist/react.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.18.1 — 2026-10-02
|
|
4
|
+
|
|
5
|
+
- **An apply belongs to the block, not to the card that asked.** A note re-renders
|
|
6
|
+
its blocks while the confirm dialog is open; the card that asked was unmounted,
|
|
7
|
+
the apply still ran, and the fresh card — which had read the ledger before the
|
|
8
|
+
write landed — offered "Apply" for an update that had already run. From the yes
|
|
9
|
+
on, the apply's progress and outcome are held per apply authority (the host's
|
|
10
|
+
`confirm`) and block identity, and every card drawing that block shows them.
|
|
11
|
+
Guard: `__tests__/directive-card-g6a.test.tsx` ("a card re-mounted while its
|
|
12
|
+
confirm was open…", red on 0.18.0).
|
|
13
|
+
|
|
14
|
+
No consumer action.
|
|
15
|
+
|
|
3
16
|
## 0.18.0 — 2026-10-02
|
|
4
17
|
|
|
5
18
|
The G6A review of the action cards (nightly clone). Guard:
|
package/dist/directives.cjs
CHANGED
|
@@ -289,6 +289,34 @@ function classIcon(directiveClass, noun) {
|
|
|
289
289
|
|
|
290
290
|
// directives/ApplyDirectiveButton.tsx
|
|
291
291
|
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
292
|
+
var applyOutcomes = /* @__PURE__ */ new WeakMap();
|
|
293
|
+
var EMPTY_AUTHORITY = {};
|
|
294
|
+
var outcomeListeners = /* @__PURE__ */ new Set();
|
|
295
|
+
function outcomesOf(host) {
|
|
296
|
+
let held = applyOutcomes.get(host);
|
|
297
|
+
if (!held) {
|
|
298
|
+
held = /* @__PURE__ */ new Map();
|
|
299
|
+
applyOutcomes.set(host, held);
|
|
300
|
+
}
|
|
301
|
+
return held;
|
|
302
|
+
}
|
|
303
|
+
function publishOutcome(host, identity, outcome) {
|
|
304
|
+
outcomesOf(host).set(identity, outcome);
|
|
305
|
+
for (const listener of outcomeListeners) listener();
|
|
306
|
+
}
|
|
307
|
+
function subscribeOutcomes(listener) {
|
|
308
|
+
outcomeListeners.add(listener);
|
|
309
|
+
return () => {
|
|
310
|
+
outcomeListeners.delete(listener);
|
|
311
|
+
};
|
|
312
|
+
}
|
|
313
|
+
function useApplyOutcome(host, identity) {
|
|
314
|
+
return (0, import_react2.useSyncExternalStore)(
|
|
315
|
+
subscribeOutcomes,
|
|
316
|
+
() => applyOutcomes.get(host)?.get(identity) ?? null,
|
|
317
|
+
() => null
|
|
318
|
+
);
|
|
319
|
+
}
|
|
292
320
|
var FINISH_POLL_MS = 2e3;
|
|
293
321
|
var FINISH_POLLS_MAX = 30;
|
|
294
322
|
function readsApplyLedger(host, directive) {
|
|
@@ -320,6 +348,8 @@ function ApplyDirectiveButton({
|
|
|
320
348
|
setAskingAgain(false);
|
|
321
349
|
setElapsed(0);
|
|
322
350
|
}
|
|
351
|
+
const shared = useApplyOutcome(host.confirm ?? EMPTY_AUTHORITY, identity);
|
|
352
|
+
const view = state.status === "asking" || !shared ? state : shared;
|
|
323
353
|
const currentIdentity = (0, import_react2.useRef)(identity);
|
|
324
354
|
(0, import_react2.useEffect)(() => {
|
|
325
355
|
currentIdentity.current = identity;
|
|
@@ -373,33 +403,34 @@ function ApplyDirectiveButton({
|
|
|
373
403
|
if (timer) clearTimeout(timer);
|
|
374
404
|
};
|
|
375
405
|
}, [shellKey, read, report]);
|
|
376
|
-
const appliedClean =
|
|
406
|
+
const appliedClean = view.status === "applied" && view.failed === 0 ? view : null;
|
|
377
407
|
const appliedBefore = appliedClean ? appliedClean.before : null;
|
|
378
|
-
const phaseKey =
|
|
408
|
+
const phaseKey = view.status === "checking" || view.status === "finishing" ? "pending" : appliedClean ? `applied:${JSON.stringify(appliedBefore)}` : "open";
|
|
379
409
|
(0, import_react2.useEffect)(() => {
|
|
380
410
|
if (!onPhase) return;
|
|
381
411
|
if (phaseKey === "pending") onPhase({ phase: "pending" });
|
|
382
412
|
else if (phaseKey === "open") onPhase({ phase: "open" });
|
|
383
413
|
else onPhase({ phase: "applied", before: appliedBefore });
|
|
384
414
|
}, [phaseKey, onPhase, appliedBefore]);
|
|
415
|
+
const applyingSince = view.status === "applying" ? view.startedAt : null;
|
|
385
416
|
(0, import_react2.useEffect)(() => {
|
|
386
|
-
if (
|
|
387
|
-
startedAt.current =
|
|
417
|
+
if (applyingSince === null) return;
|
|
418
|
+
startedAt.current = applyingSince;
|
|
388
419
|
const id = setInterval(
|
|
389
420
|
() => setElapsed(Math.round((Date.now() - (startedAt.current ?? 0)) / 1e3)),
|
|
390
421
|
1e3
|
|
391
422
|
);
|
|
392
423
|
return () => clearInterval(id);
|
|
393
|
-
}, [
|
|
424
|
+
}, [applyingSince]);
|
|
394
425
|
if (!directive.parsed.executes) return null;
|
|
395
426
|
const confirm = host.confirm;
|
|
396
427
|
if (!confirm) return null;
|
|
397
428
|
async function handleApply(again = false) {
|
|
398
429
|
if (!confirm) return;
|
|
399
|
-
const prior =
|
|
430
|
+
const prior = view;
|
|
400
431
|
const askedFor = identity;
|
|
401
432
|
const stillHere = () => currentIdentity.current === askedFor;
|
|
402
|
-
const priorCopies =
|
|
433
|
+
const priorCopies = view.status === "applied" ? view.copies : 0;
|
|
403
434
|
if (host.ask) {
|
|
404
435
|
if (again) setAskingAgain(true);
|
|
405
436
|
else setState({ status: "asking" });
|
|
@@ -428,14 +459,14 @@ function ApplyDirectiveButton({
|
|
|
428
459
|
}
|
|
429
460
|
}
|
|
430
461
|
setElapsed(0);
|
|
431
|
-
setState({ status: "
|
|
462
|
+
setState((prev) => prev.status === "asking" ? { status: "idle" } : prev);
|
|
463
|
+
publishOutcome(confirm, askedFor, { status: "applying", startedAt: Date.now() });
|
|
432
464
|
try {
|
|
433
465
|
const shell = { __kind: directive.slug, items };
|
|
434
466
|
if (conversationId) shell.conversationId = conversationId;
|
|
435
467
|
if (again) shell.force = true;
|
|
436
468
|
const result = await confirm(shell);
|
|
437
|
-
|
|
438
|
-
setState({
|
|
469
|
+
publishOutcome(confirm, askedFor, {
|
|
439
470
|
status: "applied",
|
|
440
471
|
applied: result.applied,
|
|
441
472
|
failed: result.failed,
|
|
@@ -447,20 +478,19 @@ function ApplyDirectiveButton({
|
|
|
447
478
|
// apply replaced is still the change this block made.
|
|
448
479
|
before: again && prior.status === "applied" && prior.before ? prior.before : result.before ?? null
|
|
449
480
|
});
|
|
450
|
-
onApplied?.();
|
|
481
|
+
if (stillHere()) onApplied?.();
|
|
451
482
|
} catch (error) {
|
|
452
|
-
|
|
453
|
-
setState({
|
|
483
|
+
publishOutcome(confirm, askedFor, {
|
|
454
484
|
status: "error",
|
|
455
485
|
message: error instanceof Error && error.message ? error.message : "That couldn't be applied just now. Please try again."
|
|
456
486
|
});
|
|
457
487
|
}
|
|
458
488
|
}
|
|
459
|
-
if (
|
|
460
|
-
const bad =
|
|
489
|
+
if (view.status === "applied") {
|
|
490
|
+
const bad = view.failed > 0;
|
|
461
491
|
const trashed = directive.directiveClass === "delete";
|
|
462
492
|
const label2 = nounText;
|
|
463
|
-
const records = host.renderRecord ?
|
|
493
|
+
const records = host.renderRecord ? view.records : [];
|
|
464
494
|
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
465
495
|
"span",
|
|
466
496
|
{
|
|
@@ -474,26 +504,26 @@ function ApplyDirectiveButton({
|
|
|
474
504
|
{
|
|
475
505
|
words: failureWords(
|
|
476
506
|
{
|
|
477
|
-
raw:
|
|
507
|
+
raw: view.message ?? `${view.failed} failed`,
|
|
478
508
|
directiveClass: directive.directiveClass,
|
|
479
509
|
noun: directive.noun,
|
|
480
510
|
nounLabel: nounText,
|
|
481
|
-
failed:
|
|
482
|
-
total:
|
|
511
|
+
failed: view.failed,
|
|
512
|
+
total: view.applied + view.failed
|
|
483
513
|
},
|
|
484
514
|
host.explainFailure
|
|
485
515
|
),
|
|
486
|
-
raw:
|
|
516
|
+
raw: view.message
|
|
487
517
|
}
|
|
488
|
-
) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "min-w-0", children:
|
|
518
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "min-w-0", children: view.message ?? `Applied ${view.applied}` })
|
|
489
519
|
] }),
|
|
490
|
-
|
|
520
|
+
view.copies > 1 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
491
521
|
"span",
|
|
492
522
|
{
|
|
493
523
|
className: "shrink-0 text-muted-foreground",
|
|
494
|
-
"data-apply-copies":
|
|
524
|
+
"data-apply-copies": view.copies,
|
|
495
525
|
title: records.length > 0 ? directive.directiveClass === "create" ? "Links to the latest copy." : "Links to the latest run." : void 0,
|
|
496
|
-
children: directive.directiveClass === "create" ? `${
|
|
526
|
+
children: directive.directiveClass === "create" ? `${view.copies} copies` : `Ran ${view.copies} times`
|
|
497
527
|
}
|
|
498
528
|
) : null,
|
|
499
529
|
records.map((record) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "inline-flex min-w-0 items-center", children: host.renderRecord?.({
|
|
@@ -520,7 +550,7 @@ function ApplyDirectiveButton({
|
|
|
520
550
|
}
|
|
521
551
|
);
|
|
522
552
|
}
|
|
523
|
-
if (
|
|
553
|
+
if (view.status === "checking") {
|
|
524
554
|
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
525
555
|
"span",
|
|
526
556
|
{
|
|
@@ -532,7 +562,7 @@ function ApplyDirectiveButton({
|
|
|
532
562
|
}
|
|
533
563
|
);
|
|
534
564
|
}
|
|
535
|
-
if (
|
|
565
|
+
if (view.status === "finishing") {
|
|
536
566
|
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
537
567
|
"span",
|
|
538
568
|
{
|
|
@@ -547,7 +577,7 @@ function ApplyDirectiveButton({
|
|
|
547
577
|
);
|
|
548
578
|
}
|
|
549
579
|
const destructive = directive.directiveClass === "delete";
|
|
550
|
-
const muted = nothingToChange &&
|
|
580
|
+
const muted = nothingToChange && view.status === "idle";
|
|
551
581
|
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "inline-flex items-center gap-2", children: [
|
|
552
582
|
muted ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "text-xs text-muted-foreground", "data-apply-nothing": "", children: "Nothing to change" }) : null,
|
|
553
583
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
@@ -555,17 +585,17 @@ function ApplyDirectiveButton({
|
|
|
555
585
|
{
|
|
556
586
|
type: "button",
|
|
557
587
|
onClick: () => void handleApply(),
|
|
558
|
-
disabled:
|
|
588
|
+
disabled: view.status === "applying" || view.status === "asking" || items.length === 0,
|
|
559
589
|
"data-apply-tone": muted ? "muted" : destructive ? "destructive" : "default",
|
|
560
590
|
title: muted ? "It sets no fields, so applying it changes nothing." : void 0,
|
|
561
591
|
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"}`,
|
|
562
592
|
children: [
|
|
563
|
-
|
|
564
|
-
|
|
593
|
+
view.status === "applying" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(LoaderIcon, { className: "h-3.5 w-3.5 animate-spin" }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PlayIcon, { className: "h-3.5 w-3.5" }),
|
|
594
|
+
view.status === "applying" ? `Applying${itemCount ? ` ${itemCount} ${itemCount === 1 ? "item" : "items"}` : ""}\u2026${elapsed ? ` ${elapsed}s` : ""}` : label
|
|
565
595
|
]
|
|
566
596
|
}
|
|
567
597
|
),
|
|
568
|
-
|
|
598
|
+
view.status === "error" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
569
599
|
"span",
|
|
570
600
|
{
|
|
571
601
|
className: "inline-flex max-w-sm items-start gap-1 text-xs text-destructive",
|
|
@@ -577,14 +607,14 @@ function ApplyDirectiveButton({
|
|
|
577
607
|
{
|
|
578
608
|
words: failureWords(
|
|
579
609
|
{
|
|
580
|
-
raw:
|
|
610
|
+
raw: view.message,
|
|
581
611
|
directiveClass: directive.directiveClass,
|
|
582
612
|
noun: directive.noun,
|
|
583
613
|
nounLabel: nounText
|
|
584
614
|
},
|
|
585
615
|
host.explainFailure
|
|
586
616
|
),
|
|
587
|
-
raw:
|
|
617
|
+
raw: view.message
|
|
588
618
|
}
|
|
589
619
|
)
|
|
590
620
|
]
|