@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.cjs
CHANGED
|
@@ -134,7 +134,7 @@ var import_content_ir6 = require("@ai-matrx/content-ir");
|
|
|
134
134
|
var import_content_ir2 = require("@ai-matrx/content-ir");
|
|
135
135
|
|
|
136
136
|
// directives/ApplyDirectiveButton.tsx
|
|
137
|
-
var
|
|
137
|
+
var import_react5 = require("react");
|
|
138
138
|
var import_content_ir = require("@ai-matrx/content-ir");
|
|
139
139
|
|
|
140
140
|
// directives/item-changes.ts
|
|
@@ -210,6 +210,73 @@ function itemChanges(item, current, options = {}) {
|
|
|
210
210
|
return out;
|
|
211
211
|
}
|
|
212
212
|
|
|
213
|
+
// directives/record-values.ts
|
|
214
|
+
var import_react4 = require("react");
|
|
215
|
+
var STORE_SLOT = /* @__PURE__ */ Symbol.for("@ai-matrx/content-ir-react/record-revisions");
|
|
216
|
+
function revisionStore() {
|
|
217
|
+
const slots = globalThis;
|
|
218
|
+
let store = slots[STORE_SLOT];
|
|
219
|
+
if (!store) {
|
|
220
|
+
store = { revisions: /* @__PURE__ */ new Map(), listeners: /* @__PURE__ */ new Set() };
|
|
221
|
+
slots[STORE_SLOT] = store;
|
|
222
|
+
}
|
|
223
|
+
return store;
|
|
224
|
+
}
|
|
225
|
+
var { revisions, listeners } = revisionStore();
|
|
226
|
+
function recordRevision(id) {
|
|
227
|
+
return revisions.get(id) ?? 0;
|
|
228
|
+
}
|
|
229
|
+
function noteRecordChanged(id) {
|
|
230
|
+
if (!id) return;
|
|
231
|
+
revisions.set(id, recordRevision(id) + 1);
|
|
232
|
+
for (const listener of listeners) listener();
|
|
233
|
+
}
|
|
234
|
+
function subscribeRevisions(listener) {
|
|
235
|
+
listeners.add(listener);
|
|
236
|
+
return () => {
|
|
237
|
+
listeners.delete(listener);
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
function useRecordRevision(id) {
|
|
241
|
+
return (0, import_react4.useSyncExternalStore)(
|
|
242
|
+
subscribeRevisions,
|
|
243
|
+
() => recordRevision(id),
|
|
244
|
+
() => 0
|
|
245
|
+
);
|
|
246
|
+
}
|
|
247
|
+
function useRecordValues(read, ref) {
|
|
248
|
+
const revision = useRecordRevision(ref?.id ?? "");
|
|
249
|
+
const key = ref && read ? `${ref.noun}:${ref.id}#${revision}` : "";
|
|
250
|
+
const [result, setResult] = (0, import_react4.useState)({
|
|
251
|
+
key: "",
|
|
252
|
+
values: null,
|
|
253
|
+
status: "idle"
|
|
254
|
+
});
|
|
255
|
+
(0, import_react4.useEffect)(() => {
|
|
256
|
+
if (!key || !read) return;
|
|
257
|
+
const split = key.indexOf(":");
|
|
258
|
+
const target = {
|
|
259
|
+
noun: key.slice(0, split),
|
|
260
|
+
id: key.slice(split + 1, key.lastIndexOf("#"))
|
|
261
|
+
};
|
|
262
|
+
let live = true;
|
|
263
|
+
setResult({ key, values: null, status: "loading" });
|
|
264
|
+
read(target).then((values) => {
|
|
265
|
+
if (!live) return;
|
|
266
|
+
setResult({ key, values, status: values ? "ready" : "unavailable" });
|
|
267
|
+
}).catch(() => {
|
|
268
|
+
if (!live) return;
|
|
269
|
+
setResult({ key, values: null, status: "unavailable" });
|
|
270
|
+
});
|
|
271
|
+
return () => {
|
|
272
|
+
live = false;
|
|
273
|
+
};
|
|
274
|
+
}, [key, read]);
|
|
275
|
+
if (!key) return { values: null, status: "idle" };
|
|
276
|
+
if (result.key !== key) return { values: null, status: "loading" };
|
|
277
|
+
return { values: result.values, status: result.status };
|
|
278
|
+
}
|
|
279
|
+
|
|
213
280
|
// directives/failure-words.ts
|
|
214
281
|
var PAST = {
|
|
215
282
|
create: "created",
|
|
@@ -329,6 +396,13 @@ function classIcon(directiveClass, noun) {
|
|
|
329
396
|
|
|
330
397
|
// directives/ApplyDirectiveButton.tsx
|
|
331
398
|
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
399
|
+
function announceChangedRecords(directive, items) {
|
|
400
|
+
if (!TARGETING_CLASSES.has(directive.directiveClass)) return;
|
|
401
|
+
for (const item of items) {
|
|
402
|
+
const id = itemRecordId(item);
|
|
403
|
+
if (id) noteRecordChanged(id);
|
|
404
|
+
}
|
|
405
|
+
}
|
|
332
406
|
var applyOutcomes = /* @__PURE__ */ new WeakMap();
|
|
333
407
|
var EMPTY_AUTHORITY = {};
|
|
334
408
|
var outcomeListeners = /* @__PURE__ */ new Set();
|
|
@@ -351,7 +425,7 @@ function subscribeOutcomes(listener) {
|
|
|
351
425
|
};
|
|
352
426
|
}
|
|
353
427
|
function useApplyOutcome(host, identity) {
|
|
354
|
-
return (0,
|
|
428
|
+
return (0, import_react5.useSyncExternalStore)(
|
|
355
429
|
subscribeOutcomes,
|
|
356
430
|
() => applyOutcomes.get(host)?.get(identity) ?? null,
|
|
357
431
|
() => null
|
|
@@ -376,12 +450,12 @@ function ApplyDirectiveButton({
|
|
|
376
450
|
const items = directive.items;
|
|
377
451
|
const readsLedger = readsApplyLedger(host, directive);
|
|
378
452
|
const initial = readsLedger ? { status: "checking" } : { status: "idle" };
|
|
379
|
-
const [state, setState] = (0,
|
|
380
|
-
const [elapsed, setElapsed] = (0,
|
|
381
|
-
const [askingAgain, setAskingAgain] = (0,
|
|
382
|
-
const startedAt = (0,
|
|
453
|
+
const [state, setState] = (0, import_react5.useState)(initial);
|
|
454
|
+
const [elapsed, setElapsed] = (0, import_react5.useState)(0);
|
|
455
|
+
const [askingAgain, setAskingAgain] = (0, import_react5.useState)(false);
|
|
456
|
+
const startedAt = (0, import_react5.useRef)(null);
|
|
383
457
|
const identity = JSON.stringify([directive.slug, items, conversationId ?? null]);
|
|
384
|
-
const [stateFor, setStateFor] = (0,
|
|
458
|
+
const [stateFor, setStateFor] = (0, import_react5.useState)(identity);
|
|
385
459
|
if (stateFor !== identity) {
|
|
386
460
|
setStateFor(identity);
|
|
387
461
|
setState(initial);
|
|
@@ -390,15 +464,15 @@ function ApplyDirectiveButton({
|
|
|
390
464
|
}
|
|
391
465
|
const shared = useApplyOutcome(host.confirm ?? EMPTY_AUTHORITY, identity);
|
|
392
466
|
const view = state.status === "asking" || !shared ? state : shared;
|
|
393
|
-
const currentIdentity = (0,
|
|
394
|
-
(0,
|
|
467
|
+
const currentIdentity = (0, import_react5.useRef)(identity);
|
|
468
|
+
(0, import_react5.useEffect)(() => {
|
|
395
469
|
currentIdentity.current = identity;
|
|
396
470
|
}, [identity]);
|
|
397
471
|
const nounText = (0, import_content_ir.nounLabel)(directive.noun, host.nouns);
|
|
398
472
|
const shellKey = readsLedger ? JSON.stringify([directive.slug, items, conversationId ?? null]) : "";
|
|
399
473
|
const read = host.applyState;
|
|
400
474
|
const report = host.reportError;
|
|
401
|
-
(0,
|
|
475
|
+
(0, import_react5.useEffect)(() => {
|
|
402
476
|
if (!shellKey || !read) return;
|
|
403
477
|
const [slug, shellItems, inConversation] = JSON.parse(shellKey);
|
|
404
478
|
const shell = { __kind: slug, items: shellItems };
|
|
@@ -446,14 +520,14 @@ function ApplyDirectiveButton({
|
|
|
446
520
|
const appliedClean = view.status === "applied" && view.failed === 0 ? view : null;
|
|
447
521
|
const appliedBefore = appliedClean ? appliedClean.before : null;
|
|
448
522
|
const phaseKey = view.status === "checking" || view.status === "finishing" ? "pending" : appliedClean ? `applied:${JSON.stringify(appliedBefore)}` : "open";
|
|
449
|
-
(0,
|
|
523
|
+
(0, import_react5.useEffect)(() => {
|
|
450
524
|
if (!onPhase) return;
|
|
451
525
|
if (phaseKey === "pending") onPhase({ phase: "pending" });
|
|
452
526
|
else if (phaseKey === "open") onPhase({ phase: "open" });
|
|
453
527
|
else onPhase({ phase: "applied", before: appliedBefore });
|
|
454
528
|
}, [phaseKey, onPhase, appliedBefore]);
|
|
455
529
|
const applyingSince = view.status === "applying" ? view.startedAt : null;
|
|
456
|
-
(0,
|
|
530
|
+
(0, import_react5.useEffect)(() => {
|
|
457
531
|
if (applyingSince === null) return;
|
|
458
532
|
startedAt.current = applyingSince;
|
|
459
533
|
const id = setInterval(
|
|
@@ -505,7 +579,13 @@ function ApplyDirectiveButton({
|
|
|
505
579
|
const shell = { __kind: directive.slug, items };
|
|
506
580
|
if (conversationId) shell.conversationId = conversationId;
|
|
507
581
|
if (again) shell.force = true;
|
|
508
|
-
|
|
582
|
+
let result;
|
|
583
|
+
try {
|
|
584
|
+
result = await confirm(shell);
|
|
585
|
+
} finally {
|
|
586
|
+
announceChangedRecords(directive, items);
|
|
587
|
+
}
|
|
588
|
+
for (const record of result.records ?? []) noteRecordChanged(record.id);
|
|
509
589
|
publishOutcome(confirm, askedFor, {
|
|
510
590
|
status: "applied",
|
|
511
591
|
applied: result.applied,
|
|
@@ -666,7 +746,7 @@ function FailureNotice({
|
|
|
666
746
|
words,
|
|
667
747
|
raw
|
|
668
748
|
}) {
|
|
669
|
-
const [open, setOpen] = (0,
|
|
749
|
+
const [open, setOpen] = (0, import_react5.useState)(false);
|
|
670
750
|
const detail = raw?.trim() ?? "";
|
|
671
751
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "flex min-w-0 flex-col gap-0.5", "data-apply-failure": true, children: [
|
|
672
752
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "min-w-0", children: [
|
|
@@ -777,39 +857,6 @@ function getDirectiveRenderer(directive) {
|
|
|
777
857
|
// directives/SideEffectDirectiveCard.tsx
|
|
778
858
|
var import_react6 = require("react");
|
|
779
859
|
var import_content_ir5 = require("@ai-matrx/content-ir");
|
|
780
|
-
|
|
781
|
-
// directives/record-values.ts
|
|
782
|
-
var import_react5 = require("react");
|
|
783
|
-
function useRecordValues(read, ref) {
|
|
784
|
-
const key = ref && read ? `${ref.noun}:${ref.id}` : "";
|
|
785
|
-
const [result, setResult] = (0, import_react5.useState)({
|
|
786
|
-
key: "",
|
|
787
|
-
values: null,
|
|
788
|
-
status: "idle"
|
|
789
|
-
});
|
|
790
|
-
(0, import_react5.useEffect)(() => {
|
|
791
|
-
if (!key || !read) return;
|
|
792
|
-
const split = key.indexOf(":");
|
|
793
|
-
const target = { noun: key.slice(0, split), id: key.slice(split + 1) };
|
|
794
|
-
let live = true;
|
|
795
|
-
setResult({ key, values: null, status: "loading" });
|
|
796
|
-
read(target).then((values) => {
|
|
797
|
-
if (!live) return;
|
|
798
|
-
setResult({ key, values, status: values ? "ready" : "unavailable" });
|
|
799
|
-
}).catch(() => {
|
|
800
|
-
if (!live) return;
|
|
801
|
-
setResult({ key, values: null, status: "unavailable" });
|
|
802
|
-
});
|
|
803
|
-
return () => {
|
|
804
|
-
live = false;
|
|
805
|
-
};
|
|
806
|
-
}, [key, read]);
|
|
807
|
-
if (!key) return { values: null, status: "idle" };
|
|
808
|
-
if (result.key !== key) return { values: null, status: "loading" };
|
|
809
|
-
return { values: result.values, status: result.status };
|
|
810
|
-
}
|
|
811
|
-
|
|
812
|
-
// directives/SideEffectDirectiveCard.tsx
|
|
813
860
|
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
814
861
|
var ROWS_BEFORE_FOLD = 3;
|
|
815
862
|
function ItemRow({
|