@ai-matrx/content-ir-react 0.13.18 → 0.14.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/dist/react.d.cts CHANGED
@@ -1,9 +1,9 @@
1
- import { c as KindDefinitionSource, C as ContentIrHost } from './host-types-BgROpyjE.cjs';
1
+ import { c as KindDefinitionSource, C as ContentIrHost } from './host-types-BpmKg07p.cjs';
2
2
  import { d as ComponentResolutionSource } from './component-resolution.types-C1MzCf2s.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-Bl-ZgJWp.cjs';
6
+ import './directive-host-DLp5QFI2.cjs';
7
7
 
8
8
  /**
9
9
  * The two registries this hook watches. Passed explicitly by a host whose
package/dist/react.d.ts CHANGED
@@ -1,9 +1,9 @@
1
- import { c as KindDefinitionSource, C as ContentIrHost } from './host-types-Cz-1pGHz.js';
1
+ import { c as KindDefinitionSource, C as ContentIrHost } from './host-types-DHKFg06S.js';
2
2
  import { d as ComponentResolutionSource } from './component-resolution.types-C1MzCf2s.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-Bl-ZgJWp.js';
6
+ import './directive-host-DLp5QFI2.js';
7
7
 
8
8
  /**
9
9
  * The two registries this hook watches. Passed explicitly by a host whose
package/dist/react.js CHANGED
@@ -234,6 +234,8 @@ function classIcon(directiveClass, noun) {
234
234
 
235
235
  // directives/ApplyDirectiveButton.tsx
236
236
  import { jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
237
+ var FINISH_POLL_MS = 2e3;
238
+ var FINISH_POLLS_MAX = 30;
237
239
  function ApplyDirectiveButton({
238
240
  directive,
239
241
  label = "Apply",
@@ -241,9 +243,58 @@ function ApplyDirectiveButton({
241
243
  onApplied
242
244
  }) {
243
245
  const host = useDirectiveHost();
244
- const [state, setState] = useState({ status: "idle" });
246
+ const items = directive.items;
247
+ const readsLedger = !!host.applyState && !!host.confirm && directive.parsed.executes && items.length > 0;
248
+ const [state, setState] = useState(
249
+ readsLedger ? { status: "checking" } : { status: "idle" }
250
+ );
245
251
  const [elapsed, setElapsed] = useState(0);
246
252
  const startedAt = useRef(null);
253
+ const nounText = nounLabel(directive.noun, host.nouns);
254
+ const shellKey = readsLedger ? JSON.stringify([directive.slug, items]) : "";
255
+ const read = host.applyState;
256
+ const report = host.reportError;
257
+ useEffect(() => {
258
+ if (!shellKey || !read) return;
259
+ const [slug, shellItems] = JSON.parse(shellKey);
260
+ let live = true;
261
+ let polls = 0;
262
+ let timer = null;
263
+ const ask = () => {
264
+ read({ __kind: slug, items: shellItems }).then((answer) => {
265
+ if (!live) return;
266
+ if (answer.state === "applied") {
267
+ setState(
268
+ (prev) => prev.status === "checking" || prev.status === "finishing" ? {
269
+ status: "applied",
270
+ applied: shellItems.length,
271
+ failed: 0,
272
+ message: answer.message?.trim() ? answer.message.trim() : null,
273
+ records: answer.records ?? []
274
+ } : prev
275
+ );
276
+ } else if (answer.state === "in_flight" && polls < FINISH_POLLS_MAX) {
277
+ polls += 1;
278
+ setState((prev) => prev.status === "checking" || prev.status === "finishing" ? { status: "finishing" } : prev);
279
+ timer = setTimeout(ask, FINISH_POLL_MS);
280
+ } else {
281
+ setState((prev) => prev.status === "checking" || prev.status === "finishing" ? { status: "idle" } : prev);
282
+ }
283
+ }).catch((error) => {
284
+ if (!live) return;
285
+ const why = error instanceof Error && error.message ? error.message : String(error);
286
+ (report ?? console.error)(
287
+ `[kind-directives] Could not read whether ${slug} was already applied: ${why}`
288
+ );
289
+ setState((prev) => prev.status === "checking" || prev.status === "finishing" ? { status: "idle" } : prev);
290
+ });
291
+ };
292
+ ask();
293
+ return () => {
294
+ live = false;
295
+ if (timer) clearTimeout(timer);
296
+ };
297
+ }, [shellKey, read, report]);
247
298
  useEffect(() => {
248
299
  if (state.status !== "applying") return;
249
300
  startedAt.current = Date.now();
@@ -256,7 +307,6 @@ function ApplyDirectiveButton({
256
307
  if (!directive.parsed.executes) return null;
257
308
  const confirm = host.confirm;
258
309
  if (!confirm) return null;
259
- const items = directive.items;
260
310
  async function handleApply() {
261
311
  if (!confirm) return;
262
312
  if (host.ask) {
@@ -266,7 +316,7 @@ function ApplyDirectiveButton({
266
316
  ok = await host.ask({
267
317
  directive,
268
318
  items,
269
- nounLabel: nounLabel(directive.noun, host.nouns)
319
+ nounLabel: nounText
270
320
  });
271
321
  } catch (error) {
272
322
  setState({
@@ -302,7 +352,7 @@ function ApplyDirectiveButton({
302
352
  if (state.status === "applied") {
303
353
  const bad = state.failed > 0;
304
354
  const trashed = directive.directiveClass === "delete";
305
- const label2 = nounLabel(directive.noun, host.nouns);
355
+ const label2 = nounText;
306
356
  const records = host.renderRecord ? state.records : [];
307
357
  return /* @__PURE__ */ jsxs2(
308
358
  "span",
@@ -325,6 +375,32 @@ function ApplyDirectiveButton({
325
375
  }
326
376
  );
327
377
  }
378
+ if (state.status === "checking") {
379
+ return /* @__PURE__ */ jsx4(
380
+ "span",
381
+ {
382
+ className: "inline-flex h-6 w-6 items-center justify-center text-muted-foreground",
383
+ role: "status",
384
+ "aria-label": "Checking whether this already ran",
385
+ "data-apply-state": "checking",
386
+ children: /* @__PURE__ */ jsx4(LoaderIcon, { className: "h-3.5 w-3.5 animate-spin" })
387
+ }
388
+ );
389
+ }
390
+ if (state.status === "finishing") {
391
+ return /* @__PURE__ */ jsxs2(
392
+ "span",
393
+ {
394
+ className: "inline-flex items-center gap-1 text-xs text-muted-foreground",
395
+ role: "status",
396
+ "data-apply-state": "finishing",
397
+ children: [
398
+ /* @__PURE__ */ jsx4(LoaderIcon, { className: "h-3.5 w-3.5 animate-spin" }),
399
+ "Finishing\u2026"
400
+ ]
401
+ }
402
+ );
403
+ }
328
404
  return /* @__PURE__ */ jsxs2("span", { className: "inline-flex items-center gap-2", children: [
329
405
  /* @__PURE__ */ jsxs2(
330
406
  "button",