@almadar/ui 5.158.0 → 5.160.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/{EntityBindingContext-Bn3ePJQC.d.cts → EntityBindingContext-0Evn_LcT.d.cts} +1 -1
- package/dist/{EntityBindingContext-Bn3ePJQC.d.ts → EntityBindingContext-0Evn_LcT.d.ts} +1 -1
- package/dist/avl/index.cjs +177 -54
- package/dist/avl/index.js +178 -55
- package/dist/components/index.cjs +225 -27
- package/dist/components/index.d.cts +8 -0
- package/dist/components/index.d.ts +8 -0
- package/dist/components/index.js +226 -28
- package/dist/context/index.cjs +134 -39
- package/dist/context/index.js +92 -1
- package/dist/hooks/index.cjs +328 -233
- package/dist/hooks/index.js +93 -2
- package/dist/lib/index.cjs +92 -0
- package/dist/lib/index.d.cts +58 -1
- package/dist/lib/index.d.ts +58 -1
- package/dist/lib/index.js +62 -1
- package/dist/locales/index.cjs +3 -0
- package/dist/locales/index.js +3 -0
- package/dist/perf-DaVdsbU0.d.cts +21 -0
- package/dist/perf-DaVdsbU0.d.ts +21 -0
- package/dist/providers/index.cjs +289 -116
- package/dist/providers/index.d.cts +1 -1
- package/dist/providers/index.d.ts +1 -1
- package/dist/providers/index.js +290 -117
- package/dist/runtime/index.cjs +185 -59
- package/dist/runtime/index.d.cts +5 -22
- package/dist/runtime/index.d.ts +5 -22
- package/dist/runtime/index.js +187 -60
- package/locales/ar.json +1 -0
- package/locales/en.json +1 -0
- package/locales/sl.json +1 -0
- package/package.json +5 -5
package/dist/avl/index.js
CHANGED
|
@@ -13,7 +13,7 @@ import { Loader2, X, Code, FileText, WrapText, Check, Copy, Lightbulb, CheckCirc
|
|
|
13
13
|
import { createPortal } from 'react-dom';
|
|
14
14
|
import { UISlotProvider, useUISlots, useTheme } from '@almadar/ui/context';
|
|
15
15
|
import { evaluateGuard, evaluateListenPayloadExpr, evaluate, createMinimalContext, executeEffects } from '@almadar/evaluator';
|
|
16
|
-
import { prepareSchemaForPreview, collectTraitRefsFromResolvedTrait, buildOrbitalsByTrait, collectEmbeddedTraits,
|
|
16
|
+
import { prepareSchemaForPreview, collectTraitRefsFromResolvedTrait, buildOrbitalsByTrait, collectEmbeddedTraits, perfStart, perfEnd, perfGauge, perfTimeAsync, wrapCallbackForEvent, pushPerfEntry } from '@almadar/runtime/ui';
|
|
17
17
|
import { Link, Outlet, useLocation } from 'react-router-dom';
|
|
18
18
|
import SyntaxHighlighter from 'react-syntax-highlighter/dist/esm/prism-light.js';
|
|
19
19
|
import dark from 'react-syntax-highlighter/dist/esm/styles/prism/vsc-dark-plus.js';
|
|
@@ -4588,7 +4588,16 @@ function isPlainObject(value) {
|
|
|
4588
4588
|
if (typeof value === "function") return false;
|
|
4589
4589
|
return true;
|
|
4590
4590
|
}
|
|
4591
|
+
function isEvaluatorResolvedData(value) {
|
|
4592
|
+
return evaluatorResolvedData.has(value);
|
|
4593
|
+
}
|
|
4594
|
+
function brandResolved(value) {
|
|
4595
|
+
if (value !== null && typeof value === "object" && !React94__default.isValidElement(value) && !(value instanceof Date)) {
|
|
4596
|
+
resolvedMarkerFree.add(value);
|
|
4597
|
+
}
|
|
4598
|
+
}
|
|
4591
4599
|
function subtreeHasMarker(value) {
|
|
4600
|
+
if (resolvedMarkerFree.has(value)) return false;
|
|
4592
4601
|
const cached = markerPresenceCache.get(value);
|
|
4593
4602
|
if (cached !== void 0) return cached;
|
|
4594
4603
|
let found = false;
|
|
@@ -4610,10 +4619,23 @@ function subtreeHasMarker(value) {
|
|
|
4610
4619
|
}
|
|
4611
4620
|
function walkValue(value, scopeTrait, entity, config, state) {
|
|
4612
4621
|
if (isRenderBindingMarker(value)) {
|
|
4613
|
-
|
|
4622
|
+
const cached = markerResolutionCache.get(value);
|
|
4623
|
+
if (cached !== void 0 && cached.entity === entity && cached.config === config && cached.state === state) {
|
|
4624
|
+
return { resolved: cached.resolved, changed: false };
|
|
4625
|
+
}
|
|
4626
|
+
const resolved = resolveMarkerExpression(value.expression, entity, config, state);
|
|
4627
|
+
markerResolutionCache.set(value, { entity, config, state, resolved });
|
|
4628
|
+
if (resolved !== null && typeof resolved === "object" && !React94__default.isValidElement(resolved) && !(resolved instanceof Date)) {
|
|
4629
|
+
resolvedMarkerFree.add(resolved);
|
|
4630
|
+
evaluatorResolvedData.add(resolved);
|
|
4631
|
+
}
|
|
4632
|
+
return { resolved, changed: true };
|
|
4614
4633
|
}
|
|
4615
4634
|
if (Array.isArray(value)) {
|
|
4616
|
-
if (!subtreeHasMarker(value))
|
|
4635
|
+
if (!subtreeHasMarker(value)) {
|
|
4636
|
+
brandResolved(value);
|
|
4637
|
+
return { resolved: value, changed: false };
|
|
4638
|
+
}
|
|
4617
4639
|
const out = [];
|
|
4618
4640
|
let changed = false;
|
|
4619
4641
|
for (const item of value) {
|
|
@@ -4628,10 +4650,14 @@ function walkValue(value, scopeTrait, entity, config, state) {
|
|
|
4628
4650
|
out.push(resolved);
|
|
4629
4651
|
if (itemChanged) changed = true;
|
|
4630
4652
|
}
|
|
4653
|
+
brandResolved(out);
|
|
4631
4654
|
return changed ? { resolved: out, changed: true } : { resolved: value, changed: false };
|
|
4632
4655
|
}
|
|
4633
4656
|
if (isPlainObject(value)) {
|
|
4634
|
-
if (!subtreeHasMarker(value))
|
|
4657
|
+
if (!subtreeHasMarker(value)) {
|
|
4658
|
+
brandResolved(value);
|
|
4659
|
+
return { resolved: value, changed: false };
|
|
4660
|
+
}
|
|
4635
4661
|
const sourceTrait = value._sourceTrait;
|
|
4636
4662
|
if (typeof sourceTrait === "string" && sourceTrait !== scopeTrait) {
|
|
4637
4663
|
return { resolved: value, changed: false };
|
|
@@ -4643,11 +4669,13 @@ function walkValue(value, scopeTrait, entity, config, state) {
|
|
|
4643
4669
|
out[key] = resolved;
|
|
4644
4670
|
if (itemChanged) changed = true;
|
|
4645
4671
|
}
|
|
4672
|
+
brandResolved(out);
|
|
4646
4673
|
return changed ? { resolved: out, changed: true } : { resolved: value, changed: false };
|
|
4647
4674
|
}
|
|
4648
4675
|
return { resolved: value, changed: false };
|
|
4649
4676
|
}
|
|
4650
4677
|
function resolveRenderBindingMarkers(props, scopeTrait, entity, config, state) {
|
|
4678
|
+
if (resolvedMarkerFree.has(props)) return props;
|
|
4651
4679
|
const out = {};
|
|
4652
4680
|
let changed = false;
|
|
4653
4681
|
for (const [key, value] of Object.entries(props)) {
|
|
@@ -4655,13 +4683,17 @@ function resolveRenderBindingMarkers(props, scopeTrait, entity, config, state) {
|
|
|
4655
4683
|
out[key] = resolved;
|
|
4656
4684
|
if (propChanged) changed = true;
|
|
4657
4685
|
}
|
|
4686
|
+
brandResolved(out);
|
|
4658
4687
|
return changed ? out : props;
|
|
4659
4688
|
}
|
|
4660
|
-
var markerPresenceCache;
|
|
4689
|
+
var markerPresenceCache, markerResolutionCache, resolvedMarkerFree, evaluatorResolvedData;
|
|
4661
4690
|
var init_resolve_render_bindings = __esm({
|
|
4662
4691
|
"lib/resolve-render-bindings.ts"() {
|
|
4663
4692
|
"use client";
|
|
4664
4693
|
markerPresenceCache = /* @__PURE__ */ new WeakMap();
|
|
4694
|
+
markerResolutionCache = /* @__PURE__ */ new WeakMap();
|
|
4695
|
+
resolvedMarkerFree = /* @__PURE__ */ new WeakSet();
|
|
4696
|
+
evaluatorResolvedData = /* @__PURE__ */ new WeakSet();
|
|
4665
4697
|
}
|
|
4666
4698
|
});
|
|
4667
4699
|
function getCurrentIconFamily() {
|
|
@@ -15266,6 +15298,19 @@ var init_molecules = __esm({
|
|
|
15266
15298
|
init_puzzleObject();
|
|
15267
15299
|
}
|
|
15268
15300
|
});
|
|
15301
|
+
var profilerOnRender;
|
|
15302
|
+
var init_perf = __esm({
|
|
15303
|
+
"lib/perf.ts"() {
|
|
15304
|
+
profilerOnRender = (id, phase, actualDuration, baseDuration, _startTime, commitTime) => {
|
|
15305
|
+
pushPerfEntry({
|
|
15306
|
+
name: `profiler:${id}:${phase}`,
|
|
15307
|
+
durationMs: actualDuration,
|
|
15308
|
+
ts: commitTime,
|
|
15309
|
+
detail: { baseDuration }
|
|
15310
|
+
});
|
|
15311
|
+
};
|
|
15312
|
+
}
|
|
15313
|
+
});
|
|
15269
15314
|
function themeBodyFont(el) {
|
|
15270
15315
|
if (typeof getComputedStyle !== "function") return "system-ui, sans-serif";
|
|
15271
15316
|
const v = getComputedStyle(el).getPropertyValue("--font-family-body").trim();
|
|
@@ -15614,6 +15659,7 @@ var init_LearningCanvas = __esm({
|
|
|
15614
15659
|
"components/learning/atoms/LearningCanvas.tsx"() {
|
|
15615
15660
|
"use client";
|
|
15616
15661
|
init_cn();
|
|
15662
|
+
init_perf();
|
|
15617
15663
|
init_useEventBus();
|
|
15618
15664
|
DASH_PATTERNS = { dashed: [6, 4], dotted: [2, 3] };
|
|
15619
15665
|
TRACE_SERIES_COLORS = ["#2563eb", "#dc2626", "#16a34a", "#f59e0b"];
|
|
@@ -15657,6 +15703,7 @@ var init_LearningCanvas = __esm({
|
|
|
15657
15703
|
return [...shapes, ...traceOut, ...readoutOut];
|
|
15658
15704
|
}, [shapes, traces, readouts, width, height]);
|
|
15659
15705
|
const draw = useCallback(() => {
|
|
15706
|
+
const _perfT = perfStart("learningcanvas:paint");
|
|
15660
15707
|
const canvas = canvasRef.current;
|
|
15661
15708
|
if (!canvas) return;
|
|
15662
15709
|
const ctx = canvas.getContext("2d");
|
|
@@ -15678,6 +15725,7 @@ var init_LearningCanvas = __esm({
|
|
|
15678
15725
|
for (const shape of derivedShapes) {
|
|
15679
15726
|
if (shape.type === "text") drawShape(ctx, shape, width, height, derivedShapes);
|
|
15680
15727
|
}
|
|
15728
|
+
perfEnd("learningcanvas:paint", _perfT);
|
|
15681
15729
|
}, [width, height, backgroundColor, derivedShapes]);
|
|
15682
15730
|
useEffect(() => {
|
|
15683
15731
|
draw();
|
|
@@ -28764,8 +28812,8 @@ function DataGrid({
|
|
|
28764
28812
|
}
|
|
28765
28813
|
return /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "items-center", children: [
|
|
28766
28814
|
field.icon && renderIconInput(field.icon, { size: "xs", className: "text-muted-foreground" }),
|
|
28767
|
-
/* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", children: (field.label ?? fieldLabel2(field.name)) + ":" }),
|
|
28768
|
-
/* @__PURE__ */ jsx(Typography, { variant: "small", children: formatValue(value, field.format) })
|
|
28815
|
+
/* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", className: "sr-only", children: (field.label ?? fieldLabel2(field.name)) + ":" }),
|
|
28816
|
+
/* @__PURE__ */ jsx(Typography, { variant: "small", color: "secondary", children: formatValue(value, field.format) })
|
|
28769
28817
|
] }, field.name);
|
|
28770
28818
|
}) })
|
|
28771
28819
|
] }) })
|
|
@@ -29193,7 +29241,11 @@ function DataList({
|
|
|
29193
29241
|
Box,
|
|
29194
29242
|
{
|
|
29195
29243
|
className: cn(
|
|
29196
|
-
|
|
29244
|
+
// items-start, not items-center: a multi-line row (title + meta +
|
|
29245
|
+
// progress) centred its action cluster in the vertical middle, so
|
|
29246
|
+
// the buttons floated between the meta fields instead of anchoring
|
|
29247
|
+
// to the title they act on (U-DATALIST-ACTIONS-FLOAT-MID-ROW).
|
|
29248
|
+
"group flex items-start gap-4 transition-all duration-fast",
|
|
29197
29249
|
isCompact ? "px-4 py-2" : "px-6 py-4",
|
|
29198
29250
|
"hover:bg-muted/80",
|
|
29199
29251
|
!isCard && !isCompact && "rounded-lg border border-transparent hover:border-border"
|
|
@@ -29224,11 +29276,19 @@ function DataList({
|
|
|
29224
29276
|
if (value === void 0 || value === null || value === "") return null;
|
|
29225
29277
|
return /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "items-center", children: [
|
|
29226
29278
|
field.icon && renderIconInput2(field.icon, { size: "xs", className: "text-muted-foreground" }),
|
|
29227
|
-
/* @__PURE__ */ jsxs(
|
|
29228
|
-
|
|
29229
|
-
|
|
29230
|
-
|
|
29231
|
-
|
|
29279
|
+
/* @__PURE__ */ jsxs(
|
|
29280
|
+
Typography,
|
|
29281
|
+
{
|
|
29282
|
+
variant: "caption",
|
|
29283
|
+
color: "secondary",
|
|
29284
|
+
className: cn(field.format !== "boolean" && "sr-only"),
|
|
29285
|
+
children: [
|
|
29286
|
+
field.label ?? fieldLabel3(field.name),
|
|
29287
|
+
":"
|
|
29288
|
+
]
|
|
29289
|
+
}
|
|
29290
|
+
),
|
|
29291
|
+
/* @__PURE__ */ jsx(Typography, { variant: "small", color: "secondary", children: formatValue2(value, field.format, { yes: t("common.yes"), no: t("common.no") }) })
|
|
29232
29292
|
] }, field.name);
|
|
29233
29293
|
}) }),
|
|
29234
29294
|
progressFields.map((field) => {
|
|
@@ -29247,7 +29307,7 @@ function DataList({
|
|
|
29247
29307
|
]
|
|
29248
29308
|
}
|
|
29249
29309
|
),
|
|
29250
|
-
isCard && !isLast && /* @__PURE__ */ jsx(Box, { className: "
|
|
29310
|
+
(isCard || isCompact) && !isLast && /* @__PURE__ */ jsx(Box, { className: cn("border-b border-border/40", isCompact ? "mx-4" : "mx-6") })
|
|
29251
29311
|
] }, id)
|
|
29252
29312
|
);
|
|
29253
29313
|
};
|
|
@@ -29257,7 +29317,13 @@ function DataList({
|
|
|
29257
29317
|
{
|
|
29258
29318
|
className: cn(
|
|
29259
29319
|
isCard && "bg-card rounded-xl border border-border shadow-elevation-dialog overflow-hidden",
|
|
29260
|
-
|
|
29320
|
+
// `gap-*` is inert on a block container, and Box only emits a display
|
|
29321
|
+
// class when its `display` prop is set — so every non-card list had
|
|
29322
|
+
// been asking for a gap that CSS silently dropped. flex-col makes it
|
|
29323
|
+
// real. `compact` keeps gap-0 on purpose: it separates with the row
|
|
29324
|
+
// divider above instead, never both (Almadar_UI_Beauty.md 6).
|
|
29325
|
+
!isCard && "flex flex-col",
|
|
29326
|
+
!isCard && !isCompact && gapClass,
|
|
29261
29327
|
listLookStyles[look],
|
|
29262
29328
|
className
|
|
29263
29329
|
),
|
|
@@ -32872,6 +32938,7 @@ var init_MathCanvas = __esm({
|
|
|
32872
32938
|
"components/learning/molecules/MathCanvas.tsx"() {
|
|
32873
32939
|
"use client";
|
|
32874
32940
|
init_useEventBus();
|
|
32941
|
+
init_perf();
|
|
32875
32942
|
init_atoms();
|
|
32876
32943
|
init_Stack();
|
|
32877
32944
|
init_LearningCanvas();
|
|
@@ -32937,6 +33004,7 @@ var init_MathCanvas = __esm({
|
|
|
32937
33004
|
};
|
|
32938
33005
|
}, [stableKeyMap, stableKeyUpMap, eventBus]);
|
|
32939
33006
|
const derivedShapes = useMemo(() => {
|
|
33007
|
+
const _perfT = perfStart("mathcanvas:derive");
|
|
32940
33008
|
const out = [];
|
|
32941
33009
|
const margin = 24;
|
|
32942
33010
|
const plotW = width - margin * 2;
|
|
@@ -33180,6 +33248,7 @@ var init_MathCanvas = __esm({
|
|
|
33180
33248
|
}
|
|
33181
33249
|
}
|
|
33182
33250
|
out.push(...shapes);
|
|
33251
|
+
perfEnd("mathcanvas:derive", _perfT);
|
|
33183
33252
|
return out;
|
|
33184
33253
|
}, [
|
|
33185
33254
|
width,
|
|
@@ -39533,7 +39602,7 @@ var init_RichBlockEditor = __esm({
|
|
|
39533
39602
|
{
|
|
39534
39603
|
variant: "bordered",
|
|
39535
39604
|
padding: "none",
|
|
39536
|
-
className: cn("flex flex-col", className),
|
|
39605
|
+
className: cn("flex flex-col text-card-foreground", className),
|
|
39537
39606
|
children: [
|
|
39538
39607
|
enableBlocks && showToolbar && !readOnly && /* @__PURE__ */ jsx(
|
|
39539
39608
|
Box,
|
|
@@ -44352,6 +44421,7 @@ var init_DetailPanel = __esm({
|
|
|
44352
44421
|
"use client";
|
|
44353
44422
|
init_atoms();
|
|
44354
44423
|
init_Box();
|
|
44424
|
+
init_Input();
|
|
44355
44425
|
init_Stack();
|
|
44356
44426
|
init_SimpleGrid();
|
|
44357
44427
|
init_Menu();
|
|
@@ -44367,6 +44437,7 @@ var init_DetailPanel = __esm({
|
|
|
44367
44437
|
ReactMarkdown2 = lazy(() => import('react-markdown'));
|
|
44368
44438
|
DetailPanel = ({
|
|
44369
44439
|
title: propTitle,
|
|
44440
|
+
onTitleCommit,
|
|
44370
44441
|
subtitle,
|
|
44371
44442
|
status,
|
|
44372
44443
|
avatar,
|
|
@@ -44388,6 +44459,7 @@ var init_DetailPanel = __esm({
|
|
|
44388
44459
|
}) => {
|
|
44389
44460
|
const eventBus = useEventBus();
|
|
44390
44461
|
const { t } = useTranslate();
|
|
44462
|
+
const [titleDraft, setTitleDraft] = React94__default.useState(null);
|
|
44391
44463
|
const isFieldDefArray = (arr) => {
|
|
44392
44464
|
if (!arr || arr.length === 0) return false;
|
|
44393
44465
|
const first = arr[0];
|
|
@@ -44608,6 +44680,50 @@ var init_DetailPanel = __esm({
|
|
|
44608
44680
|
}),
|
|
44609
44681
|
status && /* @__PURE__ */ jsx(Badge, { variant: status.variant ?? "default", children: status.label })
|
|
44610
44682
|
] });
|
|
44683
|
+
const commitTitle = () => {
|
|
44684
|
+
if (!onTitleCommit) return;
|
|
44685
|
+
const next = (titleDraft ?? "").trim();
|
|
44686
|
+
setTitleDraft(null);
|
|
44687
|
+
if (!next || next === title) return;
|
|
44688
|
+
onTitleCommit(next, normalizedData?.id !== void 0 ? String(normalizedData.id) : "");
|
|
44689
|
+
};
|
|
44690
|
+
const titleNode = onTitleCommit && titleDraft !== null ? /* @__PURE__ */ jsx(
|
|
44691
|
+
Input,
|
|
44692
|
+
{
|
|
44693
|
+
value: titleDraft,
|
|
44694
|
+
autoFocus: true,
|
|
44695
|
+
"aria-label": t("common.title"),
|
|
44696
|
+
className: "h-auto py-1 text-3xl font-bold tracking-tight",
|
|
44697
|
+
onChange: (e) => setTitleDraft(e.target.value),
|
|
44698
|
+
onBlur: commitTitle,
|
|
44699
|
+
onKeyDown: (e) => {
|
|
44700
|
+
if (e.key === "Enter") {
|
|
44701
|
+
e.preventDefault();
|
|
44702
|
+
commitTitle();
|
|
44703
|
+
} else if (e.key === "Escape") {
|
|
44704
|
+
e.preventDefault();
|
|
44705
|
+
setTitleDraft(null);
|
|
44706
|
+
}
|
|
44707
|
+
},
|
|
44708
|
+
"data-testid": "detail-title-input"
|
|
44709
|
+
}
|
|
44710
|
+
) : onTitleCommit ? /* @__PURE__ */ jsx(
|
|
44711
|
+
Box,
|
|
44712
|
+
{
|
|
44713
|
+
role: "button",
|
|
44714
|
+
tabIndex: 0,
|
|
44715
|
+
className: "cursor-text rounded px-1 -mx-1 transition-colors hover:bg-muted/40",
|
|
44716
|
+
onClick: () => setTitleDraft(title ?? ""),
|
|
44717
|
+
onKeyDown: (e) => {
|
|
44718
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
44719
|
+
e.preventDefault();
|
|
44720
|
+
setTitleDraft(title ?? "");
|
|
44721
|
+
}
|
|
44722
|
+
},
|
|
44723
|
+
"data-testid": "detail-title-editable",
|
|
44724
|
+
children: /* @__PURE__ */ jsx(Typography, { variant: "h2", weight: "bold", children: title || "Details" })
|
|
44725
|
+
}
|
|
44726
|
+
) : /* @__PURE__ */ jsx(Typography, { variant: "h2", weight: "bold", children: title || "Details" });
|
|
44611
44727
|
const content = /* @__PURE__ */ jsx(Card, { variant: "elevated", children: /* @__PURE__ */ jsxs(VStack, { gap: "md", className: "p-6", children: [
|
|
44612
44728
|
/* @__PURE__ */ jsxs(HStack, { justify: "between", align: "start", gap: "md", children: [
|
|
44613
44729
|
/* @__PURE__ */ jsxs(HStack, { align: "start", gap: "sm", className: "min-w-0", children: [
|
|
@@ -44627,7 +44743,7 @@ var init_DetailPanel = __esm({
|
|
|
44627
44743
|
avatar,
|
|
44628
44744
|
/* @__PURE__ */ jsxs(VStack, { gap: "xs", className: "min-w-0", children: [
|
|
44629
44745
|
/* @__PURE__ */ jsxs(HStack, { align: "center", gap: "sm", wrap: true, children: [
|
|
44630
|
-
|
|
44746
|
+
titleNode,
|
|
44631
44747
|
statusBadges
|
|
44632
44748
|
] }),
|
|
44633
44749
|
subtitle && /* @__PURE__ */ jsx(Typography, { variant: "body", color: "secondary", children: subtitle })
|
|
@@ -44727,16 +44843,11 @@ var init_DetailPanel = __esm({
|
|
|
44727
44843
|
footer
|
|
44728
44844
|
] })
|
|
44729
44845
|
] }) });
|
|
44730
|
-
|
|
44731
|
-
Box,
|
|
44732
|
-
|
|
44733
|
-
|
|
44734
|
-
|
|
44735
|
-
className
|
|
44736
|
-
),
|
|
44737
|
-
children: content
|
|
44738
|
-
}
|
|
44739
|
-
);
|
|
44846
|
+
if (!slideOver) {
|
|
44847
|
+
return /* @__PURE__ */ jsx(Box, { className, children: content });
|
|
44848
|
+
}
|
|
44849
|
+
const panel = /* @__PURE__ */ jsx(Box, { className: cn("fixed inset-y-0 right-0 w-full max-w-2xl bg-card shadow-lg z-50 overflow-y-auto p-6", className), children: content });
|
|
44850
|
+
return typeof document === "undefined" ? panel : createPortal(panel, document.body);
|
|
44740
44851
|
};
|
|
44741
44852
|
DetailPanel.displayName = "DetailPanel";
|
|
44742
44853
|
}
|
|
@@ -45188,7 +45299,7 @@ var init_Form = __esm({
|
|
|
45188
45299
|
});
|
|
45189
45300
|
debug(
|
|
45190
45301
|
"forms",
|
|
45191
|
-
`Calculation triggered: ${calc.variableName} = ${value}`
|
|
45302
|
+
`Calculation triggered: ${calc.variableName} = ${String(value)}`
|
|
45192
45303
|
);
|
|
45193
45304
|
}
|
|
45194
45305
|
});
|
|
@@ -51687,6 +51798,7 @@ function isPlainConfigObject(value) {
|
|
|
51687
51798
|
return proto === Object.prototype || proto === null;
|
|
51688
51799
|
}
|
|
51689
51800
|
function subtreeHasTraitRef(value) {
|
|
51801
|
+
if (isEvaluatorResolvedData(value)) return false;
|
|
51690
51802
|
const cached = traitRefPresenceCache.get(value);
|
|
51691
51803
|
if (cached !== void 0) return cached;
|
|
51692
51804
|
let found = false;
|
|
@@ -51759,6 +51871,10 @@ function renderPatternProps(props, onDismiss, propsSchema) {
|
|
|
51759
51871
|
};
|
|
51760
51872
|
rendered[key] = /* @__PURE__ */ jsx(SlotContentRenderer, { content: childContent, onDismiss });
|
|
51761
51873
|
} else if (Array.isArray(value)) {
|
|
51874
|
+
if (!isEvaluatorResolvedData(value) && value.some((el) => isPatternConfig(el))) ; else if (!subtreeHasTraitRef(value)) {
|
|
51875
|
+
rendered[key] = value;
|
|
51876
|
+
continue;
|
|
51877
|
+
}
|
|
51762
51878
|
const isDataArray = propsSchema?.[key]?.items?.types?.includes("object") ?? false;
|
|
51763
51879
|
rendered[key] = value.map((item, i) => {
|
|
51764
51880
|
const el = item;
|
|
@@ -55785,6 +55901,7 @@ function enqueueEvent(queue, entry) {
|
|
|
55785
55901
|
}
|
|
55786
55902
|
|
|
55787
55903
|
// hooks/useTraitStateMachine.ts
|
|
55904
|
+
init_perf();
|
|
55788
55905
|
init_traitRegistry();
|
|
55789
55906
|
init_verificationRegistry();
|
|
55790
55907
|
var crossTraitLog = createLogger("almadar:ui:cross-trait");
|
|
@@ -56471,6 +56588,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
56471
56588
|
}, [eventBus]);
|
|
56472
56589
|
useEffect(() => {
|
|
56473
56590
|
const scheduler = createTickScheduler();
|
|
56591
|
+
const timedTick = (key, fn) => () => perfTimeAsync(key, fn);
|
|
56474
56592
|
const pureWriterTickKeys = /* @__PURE__ */ new Set();
|
|
56475
56593
|
for (const group of sharedGroups.values()) {
|
|
56476
56594
|
const ticksByInterval = /* @__PURE__ */ new Map();
|
|
@@ -56487,12 +56605,12 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
56487
56605
|
}
|
|
56488
56606
|
for (const entries of ticksByInterval.values()) {
|
|
56489
56607
|
const interval = entries[0].tick.interval;
|
|
56490
|
-
const onDue = () => {
|
|
56608
|
+
const onDue = timedTick(`tick:shared:${group.storeKey}@${String(interval)}`, () => {
|
|
56491
56609
|
const writers = entries.map(
|
|
56492
56610
|
({ binding, tick }) => createSharedEntityWriter(binding, tick, traitStatesRef, emitFromSharedWriter)
|
|
56493
56611
|
);
|
|
56494
56612
|
runTickFrame(group.storeKey, writers, sharedEntityStore);
|
|
56495
|
-
};
|
|
56613
|
+
});
|
|
56496
56614
|
if (interval === "frame") {
|
|
56497
56615
|
scheduler.add(0, onDue);
|
|
56498
56616
|
} else if (typeof interval === "number") {
|
|
@@ -56510,14 +56628,15 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
56510
56628
|
if (sharedKey !== void 0 && pureWriterTickKeys.has(`${binding.trait.name}::${tick.name}`)) {
|
|
56511
56629
|
continue;
|
|
56512
56630
|
}
|
|
56631
|
+
const tickKey = `tick:${binding.trait.name}::${tick.name}`;
|
|
56513
56632
|
if (tick.interval === "frame") {
|
|
56514
|
-
scheduler.add(0, () => runTickEffects(tick, binding));
|
|
56633
|
+
scheduler.add(0, timedTick(tickKey, () => runTickEffects(tick, binding)));
|
|
56515
56634
|
} else if (typeof tick.interval === "number") {
|
|
56516
|
-
scheduler.add(tick.interval, () => runTickEffects(tick, binding));
|
|
56635
|
+
scheduler.add(tick.interval, timedTick(tickKey, () => runTickEffects(tick, binding)));
|
|
56517
56636
|
} else if (isValidCronExpression(tick.interval)) {
|
|
56518
|
-
scheduler.addCron(tick.interval, () => runTickEffects(tick, binding));
|
|
56637
|
+
scheduler.addCron(tick.interval, timedTick(tickKey, () => runTickEffects(tick, binding)));
|
|
56519
56638
|
} else {
|
|
56520
|
-
scheduler.add(parseDurationString(tick.interval), () => runTickEffects(tick, binding));
|
|
56639
|
+
scheduler.add(parseDurationString(tick.interval), timedTick(tickKey, () => runTickEffects(tick, binding)));
|
|
56521
56640
|
}
|
|
56522
56641
|
}
|
|
56523
56642
|
}
|
|
@@ -56525,6 +56644,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
56525
56644
|
}, [traitBindings, runTickEffects, sharedGroups, sharedEntityStore, emitFromSharedWriter]);
|
|
56526
56645
|
const processEventQueued = useCallback(async (eventKey, payload, targetTrait, tick, sourceTrait) => {
|
|
56527
56646
|
const normalizedEvent = normalizeEventKey(eventKey);
|
|
56647
|
+
const _perfT0 = perfStart("processEvent:total");
|
|
56528
56648
|
const bindings = traitBindingsRef.current;
|
|
56529
56649
|
const currentManager = managerRef.current;
|
|
56530
56650
|
crossTraitLog.debug("processEvent:enter", () => ({
|
|
@@ -56548,6 +56668,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
56548
56668
|
entityByTrait[name] = { ...sharedEntityStore.getSnapshot(sharedKey) };
|
|
56549
56669
|
}
|
|
56550
56670
|
}
|
|
56671
|
+
const _perfT1 = perfStart("processEvent:guardMatch");
|
|
56551
56672
|
const results = currentManager.sendEvent(
|
|
56552
56673
|
normalizedEvent,
|
|
56553
56674
|
payload,
|
|
@@ -56556,6 +56677,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
56556
56677
|
void 0,
|
|
56557
56678
|
targetTrait
|
|
56558
56679
|
);
|
|
56680
|
+
perfEnd("processEvent:guardMatch", _perfT1);
|
|
56559
56681
|
crossTraitLog.debug("processEvent:results", {
|
|
56560
56682
|
event: normalizedEvent,
|
|
56561
56683
|
executedCount: results.length,
|
|
@@ -56605,6 +56727,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
56605
56727
|
transition: `${result.previousState} -> ${result.newState}`,
|
|
56606
56728
|
effects: JSON.stringify(result.effects)
|
|
56607
56729
|
}));
|
|
56730
|
+
const _perfT2 = perfStart("processEvent:executeAll");
|
|
56608
56731
|
const emittedDuringExec = await executeTransitionEffects({
|
|
56609
56732
|
binding,
|
|
56610
56733
|
// upstream gap: /runtime TransitionResult.effects is unknown[] — they are SExpr at runtime (see Almadar_UI_Gaps.md)
|
|
@@ -56616,6 +56739,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
56616
56739
|
syncOnly: false,
|
|
56617
56740
|
log: stateLog
|
|
56618
56741
|
});
|
|
56742
|
+
perfEnd("processEvent:executeAll", _perfT2);
|
|
56619
56743
|
emittedByTrait.set(traitName, emittedDuringExec);
|
|
56620
56744
|
for (const emittedKey of emittedDuringExec) {
|
|
56621
56745
|
bridgeEchoPendingRef.current.set(
|
|
@@ -56712,27 +56836,31 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
56712
56836
|
if (orbital) dispatchedOrbitals.add(orbital);
|
|
56713
56837
|
}
|
|
56714
56838
|
const relayPayload = targetTrait !== void 0 ? { ...payload ?? {}, _targetTrait: targetTrait } : payload;
|
|
56715
|
-
|
|
56716
|
-
void onEventProcessed(normalizedEvent, relayPayload, dispatchedOrbitals, tick, sourceTrait);
|
|
56717
|
-
} else {
|
|
56718
|
-
await onEventProcessed(normalizedEvent, relayPayload, dispatchedOrbitals);
|
|
56719
|
-
}
|
|
56839
|
+
void onEventProcessed(normalizedEvent, relayPayload, dispatchedOrbitals, tick, sourceTrait);
|
|
56720
56840
|
}
|
|
56841
|
+
perfEnd("processEvent:total", _perfT0);
|
|
56842
|
+
perfEnd(`event:${normalizedEvent}`, _perfT0);
|
|
56721
56843
|
}, [entities, eventBus, sharedEntityStore]);
|
|
56722
56844
|
const drainEventQueue = useCallback(async () => {
|
|
56723
56845
|
if (processingRef.current) return;
|
|
56724
56846
|
processingRef.current = true;
|
|
56847
|
+
const _perfT = perfStart("drain:pass");
|
|
56848
|
+
let _perfN = 0;
|
|
56725
56849
|
try {
|
|
56726
56850
|
while (eventQueueRef.current.length > 0) {
|
|
56727
56851
|
const entry = eventQueueRef.current.shift();
|
|
56852
|
+
_perfN++;
|
|
56728
56853
|
await processEventQueued(entry.eventKey, entry.payload, entry.targetTrait, entry.tick, entry.sourceTrait);
|
|
56729
56854
|
}
|
|
56730
56855
|
} finally {
|
|
56731
56856
|
processingRef.current = false;
|
|
56857
|
+
perfEnd("drain:pass", _perfT);
|
|
56858
|
+
perfGauge("drain:passEntries", _perfN);
|
|
56732
56859
|
}
|
|
56733
56860
|
}, [processEventQueued]);
|
|
56734
56861
|
const enqueueAndDrain = useCallback((eventKey, payload, targetTrait, tick, sourceTrait) => {
|
|
56735
56862
|
enqueueEvent(eventQueueRef.current, { eventKey, payload, targetTrait, tick, sourceTrait });
|
|
56863
|
+
perfGauge("queue:depthAtEnqueue", eventQueueRef.current.length);
|
|
56736
56864
|
void drainEventQueue();
|
|
56737
56865
|
}, [drainEventQueue]);
|
|
56738
56866
|
useCallback((eventKey, payload) => {
|
|
@@ -57031,7 +57159,7 @@ function TraitInitializer({ traits: traits2, routeParams, orbitalNames, onNaviga
|
|
|
57031
57159
|
[serverActiveTraits]
|
|
57032
57160
|
);
|
|
57033
57161
|
const uiSlots = useUISlots();
|
|
57034
|
-
const onEventProcessed = useCallback(
|
|
57162
|
+
const onEventProcessed = useCallback((event, payload, dispatchedOrbitals, tick, sourceTrait) => {
|
|
57035
57163
|
if (!bridge.connected || !orbitalNames?.length) return;
|
|
57036
57164
|
const targets = dispatchedOrbitals && dispatchedOrbitals.size > 0 ? orbitalNames.filter((n) => dispatchedOrbitals.has(n)) : orbitalNames;
|
|
57037
57165
|
xOrbitalLog.debug("TraitInitializer:fanout", () => ({
|
|
@@ -57045,9 +57173,10 @@ function TraitInitializer({ traits: traits2, routeParams, orbitalNames, onNaviga
|
|
|
57045
57173
|
void bridge.sendEvent(name, event, withActiveTraits(payload), tick, sourceTrait);
|
|
57046
57174
|
continue;
|
|
57047
57175
|
}
|
|
57048
|
-
|
|
57049
|
-
|
|
57050
|
-
|
|
57176
|
+
void bridge.sendEvent(name, event, withActiveTraits(payload)).then(({ effects, meta }) => {
|
|
57177
|
+
recordServerResponse(name, event, meta);
|
|
57178
|
+
applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits, activeTraitNames, onNavigateBack);
|
|
57179
|
+
});
|
|
57051
57180
|
}
|
|
57052
57181
|
}, [bridge.connected, bridge.sendEvent, orbitalNames, uiSlots, onNavigate, onNavigateBack, embeddedTraits, activeTraitNames, withActiveTraits]);
|
|
57053
57182
|
const opts = orbitalNames ? { onEventProcessed, navigate: onNavigate, navigateBack: onNavigateBack, traitConfigsByName, orbitalsByTrait, embeddedTraits, initPayload: routeParams } : { navigate: onNavigate, navigateBack: onNavigateBack, persistence, traitConfigsByName, orbitalsByTrait, embeddedTraits, initPayload: routeParams };
|
|
@@ -57365,14 +57494,15 @@ function OrbPreview({
|
|
|
57365
57494
|
return pattern.replace(/:([A-Za-z0-9_]+)/g, (whole, key) => routeParams[key] ?? whole);
|
|
57366
57495
|
}, [currentPagePath, routeParams]);
|
|
57367
57496
|
const navStackRef = useRef(null);
|
|
57368
|
-
const handleNavigate = useCallback((path) => {
|
|
57497
|
+
const handleNavigate = useCallback((path, navState) => {
|
|
57369
57498
|
const hit = matchPathAmong(pages, path, (entry) => entry.page.path);
|
|
57370
57499
|
const match = hit?.candidate;
|
|
57371
|
-
const params = hit?.params ?? {};
|
|
57500
|
+
const params = { ...hit?.params ?? {}, ...navState ?? {} };
|
|
57372
57501
|
navLog.debug("handleNavigate", () => ({
|
|
57373
57502
|
path,
|
|
57374
57503
|
matched: match?.page.name ?? null,
|
|
57375
57504
|
params,
|
|
57505
|
+
navState: navState ? JSON.stringify(navState) : void 0,
|
|
57376
57506
|
availablePaths: pages.map((p) => p.page.path)
|
|
57377
57507
|
}));
|
|
57378
57508
|
if (match?.page.name) {
|
|
@@ -57387,9 +57517,9 @@ function OrbPreview({
|
|
|
57387
57517
|
}
|
|
57388
57518
|
}, [pages]);
|
|
57389
57519
|
const handleNavigateEffect = useCallback(
|
|
57390
|
-
(path,
|
|
57520
|
+
(path, params, crumb) => {
|
|
57391
57521
|
navStackRef.current?.beginNavigate(path, crumb);
|
|
57392
|
-
handleNavigate(path);
|
|
57522
|
+
handleNavigate(path, params);
|
|
57393
57523
|
},
|
|
57394
57524
|
[handleNavigate]
|
|
57395
57525
|
);
|
|
@@ -59706,14 +59836,7 @@ TraitCardNode.displayName = "TraitCardNode";
|
|
|
59706
59836
|
|
|
59707
59837
|
// components/avl/organisms/FlowCanvas.tsx
|
|
59708
59838
|
init_useEventBus();
|
|
59709
|
-
|
|
59710
|
-
pushPerfEntry({
|
|
59711
|
-
name: `profiler:${id}:${phase}`,
|
|
59712
|
-
durationMs: actualDuration,
|
|
59713
|
-
ts: commitTime,
|
|
59714
|
-
detail: { baseDuration }
|
|
59715
|
-
});
|
|
59716
|
-
};
|
|
59839
|
+
init_perf();
|
|
59717
59840
|
var flowCanvasLog = createLogger("almadar:ui:flow-canvas");
|
|
59718
59841
|
var NODE_TYPES = {
|
|
59719
59842
|
preview: OrbPreviewNode,
|