@almadar/ui 5.121.3 → 5.121.4
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/avl/index.cjs +330 -67
- package/dist/avl/index.js +332 -69
- package/dist/components/index.cjs +159 -45
- package/dist/components/index.d.cts +25 -5
- package/dist/components/index.d.ts +25 -5
- package/dist/components/index.js +159 -47
- package/dist/hooks/index.cjs +31 -10
- package/dist/hooks/index.d.cts +17 -1
- package/dist/hooks/index.d.ts +17 -1
- package/dist/hooks/index.js +31 -12
- package/dist/lib/drawable/three/index.cjs +19 -10
- package/dist/lib/drawable/three/index.js +20 -11
- package/dist/lib/index.cjs +41 -13
- package/dist/lib/index.js +41 -13
- package/dist/marketing/index.cjs +29 -14
- package/dist/marketing/index.js +29 -14
- package/dist/providers/index.cjs +204 -63
- package/dist/providers/index.d.cts +33 -4
- package/dist/providers/index.d.ts +33 -4
- package/dist/providers/index.js +204 -64
- package/dist/runtime/index.cjs +330 -67
- package/dist/runtime/index.d.cts +0 -14
- package/dist/runtime/index.d.ts +0 -14
- package/dist/runtime/index.js +333 -70
- package/package.json +2 -2
- package/tailwind-preset.cjs +56 -0
- package/themes/_base.css +19 -0
package/dist/avl/index.cjs
CHANGED
|
@@ -3271,9 +3271,9 @@ function getGlobalEventBus() {
|
|
|
3271
3271
|
function useEventBus() {
|
|
3272
3272
|
const context = React90.useContext(providers.EventBusContext);
|
|
3273
3273
|
const baseBus = context ?? getGlobalEventBus() ?? fallbackEventBus;
|
|
3274
|
-
const
|
|
3274
|
+
const chain = providers.useTraitScopeChain();
|
|
3275
3275
|
return React90.useMemo(() => {
|
|
3276
|
-
if (
|
|
3276
|
+
if (chain.length === 0) {
|
|
3277
3277
|
return {
|
|
3278
3278
|
...baseBus,
|
|
3279
3279
|
emit: (type, payload, source) => {
|
|
@@ -3289,22 +3289,31 @@ function useEventBus() {
|
|
|
3289
3289
|
emit: (type, payload, source) => {
|
|
3290
3290
|
if (typeof type === "string" && type.startsWith("UI:")) {
|
|
3291
3291
|
const tail = type.slice(3);
|
|
3292
|
-
const
|
|
3293
|
-
|
|
3294
|
-
|
|
3292
|
+
const isQualified = tail.includes(".");
|
|
3293
|
+
const event = isQualified ? tail.split(".").slice(2).join(".") : tail;
|
|
3294
|
+
if (!event) {
|
|
3295
|
+
baseBus.emit(type, payload, source);
|
|
3296
|
+
return;
|
|
3297
|
+
}
|
|
3298
|
+
const keys = /* @__PURE__ */ new Set();
|
|
3299
|
+
if (isQualified) keys.add(type);
|
|
3300
|
+
for (const sc of chain) {
|
|
3301
|
+
keys.add(`UI:${sc.orbital}.${sc.trait}.${event}`);
|
|
3302
|
+
}
|
|
3303
|
+
if (keys.size > 1) {
|
|
3304
|
+
scopeLog.info("emit:fan-out", {
|
|
3295
3305
|
from: type,
|
|
3296
|
-
|
|
3297
|
-
|
|
3298
|
-
scopeTrait: scope.trait
|
|
3306
|
+
keys: Array.from(keys),
|
|
3307
|
+
chainDepth: chain.length
|
|
3299
3308
|
});
|
|
3300
3309
|
}
|
|
3301
|
-
baseBus.emit(
|
|
3310
|
+
for (const key of keys) baseBus.emit(key, payload, source);
|
|
3302
3311
|
return;
|
|
3303
3312
|
}
|
|
3304
3313
|
baseBus.emit(type, payload, source);
|
|
3305
3314
|
}
|
|
3306
3315
|
};
|
|
3307
|
-
}, [baseBus,
|
|
3316
|
+
}, [baseBus, chain]);
|
|
3308
3317
|
}
|
|
3309
3318
|
function useEventListener(event, handler) {
|
|
3310
3319
|
const eventBus = useEventBus();
|
|
@@ -4661,13 +4670,13 @@ var init_Icon = __esm({
|
|
|
4661
4670
|
style
|
|
4662
4671
|
}) => {
|
|
4663
4672
|
const directIcon = typeof icon === "string" ? void 0 : icon;
|
|
4664
|
-
const effectiveName = typeof icon === "string" ? icon : name;
|
|
4673
|
+
const effectiveName = typeof icon === "string" && icon !== "" ? icon : name;
|
|
4674
|
+
const effectiveStrokeWidth = strokeWidth != null && strokeWidth > 0 ? strokeWidth : void 0;
|
|
4665
4675
|
const family = useIconFamily();
|
|
4666
4676
|
const RenderedComponent = React90__namespace.default.useMemo(() => {
|
|
4667
4677
|
if (directIcon) return null;
|
|
4668
4678
|
return effectiveName ? resolveIconForFamily(effectiveName) : null;
|
|
4669
4679
|
}, [directIcon, effectiveName, family]);
|
|
4670
|
-
const effectiveStrokeWidth = strokeWidth ?? void 0;
|
|
4671
4680
|
const inlineStyle = {
|
|
4672
4681
|
...effectiveStrokeWidth === void 0 ? { strokeWidth: "var(--icon-stroke-width, 2)" } : {},
|
|
4673
4682
|
...style
|
|
@@ -5149,6 +5158,15 @@ var init_Modal = __esm({
|
|
|
5149
5158
|
const [dragY, setDragY] = React90.useState(0);
|
|
5150
5159
|
const dragStartY = React90.useRef(0);
|
|
5151
5160
|
const isDragging = React90.useRef(false);
|
|
5161
|
+
const [closing, setClosing] = React90.useState(false);
|
|
5162
|
+
const wasOpenRef = React90.useRef(isOpen);
|
|
5163
|
+
React90.useEffect(() => {
|
|
5164
|
+
if (wasOpenRef.current && !isOpen) setClosing(true);
|
|
5165
|
+
wasOpenRef.current = isOpen;
|
|
5166
|
+
}, [isOpen]);
|
|
5167
|
+
const handleAnimEnd = (e) => {
|
|
5168
|
+
if (closing && e.target === e.currentTarget) setClosing(false);
|
|
5169
|
+
};
|
|
5152
5170
|
React90.useEffect(() => {
|
|
5153
5171
|
if (isOpen) {
|
|
5154
5172
|
previousActiveElement.current = document.activeElement;
|
|
@@ -5182,7 +5200,11 @@ var init_Modal = __esm({
|
|
|
5182
5200
|
document.body.style.overflow = "";
|
|
5183
5201
|
};
|
|
5184
5202
|
}, [isOpen]);
|
|
5185
|
-
if (
|
|
5203
|
+
if (typeof document === "undefined") return null;
|
|
5204
|
+
const renderOpen = isOpen || closing;
|
|
5205
|
+
if (!renderOpen) return null;
|
|
5206
|
+
const dialogAnim = closing ? "animate-modal-out" : "animate-modal-in";
|
|
5207
|
+
const overlayAnim = closing ? "animate-overlay-out" : "animate-overlay-in";
|
|
5186
5208
|
const handleClose = () => {
|
|
5187
5209
|
if (closeEvent) eventBus.emit(`UI:${closeEvent}`, {});
|
|
5188
5210
|
onClose();
|
|
@@ -5199,7 +5221,8 @@ var init_Modal = __esm({
|
|
|
5199
5221
|
className: cn(
|
|
5200
5222
|
"fixed inset-0 z-[1000]",
|
|
5201
5223
|
"flex items-start justify-center px-4 pb-4 pt-[10vh]",
|
|
5202
|
-
"max-sm:items-stretch max-sm:p-0 max-sm:pt-0"
|
|
5224
|
+
"max-sm:items-stretch max-sm:p-0 max-sm:pt-0",
|
|
5225
|
+
overlayAnim
|
|
5203
5226
|
),
|
|
5204
5227
|
style: { backgroundColor: "rgba(0, 0, 0, 0.6)" },
|
|
5205
5228
|
onClick: handleOverlayClick,
|
|
@@ -5227,8 +5250,10 @@ var init_Modal = __esm({
|
|
|
5227
5250
|
// full height, no rounded corners, no min-width.
|
|
5228
5251
|
"max-sm:max-w-none max-sm:max-h-none max-sm:w-full max-sm:h-full max-sm:rounded-none",
|
|
5229
5252
|
lookStyles[look],
|
|
5230
|
-
className
|
|
5253
|
+
className,
|
|
5254
|
+
dialogAnim
|
|
5231
5255
|
),
|
|
5256
|
+
onAnimationEnd: handleAnimEnd,
|
|
5232
5257
|
style: dragY > 0 ? {
|
|
5233
5258
|
transform: `translateY(${dragY}px)`,
|
|
5234
5259
|
transition: isDragging.current ? "none" : "transform 200ms ease-out"
|
|
@@ -5337,6 +5362,7 @@ var init_Overlay = __esm({
|
|
|
5337
5362
|
className: cn(
|
|
5338
5363
|
"fixed inset-0 z-40",
|
|
5339
5364
|
blur && "backdrop-blur-sm",
|
|
5365
|
+
"animate-overlay-in",
|
|
5340
5366
|
className
|
|
5341
5367
|
),
|
|
5342
5368
|
style: { backgroundColor: "rgba(0, 0, 0, 0.6)" },
|
|
@@ -6749,7 +6775,7 @@ var init_Input = __esm({
|
|
|
6749
6775
|
eventBus.emit(`UI:${action}`, { value: e.currentTarget.value });
|
|
6750
6776
|
}
|
|
6751
6777
|
};
|
|
6752
|
-
const wrapField = (field) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full", children: [
|
|
6778
|
+
const wrapField = (field, fullWidth = true) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: fullWidth ? "w-full" : "w-fit", children: [
|
|
6753
6779
|
label && /* @__PURE__ */ jsxRuntime.jsx("label", { className: "block text-sm font-medium text-foreground mb-1", children: label }),
|
|
6754
6780
|
field,
|
|
6755
6781
|
(helperText || error) && /* @__PURE__ */ jsxRuntime.jsx("p", { className: cn("mt-1 text-xs", error ? "text-error" : "text-muted-foreground"), children: error ?? helperText })
|
|
@@ -6809,7 +6835,8 @@ var init_Input = __esm({
|
|
|
6809
6835
|
),
|
|
6810
6836
|
...props
|
|
6811
6837
|
}
|
|
6812
|
-
)
|
|
6838
|
+
),
|
|
6839
|
+
false
|
|
6813
6840
|
);
|
|
6814
6841
|
}
|
|
6815
6842
|
return wrapField(
|
|
@@ -9052,6 +9079,18 @@ var init_RangeSlider = __esm({
|
|
|
9052
9079
|
function easeOut(t) {
|
|
9053
9080
|
return t * (2 - t);
|
|
9054
9081
|
}
|
|
9082
|
+
function formatDisplay(value, format, decimals) {
|
|
9083
|
+
switch (format) {
|
|
9084
|
+
case "currency":
|
|
9085
|
+
return `$${value.toFixed(2)}`;
|
|
9086
|
+
case "percent":
|
|
9087
|
+
return `${Math.round(value)}%`;
|
|
9088
|
+
case "number":
|
|
9089
|
+
return value.toLocaleString();
|
|
9090
|
+
default:
|
|
9091
|
+
return value.toFixed(decimals);
|
|
9092
|
+
}
|
|
9093
|
+
}
|
|
9055
9094
|
var AnimatedCounter;
|
|
9056
9095
|
var init_AnimatedCounter = __esm({
|
|
9057
9096
|
"components/marketing/atoms/AnimatedCounter.tsx"() {
|
|
@@ -9063,6 +9102,7 @@ var init_AnimatedCounter = __esm({
|
|
|
9063
9102
|
duration = 600,
|
|
9064
9103
|
prefix,
|
|
9065
9104
|
suffix,
|
|
9105
|
+
format,
|
|
9066
9106
|
className
|
|
9067
9107
|
}) => {
|
|
9068
9108
|
const numericRaw = typeof rawValue === "number" ? rawValue : Number.parseFloat(String(rawValue ?? ""));
|
|
@@ -9078,6 +9118,10 @@ var init_AnimatedCounter = __esm({
|
|
|
9078
9118
|
setDisplayValue(to);
|
|
9079
9119
|
return;
|
|
9080
9120
|
}
|
|
9121
|
+
if (window.matchMedia?.("(prefers-reduced-motion: reduce)").matches) {
|
|
9122
|
+
setDisplayValue(to);
|
|
9123
|
+
return;
|
|
9124
|
+
}
|
|
9081
9125
|
const startTime = performance.now();
|
|
9082
9126
|
const diff = to - from;
|
|
9083
9127
|
function animate(currentTime) {
|
|
@@ -9099,7 +9143,7 @@ var init_AnimatedCounter = __esm({
|
|
|
9099
9143
|
};
|
|
9100
9144
|
}, [value, duration]);
|
|
9101
9145
|
const decimalPlaces = Number.isInteger(value) ? 0 : String(value).split(".")[1]?.length ?? 0;
|
|
9102
|
-
const formattedValue = displayValue
|
|
9146
|
+
const formattedValue = formatDisplay(displayValue, format, decimalPlaces);
|
|
9103
9147
|
return /* @__PURE__ */ jsxRuntime.jsxs(Typography, { variant: "h3", className: cn("tabular-nums", className), children: [
|
|
9104
9148
|
prefix,
|
|
9105
9149
|
formattedValue,
|
|
@@ -10378,14 +10422,29 @@ function recordTransition(trace) {
|
|
|
10378
10422
|
"pass"
|
|
10379
10423
|
);
|
|
10380
10424
|
} else {
|
|
10381
|
-
const
|
|
10382
|
-
|
|
10383
|
-
|
|
10384
|
-
|
|
10385
|
-
|
|
10386
|
-
"
|
|
10387
|
-
|
|
10425
|
+
const rendersEntityData = entry.effects.some(
|
|
10426
|
+
(e) => e.type === "render-ui" && JSON.stringify(e.args).includes("@entity.")
|
|
10427
|
+
);
|
|
10428
|
+
if (rendersEntityData) {
|
|
10429
|
+
const siblingSeeds = getState().transitions.some(
|
|
10430
|
+
(t) => t.event === "INIT" && t.effects.some(
|
|
10431
|
+
(e) => e.type === "fetch" || e.type === "set" && typeof e.args[0] === "string" && e.args[0].startsWith("@entity.")
|
|
10432
|
+
)
|
|
10388
10433
|
);
|
|
10434
|
+
if (siblingSeeds) {
|
|
10435
|
+
registerCheck(
|
|
10436
|
+
checkId,
|
|
10437
|
+
`INIT transition for "${entry.traitName}" has sibling entity-seed (shared entity)`,
|
|
10438
|
+
"pass"
|
|
10439
|
+
);
|
|
10440
|
+
} else {
|
|
10441
|
+
registerCheck(
|
|
10442
|
+
checkId,
|
|
10443
|
+
`INIT transition for "${entry.traitName}" missing fetch effect`,
|
|
10444
|
+
"fail",
|
|
10445
|
+
"Entity-bound render-ui without a fetch effect will show empty data"
|
|
10446
|
+
);
|
|
10447
|
+
}
|
|
10389
10448
|
}
|
|
10390
10449
|
}
|
|
10391
10450
|
}
|
|
@@ -11530,7 +11589,7 @@ function GameMenu({
|
|
|
11530
11589
|
logo,
|
|
11531
11590
|
className
|
|
11532
11591
|
}) {
|
|
11533
|
-
const resolvedOptions = options ?? menuItems ?? DEFAULT_MENU_OPTIONS;
|
|
11592
|
+
const resolvedOptions = (options?.length ? options : void 0) ?? (menuItems?.length ? menuItems : void 0) ?? DEFAULT_MENU_OPTIONS;
|
|
11534
11593
|
const eventBus = useEventBus();
|
|
11535
11594
|
const handleOptionClick = React90__namespace.useCallback(
|
|
11536
11595
|
(option) => {
|
|
@@ -12928,6 +12987,10 @@ function Canvas2D({
|
|
|
12928
12987
|
window.removeEventListener("keyup", onUp);
|
|
12929
12988
|
};
|
|
12930
12989
|
}, [keyMap, keyUpMap, eventBus]);
|
|
12990
|
+
React90.useEffect(() => {
|
|
12991
|
+
if (!keyMap && !keyUpMap) return;
|
|
12992
|
+
canvasRef.current?.focus();
|
|
12993
|
+
}, [keyMap, keyUpMap]);
|
|
12931
12994
|
if (error) {
|
|
12932
12995
|
return /* @__PURE__ */ jsxRuntime.jsx(Box, { className: cn("flex items-center justify-center w-full h-full bg-[var(--color-card)] rounded-container", className), children: /* @__PURE__ */ jsxRuntime.jsxs(Stack, { direction: "vertical", gap: "md", align: "center", children: [
|
|
12933
12996
|
/* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "alert-circle", size: "xl" }),
|
|
@@ -12976,7 +13039,7 @@ function Canvas2D({
|
|
|
12976
13039
|
onWheel: gestureHandlers.onWheel,
|
|
12977
13040
|
onContextMenu: (e) => e.preventDefault(),
|
|
12978
13041
|
className: "cursor-pointer touch-none",
|
|
12979
|
-
tabIndex: isFree ? 0 : void 0,
|
|
13042
|
+
tabIndex: isFree || keyMap || keyUpMap ? 0 : void 0,
|
|
12980
13043
|
style: {
|
|
12981
13044
|
width: viewportSize.width,
|
|
12982
13045
|
height: viewportSize.height
|
|
@@ -16400,7 +16463,8 @@ var init_LoadingState = __esm({
|
|
|
16400
16463
|
LoadingState = ({
|
|
16401
16464
|
title,
|
|
16402
16465
|
message,
|
|
16403
|
-
className
|
|
16466
|
+
className,
|
|
16467
|
+
fullPage = false
|
|
16404
16468
|
}) => {
|
|
16405
16469
|
const { t } = hooks.useTranslate();
|
|
16406
16470
|
const displayMessage = message ?? t("common.loading");
|
|
@@ -16409,7 +16473,8 @@ var init_LoadingState = __esm({
|
|
|
16409
16473
|
{
|
|
16410
16474
|
align: "center",
|
|
16411
16475
|
className: cn(
|
|
16412
|
-
"justify-center
|
|
16476
|
+
"justify-center",
|
|
16477
|
+
fullPage ? "fixed inset-0 z-[1000] py-12 bg-background/80 backdrop-blur-sm animate-overlay-in" : "py-12",
|
|
16413
16478
|
className
|
|
16414
16479
|
),
|
|
16415
16480
|
children: [
|
|
@@ -19611,7 +19676,7 @@ var init_BookCoverPage = __esm({
|
|
|
19611
19676
|
size: "lg",
|
|
19612
19677
|
action: "BOOK_START",
|
|
19613
19678
|
className: "mt-8",
|
|
19614
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", children: t("book.startReading") })
|
|
19679
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", color: "inherit", children: t("book.startReading") })
|
|
19615
19680
|
}
|
|
19616
19681
|
)
|
|
19617
19682
|
]
|
|
@@ -21923,8 +21988,9 @@ var init_Chart = __esm({
|
|
|
21923
21988
|
align: "center",
|
|
21924
21989
|
flex: true,
|
|
21925
21990
|
className: "min-w-0",
|
|
21991
|
+
style: { height: "100%" },
|
|
21926
21992
|
children: [
|
|
21927
|
-
/* @__PURE__ */ jsxRuntime.jsx(HStack, { gap: histogram ? "none" : "xs", align: "end",
|
|
21993
|
+
/* @__PURE__ */ jsxRuntime.jsx(HStack, { gap: histogram ? "none" : "xs", align: "end", justify: histogram ? void 0 : "center", className: "w-full flex-1 min-h-0", children: series.map((s, sIdx) => {
|
|
21928
21994
|
const value = valueAt(s, label);
|
|
21929
21995
|
const barHeight = value / maxValue * 100;
|
|
21930
21996
|
const color = seriesColor(s, sIdx);
|
|
@@ -21937,6 +22003,8 @@ var init_Chart = __esm({
|
|
|
21937
22003
|
),
|
|
21938
22004
|
style: {
|
|
21939
22005
|
height: `${barHeight}%`,
|
|
22006
|
+
// Cap width so a lone category doesn't paint the whole plot as one solid block; narrow columns are unaffected (flex-1 binds first).
|
|
22007
|
+
...!histogram && { maxWidth: 72 },
|
|
21940
22008
|
backgroundColor: color
|
|
21941
22009
|
},
|
|
21942
22010
|
onClick: () => onPointClick?.(
|
|
@@ -21971,8 +22039,9 @@ var init_Chart = __esm({
|
|
|
21971
22039
|
align: "center",
|
|
21972
22040
|
flex: true,
|
|
21973
22041
|
className: "min-w-0",
|
|
22042
|
+
style: { height: "100%" },
|
|
21974
22043
|
children: [
|
|
21975
|
-
/* @__PURE__ */ jsxRuntime.jsx(VStack, { gap: "none", className: "w-full
|
|
22044
|
+
/* @__PURE__ */ jsxRuntime.jsx(VStack, { gap: "none", className: "w-full flex-1 min-h-0", justify: "end", children: series.map((s, sIdx) => {
|
|
21976
22045
|
const value = valueAt(s, label);
|
|
21977
22046
|
const ratio = stack === "normalize" ? total === 0 ? 0 : value / total * 100 : value / maxValue * 100;
|
|
21978
22047
|
const color = seriesColor(s, sIdx);
|
|
@@ -22017,6 +22086,7 @@ var init_Chart = __esm({
|
|
|
22017
22086
|
const innerRadius = donut ? radius * 0.6 : 0;
|
|
22018
22087
|
const center = size / 2;
|
|
22019
22088
|
const segments = React90.useMemo(() => {
|
|
22089
|
+
if (!Number.isFinite(total) || total <= 0) return [];
|
|
22020
22090
|
let currentAngle = -Math.PI / 2;
|
|
22021
22091
|
return data.map((point, idx) => {
|
|
22022
22092
|
const angle = point.value / total * 2 * Math.PI;
|
|
@@ -22028,13 +22098,25 @@ var init_Chart = __esm({
|
|
|
22028
22098
|
const y1 = center + radius * Math.sin(startAngle);
|
|
22029
22099
|
const x2 = center + radius * Math.cos(endAngle);
|
|
22030
22100
|
const y2 = center + radius * Math.sin(endAngle);
|
|
22101
|
+
const fullCircle = angle >= 2 * Math.PI - 1e-9;
|
|
22102
|
+
const midAngle = startAngle + angle / 2;
|
|
22103
|
+
const xm = center + radius * Math.cos(midAngle);
|
|
22104
|
+
const ym = center + radius * Math.sin(midAngle);
|
|
22031
22105
|
let d;
|
|
22032
22106
|
if (innerRadius > 0) {
|
|
22033
22107
|
const ix1 = center + innerRadius * Math.cos(startAngle);
|
|
22034
22108
|
const iy1 = center + innerRadius * Math.sin(startAngle);
|
|
22035
22109
|
const ix2 = center + innerRadius * Math.cos(endAngle);
|
|
22036
22110
|
const iy2 = center + innerRadius * Math.sin(endAngle);
|
|
22037
|
-
|
|
22111
|
+
if (fullCircle) {
|
|
22112
|
+
const ixm = center + innerRadius * Math.cos(midAngle);
|
|
22113
|
+
const iym = center + innerRadius * Math.sin(midAngle);
|
|
22114
|
+
d = `M ${ix1} ${iy1} L ${x1} ${y1} A ${radius} ${radius} 0 1 1 ${xm} ${ym} A ${radius} ${radius} 0 1 1 ${x2} ${y2} L ${ix2} ${iy2} A ${innerRadius} ${innerRadius} 0 1 0 ${ixm} ${iym} A ${innerRadius} ${innerRadius} 0 1 0 ${ix1} ${iy1} Z`;
|
|
22115
|
+
} else {
|
|
22116
|
+
d = `M ${ix1} ${iy1} L ${x1} ${y1} A ${radius} ${radius} 0 ${largeArc} 1 ${x2} ${y2} L ${ix2} ${iy2} A ${innerRadius} ${innerRadius} 0 ${largeArc} 0 ${ix1} ${iy1} Z`;
|
|
22117
|
+
}
|
|
22118
|
+
} else if (fullCircle) {
|
|
22119
|
+
d = `M ${center} ${center} L ${x1} ${y1} A ${radius} ${radius} 0 1 1 ${xm} ${ym} A ${radius} ${radius} 0 1 1 ${x2} ${y2} Z`;
|
|
22038
22120
|
} else {
|
|
22039
22121
|
d = `M ${center} ${center} L ${x1} ${y1} A ${radius} ${radius} 0 ${largeArc} 1 ${x2} ${y2} Z`;
|
|
22040
22122
|
}
|
|
@@ -25061,10 +25143,10 @@ function DataGrid({
|
|
|
25061
25143
|
] }),
|
|
25062
25144
|
badgeFields.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(HStack, { gap: "xs", className: "flex-wrap", children: badgeFields.map((field) => {
|
|
25063
25145
|
const val = getNestedValue(itemData, field.name);
|
|
25064
|
-
if (val === void 0 || val === null) return null;
|
|
25146
|
+
if (val === void 0 || val === null || val === "") return null;
|
|
25065
25147
|
return /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "xs", className: "items-center", children: [
|
|
25066
25148
|
field.icon && renderIconInput(field.icon, { size: "xs" }),
|
|
25067
|
-
/* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: resolveBadgeVariant(field, String(val)), children:
|
|
25149
|
+
/* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: resolveBadgeVariant(field, String(val)), children: formatValue(val, field.format) })
|
|
25068
25150
|
] }, field.name);
|
|
25069
25151
|
}) })
|
|
25070
25152
|
] }),
|
|
@@ -32554,6 +32636,11 @@ var init_VoteStack = __esm({
|
|
|
32554
32636
|
{
|
|
32555
32637
|
className: cn(
|
|
32556
32638
|
"inline-flex items-center justify-center",
|
|
32639
|
+
// Shrink-wrap in stretch contexts (slot/sidecar wrappers are
|
|
32640
|
+
// flex-column with stretch alignment): without this the root spans
|
|
32641
|
+
// the full wrapper width and the count row's `w-full` turns the
|
|
32642
|
+
// compact pill into a page-wide band.
|
|
32643
|
+
"w-fit",
|
|
32557
32644
|
variant === "vertical" ? "flex-col" : "flex-row",
|
|
32558
32645
|
"rounded-sm",
|
|
32559
32646
|
"border-[length:var(--border-width)] border-border",
|
|
@@ -36050,7 +36137,7 @@ var init_Sidebar = __esm({
|
|
|
36050
36137
|
isActive ? [
|
|
36051
36138
|
"bg-primary text-primary-foreground",
|
|
36052
36139
|
"font-medium shadow-sm",
|
|
36053
|
-
"border-primary translate-x-1 -translate-y-0.5"
|
|
36140
|
+
"border-primary translate-x-1 rtl:-translate-x-1 -translate-y-0.5"
|
|
36054
36141
|
].join(" ") : [
|
|
36055
36142
|
"text-foreground",
|
|
36056
36143
|
"hover:bg-muted hover:border-border",
|
|
@@ -36060,10 +36147,10 @@ var init_Sidebar = __esm({
|
|
|
36060
36147
|
title: collapsed ? item.label : void 0,
|
|
36061
36148
|
children: [
|
|
36062
36149
|
item.icon && (typeof item.icon === "string" ? /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: item.icon, size: "sm", className: cn("min-w-[20px] flex-shrink-0", isActive && "text-primary-foreground") }) : /* @__PURE__ */ jsxRuntime.jsx(Icon, { icon: item.icon, size: "sm", className: cn("min-w-[20px] flex-shrink-0", isActive && "text-primary-foreground") })),
|
|
36063
|
-
!collapsed && /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", color: isActive ? "inherit" : "primary", className: "font-medium truncate flex-1 text-
|
|
36150
|
+
!collapsed && /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", color: isActive ? "inherit" : "primary", className: "font-medium truncate flex-1 text-start", children: item.label }),
|
|
36064
36151
|
!collapsed && item.badge !== void 0 && /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: "danger", size: "sm", children: item.badge }),
|
|
36065
36152
|
collapsed && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: cn(
|
|
36066
|
-
"absolute
|
|
36153
|
+
"absolute start-full ms-2 px-2 py-1 text-xs opacity-0 group-hover:opacity-100",
|
|
36067
36154
|
"pointer-events-none whitespace-nowrap z-50 transition-opacity",
|
|
36068
36155
|
"bg-primary text-primary-foreground",
|
|
36069
36156
|
"border-[length:var(--border-width-thin)] border-border",
|
|
@@ -36118,7 +36205,7 @@ var init_Sidebar = __esm({
|
|
|
36118
36205
|
as: "aside",
|
|
36119
36206
|
className: cn(
|
|
36120
36207
|
"flex flex-col h-full",
|
|
36121
|
-
"bg-card border-
|
|
36208
|
+
"bg-card border-e border-border",
|
|
36122
36209
|
"transition-all duration-300 ease-in-out",
|
|
36123
36210
|
collapsed ? "w-20" : "w-64",
|
|
36124
36211
|
className
|
|
@@ -37279,7 +37366,7 @@ function resolveColor3(color, el) {
|
|
|
37279
37366
|
function truncateLabel(label) {
|
|
37280
37367
|
return label.length > MAX_LABEL_CHARS ? label.slice(0, MAX_LABEL_CHARS - 1) + "\u2026" : label;
|
|
37281
37368
|
}
|
|
37282
|
-
var GROUP_COLORS2, GROUP_GRAVITY, UNGROUPED_GRAVITY, labelMeasureCtx, MAX_LABEL_CHARS, GraphCanvas;
|
|
37369
|
+
var GROUP_COLORS2, GROUP_GRAVITY, UNGROUPED_GRAVITY, labelMeasureCtx, MAX_LABEL_CHARS, NO_NODES, NO_EDGES, NO_SIM, GraphCanvas;
|
|
37283
37370
|
var init_GraphCanvas = __esm({
|
|
37284
37371
|
"components/core/molecules/GraphCanvas.tsx"() {
|
|
37285
37372
|
"use client";
|
|
@@ -37303,11 +37390,14 @@ var init_GraphCanvas = __esm({
|
|
|
37303
37390
|
UNGROUPED_GRAVITY = 0.02;
|
|
37304
37391
|
labelMeasureCtx = null;
|
|
37305
37392
|
MAX_LABEL_CHARS = 22;
|
|
37393
|
+
NO_NODES = [];
|
|
37394
|
+
NO_EDGES = [];
|
|
37395
|
+
NO_SIM = [];
|
|
37306
37396
|
GraphCanvas = ({
|
|
37307
37397
|
title,
|
|
37308
|
-
nodes: propNodes =
|
|
37309
|
-
edges: propEdges =
|
|
37310
|
-
similarity: propSimilarity =
|
|
37398
|
+
nodes: propNodes = NO_NODES,
|
|
37399
|
+
edges: propEdges = NO_EDGES,
|
|
37400
|
+
similarity: propSimilarity = NO_SIM,
|
|
37311
37401
|
height = 400,
|
|
37312
37402
|
showLabels = true,
|
|
37313
37403
|
interactive = true,
|
|
@@ -37357,6 +37447,7 @@ var init_GraphCanvas = __esm({
|
|
|
37357
37447
|
const interactionRef = React90.useRef({
|
|
37358
37448
|
mode: "none",
|
|
37359
37449
|
dragNodeId: null,
|
|
37450
|
+
pressedNodeId: null,
|
|
37360
37451
|
startMouse: { x: 0, y: 0 },
|
|
37361
37452
|
startOffset: { x: 0, y: 0 },
|
|
37362
37453
|
downPos: { x: 0, y: 0 }
|
|
@@ -37404,6 +37495,11 @@ var init_GraphCanvas = __esm({
|
|
|
37404
37495
|
() => [...new Set(propNodes.map((n) => n.group).filter(Boolean))],
|
|
37405
37496
|
[propNodes]
|
|
37406
37497
|
);
|
|
37498
|
+
const nodesKey = React90.useMemo(() => propNodes.map((n) => n.id).join(""), [propNodes]);
|
|
37499
|
+
const edgesKey = React90.useMemo(
|
|
37500
|
+
() => propEdges.map((e) => `${e.source}${e.target}`).join(""),
|
|
37501
|
+
[propEdges]
|
|
37502
|
+
);
|
|
37407
37503
|
React90.useEffect(() => {
|
|
37408
37504
|
const canvas = canvasRef.current;
|
|
37409
37505
|
if (!canvas || propNodes.length === 0) return;
|
|
@@ -37584,7 +37680,7 @@ var init_GraphCanvas = __esm({
|
|
|
37584
37680
|
return () => {
|
|
37585
37681
|
cancelAnimationFrame(animRef.current);
|
|
37586
37682
|
};
|
|
37587
|
-
}, [
|
|
37683
|
+
}, [nodesKey, edgesKey, propSimilarity, layout, repulsion, linkDistance, nodeSpacing, showLabels]);
|
|
37588
37684
|
React90.useEffect(() => {
|
|
37589
37685
|
const canvas = canvasRef.current;
|
|
37590
37686
|
if (!canvas) return;
|
|
@@ -37714,6 +37810,7 @@ var init_GraphCanvas = __esm({
|
|
|
37714
37810
|
const cancelSinglePointer = React90.useCallback(() => {
|
|
37715
37811
|
interactionRef.current.mode = "none";
|
|
37716
37812
|
interactionRef.current.dragNodeId = null;
|
|
37813
|
+
interactionRef.current.pressedNodeId = null;
|
|
37717
37814
|
}, []);
|
|
37718
37815
|
const handlePointerDown = React90.useCallback(
|
|
37719
37816
|
(e) => {
|
|
@@ -37724,6 +37821,7 @@ var init_GraphCanvas = __esm({
|
|
|
37724
37821
|
state.downPos = { x: e.clientX, y: e.clientY };
|
|
37725
37822
|
state.startMouse = { x: e.clientX, y: e.clientY };
|
|
37726
37823
|
state.startOffset = { ...offset };
|
|
37824
|
+
state.pressedNodeId = node?.id ?? null;
|
|
37727
37825
|
if (draggable && node) {
|
|
37728
37826
|
state.mode = "dragging";
|
|
37729
37827
|
state.dragNodeId = node.id;
|
|
@@ -37775,7 +37873,8 @@ var init_GraphCanvas = __esm({
|
|
|
37775
37873
|
if (moved < 4) {
|
|
37776
37874
|
const coords = toCoords(e);
|
|
37777
37875
|
if (!coords) return;
|
|
37778
|
-
const node = nodeAt(coords.graphX, coords.graphY);
|
|
37876
|
+
const node = (state.pressedNodeId ? nodesRef.current.find((n) => n.id === state.pressedNodeId) : void 0) ?? nodeAt(coords.graphX, coords.graphY);
|
|
37877
|
+
state.pressedNodeId = null;
|
|
37779
37878
|
if (node) {
|
|
37780
37879
|
if (node.badge && node.badge > 1 && onBadgeClick) {
|
|
37781
37880
|
const r2 = (node.size || 8) + (selectedNodeId === node.id ? 4 : 0);
|
|
@@ -37795,6 +37894,7 @@ var init_GraphCanvas = __esm({
|
|
|
37795
37894
|
);
|
|
37796
37895
|
const handlePointerLeave = React90.useCallback(() => {
|
|
37797
37896
|
setHoveredNode(null);
|
|
37897
|
+
interactionRef.current.pressedNodeId = null;
|
|
37798
37898
|
}, []);
|
|
37799
37899
|
const gestureHandlers = useCanvasGestures({
|
|
37800
37900
|
canvasRef,
|
|
@@ -40746,8 +40846,17 @@ var init_MediaGallery = __esm({
|
|
|
40746
40846
|
const eventBus = useEventBus();
|
|
40747
40847
|
const { t } = hooks.useTranslate();
|
|
40748
40848
|
const [lightboxItem, setLightboxItem] = React90.useState(null);
|
|
40849
|
+
const [failedIds, setFailedIds] = React90.useState(/* @__PURE__ */ new Set());
|
|
40749
40850
|
const closeLightbox = React90.useCallback(() => setLightboxItem(null), []);
|
|
40750
40851
|
useEventListener("UI:LIGHTBOX_CLOSE", closeLightbox);
|
|
40852
|
+
const handleImageError = React90.useCallback((id) => {
|
|
40853
|
+
setFailedIds((prev) => {
|
|
40854
|
+
if (prev.has(id)) return prev;
|
|
40855
|
+
const next = new Set(prev);
|
|
40856
|
+
next.add(id);
|
|
40857
|
+
return next;
|
|
40858
|
+
});
|
|
40859
|
+
}, []);
|
|
40751
40860
|
const handleItemClick = React90.useCallback(
|
|
40752
40861
|
(item) => {
|
|
40753
40862
|
if (selectable) {
|
|
@@ -40763,7 +40872,7 @@ var init_MediaGallery = __esm({
|
|
|
40763
40872
|
);
|
|
40764
40873
|
const entityData = Array.isArray(entity) ? entity : [];
|
|
40765
40874
|
const items = React90__namespace.default.useMemo(() => {
|
|
40766
|
-
if (propItems) return propItems;
|
|
40875
|
+
if (propItems && propItems.length > 0) return propItems;
|
|
40767
40876
|
if (entityData.length === 0) return [];
|
|
40768
40877
|
return entityData.map((record, idx) => {
|
|
40769
40878
|
return {
|
|
@@ -40846,13 +40955,14 @@ var init_MediaGallery = __esm({
|
|
|
40846
40955
|
),
|
|
40847
40956
|
onClick: () => handleItemClick(item),
|
|
40848
40957
|
children: [
|
|
40849
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
40958
|
+
failedIds.has(item.id) ? /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "w-full h-full flex items-center justify-center bg-muted text-muted-foreground", children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { icon: LucideIcons2.Image, size: "lg" }) }) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
40850
40959
|
"img",
|
|
40851
40960
|
{
|
|
40852
40961
|
src: item.thumbnail || item.src,
|
|
40853
40962
|
alt: item.alt || item.caption || "",
|
|
40854
40963
|
className: "w-full h-full object-cover",
|
|
40855
|
-
loading: "lazy"
|
|
40964
|
+
loading: "lazy",
|
|
40965
|
+
onError: () => handleImageError(item.id)
|
|
40856
40966
|
}
|
|
40857
40967
|
),
|
|
40858
40968
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -44359,6 +44469,11 @@ var init_TeamOrganism = __esm({
|
|
|
44359
44469
|
TeamOrganism.displayName = "TeamOrganism";
|
|
44360
44470
|
}
|
|
44361
44471
|
});
|
|
44472
|
+
function formatDate4(value) {
|
|
44473
|
+
const d = new Date(value);
|
|
44474
|
+
if (isNaN(d.getTime())) return value;
|
|
44475
|
+
return d.toLocaleDateString(void 0, { year: "numeric", month: "short", day: "numeric" });
|
|
44476
|
+
}
|
|
44362
44477
|
var lookStyles10, STATUS_STYLES2, Timeline;
|
|
44363
44478
|
var init_Timeline = __esm({
|
|
44364
44479
|
"components/core/organisms/Timeline.tsx"() {
|
|
@@ -44486,7 +44601,7 @@ var init_Timeline = __esm({
|
|
|
44486
44601
|
/* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "xs", className: cn("flex-1 min-w-0", !isLast && "pb-6"), children: [
|
|
44487
44602
|
/* @__PURE__ */ jsxRuntime.jsxs(HStack, { justify: "between", align: "start", wrap: true, children: [
|
|
44488
44603
|
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", weight: "semibold", children: item.title }),
|
|
44489
|
-
item.date && /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "caption", color: "secondary", className: "flex-shrink-0", children: item.date })
|
|
44604
|
+
item.date && /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "caption", color: "secondary", className: "flex-shrink-0", children: formatDate4(item.date) })
|
|
44490
44605
|
] }),
|
|
44491
44606
|
item.description && /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", color: "secondary", children: item.description }),
|
|
44492
44607
|
item.tags && item.tags.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(HStack, { gap: "xs", wrap: true, children: item.tags.map((tag, tagIdx) => /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: "default", children: tag }, tagIdx)) }),
|
|
@@ -45698,7 +45813,7 @@ function substituteTraitRefsDeep(value, pathKey) {
|
|
|
45698
45813
|
}
|
|
45699
45814
|
return value;
|
|
45700
45815
|
}
|
|
45701
|
-
function renderPatternProps(props, onDismiss) {
|
|
45816
|
+
function renderPatternProps(props, onDismiss, propsSchema) {
|
|
45702
45817
|
const rendered = {};
|
|
45703
45818
|
for (const [key, value] of Object.entries(props)) {
|
|
45704
45819
|
if (key === "children") {
|
|
@@ -45716,9 +45831,10 @@ function renderPatternProps(props, onDismiss) {
|
|
|
45716
45831
|
};
|
|
45717
45832
|
rendered[key] = /* @__PURE__ */ jsxRuntime.jsx(SlotContentRenderer, { content: childContent, onDismiss });
|
|
45718
45833
|
} else if (Array.isArray(value)) {
|
|
45834
|
+
const isDataArray = propsSchema?.[key]?.items?.types?.includes("object") ?? false;
|
|
45719
45835
|
rendered[key] = value.map((item, i) => {
|
|
45720
45836
|
const el = item;
|
|
45721
|
-
if (isPatternConfig(el)) {
|
|
45837
|
+
if (!isDataArray && isPatternConfig(el)) {
|
|
45722
45838
|
const nestedProps = {};
|
|
45723
45839
|
for (const [k, v] of Object.entries(el)) {
|
|
45724
45840
|
if (k !== "type") nestedProps[k] = v;
|
|
@@ -45806,14 +45922,15 @@ function SlotContentRenderer({
|
|
|
45806
45922
|
);
|
|
45807
45923
|
}
|
|
45808
45924
|
}
|
|
45809
|
-
const renderedProps = renderPatternProps(restProps, onDismiss);
|
|
45810
45925
|
const patternDef = patterns.getPatternDefinition(content.pattern);
|
|
45811
45926
|
const propsSchema = patternDef?.propsSchema;
|
|
45927
|
+
const renderedProps = renderPatternProps(restProps, onDismiss, propsSchema);
|
|
45812
45928
|
if (propsSchema) {
|
|
45813
45929
|
for (const [propKey, propValue] of Object.entries(renderedProps)) {
|
|
45814
45930
|
if (typeof propValue !== "string") continue;
|
|
45815
45931
|
const propDef = propsSchema[propKey];
|
|
45816
45932
|
if (!propDef || propDef.kind !== "callback") continue;
|
|
45933
|
+
if (propValue === "") continue;
|
|
45817
45934
|
renderedProps[propKey] = ui.wrapCallbackForEvent(
|
|
45818
45935
|
`UI:${propValue}`,
|
|
45819
45936
|
propDef.callbackArgs,
|
|
@@ -49608,6 +49725,7 @@ function useSharedEntityStore() {
|
|
|
49608
49725
|
}
|
|
49609
49726
|
return storeRef.current;
|
|
49610
49727
|
}
|
|
49728
|
+
React90.createContext(null);
|
|
49611
49729
|
function runTickFrame(entityId, orderedWriters, store) {
|
|
49612
49730
|
let scratch = store.getSnapshot(entityId);
|
|
49613
49731
|
for (const writer of orderedWriters) {
|
|
@@ -49705,6 +49823,11 @@ var SYNC_TICK_OPERATORS = /* @__PURE__ */ new Set([
|
|
|
49705
49823
|
"do",
|
|
49706
49824
|
"when"
|
|
49707
49825
|
]);
|
|
49826
|
+
var REACTIVE_REPAINT_PATTERN_TYPES = /* @__PURE__ */ new Set([
|
|
49827
|
+
"canvas",
|
|
49828
|
+
"game-hud",
|
|
49829
|
+
"game-shell"
|
|
49830
|
+
]);
|
|
49708
49831
|
var LIFECYCLE_EVENTS = ["INIT", "LOAD", "$MOUNT"];
|
|
49709
49832
|
function toTraitDefinition(binding) {
|
|
49710
49833
|
return {
|
|
@@ -49957,6 +50080,8 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
49957
50080
|
}, [traitStates]);
|
|
49958
50081
|
const traitSnapshotDataRef = React90.useRef(/* @__PURE__ */ new Map());
|
|
49959
50082
|
const traitFieldStatesRef = React90.useRef(/* @__PURE__ */ new Map());
|
|
50083
|
+
const lastCanvasRenderUiRef = React90.useRef(/* @__PURE__ */ new Map());
|
|
50084
|
+
const executeTransitionEffectsRef = React90.useRef(null);
|
|
49960
50085
|
React90.useEffect(() => {
|
|
49961
50086
|
const mgr = managerRef.current;
|
|
49962
50087
|
const bindings = traitBindingsRef.current;
|
|
@@ -49997,11 +50122,9 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
49997
50122
|
bindTraitStateGetter((traitName) => {
|
|
49998
50123
|
const allStates = newManager.getAllStates();
|
|
49999
50124
|
if (allStates instanceof Map) {
|
|
50000
|
-
|
|
50001
|
-
return typeof val === "string" ? val : void 0;
|
|
50125
|
+
return allStates.get(traitName)?.currentState;
|
|
50002
50126
|
}
|
|
50003
|
-
|
|
50004
|
-
return typeof state === "string" ? state : void 0;
|
|
50127
|
+
return newManager.getState(traitName)?.currentState;
|
|
50005
50128
|
});
|
|
50006
50129
|
const snapshotUnregs = [];
|
|
50007
50130
|
for (const binding of traitBindingsRef.current) {
|
|
@@ -50086,6 +50209,15 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
50086
50209
|
const existing = pendingSlots.get(slot) || [];
|
|
50087
50210
|
existing.push({ pattern, props: props || {} });
|
|
50088
50211
|
pendingSlots.set(slot, existing);
|
|
50212
|
+
const patternType = pattern?.type;
|
|
50213
|
+
if (patternType !== void 0 && REACTIVE_REPAINT_PATTERN_TYPES.has(patternType)) {
|
|
50214
|
+
const rawForSlot = effects.filter(
|
|
50215
|
+
(e) => Array.isArray(e) && (e[0] === "render-ui" || e[0] === "render") && e[1] === slot
|
|
50216
|
+
);
|
|
50217
|
+
if (rawForSlot.length > 0) {
|
|
50218
|
+
lastCanvasRenderUiRef.current.set(traitName, rawForSlot);
|
|
50219
|
+
}
|
|
50220
|
+
}
|
|
50089
50221
|
},
|
|
50090
50222
|
clearSlot: (slot) => {
|
|
50091
50223
|
pendingSlots.set(slot, []);
|
|
@@ -50156,11 +50288,15 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
50156
50288
|
notify: clientHandlers.notify
|
|
50157
50289
|
};
|
|
50158
50290
|
}
|
|
50291
|
+
const sharedWrites = [];
|
|
50159
50292
|
const baseSet = handlers.set;
|
|
50160
50293
|
handlers = {
|
|
50161
50294
|
...handlers,
|
|
50162
50295
|
set: async (targetId, field, value) => {
|
|
50163
50296
|
if (baseSet) await baseSet(targetId, field, value);
|
|
50297
|
+
if (sharedKey !== void 0) {
|
|
50298
|
+
sharedWrites.push({ field, value });
|
|
50299
|
+
}
|
|
50164
50300
|
log11.debug("set:write", {
|
|
50165
50301
|
traitName,
|
|
50166
50302
|
field,
|
|
@@ -50236,7 +50372,10 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
50236
50372
|
});
|
|
50237
50373
|
}
|
|
50238
50374
|
if (sharedKey !== void 0) {
|
|
50239
|
-
sharedEntityStore.commit(
|
|
50375
|
+
sharedEntityStore.commit(
|
|
50376
|
+
sharedKey,
|
|
50377
|
+
core.mergeEntityFrame(sharedEntityStore.getSnapshot(sharedKey), sharedWrites)
|
|
50378
|
+
);
|
|
50240
50379
|
}
|
|
50241
50380
|
log11.debug("effects:executed", () => ({
|
|
50242
50381
|
traitName,
|
|
@@ -50262,6 +50401,38 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
50262
50401
|
entity: binding.linkedEntity
|
|
50263
50402
|
});
|
|
50264
50403
|
}
|
|
50404
|
+
if (pendingSlots.size === 0 && effectsCallOp(effects, SHARED_ENTITY_WRITE_OPS)) {
|
|
50405
|
+
const stashed = lastCanvasRenderUiRef.current.get(traitName);
|
|
50406
|
+
if (stashed !== void 0 && stashed.length > 0) {
|
|
50407
|
+
await executor.executeAll(stashed);
|
|
50408
|
+
for (const [slot, patterns] of pendingSlots) {
|
|
50409
|
+
flushSlot(traitName, slot, patterns, {
|
|
50410
|
+
event: flushEvent,
|
|
50411
|
+
state: previousState,
|
|
50412
|
+
entity: binding.linkedEntity
|
|
50413
|
+
});
|
|
50414
|
+
}
|
|
50415
|
+
}
|
|
50416
|
+
if (sharedKey !== void 0 && executeTransitionEffectsRef.current !== null) {
|
|
50417
|
+
for (const sibling of traitBindingsRef.current) {
|
|
50418
|
+
const siblingName = sibling.trait.name;
|
|
50419
|
+
if (siblingName === traitName) continue;
|
|
50420
|
+
if (sharedKeyByTraitNameRef.current.get(siblingName) !== sharedKey) continue;
|
|
50421
|
+
const siblingStash = lastCanvasRenderUiRef.current.get(siblingName);
|
|
50422
|
+
if (siblingStash === void 0 || siblingStash.length === 0) continue;
|
|
50423
|
+
const siblingState = traitStatesRef.current.get(siblingName)?.currentState ?? "";
|
|
50424
|
+
await executeTransitionEffectsRef.current({
|
|
50425
|
+
binding: sibling,
|
|
50426
|
+
effects: siblingStash,
|
|
50427
|
+
previousState: siblingState,
|
|
50428
|
+
newState: siblingState,
|
|
50429
|
+
flushEvent: `${flushEvent}:repaint`,
|
|
50430
|
+
syncOnly,
|
|
50431
|
+
log: log11
|
|
50432
|
+
});
|
|
50433
|
+
}
|
|
50434
|
+
}
|
|
50435
|
+
}
|
|
50265
50436
|
} catch (error) {
|
|
50266
50437
|
log11.error("effects:error", {
|
|
50267
50438
|
traitName,
|
|
@@ -50273,6 +50444,9 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
50273
50444
|
}
|
|
50274
50445
|
return emittedDuringExec;
|
|
50275
50446
|
}, [eventBus, flushSlot, sharedEntityStore]);
|
|
50447
|
+
React90.useEffect(() => {
|
|
50448
|
+
executeTransitionEffectsRef.current = executeTransitionEffects;
|
|
50449
|
+
}, [executeTransitionEffects]);
|
|
50276
50450
|
const runTickEffects = React90.useCallback((tick, binding) => {
|
|
50277
50451
|
const traitName = binding.trait.name;
|
|
50278
50452
|
const currentState = traitStatesRef.current.get(traitName)?.currentState ?? "";
|
|
@@ -50335,6 +50509,24 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
50335
50509
|
({ binding, tick }) => createSharedEntityWriter(binding, tick, traitStatesRef, emitFromSharedWriter)
|
|
50336
50510
|
);
|
|
50337
50511
|
runTickFrame(group.storeKey, writers, sharedEntityStore);
|
|
50512
|
+
const repaint = executeTransitionEffectsRef.current;
|
|
50513
|
+
if (repaint !== null) {
|
|
50514
|
+
for (const renderBinding of group.renderBindings) {
|
|
50515
|
+
const renderTraitName = renderBinding.trait.name;
|
|
50516
|
+
const stash = lastCanvasRenderUiRef.current.get(renderTraitName);
|
|
50517
|
+
if (stash === void 0 || stash.length === 0) continue;
|
|
50518
|
+
const renderState = traitStatesRef.current.get(renderTraitName)?.currentState ?? "";
|
|
50519
|
+
void repaint({
|
|
50520
|
+
binding: renderBinding,
|
|
50521
|
+
effects: stash,
|
|
50522
|
+
previousState: renderState,
|
|
50523
|
+
newState: renderState,
|
|
50524
|
+
flushEvent: "tick:repaint",
|
|
50525
|
+
syncOnly: true,
|
|
50526
|
+
log: sharedEntityLog
|
|
50527
|
+
});
|
|
50528
|
+
}
|
|
50529
|
+
}
|
|
50338
50530
|
};
|
|
50339
50531
|
if (interval === "frame") {
|
|
50340
50532
|
scheduler.add(0, onDue);
|
|
@@ -50384,6 +50576,13 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
50384
50576
|
entityByTrait[name] = fields;
|
|
50385
50577
|
}
|
|
50386
50578
|
}
|
|
50579
|
+
for (const binding of bindings) {
|
|
50580
|
+
const name = binding.trait.name;
|
|
50581
|
+
const sharedKey = sharedKeyByTraitNameRef.current.get(name);
|
|
50582
|
+
if (sharedKey !== void 0) {
|
|
50583
|
+
entityByTrait[name] = { ...sharedEntityStore.getSnapshot(sharedKey) };
|
|
50584
|
+
}
|
|
50585
|
+
}
|
|
50387
50586
|
const results = currentManager.sendEvent(
|
|
50388
50587
|
normalizedEvent,
|
|
50389
50588
|
payload,
|
|
@@ -50537,7 +50736,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
50537
50736
|
}
|
|
50538
50737
|
await onEventProcessed(normalizedEvent, payload, dispatchedOrbitals);
|
|
50539
50738
|
}
|
|
50540
|
-
}, [entities, eventBus]);
|
|
50739
|
+
}, [entities, eventBus, sharedEntityStore]);
|
|
50541
50740
|
const drainEventQueue = React90.useCallback(async () => {
|
|
50542
50741
|
if (processingRef.current) return;
|
|
50543
50742
|
processingRef.current = true;
|
|
@@ -50607,6 +50806,24 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
50607
50806
|
});
|
|
50608
50807
|
}
|
|
50609
50808
|
}
|
|
50809
|
+
const bareCascadeKeys = /* @__PURE__ */ new Set();
|
|
50810
|
+
for (const binding of traitBindings) {
|
|
50811
|
+
for (const transition of binding.trait.transitions) {
|
|
50812
|
+
const eventKey = transition.event;
|
|
50813
|
+
if (LIFECYCLE_EVENTS.includes(eventKey)) continue;
|
|
50814
|
+
if (bareCascadeKeys.has(eventKey)) continue;
|
|
50815
|
+
bareCascadeKeys.add(eventKey);
|
|
50816
|
+
const bareKey = `UI:${eventKey}`;
|
|
50817
|
+
const unsub = eventBus.on(bareKey, (event) => {
|
|
50818
|
+
crossTraitLog.debug("bare-cascade:fire", { bareKey, eventKey });
|
|
50819
|
+
enqueueAndDrain(eventKey, event.payload);
|
|
50820
|
+
});
|
|
50821
|
+
unsubscribes.push(() => {
|
|
50822
|
+
crossTraitLog.debug("bare-cascade:unsubscribe", { bareKey, eventKey });
|
|
50823
|
+
unsub();
|
|
50824
|
+
});
|
|
50825
|
+
}
|
|
50826
|
+
}
|
|
50610
50827
|
for (const binding of traitBindings) {
|
|
50611
50828
|
const ownOrbital = orbitalsByTrait?.[binding.trait.name];
|
|
50612
50829
|
const listens = binding.trait.listens ?? [];
|
|
@@ -50690,9 +50907,16 @@ function normalizeChild(child) {
|
|
|
50690
50907
|
props: { ...rest, ...normalizedChildren !== void 0 ? { children: normalizedChildren } : {} }
|
|
50691
50908
|
};
|
|
50692
50909
|
}
|
|
50693
|
-
function applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits) {
|
|
50910
|
+
function applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits, activeTraits) {
|
|
50694
50911
|
for (const eff of effects) {
|
|
50695
50912
|
if (eff.type === "render-ui" && eff.slot && eff.pattern) {
|
|
50913
|
+
if (eff.traitName && activeTraits && !activeTraits.has(eff.traitName)) {
|
|
50914
|
+
xOrbitalLog.debug("slot:off-page-trait-skipped", {
|
|
50915
|
+
sourceTrait: eff.traitName,
|
|
50916
|
+
slot: eff.slot
|
|
50917
|
+
});
|
|
50918
|
+
continue;
|
|
50919
|
+
}
|
|
50696
50920
|
const patternRecord = eff.pattern;
|
|
50697
50921
|
const { type: patternType, children, ...inlineProps } = patternRecord;
|
|
50698
50922
|
const normalizedChildren = Array.isArray(children) ? children.map((c) => normalizeChild(c)) : children;
|
|
@@ -50733,8 +50957,38 @@ function applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits) {
|
|
|
50733
50957
|
}
|
|
50734
50958
|
}
|
|
50735
50959
|
}
|
|
50736
|
-
function
|
|
50960
|
+
function collectServerActiveTraits(ir, allTraits, mountedTraitNames) {
|
|
50961
|
+
if (!ir?.pages || ir.pages.size <= 1) return void 0;
|
|
50962
|
+
const pageBound = /* @__PURE__ */ new Set();
|
|
50963
|
+
for (const page of ir.pages.values()) {
|
|
50964
|
+
const queue = page.traits.map((b) => b.trait.name).filter((n) => !!n);
|
|
50965
|
+
for (const name of queue) {
|
|
50966
|
+
if (pageBound.has(name)) continue;
|
|
50967
|
+
pageBound.add(name);
|
|
50968
|
+
const rt = allTraits.get(name);
|
|
50969
|
+
if (!rt) continue;
|
|
50970
|
+
queue.push(...ui.collectTraitRefsFromResolvedTrait(rt));
|
|
50971
|
+
}
|
|
50972
|
+
}
|
|
50973
|
+
const active = new Set(mountedTraitNames);
|
|
50974
|
+
for (const name of allTraits.keys()) {
|
|
50975
|
+
if (!pageBound.has(name)) active.add(name);
|
|
50976
|
+
}
|
|
50977
|
+
return active;
|
|
50978
|
+
}
|
|
50979
|
+
function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFallback, persistence, traitConfigsByName, orbitalsByTrait, embeddedTraits, serverActiveTraits }) {
|
|
50737
50980
|
const bridge = providers.useServerBridge();
|
|
50981
|
+
const activeTraitNames = React90.useMemo(
|
|
50982
|
+
() => new Set(traits2.map((b) => b.trait.name).filter((n) => !!n)),
|
|
50983
|
+
[traits2]
|
|
50984
|
+
);
|
|
50985
|
+
const withActiveTraits = React90.useCallback(
|
|
50986
|
+
(payload) => {
|
|
50987
|
+
if (!serverActiveTraits || serverActiveTraits.size === 0) return payload;
|
|
50988
|
+
return { ...payload ?? {}, _activeTraits: Array.from(serverActiveTraits) };
|
|
50989
|
+
},
|
|
50990
|
+
[serverActiveTraits]
|
|
50991
|
+
);
|
|
50738
50992
|
const uiSlots = context.useUISlots();
|
|
50739
50993
|
const onEventProcessed = React90.useCallback(async (event, payload, dispatchedOrbitals) => {
|
|
50740
50994
|
if (!bridge.connected || !orbitalNames?.length) return;
|
|
@@ -50746,11 +51000,11 @@ function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFa
|
|
|
50746
51000
|
dispatchedOrbitalsSize: dispatchedOrbitals?.size ?? 0
|
|
50747
51001
|
}));
|
|
50748
51002
|
for (const name of targets) {
|
|
50749
|
-
const { effects, meta } = await bridge.sendEvent(name, event, payload);
|
|
51003
|
+
const { effects, meta } = await bridge.sendEvent(name, event, withActiveTraits(payload));
|
|
50750
51004
|
recordServerResponse(name, event, meta);
|
|
50751
|
-
applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits);
|
|
51005
|
+
applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits, activeTraitNames);
|
|
50752
51006
|
}
|
|
50753
|
-
}, [bridge.connected, bridge.sendEvent, orbitalNames, uiSlots, onNavigate, embeddedTraits]);
|
|
51007
|
+
}, [bridge.connected, bridge.sendEvent, orbitalNames, uiSlots, onNavigate, embeddedTraits, activeTraitNames, withActiveTraits]);
|
|
50754
51008
|
const opts = orbitalNames ? { onEventProcessed, navigate: onNavigate, traitConfigsByName, orbitalsByTrait, embeddedTraits } : { navigate: onNavigate, persistence, traitConfigsByName, orbitalsByTrait, embeddedTraits };
|
|
50755
51009
|
const { sendEvent } = useTraitStateMachine(traits2, uiSlots, opts);
|
|
50756
51010
|
const initSentRef = React90.useRef(false);
|
|
@@ -50787,7 +51041,7 @@ function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFa
|
|
|
50787
51041
|
initSentRef.current = true;
|
|
50788
51042
|
(async () => {
|
|
50789
51043
|
for (const name of orbitalNames) {
|
|
50790
|
-
const { effects, meta } = await bridge.sendEvent(name, "INIT", {});
|
|
51044
|
+
const { effects, meta } = await bridge.sendEvent(name, "INIT", withActiveTraits({}));
|
|
50791
51045
|
recordServerResponse(name, "INIT", meta);
|
|
50792
51046
|
const effectTraces = [
|
|
50793
51047
|
{ type: "fetch", args: [], status: "executed" },
|
|
@@ -50805,10 +51059,10 @@ function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFa
|
|
|
50805
51059
|
effects: effectTraces,
|
|
50806
51060
|
timestamp: Date.now()
|
|
50807
51061
|
});
|
|
50808
|
-
applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits);
|
|
51062
|
+
applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits, activeTraitNames);
|
|
50809
51063
|
}
|
|
50810
51064
|
})();
|
|
50811
|
-
}, [bridge.connected, orbitalNames, bridge.sendEvent, uiSlots, onNavigate, embeddedTraits]);
|
|
51065
|
+
}, [bridge.connected, orbitalNames, bridge.sendEvent, uiSlots, onNavigate, embeddedTraits, activeTraitNames, withActiveTraits]);
|
|
50812
51066
|
return null;
|
|
50813
51067
|
}
|
|
50814
51068
|
function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, onNavigate, onLocalFallback, persistence }) {
|
|
@@ -50895,6 +51149,14 @@ function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, onNavi
|
|
|
50895
51149
|
}
|
|
50896
51150
|
return Array.from(set);
|
|
50897
51151
|
}, [allPageTraits, orbitalsByTrait]);
|
|
51152
|
+
const serverActiveTraits = React90.useMemo(
|
|
51153
|
+
() => collectServerActiveTraits(
|
|
51154
|
+
ir,
|
|
51155
|
+
allTraits,
|
|
51156
|
+
new Set(allPageTraits.map((b) => b.trait.name).filter((n) => !!n))
|
|
51157
|
+
),
|
|
51158
|
+
[ir, allTraits, allPageTraits]
|
|
51159
|
+
);
|
|
50898
51160
|
React90.useEffect(() => {
|
|
50899
51161
|
const traitNames = allPageTraits.map((b) => b.trait.name);
|
|
50900
51162
|
const orbitalsByTraitForPage = {};
|
|
@@ -50904,7 +51166,7 @@ function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, onNavi
|
|
|
50904
51166
|
}
|
|
50905
51167
|
xOrbitalLog.info("SchemaRunner:mount", {
|
|
50906
51168
|
pageName,
|
|
50907
|
-
traitNames,
|
|
51169
|
+
traitNames: traitNames.join(","),
|
|
50908
51170
|
orbitalsByTraitForPage,
|
|
50909
51171
|
pageOrbitalNames: pageOrbitalNames.join(",")
|
|
50910
51172
|
});
|
|
@@ -50949,6 +51211,7 @@ function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, onNavi
|
|
|
50949
51211
|
traitConfigsByName,
|
|
50950
51212
|
orbitalsByTrait,
|
|
50951
51213
|
embeddedTraits,
|
|
51214
|
+
serverActiveTraits,
|
|
50952
51215
|
onNavigate,
|
|
50953
51216
|
onLocalFallback,
|
|
50954
51217
|
persistence
|