@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/providers/index.cjs
CHANGED
|
@@ -360,7 +360,16 @@ function isPlainObject(value) {
|
|
|
360
360
|
if (typeof value === "function") return false;
|
|
361
361
|
return true;
|
|
362
362
|
}
|
|
363
|
+
function isEvaluatorResolvedData(value) {
|
|
364
|
+
return evaluatorResolvedData.has(value);
|
|
365
|
+
}
|
|
366
|
+
function brandResolved(value) {
|
|
367
|
+
if (value !== null && typeof value === "object" && !React87__namespace.default.isValidElement(value) && !(value instanceof Date)) {
|
|
368
|
+
resolvedMarkerFree.add(value);
|
|
369
|
+
}
|
|
370
|
+
}
|
|
363
371
|
function subtreeHasMarker(value) {
|
|
372
|
+
if (resolvedMarkerFree.has(value)) return false;
|
|
364
373
|
const cached = markerPresenceCache.get(value);
|
|
365
374
|
if (cached !== void 0) return cached;
|
|
366
375
|
let found = false;
|
|
@@ -382,10 +391,23 @@ function subtreeHasMarker(value) {
|
|
|
382
391
|
}
|
|
383
392
|
function walkValue(value, scopeTrait, entity, config, state) {
|
|
384
393
|
if (core.isRenderBindingMarker(value)) {
|
|
385
|
-
|
|
394
|
+
const cached = markerResolutionCache.get(value);
|
|
395
|
+
if (cached !== void 0 && cached.entity === entity && cached.config === config && cached.state === state) {
|
|
396
|
+
return { resolved: cached.resolved, changed: false };
|
|
397
|
+
}
|
|
398
|
+
const resolved = resolveMarkerExpression(value.expression, entity, config, state);
|
|
399
|
+
markerResolutionCache.set(value, { entity, config, state, resolved });
|
|
400
|
+
if (resolved !== null && typeof resolved === "object" && !React87__namespace.default.isValidElement(resolved) && !(resolved instanceof Date)) {
|
|
401
|
+
resolvedMarkerFree.add(resolved);
|
|
402
|
+
evaluatorResolvedData.add(resolved);
|
|
403
|
+
}
|
|
404
|
+
return { resolved, changed: true };
|
|
386
405
|
}
|
|
387
406
|
if (Array.isArray(value)) {
|
|
388
|
-
if (!subtreeHasMarker(value))
|
|
407
|
+
if (!subtreeHasMarker(value)) {
|
|
408
|
+
brandResolved(value);
|
|
409
|
+
return { resolved: value, changed: false };
|
|
410
|
+
}
|
|
389
411
|
const out = [];
|
|
390
412
|
let changed = false;
|
|
391
413
|
for (const item of value) {
|
|
@@ -400,10 +422,14 @@ function walkValue(value, scopeTrait, entity, config, state) {
|
|
|
400
422
|
out.push(resolved);
|
|
401
423
|
if (itemChanged) changed = true;
|
|
402
424
|
}
|
|
425
|
+
brandResolved(out);
|
|
403
426
|
return changed ? { resolved: out, changed: true } : { resolved: value, changed: false };
|
|
404
427
|
}
|
|
405
428
|
if (isPlainObject(value)) {
|
|
406
|
-
if (!subtreeHasMarker(value))
|
|
429
|
+
if (!subtreeHasMarker(value)) {
|
|
430
|
+
brandResolved(value);
|
|
431
|
+
return { resolved: value, changed: false };
|
|
432
|
+
}
|
|
407
433
|
const sourceTrait = value._sourceTrait;
|
|
408
434
|
if (typeof sourceTrait === "string" && sourceTrait !== scopeTrait) {
|
|
409
435
|
return { resolved: value, changed: false };
|
|
@@ -415,11 +441,13 @@ function walkValue(value, scopeTrait, entity, config, state) {
|
|
|
415
441
|
out[key] = resolved;
|
|
416
442
|
if (itemChanged) changed = true;
|
|
417
443
|
}
|
|
444
|
+
brandResolved(out);
|
|
418
445
|
return changed ? { resolved: out, changed: true } : { resolved: value, changed: false };
|
|
419
446
|
}
|
|
420
447
|
return { resolved: value, changed: false };
|
|
421
448
|
}
|
|
422
449
|
function resolveRenderBindingMarkers(props, scopeTrait, entity, config, state) {
|
|
450
|
+
if (resolvedMarkerFree.has(props)) return props;
|
|
423
451
|
const out = {};
|
|
424
452
|
let changed = false;
|
|
425
453
|
for (const [key, value] of Object.entries(props)) {
|
|
@@ -427,13 +455,17 @@ function resolveRenderBindingMarkers(props, scopeTrait, entity, config, state) {
|
|
|
427
455
|
out[key] = resolved;
|
|
428
456
|
if (propChanged) changed = true;
|
|
429
457
|
}
|
|
458
|
+
brandResolved(out);
|
|
430
459
|
return changed ? out : props;
|
|
431
460
|
}
|
|
432
|
-
var markerPresenceCache;
|
|
461
|
+
var markerPresenceCache, markerResolutionCache, resolvedMarkerFree, evaluatorResolvedData;
|
|
433
462
|
var init_resolve_render_bindings = __esm({
|
|
434
463
|
"lib/resolve-render-bindings.ts"() {
|
|
435
464
|
"use client";
|
|
436
465
|
markerPresenceCache = /* @__PURE__ */ new WeakMap();
|
|
466
|
+
markerResolutionCache = /* @__PURE__ */ new WeakMap();
|
|
467
|
+
resolvedMarkerFree = /* @__PURE__ */ new WeakSet();
|
|
468
|
+
evaluatorResolvedData = /* @__PURE__ */ new WeakSet();
|
|
437
469
|
}
|
|
438
470
|
});
|
|
439
471
|
function cn(...inputs) {
|
|
@@ -11867,6 +11899,10 @@ var init_molecules = __esm({
|
|
|
11867
11899
|
init_puzzleObject();
|
|
11868
11900
|
}
|
|
11869
11901
|
});
|
|
11902
|
+
var init_perf = __esm({
|
|
11903
|
+
"lib/perf.ts"() {
|
|
11904
|
+
}
|
|
11905
|
+
});
|
|
11870
11906
|
function themeBodyFont(el) {
|
|
11871
11907
|
if (typeof getComputedStyle !== "function") return "system-ui, sans-serif";
|
|
11872
11908
|
const v = getComputedStyle(el).getPropertyValue("--font-family-body").trim();
|
|
@@ -12215,6 +12251,7 @@ var init_LearningCanvas = __esm({
|
|
|
12215
12251
|
"components/learning/atoms/LearningCanvas.tsx"() {
|
|
12216
12252
|
"use client";
|
|
12217
12253
|
init_cn();
|
|
12254
|
+
init_perf();
|
|
12218
12255
|
init_useEventBus();
|
|
12219
12256
|
DASH_PATTERNS = { dashed: [6, 4], dotted: [2, 3] };
|
|
12220
12257
|
TRACE_SERIES_COLORS = ["#2563eb", "#dc2626", "#16a34a", "#f59e0b"];
|
|
@@ -12258,6 +12295,7 @@ var init_LearningCanvas = __esm({
|
|
|
12258
12295
|
return [...shapes, ...traceOut, ...readoutOut];
|
|
12259
12296
|
}, [shapes, traces, readouts, width, height]);
|
|
12260
12297
|
const draw = React87.useCallback(() => {
|
|
12298
|
+
const _perfT = ui.perfStart("learningcanvas:paint");
|
|
12261
12299
|
const canvas = canvasRef.current;
|
|
12262
12300
|
if (!canvas) return;
|
|
12263
12301
|
const ctx = canvas.getContext("2d");
|
|
@@ -12279,6 +12317,7 @@ var init_LearningCanvas = __esm({
|
|
|
12279
12317
|
for (const shape of derivedShapes) {
|
|
12280
12318
|
if (shape.type === "text") drawShape(ctx, shape, width, height, derivedShapes);
|
|
12281
12319
|
}
|
|
12320
|
+
ui.perfEnd("learningcanvas:paint", _perfT);
|
|
12282
12321
|
}, [width, height, backgroundColor, derivedShapes]);
|
|
12283
12322
|
React87.useEffect(() => {
|
|
12284
12323
|
draw();
|
|
@@ -26575,8 +26614,8 @@ function DataGrid({
|
|
|
26575
26614
|
}
|
|
26576
26615
|
return /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "xs", className: "items-center", children: [
|
|
26577
26616
|
field.icon && renderIconInput(field.icon, { size: "xs", className: "text-muted-foreground" }),
|
|
26578
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "caption", color: "secondary", children: (field.label ?? fieldLabel2(field.name)) + ":" }),
|
|
26579
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", children: formatValue(value, field.format) })
|
|
26617
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "caption", color: "secondary", className: "sr-only", children: (field.label ?? fieldLabel2(field.name)) + ":" }),
|
|
26618
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", color: "secondary", children: formatValue(value, field.format) })
|
|
26580
26619
|
] }, field.name);
|
|
26581
26620
|
}) })
|
|
26582
26621
|
] }) })
|
|
@@ -27004,7 +27043,11 @@ function DataList({
|
|
|
27004
27043
|
Box,
|
|
27005
27044
|
{
|
|
27006
27045
|
className: cn(
|
|
27007
|
-
|
|
27046
|
+
// items-start, not items-center: a multi-line row (title + meta +
|
|
27047
|
+
// progress) centred its action cluster in the vertical middle, so
|
|
27048
|
+
// the buttons floated between the meta fields instead of anchoring
|
|
27049
|
+
// to the title they act on (U-DATALIST-ACTIONS-FLOAT-MID-ROW).
|
|
27050
|
+
"group flex items-start gap-4 transition-all duration-fast",
|
|
27008
27051
|
isCompact ? "px-4 py-2" : "px-6 py-4",
|
|
27009
27052
|
"hover:bg-muted/80",
|
|
27010
27053
|
!isCard && !isCompact && "rounded-lg border border-transparent hover:border-border"
|
|
@@ -27035,11 +27078,19 @@ function DataList({
|
|
|
27035
27078
|
if (value === void 0 || value === null || value === "") return null;
|
|
27036
27079
|
return /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "xs", className: "items-center", children: [
|
|
27037
27080
|
field.icon && renderIconInput2(field.icon, { size: "xs", className: "text-muted-foreground" }),
|
|
27038
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
27039
|
-
|
|
27040
|
-
|
|
27041
|
-
|
|
27042
|
-
|
|
27081
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
27082
|
+
Typography,
|
|
27083
|
+
{
|
|
27084
|
+
variant: "caption",
|
|
27085
|
+
color: "secondary",
|
|
27086
|
+
className: cn(field.format !== "boolean" && "sr-only"),
|
|
27087
|
+
children: [
|
|
27088
|
+
field.label ?? fieldLabel3(field.name),
|
|
27089
|
+
":"
|
|
27090
|
+
]
|
|
27091
|
+
}
|
|
27092
|
+
),
|
|
27093
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", color: "secondary", children: formatValue2(value, field.format, { yes: t("common.yes"), no: t("common.no") }) })
|
|
27043
27094
|
] }, field.name);
|
|
27044
27095
|
}) }),
|
|
27045
27096
|
progressFields.map((field) => {
|
|
@@ -27058,7 +27109,7 @@ function DataList({
|
|
|
27058
27109
|
]
|
|
27059
27110
|
}
|
|
27060
27111
|
),
|
|
27061
|
-
isCard && !isLast && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "
|
|
27112
|
+
(isCard || isCompact) && !isLast && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: cn("border-b border-border/40", isCompact ? "mx-4" : "mx-6") })
|
|
27062
27113
|
] }, id)
|
|
27063
27114
|
);
|
|
27064
27115
|
};
|
|
@@ -27068,7 +27119,13 @@ function DataList({
|
|
|
27068
27119
|
{
|
|
27069
27120
|
className: cn(
|
|
27070
27121
|
isCard && "bg-card rounded-xl border border-border shadow-elevation-dialog overflow-hidden",
|
|
27071
|
-
|
|
27122
|
+
// `gap-*` is inert on a block container, and Box only emits a display
|
|
27123
|
+
// class when its `display` prop is set — so every non-card list had
|
|
27124
|
+
// been asking for a gap that CSS silently dropped. flex-col makes it
|
|
27125
|
+
// real. `compact` keeps gap-0 on purpose: it separates with the row
|
|
27126
|
+
// divider above instead, never both (Almadar_UI_Beauty.md 6).
|
|
27127
|
+
!isCard && "flex flex-col",
|
|
27128
|
+
!isCard && !isCompact && gapClass,
|
|
27072
27129
|
listLookStyles[look],
|
|
27073
27130
|
className
|
|
27074
27131
|
),
|
|
@@ -30683,6 +30740,7 @@ var init_MathCanvas = __esm({
|
|
|
30683
30740
|
"components/learning/molecules/MathCanvas.tsx"() {
|
|
30684
30741
|
"use client";
|
|
30685
30742
|
init_useEventBus();
|
|
30743
|
+
init_perf();
|
|
30686
30744
|
init_atoms();
|
|
30687
30745
|
init_Stack();
|
|
30688
30746
|
init_LearningCanvas();
|
|
@@ -30748,6 +30806,7 @@ var init_MathCanvas = __esm({
|
|
|
30748
30806
|
};
|
|
30749
30807
|
}, [stableKeyMap, stableKeyUpMap, eventBus]);
|
|
30750
30808
|
const derivedShapes = React87.useMemo(() => {
|
|
30809
|
+
const _perfT = ui.perfStart("mathcanvas:derive");
|
|
30751
30810
|
const out = [];
|
|
30752
30811
|
const margin = 24;
|
|
30753
30812
|
const plotW = width - margin * 2;
|
|
@@ -30991,6 +31050,7 @@ var init_MathCanvas = __esm({
|
|
|
30991
31050
|
}
|
|
30992
31051
|
}
|
|
30993
31052
|
out.push(...shapes);
|
|
31053
|
+
ui.perfEnd("mathcanvas:derive", _perfT);
|
|
30994
31054
|
return out;
|
|
30995
31055
|
}, [
|
|
30996
31056
|
width,
|
|
@@ -32254,12 +32314,12 @@ var init_MapView = __esm({
|
|
|
32254
32314
|
shadowSize: [41, 41]
|
|
32255
32315
|
});
|
|
32256
32316
|
L.Marker.prototype.options.icon = defaultIcon;
|
|
32257
|
-
const { useEffect: useEffect67, useRef:
|
|
32317
|
+
const { useEffect: useEffect67, useRef: useRef65, useCallback: useCallback97, useState: useState95 } = React87__namespace.default;
|
|
32258
32318
|
const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
|
|
32259
32319
|
const { useEventBus: useEventBus2 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
|
|
32260
32320
|
function MapUpdater({ centerLat, centerLng, zoom }) {
|
|
32261
32321
|
const map = useMap();
|
|
32262
|
-
const prevRef =
|
|
32322
|
+
const prevRef = useRef65({ centerLat, centerLng, zoom });
|
|
32263
32323
|
useEffect67(() => {
|
|
32264
32324
|
const prev = prevRef.current;
|
|
32265
32325
|
if (prev.centerLat !== centerLat || prev.centerLng !== centerLng || prev.zoom !== zoom) {
|
|
@@ -37344,7 +37404,7 @@ var init_RichBlockEditor = __esm({
|
|
|
37344
37404
|
{
|
|
37345
37405
|
variant: "bordered",
|
|
37346
37406
|
padding: "none",
|
|
37347
|
-
className: cn("flex flex-col", className),
|
|
37407
|
+
className: cn("flex flex-col text-card-foreground", className),
|
|
37348
37408
|
children: [
|
|
37349
37409
|
enableBlocks && showToolbar && !readOnly && /* @__PURE__ */ jsxRuntime.jsx(
|
|
37350
37410
|
Box,
|
|
@@ -42572,6 +42632,7 @@ var init_DetailPanel = __esm({
|
|
|
42572
42632
|
"use client";
|
|
42573
42633
|
init_atoms();
|
|
42574
42634
|
init_Box();
|
|
42635
|
+
init_Input();
|
|
42575
42636
|
init_Stack();
|
|
42576
42637
|
init_SimpleGrid();
|
|
42577
42638
|
init_Menu();
|
|
@@ -42587,6 +42648,7 @@ var init_DetailPanel = __esm({
|
|
|
42587
42648
|
ReactMarkdown2 = React87.lazy(() => import('react-markdown'));
|
|
42588
42649
|
DetailPanel = ({
|
|
42589
42650
|
title: propTitle,
|
|
42651
|
+
onTitleCommit,
|
|
42590
42652
|
subtitle,
|
|
42591
42653
|
status,
|
|
42592
42654
|
avatar,
|
|
@@ -42608,6 +42670,7 @@ var init_DetailPanel = __esm({
|
|
|
42608
42670
|
}) => {
|
|
42609
42671
|
const eventBus = useEventBus();
|
|
42610
42672
|
const { t } = hooks.useTranslate();
|
|
42673
|
+
const [titleDraft, setTitleDraft] = React87__namespace.default.useState(null);
|
|
42611
42674
|
const isFieldDefArray = (arr) => {
|
|
42612
42675
|
if (!arr || arr.length === 0) return false;
|
|
42613
42676
|
const first = arr[0];
|
|
@@ -42828,6 +42891,50 @@ var init_DetailPanel = __esm({
|
|
|
42828
42891
|
}),
|
|
42829
42892
|
status && /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: status.variant ?? "default", children: status.label })
|
|
42830
42893
|
] });
|
|
42894
|
+
const commitTitle = () => {
|
|
42895
|
+
if (!onTitleCommit) return;
|
|
42896
|
+
const next = (titleDraft ?? "").trim();
|
|
42897
|
+
setTitleDraft(null);
|
|
42898
|
+
if (!next || next === title) return;
|
|
42899
|
+
onTitleCommit(next, normalizedData?.id !== void 0 ? String(normalizedData.id) : "");
|
|
42900
|
+
};
|
|
42901
|
+
const titleNode = onTitleCommit && titleDraft !== null ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
42902
|
+
Input,
|
|
42903
|
+
{
|
|
42904
|
+
value: titleDraft,
|
|
42905
|
+
autoFocus: true,
|
|
42906
|
+
"aria-label": t("common.title"),
|
|
42907
|
+
className: "h-auto py-1 text-3xl font-bold tracking-tight",
|
|
42908
|
+
onChange: (e) => setTitleDraft(e.target.value),
|
|
42909
|
+
onBlur: commitTitle,
|
|
42910
|
+
onKeyDown: (e) => {
|
|
42911
|
+
if (e.key === "Enter") {
|
|
42912
|
+
e.preventDefault();
|
|
42913
|
+
commitTitle();
|
|
42914
|
+
} else if (e.key === "Escape") {
|
|
42915
|
+
e.preventDefault();
|
|
42916
|
+
setTitleDraft(null);
|
|
42917
|
+
}
|
|
42918
|
+
},
|
|
42919
|
+
"data-testid": "detail-title-input"
|
|
42920
|
+
}
|
|
42921
|
+
) : onTitleCommit ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
42922
|
+
Box,
|
|
42923
|
+
{
|
|
42924
|
+
role: "button",
|
|
42925
|
+
tabIndex: 0,
|
|
42926
|
+
className: "cursor-text rounded px-1 -mx-1 transition-colors hover:bg-muted/40",
|
|
42927
|
+
onClick: () => setTitleDraft(title ?? ""),
|
|
42928
|
+
onKeyDown: (e) => {
|
|
42929
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
42930
|
+
e.preventDefault();
|
|
42931
|
+
setTitleDraft(title ?? "");
|
|
42932
|
+
}
|
|
42933
|
+
},
|
|
42934
|
+
"data-testid": "detail-title-editable",
|
|
42935
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "h2", weight: "bold", children: title || "Details" })
|
|
42936
|
+
}
|
|
42937
|
+
) : /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "h2", weight: "bold", children: title || "Details" });
|
|
42831
42938
|
const content = /* @__PURE__ */ jsxRuntime.jsx(Card, { variant: "elevated", children: /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "md", className: "p-6", children: [
|
|
42832
42939
|
/* @__PURE__ */ jsxRuntime.jsxs(HStack, { justify: "between", align: "start", gap: "md", children: [
|
|
42833
42940
|
/* @__PURE__ */ jsxRuntime.jsxs(HStack, { align: "start", gap: "sm", className: "min-w-0", children: [
|
|
@@ -42847,7 +42954,7 @@ var init_DetailPanel = __esm({
|
|
|
42847
42954
|
avatar,
|
|
42848
42955
|
/* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "xs", className: "min-w-0", children: [
|
|
42849
42956
|
/* @__PURE__ */ jsxRuntime.jsxs(HStack, { align: "center", gap: "sm", wrap: true, children: [
|
|
42850
|
-
|
|
42957
|
+
titleNode,
|
|
42851
42958
|
statusBadges
|
|
42852
42959
|
] }),
|
|
42853
42960
|
subtitle && /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", color: "secondary", children: subtitle })
|
|
@@ -42947,16 +43054,11 @@ var init_DetailPanel = __esm({
|
|
|
42947
43054
|
footer
|
|
42948
43055
|
] })
|
|
42949
43056
|
] }) });
|
|
42950
|
-
|
|
42951
|
-
Box,
|
|
42952
|
-
|
|
42953
|
-
|
|
42954
|
-
|
|
42955
|
-
className
|
|
42956
|
-
),
|
|
42957
|
-
children: content
|
|
42958
|
-
}
|
|
42959
|
-
);
|
|
43057
|
+
if (!slideOver) {
|
|
43058
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Box, { className, children: content });
|
|
43059
|
+
}
|
|
43060
|
+
const panel = /* @__PURE__ */ jsxRuntime.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 });
|
|
43061
|
+
return typeof document === "undefined" ? panel : reactDom.createPortal(panel, document.body);
|
|
42960
43062
|
};
|
|
42961
43063
|
DetailPanel.displayName = "DetailPanel";
|
|
42962
43064
|
}
|
|
@@ -43408,7 +43510,7 @@ var init_Form = __esm({
|
|
|
43408
43510
|
});
|
|
43409
43511
|
debug(
|
|
43410
43512
|
"forms",
|
|
43411
|
-
`Calculation triggered: ${calc.variableName} = ${value}`
|
|
43513
|
+
`Calculation triggered: ${calc.variableName} = ${String(value)}`
|
|
43412
43514
|
);
|
|
43413
43515
|
}
|
|
43414
43516
|
});
|
|
@@ -49888,6 +49990,7 @@ function isPlainConfigObject(value) {
|
|
|
49888
49990
|
return proto === Object.prototype || proto === null;
|
|
49889
49991
|
}
|
|
49890
49992
|
function subtreeHasTraitRef(value) {
|
|
49993
|
+
if (isEvaluatorResolvedData(value)) return false;
|
|
49891
49994
|
const cached = traitRefPresenceCache.get(value);
|
|
49892
49995
|
if (cached !== void 0) return cached;
|
|
49893
49996
|
let found = false;
|
|
@@ -49960,6 +50063,10 @@ function renderPatternProps(props, onDismiss, propsSchema) {
|
|
|
49960
50063
|
};
|
|
49961
50064
|
rendered[key] = /* @__PURE__ */ jsxRuntime.jsx(SlotContentRenderer, { content: childContent, onDismiss });
|
|
49962
50065
|
} else if (Array.isArray(value)) {
|
|
50066
|
+
if (!isEvaluatorResolvedData(value) && value.some((el) => isPatternConfig(el))) ; else if (!subtreeHasTraitRef(value)) {
|
|
50067
|
+
rendered[key] = value;
|
|
50068
|
+
continue;
|
|
50069
|
+
}
|
|
49963
50070
|
const isDataArray = propsSchema?.[key]?.items?.types?.includes("object") ?? false;
|
|
49964
50071
|
rendered[key] = value.map((item, i) => {
|
|
49965
50072
|
const el = item;
|
|
@@ -51401,6 +51508,53 @@ function useNavigationId2() {
|
|
|
51401
51508
|
|
|
51402
51509
|
// providers/ServerBridge.tsx
|
|
51403
51510
|
init_useEventBus();
|
|
51511
|
+
|
|
51512
|
+
// lib/tick-send-relay.ts
|
|
51513
|
+
function createTickSendRelay(send) {
|
|
51514
|
+
const lanes = /* @__PURE__ */ new Map();
|
|
51515
|
+
const flush = (key, lane) => {
|
|
51516
|
+
const next = lane.pending;
|
|
51517
|
+
lane.pending = void 0;
|
|
51518
|
+
if (next === void 0) {
|
|
51519
|
+
lane.inFlight = false;
|
|
51520
|
+
return;
|
|
51521
|
+
}
|
|
51522
|
+
lane.inFlight = true;
|
|
51523
|
+
void send(key, next).catch(() => void 0).then(() => flush(key, lane));
|
|
51524
|
+
};
|
|
51525
|
+
return {
|
|
51526
|
+
send(key, value) {
|
|
51527
|
+
const lane = lanes.get(key) ?? { inFlight: false };
|
|
51528
|
+
lanes.set(key, lane);
|
|
51529
|
+
if (lane.inFlight) {
|
|
51530
|
+
lane.pending = value;
|
|
51531
|
+
return;
|
|
51532
|
+
}
|
|
51533
|
+
lane.pending = value;
|
|
51534
|
+
flush(key, lane);
|
|
51535
|
+
},
|
|
51536
|
+
clear() {
|
|
51537
|
+
for (const lane of lanes.values()) {
|
|
51538
|
+
lane.pending = void 0;
|
|
51539
|
+
}
|
|
51540
|
+
}
|
|
51541
|
+
};
|
|
51542
|
+
}
|
|
51543
|
+
|
|
51544
|
+
// lib/command-send-pump.ts
|
|
51545
|
+
function createCommandSendPump() {
|
|
51546
|
+
let tail = Promise.resolve();
|
|
51547
|
+
return {
|
|
51548
|
+
enqueue(job) {
|
|
51549
|
+
const result = tail.then(job);
|
|
51550
|
+
tail = result.then(
|
|
51551
|
+
() => void 0,
|
|
51552
|
+
() => void 0
|
|
51553
|
+
);
|
|
51554
|
+
return result;
|
|
51555
|
+
}
|
|
51556
|
+
};
|
|
51557
|
+
}
|
|
51404
51558
|
var xOrbitalLog = logger.createLogger("almadar:runtime:cross-orbital");
|
|
51405
51559
|
var serverBridgeLog = logger.createLogger("almadar:ui:server-bridge");
|
|
51406
51560
|
function reEmitServerEvent(eventBus, emitted, origin) {
|
|
@@ -51535,99 +51689,118 @@ function ServerBridgeProvider({
|
|
|
51535
51689
|
async () => transport.unregister(),
|
|
51536
51690
|
[transport]
|
|
51537
51691
|
);
|
|
51692
|
+
const tickRelay = React87.useMemo(
|
|
51693
|
+
() => createTickSendRelay(async (_key, snap) => {
|
|
51694
|
+
await transport.sendEvent(snap.orbitalName, snap.event, snap.payload, getTabClientId(), snap.tick, snap.sourceTrait);
|
|
51695
|
+
}),
|
|
51696
|
+
[transport]
|
|
51697
|
+
);
|
|
51698
|
+
React87.useEffect(() => () => tickRelay.clear(), [tickRelay]);
|
|
51699
|
+
const commandPump = React87.useMemo(createCommandSendPump, []);
|
|
51700
|
+
const disposedRef = React87.useRef(false);
|
|
51701
|
+
React87.useEffect(() => {
|
|
51702
|
+
disposedRef.current = false;
|
|
51703
|
+
return () => {
|
|
51704
|
+
disposedRef.current = true;
|
|
51705
|
+
};
|
|
51706
|
+
}, []);
|
|
51538
51707
|
const sendEvent = React87.useCallback(async (orbitalName, event, payload, tick, sourceTrait) => {
|
|
51539
51708
|
const emptyMeta = { success: false, clientEffects: 0, dataEntities: {}, emittedEvents: [] };
|
|
51540
51709
|
if (!connected) return { effects: [], meta: emptyMeta };
|
|
51541
|
-
|
|
51542
|
-
|
|
51543
|
-
|
|
51544
|
-
|
|
51545
|
-
|
|
51546
|
-
}
|
|
51547
|
-
|
|
51548
|
-
|
|
51549
|
-
|
|
51550
|
-
|
|
51551
|
-
|
|
51552
|
-
|
|
51553
|
-
|
|
51554
|
-
|
|
51555
|
-
|
|
51556
|
-
|
|
51557
|
-
|
|
51558
|
-
|
|
51559
|
-
|
|
51560
|
-
|
|
51561
|
-
|
|
51562
|
-
|
|
51563
|
-
|
|
51564
|
-
const
|
|
51565
|
-
|
|
51566
|
-
|
|
51567
|
-
const
|
|
51568
|
-
|
|
51569
|
-
|
|
51570
|
-
|
|
51571
|
-
|
|
51572
|
-
|
|
51573
|
-
|
|
51574
|
-
|
|
51575
|
-
|
|
51576
|
-
|
|
51577
|
-
|
|
51578
|
-
|
|
51579
|
-
|
|
51580
|
-
|
|
51581
|
-
|
|
51582
|
-
|
|
51583
|
-
|
|
51584
|
-
|
|
51585
|
-
|
|
51586
|
-
|
|
51587
|
-
|
|
51588
|
-
|
|
51589
|
-
|
|
51590
|
-
|
|
51591
|
-
|
|
51592
|
-
|
|
51593
|
-
|
|
51594
|
-
|
|
51595
|
-
|
|
51596
|
-
|
|
51597
|
-
|
|
51598
|
-
|
|
51599
|
-
|
|
51600
|
-
|
|
51601
|
-
|
|
51710
|
+
if (tick !== void 0) {
|
|
51711
|
+
tickRelay.send(`${orbitalName}:${event}`, { orbitalName, event, payload, tick, sourceTrait });
|
|
51712
|
+
return { effects: [], meta: { ...emptyMeta, success: true } };
|
|
51713
|
+
}
|
|
51714
|
+
return commandPump.enqueue(async () => {
|
|
51715
|
+
if (disposedRef.current) return { effects: [], meta: emptyMeta };
|
|
51716
|
+
try {
|
|
51717
|
+
const result = await transport.sendEvent(orbitalName, event, payload, getTabClientId(), tick, sourceTrait);
|
|
51718
|
+
const effects = [];
|
|
51719
|
+
const responseData = result.data || {};
|
|
51720
|
+
const dataEntities = {};
|
|
51721
|
+
for (const [entityName, records] of Object.entries(responseData)) {
|
|
51722
|
+
dataEntities[entityName] = Array.isArray(records) ? records.length : 0;
|
|
51723
|
+
}
|
|
51724
|
+
const meta = {
|
|
51725
|
+
success: !!result.success,
|
|
51726
|
+
clientEffects: result.clientEffects?.length ?? 0,
|
|
51727
|
+
dataEntities,
|
|
51728
|
+
data: responseData,
|
|
51729
|
+
emittedEvents: result.emittedEvents?.map((e) => e.event) ?? [],
|
|
51730
|
+
error: result.error
|
|
51731
|
+
};
|
|
51732
|
+
if (result.success) {
|
|
51733
|
+
const tagged = result.clientEffectsByTrait;
|
|
51734
|
+
const tuples = tagged ? tagged.map((entry) => ({ effect: entry.effect, traitName: entry.traitName })) : (result.clientEffects ?? []).map((eff) => ({ effect: eff }));
|
|
51735
|
+
for (const { effect, traitName } of tuples) {
|
|
51736
|
+
const effectType = effect[0];
|
|
51737
|
+
if (effectType === "render-ui") {
|
|
51738
|
+
const slot = effect[1];
|
|
51739
|
+
const pattern = effect[2];
|
|
51740
|
+
effects.push({
|
|
51741
|
+
type: "render-ui",
|
|
51742
|
+
slot,
|
|
51743
|
+
pattern: pattern !== null && typeof pattern === "object" ? pattern : void 0,
|
|
51744
|
+
traitName
|
|
51745
|
+
});
|
|
51746
|
+
} else if (effectType === "navigate") {
|
|
51747
|
+
const route = effect[1];
|
|
51748
|
+
const rawParams = effect[2];
|
|
51749
|
+
const rawOptions = effect[3];
|
|
51750
|
+
const optionsObj = rawOptions !== null && rawOptions !== void 0 && typeof rawOptions === "object" && !Array.isArray(rawOptions) ? rawOptions : void 0;
|
|
51751
|
+
const crumb = typeof optionsObj?.crumb === "string" ? optionsObj.crumb : void 0;
|
|
51752
|
+
effects.push({
|
|
51753
|
+
type: "navigate",
|
|
51754
|
+
route,
|
|
51755
|
+
params: rawParams !== null && rawParams !== void 0 && typeof rawParams === "object" && !Array.isArray(rawParams) ? rawParams : void 0,
|
|
51756
|
+
crumb,
|
|
51757
|
+
traitName
|
|
51758
|
+
});
|
|
51759
|
+
} else if (effectType === "navigate-back") {
|
|
51760
|
+
effects.push({ type: "navigate-back", traitName });
|
|
51761
|
+
} else if (effectType === "notify") {
|
|
51762
|
+
const message = effect[1];
|
|
51763
|
+
effects.push({ type: "notify", message: typeof message === "string" ? message : void 0, traitName });
|
|
51764
|
+
}
|
|
51765
|
+
}
|
|
51766
|
+
if (result.emittedEvents) {
|
|
51767
|
+
for (const emitted of result.emittedEvents) {
|
|
51768
|
+
if (emitted.event === event) continue;
|
|
51769
|
+
reEmitServerEvent(
|
|
51770
|
+
eventBus,
|
|
51771
|
+
{ ...emitted, source: { ...emitted.source, dispatched: true } },
|
|
51772
|
+
orbitalName
|
|
51773
|
+
);
|
|
51774
|
+
}
|
|
51602
51775
|
}
|
|
51776
|
+
} else if (result.error) {
|
|
51777
|
+
xOrbitalLog.warn("response:fail", {
|
|
51778
|
+
orbital: orbitalName,
|
|
51779
|
+
event,
|
|
51780
|
+
error: result.error
|
|
51781
|
+
});
|
|
51603
51782
|
}
|
|
51604
|
-
|
|
51605
|
-
|
|
51606
|
-
|
|
51607
|
-
|
|
51608
|
-
|
|
51609
|
-
|
|
51610
|
-
|
|
51611
|
-
|
|
51612
|
-
|
|
51613
|
-
|
|
51614
|
-
|
|
51615
|
-
|
|
51616
|
-
|
|
51617
|
-
|
|
51618
|
-
|
|
51619
|
-
|
|
51620
|
-
}
|
|
51621
|
-
|
|
51622
|
-
xOrbitalLog.error("response:network", {
|
|
51623
|
-
orbital: orbitalName,
|
|
51624
|
-
event,
|
|
51625
|
-
error: msg
|
|
51626
|
-
});
|
|
51783
|
+
return { effects, meta };
|
|
51784
|
+
} catch (err) {
|
|
51785
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
51786
|
+
if (err instanceof TypeError) {
|
|
51787
|
+
xOrbitalLog.warn("response:network", {
|
|
51788
|
+
orbital: orbitalName,
|
|
51789
|
+
event,
|
|
51790
|
+
error: msg,
|
|
51791
|
+
reason: "peer endpoint unreachable (expected in standalone single-orbital mode)"
|
|
51792
|
+
});
|
|
51793
|
+
} else {
|
|
51794
|
+
xOrbitalLog.error("response:network", {
|
|
51795
|
+
orbital: orbitalName,
|
|
51796
|
+
event,
|
|
51797
|
+
error: msg
|
|
51798
|
+
});
|
|
51799
|
+
}
|
|
51800
|
+
return { effects: [], meta: { ...emptyMeta, error: msg } };
|
|
51627
51801
|
}
|
|
51628
|
-
|
|
51629
|
-
|
|
51630
|
-
}, [connected, transport, eventBus]);
|
|
51802
|
+
});
|
|
51803
|
+
}, [connected, transport, eventBus, tickRelay, commandPump]);
|
|
51631
51804
|
React87.useEffect(() => {
|
|
51632
51805
|
if (!schema) return;
|
|
51633
51806
|
let cancelled = false;
|
|
@@ -3,7 +3,7 @@ import { EntityRow, SExpr } from '@almadar/core';
|
|
|
3
3
|
export { ANONYMOUS_USER } from '@almadar/core';
|
|
4
4
|
import { U as UIThemeDefinition, j as UserData } from '../UserContext-g_LcDiGN.cjs';
|
|
5
5
|
export { a as CurrentPagePathContext, b as CurrentPagePathProvider, c as CurrentPagePathProviderProps, d as DesignThemeProvider, O as OrbitalThemeProvider, e as OrbitalThemeProviderProps, h as UserContext, i as UserContextValue, k as UserProvider, l as UserProviderProps, u as useCurrentPagePath, m as useDesignTheme, n as useHasPermission, o as useHasRole, q as useUser, r as useUserForEvaluation } from '../UserContext-g_LcDiGN.cjs';
|
|
6
|
-
export {
|
|
6
|
+
export { o as EntityBindingContext, E as EntityBindingSource, a as EntitySchemaContextValue, b as EntitySchemaProvider, c as EntitySchemaProviderProps, p as SendEventResult, d as ServerBridgeContextValue, e as ServerBridgeProvider, q as ServerBridgeProviderProps, S as ServerBridgeTransport, f as ServerClientEffect, r as ServerResponseMeta, T as TraitContext, g as TraitContextValue, h as TraitInstance, i as TraitProvider, j as TraitProviderProps, s as useEntityBindingSnapshot, u as useEntitySchema, k as useEntitySchemaOptional, l as useServerBridge, m as useTrait, n as useTraitContext } from '../EntityBindingContext-0Evn_LcT.cjs';
|
|
7
7
|
import { j as UseOfflineExecutorResult, U as UseOfflineExecutorOptions } from '../offline-executor-QUdKOj7f.cjs';
|
|
8
8
|
export { c as NavigationContextValue, d as NavigationProvider, e as NavigationProviderProps, f as NavigationState, k as comparePathSpecificity, m as extractRouteParams, n as findPageByName, o as findPageByPath, p as getAllPages, q as getDefaultPage, r as matchPath, s as matchPathAmong, t as pathMatches, u as useActivePage, v as useInitPayload, w as useNavigateTo, x as useNavigation, y as useNavigationId, z as useNavigationState } from '../offline-executor-QUdKOj7f.cjs';
|
|
9
9
|
import { E as EventBusContextType } from '../event-bus-types-Bl78kokd.cjs';
|