@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/runtime/index.cjs
CHANGED
|
@@ -142,9 +142,9 @@ function getGlobalEventBus() {
|
|
|
142
142
|
function useEventBus() {
|
|
143
143
|
const context = React81.useContext(providers.EventBusContext);
|
|
144
144
|
const baseBus = context ?? getGlobalEventBus() ?? fallbackEventBus;
|
|
145
|
-
const
|
|
145
|
+
const chain = providers.useTraitScopeChain();
|
|
146
146
|
return React81.useMemo(() => {
|
|
147
|
-
if (
|
|
147
|
+
if (chain.length === 0) {
|
|
148
148
|
return {
|
|
149
149
|
...baseBus,
|
|
150
150
|
emit: (type, payload, source) => {
|
|
@@ -160,22 +160,31 @@ function useEventBus() {
|
|
|
160
160
|
emit: (type, payload, source) => {
|
|
161
161
|
if (typeof type === "string" && type.startsWith("UI:")) {
|
|
162
162
|
const tail = type.slice(3);
|
|
163
|
-
const
|
|
164
|
-
|
|
165
|
-
|
|
163
|
+
const isQualified = tail.includes(".");
|
|
164
|
+
const event = isQualified ? tail.split(".").slice(2).join(".") : tail;
|
|
165
|
+
if (!event) {
|
|
166
|
+
baseBus.emit(type, payload, source);
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
const keys = /* @__PURE__ */ new Set();
|
|
170
|
+
if (isQualified) keys.add(type);
|
|
171
|
+
for (const sc of chain) {
|
|
172
|
+
keys.add(`UI:${sc.orbital}.${sc.trait}.${event}`);
|
|
173
|
+
}
|
|
174
|
+
if (keys.size > 1) {
|
|
175
|
+
scopeLog.info("emit:fan-out", {
|
|
166
176
|
from: type,
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
scopeTrait: scope.trait
|
|
177
|
+
keys: Array.from(keys),
|
|
178
|
+
chainDepth: chain.length
|
|
170
179
|
});
|
|
171
180
|
}
|
|
172
|
-
baseBus.emit(
|
|
181
|
+
for (const key of keys) baseBus.emit(key, payload, source);
|
|
173
182
|
return;
|
|
174
183
|
}
|
|
175
184
|
baseBus.emit(type, payload, source);
|
|
176
185
|
}
|
|
177
186
|
};
|
|
178
|
-
}, [baseBus,
|
|
187
|
+
}, [baseBus, chain]);
|
|
179
188
|
}
|
|
180
189
|
function useEventListener(event, handler) {
|
|
181
190
|
const eventBus = useEventBus();
|
|
@@ -1192,13 +1201,13 @@ var init_Icon = __esm({
|
|
|
1192
1201
|
style
|
|
1193
1202
|
}) => {
|
|
1194
1203
|
const directIcon = typeof icon === "string" ? void 0 : icon;
|
|
1195
|
-
const effectiveName = typeof icon === "string" ? icon : name;
|
|
1204
|
+
const effectiveName = typeof icon === "string" && icon !== "" ? icon : name;
|
|
1205
|
+
const effectiveStrokeWidth = strokeWidth != null && strokeWidth > 0 ? strokeWidth : void 0;
|
|
1196
1206
|
const family = useIconFamily();
|
|
1197
1207
|
const RenderedComponent = React81__namespace.default.useMemo(() => {
|
|
1198
1208
|
if (directIcon) return null;
|
|
1199
1209
|
return effectiveName ? resolveIconForFamily(effectiveName) : null;
|
|
1200
1210
|
}, [directIcon, effectiveName, family]);
|
|
1201
|
-
const effectiveStrokeWidth = strokeWidth ?? void 0;
|
|
1202
1211
|
const inlineStyle = {
|
|
1203
1212
|
...effectiveStrokeWidth === void 0 ? { strokeWidth: "var(--icon-stroke-width, 2)" } : {},
|
|
1204
1213
|
...style
|
|
@@ -1798,6 +1807,15 @@ var init_Modal = __esm({
|
|
|
1798
1807
|
const [dragY, setDragY] = React81.useState(0);
|
|
1799
1808
|
const dragStartY = React81.useRef(0);
|
|
1800
1809
|
const isDragging = React81.useRef(false);
|
|
1810
|
+
const [closing, setClosing] = React81.useState(false);
|
|
1811
|
+
const wasOpenRef = React81.useRef(isOpen);
|
|
1812
|
+
React81.useEffect(() => {
|
|
1813
|
+
if (wasOpenRef.current && !isOpen) setClosing(true);
|
|
1814
|
+
wasOpenRef.current = isOpen;
|
|
1815
|
+
}, [isOpen]);
|
|
1816
|
+
const handleAnimEnd = (e) => {
|
|
1817
|
+
if (closing && e.target === e.currentTarget) setClosing(false);
|
|
1818
|
+
};
|
|
1801
1819
|
React81.useEffect(() => {
|
|
1802
1820
|
if (isOpen) {
|
|
1803
1821
|
previousActiveElement.current = document.activeElement;
|
|
@@ -1831,7 +1849,11 @@ var init_Modal = __esm({
|
|
|
1831
1849
|
document.body.style.overflow = "";
|
|
1832
1850
|
};
|
|
1833
1851
|
}, [isOpen]);
|
|
1834
|
-
if (
|
|
1852
|
+
if (typeof document === "undefined") return null;
|
|
1853
|
+
const renderOpen = isOpen || closing;
|
|
1854
|
+
if (!renderOpen) return null;
|
|
1855
|
+
const dialogAnim = closing ? "animate-modal-out" : "animate-modal-in";
|
|
1856
|
+
const overlayAnim = closing ? "animate-overlay-out" : "animate-overlay-in";
|
|
1835
1857
|
const handleClose = () => {
|
|
1836
1858
|
if (closeEvent) eventBus.emit(`UI:${closeEvent}`, {});
|
|
1837
1859
|
onClose();
|
|
@@ -1848,7 +1870,8 @@ var init_Modal = __esm({
|
|
|
1848
1870
|
className: cn(
|
|
1849
1871
|
"fixed inset-0 z-[1000]",
|
|
1850
1872
|
"flex items-start justify-center px-4 pb-4 pt-[10vh]",
|
|
1851
|
-
"max-sm:items-stretch max-sm:p-0 max-sm:pt-0"
|
|
1873
|
+
"max-sm:items-stretch max-sm:p-0 max-sm:pt-0",
|
|
1874
|
+
overlayAnim
|
|
1852
1875
|
),
|
|
1853
1876
|
style: { backgroundColor: "rgba(0, 0, 0, 0.6)" },
|
|
1854
1877
|
onClick: handleOverlayClick,
|
|
@@ -1876,8 +1899,10 @@ var init_Modal = __esm({
|
|
|
1876
1899
|
// full height, no rounded corners, no min-width.
|
|
1877
1900
|
"max-sm:max-w-none max-sm:max-h-none max-sm:w-full max-sm:h-full max-sm:rounded-none",
|
|
1878
1901
|
lookStyles[look],
|
|
1879
|
-
className
|
|
1902
|
+
className,
|
|
1903
|
+
dialogAnim
|
|
1880
1904
|
),
|
|
1905
|
+
onAnimationEnd: handleAnimEnd,
|
|
1881
1906
|
style: dragY > 0 ? {
|
|
1882
1907
|
transform: `translateY(${dragY}px)`,
|
|
1883
1908
|
transition: isDragging.current ? "none" : "transform 200ms ease-out"
|
|
@@ -1986,6 +2011,7 @@ var init_Overlay = __esm({
|
|
|
1986
2011
|
className: cn(
|
|
1987
2012
|
"fixed inset-0 z-40",
|
|
1988
2013
|
blur && "backdrop-blur-sm",
|
|
2014
|
+
"animate-overlay-in",
|
|
1989
2015
|
className
|
|
1990
2016
|
),
|
|
1991
2017
|
style: { backgroundColor: "rgba(0, 0, 0, 0.6)" },
|
|
@@ -3398,7 +3424,7 @@ var init_Input = __esm({
|
|
|
3398
3424
|
eventBus.emit(`UI:${action}`, { value: e.currentTarget.value });
|
|
3399
3425
|
}
|
|
3400
3426
|
};
|
|
3401
|
-
const wrapField = (field) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full", children: [
|
|
3427
|
+
const wrapField = (field, fullWidth = true) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: fullWidth ? "w-full" : "w-fit", children: [
|
|
3402
3428
|
label && /* @__PURE__ */ jsxRuntime.jsx("label", { className: "block text-sm font-medium text-foreground mb-1", children: label }),
|
|
3403
3429
|
field,
|
|
3404
3430
|
(helperText || error) && /* @__PURE__ */ jsxRuntime.jsx("p", { className: cn("mt-1 text-xs", error ? "text-error" : "text-muted-foreground"), children: error ?? helperText })
|
|
@@ -3458,7 +3484,8 @@ var init_Input = __esm({
|
|
|
3458
3484
|
),
|
|
3459
3485
|
...props
|
|
3460
3486
|
}
|
|
3461
|
-
)
|
|
3487
|
+
),
|
|
3488
|
+
false
|
|
3462
3489
|
);
|
|
3463
3490
|
}
|
|
3464
3491
|
return wrapField(
|
|
@@ -5786,6 +5813,18 @@ var init_RangeSlider = __esm({
|
|
|
5786
5813
|
function easeOut(t) {
|
|
5787
5814
|
return t * (2 - t);
|
|
5788
5815
|
}
|
|
5816
|
+
function formatDisplay(value, format, decimals) {
|
|
5817
|
+
switch (format) {
|
|
5818
|
+
case "currency":
|
|
5819
|
+
return `$${value.toFixed(2)}`;
|
|
5820
|
+
case "percent":
|
|
5821
|
+
return `${Math.round(value)}%`;
|
|
5822
|
+
case "number":
|
|
5823
|
+
return value.toLocaleString();
|
|
5824
|
+
default:
|
|
5825
|
+
return value.toFixed(decimals);
|
|
5826
|
+
}
|
|
5827
|
+
}
|
|
5789
5828
|
var AnimatedCounter;
|
|
5790
5829
|
var init_AnimatedCounter = __esm({
|
|
5791
5830
|
"components/marketing/atoms/AnimatedCounter.tsx"() {
|
|
@@ -5797,6 +5836,7 @@ var init_AnimatedCounter = __esm({
|
|
|
5797
5836
|
duration = 600,
|
|
5798
5837
|
prefix,
|
|
5799
5838
|
suffix,
|
|
5839
|
+
format,
|
|
5800
5840
|
className
|
|
5801
5841
|
}) => {
|
|
5802
5842
|
const numericRaw = typeof rawValue === "number" ? rawValue : Number.parseFloat(String(rawValue ?? ""));
|
|
@@ -5812,6 +5852,10 @@ var init_AnimatedCounter = __esm({
|
|
|
5812
5852
|
setDisplayValue(to);
|
|
5813
5853
|
return;
|
|
5814
5854
|
}
|
|
5855
|
+
if (window.matchMedia?.("(prefers-reduced-motion: reduce)").matches) {
|
|
5856
|
+
setDisplayValue(to);
|
|
5857
|
+
return;
|
|
5858
|
+
}
|
|
5815
5859
|
const startTime = performance.now();
|
|
5816
5860
|
const diff = to - from;
|
|
5817
5861
|
function animate(currentTime) {
|
|
@@ -5833,7 +5877,7 @@ var init_AnimatedCounter = __esm({
|
|
|
5833
5877
|
};
|
|
5834
5878
|
}, [value, duration]);
|
|
5835
5879
|
const decimalPlaces = Number.isInteger(value) ? 0 : String(value).split(".")[1]?.length ?? 0;
|
|
5836
|
-
const formattedValue = displayValue
|
|
5880
|
+
const formattedValue = formatDisplay(displayValue, format, decimalPlaces);
|
|
5837
5881
|
return /* @__PURE__ */ jsxRuntime.jsxs(Typography, { variant: "h3", className: cn("tabular-nums", className), children: [
|
|
5838
5882
|
prefix,
|
|
5839
5883
|
formattedValue,
|
|
@@ -7077,14 +7121,29 @@ function recordTransition(trace) {
|
|
|
7077
7121
|
"pass"
|
|
7078
7122
|
);
|
|
7079
7123
|
} else {
|
|
7080
|
-
const
|
|
7081
|
-
|
|
7082
|
-
|
|
7083
|
-
|
|
7084
|
-
|
|
7085
|
-
"
|
|
7086
|
-
|
|
7124
|
+
const rendersEntityData = entry.effects.some(
|
|
7125
|
+
(e) => e.type === "render-ui" && JSON.stringify(e.args).includes("@entity.")
|
|
7126
|
+
);
|
|
7127
|
+
if (rendersEntityData) {
|
|
7128
|
+
const siblingSeeds = getState().transitions.some(
|
|
7129
|
+
(t) => t.event === "INIT" && t.effects.some(
|
|
7130
|
+
(e) => e.type === "fetch" || e.type === "set" && typeof e.args[0] === "string" && e.args[0].startsWith("@entity.")
|
|
7131
|
+
)
|
|
7087
7132
|
);
|
|
7133
|
+
if (siblingSeeds) {
|
|
7134
|
+
registerCheck(
|
|
7135
|
+
checkId,
|
|
7136
|
+
`INIT transition for "${entry.traitName}" has sibling entity-seed (shared entity)`,
|
|
7137
|
+
"pass"
|
|
7138
|
+
);
|
|
7139
|
+
} else {
|
|
7140
|
+
registerCheck(
|
|
7141
|
+
checkId,
|
|
7142
|
+
`INIT transition for "${entry.traitName}" missing fetch effect`,
|
|
7143
|
+
"fail",
|
|
7144
|
+
"Entity-bound render-ui without a fetch effect will show empty data"
|
|
7145
|
+
);
|
|
7146
|
+
}
|
|
7088
7147
|
}
|
|
7089
7148
|
}
|
|
7090
7149
|
}
|
|
@@ -8229,7 +8288,7 @@ function GameMenu({
|
|
|
8229
8288
|
logo,
|
|
8230
8289
|
className
|
|
8231
8290
|
}) {
|
|
8232
|
-
const resolvedOptions = options ?? menuItems ?? DEFAULT_MENU_OPTIONS;
|
|
8291
|
+
const resolvedOptions = (options?.length ? options : void 0) ?? (menuItems?.length ? menuItems : void 0) ?? DEFAULT_MENU_OPTIONS;
|
|
8233
8292
|
const eventBus = useEventBus();
|
|
8234
8293
|
const handleOptionClick = React81__namespace.useCallback(
|
|
8235
8294
|
(option) => {
|
|
@@ -9520,6 +9579,10 @@ function Canvas2D({
|
|
|
9520
9579
|
window.removeEventListener("keyup", onUp);
|
|
9521
9580
|
};
|
|
9522
9581
|
}, [keyMap, keyUpMap, eventBus]);
|
|
9582
|
+
React81.useEffect(() => {
|
|
9583
|
+
if (!keyMap && !keyUpMap) return;
|
|
9584
|
+
canvasRef.current?.focus();
|
|
9585
|
+
}, [keyMap, keyUpMap]);
|
|
9523
9586
|
if (error) {
|
|
9524
9587
|
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: [
|
|
9525
9588
|
/* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "alert-circle", size: "xl" }),
|
|
@@ -9568,7 +9631,7 @@ function Canvas2D({
|
|
|
9568
9631
|
onWheel: gestureHandlers.onWheel,
|
|
9569
9632
|
onContextMenu: (e) => e.preventDefault(),
|
|
9570
9633
|
className: "cursor-pointer touch-none",
|
|
9571
|
-
tabIndex: isFree ? 0 : void 0,
|
|
9634
|
+
tabIndex: isFree || keyMap || keyUpMap ? 0 : void 0,
|
|
9572
9635
|
style: {
|
|
9573
9636
|
width: viewportSize.width,
|
|
9574
9637
|
height: viewportSize.height
|
|
@@ -13819,7 +13882,8 @@ var init_LoadingState = __esm({
|
|
|
13819
13882
|
LoadingState = ({
|
|
13820
13883
|
title,
|
|
13821
13884
|
message,
|
|
13822
|
-
className
|
|
13885
|
+
className,
|
|
13886
|
+
fullPage = false
|
|
13823
13887
|
}) => {
|
|
13824
13888
|
const { t } = hooks.useTranslate();
|
|
13825
13889
|
const displayMessage = message ?? t("common.loading");
|
|
@@ -13828,7 +13892,8 @@ var init_LoadingState = __esm({
|
|
|
13828
13892
|
{
|
|
13829
13893
|
align: "center",
|
|
13830
13894
|
className: cn(
|
|
13831
|
-
"justify-center
|
|
13895
|
+
"justify-center",
|
|
13896
|
+
fullPage ? "fixed inset-0 z-[1000] py-12 bg-background/80 backdrop-blur-sm animate-overlay-in" : "py-12",
|
|
13832
13897
|
className
|
|
13833
13898
|
),
|
|
13834
13899
|
children: [
|
|
@@ -16980,7 +17045,7 @@ var init_BookCoverPage = __esm({
|
|
|
16980
17045
|
size: "lg",
|
|
16981
17046
|
action: "BOOK_START",
|
|
16982
17047
|
className: "mt-8",
|
|
16983
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", children: t("book.startReading") })
|
|
17048
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", color: "inherit", children: t("book.startReading") })
|
|
16984
17049
|
}
|
|
16985
17050
|
)
|
|
16986
17051
|
]
|
|
@@ -19225,8 +19290,9 @@ var init_Chart = __esm({
|
|
|
19225
19290
|
align: "center",
|
|
19226
19291
|
flex: true,
|
|
19227
19292
|
className: "min-w-0",
|
|
19293
|
+
style: { height: "100%" },
|
|
19228
19294
|
children: [
|
|
19229
|
-
/* @__PURE__ */ jsxRuntime.jsx(HStack, { gap: histogram ? "none" : "xs", align: "end",
|
|
19295
|
+
/* @__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) => {
|
|
19230
19296
|
const value = valueAt(s, label);
|
|
19231
19297
|
const barHeight = value / maxValue * 100;
|
|
19232
19298
|
const color = seriesColor(s, sIdx);
|
|
@@ -19239,6 +19305,8 @@ var init_Chart = __esm({
|
|
|
19239
19305
|
),
|
|
19240
19306
|
style: {
|
|
19241
19307
|
height: `${barHeight}%`,
|
|
19308
|
+
// Cap width so a lone category doesn't paint the whole plot as one solid block; narrow columns are unaffected (flex-1 binds first).
|
|
19309
|
+
...!histogram && { maxWidth: 72 },
|
|
19242
19310
|
backgroundColor: color
|
|
19243
19311
|
},
|
|
19244
19312
|
onClick: () => onPointClick?.(
|
|
@@ -19273,8 +19341,9 @@ var init_Chart = __esm({
|
|
|
19273
19341
|
align: "center",
|
|
19274
19342
|
flex: true,
|
|
19275
19343
|
className: "min-w-0",
|
|
19344
|
+
style: { height: "100%" },
|
|
19276
19345
|
children: [
|
|
19277
|
-
/* @__PURE__ */ jsxRuntime.jsx(VStack, { gap: "none", className: "w-full
|
|
19346
|
+
/* @__PURE__ */ jsxRuntime.jsx(VStack, { gap: "none", className: "w-full flex-1 min-h-0", justify: "end", children: series.map((s, sIdx) => {
|
|
19278
19347
|
const value = valueAt(s, label);
|
|
19279
19348
|
const ratio = stack === "normalize" ? total === 0 ? 0 : value / total * 100 : value / maxValue * 100;
|
|
19280
19349
|
const color = seriesColor(s, sIdx);
|
|
@@ -19319,6 +19388,7 @@ var init_Chart = __esm({
|
|
|
19319
19388
|
const innerRadius = donut ? radius * 0.6 : 0;
|
|
19320
19389
|
const center = size / 2;
|
|
19321
19390
|
const segments = React81.useMemo(() => {
|
|
19391
|
+
if (!Number.isFinite(total) || total <= 0) return [];
|
|
19322
19392
|
let currentAngle = -Math.PI / 2;
|
|
19323
19393
|
return data.map((point, idx) => {
|
|
19324
19394
|
const angle = point.value / total * 2 * Math.PI;
|
|
@@ -19330,13 +19400,25 @@ var init_Chart = __esm({
|
|
|
19330
19400
|
const y1 = center + radius * Math.sin(startAngle);
|
|
19331
19401
|
const x2 = center + radius * Math.cos(endAngle);
|
|
19332
19402
|
const y2 = center + radius * Math.sin(endAngle);
|
|
19403
|
+
const fullCircle = angle >= 2 * Math.PI - 1e-9;
|
|
19404
|
+
const midAngle = startAngle + angle / 2;
|
|
19405
|
+
const xm = center + radius * Math.cos(midAngle);
|
|
19406
|
+
const ym = center + radius * Math.sin(midAngle);
|
|
19333
19407
|
let d;
|
|
19334
19408
|
if (innerRadius > 0) {
|
|
19335
19409
|
const ix1 = center + innerRadius * Math.cos(startAngle);
|
|
19336
19410
|
const iy1 = center + innerRadius * Math.sin(startAngle);
|
|
19337
19411
|
const ix2 = center + innerRadius * Math.cos(endAngle);
|
|
19338
19412
|
const iy2 = center + innerRadius * Math.sin(endAngle);
|
|
19339
|
-
|
|
19413
|
+
if (fullCircle) {
|
|
19414
|
+
const ixm = center + innerRadius * Math.cos(midAngle);
|
|
19415
|
+
const iym = center + innerRadius * Math.sin(midAngle);
|
|
19416
|
+
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`;
|
|
19417
|
+
} else {
|
|
19418
|
+
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`;
|
|
19419
|
+
}
|
|
19420
|
+
} else if (fullCircle) {
|
|
19421
|
+
d = `M ${center} ${center} L ${x1} ${y1} A ${radius} ${radius} 0 1 1 ${xm} ${ym} A ${radius} ${radius} 0 1 1 ${x2} ${y2} Z`;
|
|
19340
19422
|
} else {
|
|
19341
19423
|
d = `M ${center} ${center} L ${x1} ${y1} A ${radius} ${radius} 0 ${largeArc} 1 ${x2} ${y2} Z`;
|
|
19342
19424
|
}
|
|
@@ -22349,10 +22431,10 @@ function DataGrid({
|
|
|
22349
22431
|
] }),
|
|
22350
22432
|
badgeFields.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(HStack, { gap: "xs", className: "flex-wrap", children: badgeFields.map((field) => {
|
|
22351
22433
|
const val = getNestedValue(itemData, field.name);
|
|
22352
|
-
if (val === void 0 || val === null) return null;
|
|
22434
|
+
if (val === void 0 || val === null || val === "") return null;
|
|
22353
22435
|
return /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "xs", className: "items-center", children: [
|
|
22354
22436
|
field.icon && renderIconInput(field.icon, { size: "xs" }),
|
|
22355
|
-
/* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: resolveBadgeVariant(field, String(val)), children:
|
|
22437
|
+
/* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: resolveBadgeVariant(field, String(val)), children: formatValue(val, field.format) })
|
|
22356
22438
|
] }, field.name);
|
|
22357
22439
|
}) })
|
|
22358
22440
|
] }),
|
|
@@ -29640,6 +29722,11 @@ var init_VoteStack = __esm({
|
|
|
29640
29722
|
{
|
|
29641
29723
|
className: cn(
|
|
29642
29724
|
"inline-flex items-center justify-center",
|
|
29725
|
+
// Shrink-wrap in stretch contexts (slot/sidecar wrappers are
|
|
29726
|
+
// flex-column with stretch alignment): without this the root spans
|
|
29727
|
+
// the full wrapper width and the count row's `w-full` turns the
|
|
29728
|
+
// compact pill into a page-wide band.
|
|
29729
|
+
"w-fit",
|
|
29643
29730
|
variant === "vertical" ? "flex-col" : "flex-row",
|
|
29644
29731
|
"rounded-sm",
|
|
29645
29732
|
"border-[length:var(--border-width)] border-border",
|
|
@@ -33545,7 +33632,7 @@ var init_Sidebar = __esm({
|
|
|
33545
33632
|
isActive ? [
|
|
33546
33633
|
"bg-primary text-primary-foreground",
|
|
33547
33634
|
"font-medium shadow-sm",
|
|
33548
|
-
"border-primary translate-x-1 -translate-y-0.5"
|
|
33635
|
+
"border-primary translate-x-1 rtl:-translate-x-1 -translate-y-0.5"
|
|
33549
33636
|
].join(" ") : [
|
|
33550
33637
|
"text-foreground",
|
|
33551
33638
|
"hover:bg-muted hover:border-border",
|
|
@@ -33555,10 +33642,10 @@ var init_Sidebar = __esm({
|
|
|
33555
33642
|
title: collapsed ? item.label : void 0,
|
|
33556
33643
|
children: [
|
|
33557
33644
|
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") })),
|
|
33558
|
-
!collapsed && /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", color: isActive ? "inherit" : "primary", className: "font-medium truncate flex-1 text-
|
|
33645
|
+
!collapsed && /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", color: isActive ? "inherit" : "primary", className: "font-medium truncate flex-1 text-start", children: item.label }),
|
|
33559
33646
|
!collapsed && item.badge !== void 0 && /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: "danger", size: "sm", children: item.badge }),
|
|
33560
33647
|
collapsed && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: cn(
|
|
33561
|
-
"absolute
|
|
33648
|
+
"absolute start-full ms-2 px-2 py-1 text-xs opacity-0 group-hover:opacity-100",
|
|
33562
33649
|
"pointer-events-none whitespace-nowrap z-50 transition-opacity",
|
|
33563
33650
|
"bg-primary text-primary-foreground",
|
|
33564
33651
|
"border-[length:var(--border-width-thin)] border-border",
|
|
@@ -33613,7 +33700,7 @@ var init_Sidebar = __esm({
|
|
|
33613
33700
|
as: "aside",
|
|
33614
33701
|
className: cn(
|
|
33615
33702
|
"flex flex-col h-full",
|
|
33616
|
-
"bg-card border-
|
|
33703
|
+
"bg-card border-e border-border",
|
|
33617
33704
|
"transition-all duration-300 ease-in-out",
|
|
33618
33705
|
collapsed ? "w-20" : "w-64",
|
|
33619
33706
|
className
|
|
@@ -34774,7 +34861,7 @@ function resolveColor3(color, el) {
|
|
|
34774
34861
|
function truncateLabel(label) {
|
|
34775
34862
|
return label.length > MAX_LABEL_CHARS ? label.slice(0, MAX_LABEL_CHARS - 1) + "\u2026" : label;
|
|
34776
34863
|
}
|
|
34777
|
-
var GROUP_COLORS2, GROUP_GRAVITY, UNGROUPED_GRAVITY, labelMeasureCtx, MAX_LABEL_CHARS, GraphCanvas;
|
|
34864
|
+
var GROUP_COLORS2, GROUP_GRAVITY, UNGROUPED_GRAVITY, labelMeasureCtx, MAX_LABEL_CHARS, NO_NODES, NO_EDGES, NO_SIM, GraphCanvas;
|
|
34778
34865
|
var init_GraphCanvas = __esm({
|
|
34779
34866
|
"components/core/molecules/GraphCanvas.tsx"() {
|
|
34780
34867
|
"use client";
|
|
@@ -34798,11 +34885,14 @@ var init_GraphCanvas = __esm({
|
|
|
34798
34885
|
UNGROUPED_GRAVITY = 0.02;
|
|
34799
34886
|
labelMeasureCtx = null;
|
|
34800
34887
|
MAX_LABEL_CHARS = 22;
|
|
34888
|
+
NO_NODES = [];
|
|
34889
|
+
NO_EDGES = [];
|
|
34890
|
+
NO_SIM = [];
|
|
34801
34891
|
GraphCanvas = ({
|
|
34802
34892
|
title,
|
|
34803
|
-
nodes: propNodes =
|
|
34804
|
-
edges: propEdges =
|
|
34805
|
-
similarity: propSimilarity =
|
|
34893
|
+
nodes: propNodes = NO_NODES,
|
|
34894
|
+
edges: propEdges = NO_EDGES,
|
|
34895
|
+
similarity: propSimilarity = NO_SIM,
|
|
34806
34896
|
height = 400,
|
|
34807
34897
|
showLabels = true,
|
|
34808
34898
|
interactive = true,
|
|
@@ -34852,6 +34942,7 @@ var init_GraphCanvas = __esm({
|
|
|
34852
34942
|
const interactionRef = React81.useRef({
|
|
34853
34943
|
mode: "none",
|
|
34854
34944
|
dragNodeId: null,
|
|
34945
|
+
pressedNodeId: null,
|
|
34855
34946
|
startMouse: { x: 0, y: 0 },
|
|
34856
34947
|
startOffset: { x: 0, y: 0 },
|
|
34857
34948
|
downPos: { x: 0, y: 0 }
|
|
@@ -34899,6 +34990,11 @@ var init_GraphCanvas = __esm({
|
|
|
34899
34990
|
() => [...new Set(propNodes.map((n) => n.group).filter(Boolean))],
|
|
34900
34991
|
[propNodes]
|
|
34901
34992
|
);
|
|
34993
|
+
const nodesKey = React81.useMemo(() => propNodes.map((n) => n.id).join(""), [propNodes]);
|
|
34994
|
+
const edgesKey = React81.useMemo(
|
|
34995
|
+
() => propEdges.map((e) => `${e.source}${e.target}`).join(""),
|
|
34996
|
+
[propEdges]
|
|
34997
|
+
);
|
|
34902
34998
|
React81.useEffect(() => {
|
|
34903
34999
|
const canvas = canvasRef.current;
|
|
34904
35000
|
if (!canvas || propNodes.length === 0) return;
|
|
@@ -35079,7 +35175,7 @@ var init_GraphCanvas = __esm({
|
|
|
35079
35175
|
return () => {
|
|
35080
35176
|
cancelAnimationFrame(animRef.current);
|
|
35081
35177
|
};
|
|
35082
|
-
}, [
|
|
35178
|
+
}, [nodesKey, edgesKey, propSimilarity, layout, repulsion, linkDistance, nodeSpacing, showLabels]);
|
|
35083
35179
|
React81.useEffect(() => {
|
|
35084
35180
|
const canvas = canvasRef.current;
|
|
35085
35181
|
if (!canvas) return;
|
|
@@ -35209,6 +35305,7 @@ var init_GraphCanvas = __esm({
|
|
|
35209
35305
|
const cancelSinglePointer = React81.useCallback(() => {
|
|
35210
35306
|
interactionRef.current.mode = "none";
|
|
35211
35307
|
interactionRef.current.dragNodeId = null;
|
|
35308
|
+
interactionRef.current.pressedNodeId = null;
|
|
35212
35309
|
}, []);
|
|
35213
35310
|
const handlePointerDown = React81.useCallback(
|
|
35214
35311
|
(e) => {
|
|
@@ -35219,6 +35316,7 @@ var init_GraphCanvas = __esm({
|
|
|
35219
35316
|
state.downPos = { x: e.clientX, y: e.clientY };
|
|
35220
35317
|
state.startMouse = { x: e.clientX, y: e.clientY };
|
|
35221
35318
|
state.startOffset = { ...offset };
|
|
35319
|
+
state.pressedNodeId = node?.id ?? null;
|
|
35222
35320
|
if (draggable && node) {
|
|
35223
35321
|
state.mode = "dragging";
|
|
35224
35322
|
state.dragNodeId = node.id;
|
|
@@ -35270,7 +35368,8 @@ var init_GraphCanvas = __esm({
|
|
|
35270
35368
|
if (moved < 4) {
|
|
35271
35369
|
const coords = toCoords(e);
|
|
35272
35370
|
if (!coords) return;
|
|
35273
|
-
const node = nodeAt(coords.graphX, coords.graphY);
|
|
35371
|
+
const node = (state.pressedNodeId ? nodesRef.current.find((n) => n.id === state.pressedNodeId) : void 0) ?? nodeAt(coords.graphX, coords.graphY);
|
|
35372
|
+
state.pressedNodeId = null;
|
|
35274
35373
|
if (node) {
|
|
35275
35374
|
if (node.badge && node.badge > 1 && onBadgeClick) {
|
|
35276
35375
|
const r = (node.size || 8) + (selectedNodeId === node.id ? 4 : 0);
|
|
@@ -35290,6 +35389,7 @@ var init_GraphCanvas = __esm({
|
|
|
35290
35389
|
);
|
|
35291
35390
|
const handlePointerLeave = React81.useCallback(() => {
|
|
35292
35391
|
setHoveredNode(null);
|
|
35392
|
+
interactionRef.current.pressedNodeId = null;
|
|
35293
35393
|
}, []);
|
|
35294
35394
|
const gestureHandlers = useCanvasGestures({
|
|
35295
35395
|
canvasRef,
|
|
@@ -38241,8 +38341,17 @@ var init_MediaGallery = __esm({
|
|
|
38241
38341
|
const eventBus = useEventBus();
|
|
38242
38342
|
const { t } = hooks.useTranslate();
|
|
38243
38343
|
const [lightboxItem, setLightboxItem] = React81.useState(null);
|
|
38344
|
+
const [failedIds, setFailedIds] = React81.useState(/* @__PURE__ */ new Set());
|
|
38244
38345
|
const closeLightbox = React81.useCallback(() => setLightboxItem(null), []);
|
|
38245
38346
|
useEventListener("UI:LIGHTBOX_CLOSE", closeLightbox);
|
|
38347
|
+
const handleImageError = React81.useCallback((id) => {
|
|
38348
|
+
setFailedIds((prev) => {
|
|
38349
|
+
if (prev.has(id)) return prev;
|
|
38350
|
+
const next = new Set(prev);
|
|
38351
|
+
next.add(id);
|
|
38352
|
+
return next;
|
|
38353
|
+
});
|
|
38354
|
+
}, []);
|
|
38246
38355
|
const handleItemClick = React81.useCallback(
|
|
38247
38356
|
(item) => {
|
|
38248
38357
|
if (selectable) {
|
|
@@ -38258,7 +38367,7 @@ var init_MediaGallery = __esm({
|
|
|
38258
38367
|
);
|
|
38259
38368
|
const entityData = Array.isArray(entity) ? entity : [];
|
|
38260
38369
|
const items = React81__namespace.default.useMemo(() => {
|
|
38261
|
-
if (propItems) return propItems;
|
|
38370
|
+
if (propItems && propItems.length > 0) return propItems;
|
|
38262
38371
|
if (entityData.length === 0) return [];
|
|
38263
38372
|
return entityData.map((record, idx) => {
|
|
38264
38373
|
return {
|
|
@@ -38341,13 +38450,14 @@ var init_MediaGallery = __esm({
|
|
|
38341
38450
|
),
|
|
38342
38451
|
onClick: () => handleItemClick(item),
|
|
38343
38452
|
children: [
|
|
38344
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
38453
|
+
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(
|
|
38345
38454
|
"img",
|
|
38346
38455
|
{
|
|
38347
38456
|
src: item.thumbnail || item.src,
|
|
38348
38457
|
alt: item.alt || item.caption || "",
|
|
38349
38458
|
className: "w-full h-full object-cover",
|
|
38350
|
-
loading: "lazy"
|
|
38459
|
+
loading: "lazy",
|
|
38460
|
+
onError: () => handleImageError(item.id)
|
|
38351
38461
|
}
|
|
38352
38462
|
),
|
|
38353
38463
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -41854,6 +41964,11 @@ var init_TeamOrganism = __esm({
|
|
|
41854
41964
|
TeamOrganism.displayName = "TeamOrganism";
|
|
41855
41965
|
}
|
|
41856
41966
|
});
|
|
41967
|
+
function formatDate4(value) {
|
|
41968
|
+
const d = new Date(value);
|
|
41969
|
+
if (isNaN(d.getTime())) return value;
|
|
41970
|
+
return d.toLocaleDateString(void 0, { year: "numeric", month: "short", day: "numeric" });
|
|
41971
|
+
}
|
|
41857
41972
|
var lookStyles10, STATUS_STYLES2, Timeline;
|
|
41858
41973
|
var init_Timeline = __esm({
|
|
41859
41974
|
"components/core/organisms/Timeline.tsx"() {
|
|
@@ -41981,7 +42096,7 @@ var init_Timeline = __esm({
|
|
|
41981
42096
|
/* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "xs", className: cn("flex-1 min-w-0", !isLast && "pb-6"), children: [
|
|
41982
42097
|
/* @__PURE__ */ jsxRuntime.jsxs(HStack, { justify: "between", align: "start", wrap: true, children: [
|
|
41983
42098
|
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", weight: "semibold", children: item.title }),
|
|
41984
|
-
item.date && /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "caption", color: "secondary", className: "flex-shrink-0", children: item.date })
|
|
42099
|
+
item.date && /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "caption", color: "secondary", className: "flex-shrink-0", children: formatDate4(item.date) })
|
|
41985
42100
|
] }),
|
|
41986
42101
|
item.description && /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", color: "secondary", children: item.description }),
|
|
41987
42102
|
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)) }),
|
|
@@ -43193,7 +43308,7 @@ function substituteTraitRefsDeep(value, pathKey) {
|
|
|
43193
43308
|
}
|
|
43194
43309
|
return value;
|
|
43195
43310
|
}
|
|
43196
|
-
function renderPatternProps(props, onDismiss) {
|
|
43311
|
+
function renderPatternProps(props, onDismiss, propsSchema) {
|
|
43197
43312
|
const rendered = {};
|
|
43198
43313
|
for (const [key, value] of Object.entries(props)) {
|
|
43199
43314
|
if (key === "children") {
|
|
@@ -43211,9 +43326,10 @@ function renderPatternProps(props, onDismiss) {
|
|
|
43211
43326
|
};
|
|
43212
43327
|
rendered[key] = /* @__PURE__ */ jsxRuntime.jsx(SlotContentRenderer, { content: childContent, onDismiss });
|
|
43213
43328
|
} else if (Array.isArray(value)) {
|
|
43329
|
+
const isDataArray = propsSchema?.[key]?.items?.types?.includes("object") ?? false;
|
|
43214
43330
|
rendered[key] = value.map((item, i) => {
|
|
43215
43331
|
const el = item;
|
|
43216
|
-
if (isPatternConfig(el)) {
|
|
43332
|
+
if (!isDataArray && isPatternConfig(el)) {
|
|
43217
43333
|
const nestedProps = {};
|
|
43218
43334
|
for (const [k, v] of Object.entries(el)) {
|
|
43219
43335
|
if (k !== "type") nestedProps[k] = v;
|
|
@@ -43301,14 +43417,15 @@ function SlotContentRenderer({
|
|
|
43301
43417
|
);
|
|
43302
43418
|
}
|
|
43303
43419
|
}
|
|
43304
|
-
const renderedProps = renderPatternProps(restProps, onDismiss);
|
|
43305
43420
|
const patternDef = patterns.getPatternDefinition(content.pattern);
|
|
43306
43421
|
const propsSchema = patternDef?.propsSchema;
|
|
43422
|
+
const renderedProps = renderPatternProps(restProps, onDismiss, propsSchema);
|
|
43307
43423
|
if (propsSchema) {
|
|
43308
43424
|
for (const [propKey, propValue] of Object.entries(renderedProps)) {
|
|
43309
43425
|
if (typeof propValue !== "string") continue;
|
|
43310
43426
|
const propDef = propsSchema[propKey];
|
|
43311
43427
|
if (!propDef || propDef.kind !== "callback") continue;
|
|
43428
|
+
if (propValue === "") continue;
|
|
43312
43429
|
renderedProps[propKey] = ui.wrapCallbackForEvent(
|
|
43313
43430
|
`UI:${propValue}`,
|
|
43314
43431
|
propDef.callbackArgs,
|
|
@@ -43591,6 +43708,7 @@ function useSharedEntityStore() {
|
|
|
43591
43708
|
}
|
|
43592
43709
|
return storeRef.current;
|
|
43593
43710
|
}
|
|
43711
|
+
React81.createContext(null);
|
|
43594
43712
|
function runTickFrame(entityId, orderedWriters, store) {
|
|
43595
43713
|
let scratch = store.getSnapshot(entityId);
|
|
43596
43714
|
for (const writer of orderedWriters) {
|
|
@@ -43826,6 +43944,11 @@ var SYNC_TICK_OPERATORS = /* @__PURE__ */ new Set([
|
|
|
43826
43944
|
"do",
|
|
43827
43945
|
"when"
|
|
43828
43946
|
]);
|
|
43947
|
+
var REACTIVE_REPAINT_PATTERN_TYPES = /* @__PURE__ */ new Set([
|
|
43948
|
+
"canvas",
|
|
43949
|
+
"game-hud",
|
|
43950
|
+
"game-shell"
|
|
43951
|
+
]);
|
|
43829
43952
|
var LIFECYCLE_EVENTS = ["INIT", "LOAD", "$MOUNT"];
|
|
43830
43953
|
function toTraitDefinition(binding) {
|
|
43831
43954
|
return {
|
|
@@ -44078,6 +44201,8 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
44078
44201
|
}, [traitStates]);
|
|
44079
44202
|
const traitSnapshotDataRef = React81.useRef(/* @__PURE__ */ new Map());
|
|
44080
44203
|
const traitFieldStatesRef = React81.useRef(/* @__PURE__ */ new Map());
|
|
44204
|
+
const lastCanvasRenderUiRef = React81.useRef(/* @__PURE__ */ new Map());
|
|
44205
|
+
const executeTransitionEffectsRef = React81.useRef(null);
|
|
44081
44206
|
React81.useEffect(() => {
|
|
44082
44207
|
const mgr = managerRef.current;
|
|
44083
44208
|
const bindings = traitBindingsRef.current;
|
|
@@ -44118,11 +44243,9 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
44118
44243
|
bindTraitStateGetter((traitName) => {
|
|
44119
44244
|
const allStates = newManager.getAllStates();
|
|
44120
44245
|
if (allStates instanceof Map) {
|
|
44121
|
-
|
|
44122
|
-
return typeof val === "string" ? val : void 0;
|
|
44246
|
+
return allStates.get(traitName)?.currentState;
|
|
44123
44247
|
}
|
|
44124
|
-
|
|
44125
|
-
return typeof state === "string" ? state : void 0;
|
|
44248
|
+
return newManager.getState(traitName)?.currentState;
|
|
44126
44249
|
});
|
|
44127
44250
|
const snapshotUnregs = [];
|
|
44128
44251
|
for (const binding of traitBindingsRef.current) {
|
|
@@ -44207,6 +44330,15 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
44207
44330
|
const existing = pendingSlots.get(slot) || [];
|
|
44208
44331
|
existing.push({ pattern, props: props || {} });
|
|
44209
44332
|
pendingSlots.set(slot, existing);
|
|
44333
|
+
const patternType = pattern?.type;
|
|
44334
|
+
if (patternType !== void 0 && REACTIVE_REPAINT_PATTERN_TYPES.has(patternType)) {
|
|
44335
|
+
const rawForSlot = effects.filter(
|
|
44336
|
+
(e) => Array.isArray(e) && (e[0] === "render-ui" || e[0] === "render") && e[1] === slot
|
|
44337
|
+
);
|
|
44338
|
+
if (rawForSlot.length > 0) {
|
|
44339
|
+
lastCanvasRenderUiRef.current.set(traitName, rawForSlot);
|
|
44340
|
+
}
|
|
44341
|
+
}
|
|
44210
44342
|
},
|
|
44211
44343
|
clearSlot: (slot) => {
|
|
44212
44344
|
pendingSlots.set(slot, []);
|
|
@@ -44277,11 +44409,15 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
44277
44409
|
notify: clientHandlers.notify
|
|
44278
44410
|
};
|
|
44279
44411
|
}
|
|
44412
|
+
const sharedWrites = [];
|
|
44280
44413
|
const baseSet = handlers.set;
|
|
44281
44414
|
handlers = {
|
|
44282
44415
|
...handlers,
|
|
44283
44416
|
set: async (targetId, field, value) => {
|
|
44284
44417
|
if (baseSet) await baseSet(targetId, field, value);
|
|
44418
|
+
if (sharedKey !== void 0) {
|
|
44419
|
+
sharedWrites.push({ field, value });
|
|
44420
|
+
}
|
|
44285
44421
|
log9.debug("set:write", {
|
|
44286
44422
|
traitName,
|
|
44287
44423
|
field,
|
|
@@ -44357,7 +44493,10 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
44357
44493
|
});
|
|
44358
44494
|
}
|
|
44359
44495
|
if (sharedKey !== void 0) {
|
|
44360
|
-
sharedEntityStore.commit(
|
|
44496
|
+
sharedEntityStore.commit(
|
|
44497
|
+
sharedKey,
|
|
44498
|
+
core.mergeEntityFrame(sharedEntityStore.getSnapshot(sharedKey), sharedWrites)
|
|
44499
|
+
);
|
|
44361
44500
|
}
|
|
44362
44501
|
log9.debug("effects:executed", () => ({
|
|
44363
44502
|
traitName,
|
|
@@ -44383,6 +44522,38 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
44383
44522
|
entity: binding.linkedEntity
|
|
44384
44523
|
});
|
|
44385
44524
|
}
|
|
44525
|
+
if (pendingSlots.size === 0 && effectsCallOp(effects, SHARED_ENTITY_WRITE_OPS)) {
|
|
44526
|
+
const stashed = lastCanvasRenderUiRef.current.get(traitName);
|
|
44527
|
+
if (stashed !== void 0 && stashed.length > 0) {
|
|
44528
|
+
await executor.executeAll(stashed);
|
|
44529
|
+
for (const [slot, patterns] of pendingSlots) {
|
|
44530
|
+
flushSlot(traitName, slot, patterns, {
|
|
44531
|
+
event: flushEvent,
|
|
44532
|
+
state: previousState,
|
|
44533
|
+
entity: binding.linkedEntity
|
|
44534
|
+
});
|
|
44535
|
+
}
|
|
44536
|
+
}
|
|
44537
|
+
if (sharedKey !== void 0 && executeTransitionEffectsRef.current !== null) {
|
|
44538
|
+
for (const sibling of traitBindingsRef.current) {
|
|
44539
|
+
const siblingName = sibling.trait.name;
|
|
44540
|
+
if (siblingName === traitName) continue;
|
|
44541
|
+
if (sharedKeyByTraitNameRef.current.get(siblingName) !== sharedKey) continue;
|
|
44542
|
+
const siblingStash = lastCanvasRenderUiRef.current.get(siblingName);
|
|
44543
|
+
if (siblingStash === void 0 || siblingStash.length === 0) continue;
|
|
44544
|
+
const siblingState = traitStatesRef.current.get(siblingName)?.currentState ?? "";
|
|
44545
|
+
await executeTransitionEffectsRef.current({
|
|
44546
|
+
binding: sibling,
|
|
44547
|
+
effects: siblingStash,
|
|
44548
|
+
previousState: siblingState,
|
|
44549
|
+
newState: siblingState,
|
|
44550
|
+
flushEvent: `${flushEvent}:repaint`,
|
|
44551
|
+
syncOnly,
|
|
44552
|
+
log: log9
|
|
44553
|
+
});
|
|
44554
|
+
}
|
|
44555
|
+
}
|
|
44556
|
+
}
|
|
44386
44557
|
} catch (error) {
|
|
44387
44558
|
log9.error("effects:error", {
|
|
44388
44559
|
traitName,
|
|
@@ -44394,6 +44565,9 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
44394
44565
|
}
|
|
44395
44566
|
return emittedDuringExec;
|
|
44396
44567
|
}, [eventBus, flushSlot, sharedEntityStore]);
|
|
44568
|
+
React81.useEffect(() => {
|
|
44569
|
+
executeTransitionEffectsRef.current = executeTransitionEffects;
|
|
44570
|
+
}, [executeTransitionEffects]);
|
|
44397
44571
|
const runTickEffects = React81.useCallback((tick, binding) => {
|
|
44398
44572
|
const traitName = binding.trait.name;
|
|
44399
44573
|
const currentState = traitStatesRef.current.get(traitName)?.currentState ?? "";
|
|
@@ -44456,6 +44630,24 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
44456
44630
|
({ binding, tick }) => createSharedEntityWriter(binding, tick, traitStatesRef, emitFromSharedWriter)
|
|
44457
44631
|
);
|
|
44458
44632
|
runTickFrame(group.storeKey, writers, sharedEntityStore);
|
|
44633
|
+
const repaint = executeTransitionEffectsRef.current;
|
|
44634
|
+
if (repaint !== null) {
|
|
44635
|
+
for (const renderBinding of group.renderBindings) {
|
|
44636
|
+
const renderTraitName = renderBinding.trait.name;
|
|
44637
|
+
const stash = lastCanvasRenderUiRef.current.get(renderTraitName);
|
|
44638
|
+
if (stash === void 0 || stash.length === 0) continue;
|
|
44639
|
+
const renderState = traitStatesRef.current.get(renderTraitName)?.currentState ?? "";
|
|
44640
|
+
void repaint({
|
|
44641
|
+
binding: renderBinding,
|
|
44642
|
+
effects: stash,
|
|
44643
|
+
previousState: renderState,
|
|
44644
|
+
newState: renderState,
|
|
44645
|
+
flushEvent: "tick:repaint",
|
|
44646
|
+
syncOnly: true,
|
|
44647
|
+
log: sharedEntityLog
|
|
44648
|
+
});
|
|
44649
|
+
}
|
|
44650
|
+
}
|
|
44459
44651
|
};
|
|
44460
44652
|
if (interval === "frame") {
|
|
44461
44653
|
scheduler.add(0, onDue);
|
|
@@ -44505,6 +44697,13 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
44505
44697
|
entityByTrait[name] = fields;
|
|
44506
44698
|
}
|
|
44507
44699
|
}
|
|
44700
|
+
for (const binding of bindings) {
|
|
44701
|
+
const name = binding.trait.name;
|
|
44702
|
+
const sharedKey = sharedKeyByTraitNameRef.current.get(name);
|
|
44703
|
+
if (sharedKey !== void 0) {
|
|
44704
|
+
entityByTrait[name] = { ...sharedEntityStore.getSnapshot(sharedKey) };
|
|
44705
|
+
}
|
|
44706
|
+
}
|
|
44508
44707
|
const results = currentManager.sendEvent(
|
|
44509
44708
|
normalizedEvent,
|
|
44510
44709
|
payload,
|
|
@@ -44658,7 +44857,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
44658
44857
|
}
|
|
44659
44858
|
await onEventProcessed(normalizedEvent, payload, dispatchedOrbitals);
|
|
44660
44859
|
}
|
|
44661
|
-
}, [entities, eventBus]);
|
|
44860
|
+
}, [entities, eventBus, sharedEntityStore]);
|
|
44662
44861
|
const drainEventQueue = React81.useCallback(async () => {
|
|
44663
44862
|
if (processingRef.current) return;
|
|
44664
44863
|
processingRef.current = true;
|
|
@@ -44728,6 +44927,24 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
44728
44927
|
});
|
|
44729
44928
|
}
|
|
44730
44929
|
}
|
|
44930
|
+
const bareCascadeKeys = /* @__PURE__ */ new Set();
|
|
44931
|
+
for (const binding of traitBindings) {
|
|
44932
|
+
for (const transition of binding.trait.transitions) {
|
|
44933
|
+
const eventKey = transition.event;
|
|
44934
|
+
if (LIFECYCLE_EVENTS.includes(eventKey)) continue;
|
|
44935
|
+
if (bareCascadeKeys.has(eventKey)) continue;
|
|
44936
|
+
bareCascadeKeys.add(eventKey);
|
|
44937
|
+
const bareKey = `UI:${eventKey}`;
|
|
44938
|
+
const unsub = eventBus.on(bareKey, (event) => {
|
|
44939
|
+
crossTraitLog.debug("bare-cascade:fire", { bareKey, eventKey });
|
|
44940
|
+
enqueueAndDrain(eventKey, event.payload);
|
|
44941
|
+
});
|
|
44942
|
+
unsubscribes.push(() => {
|
|
44943
|
+
crossTraitLog.debug("bare-cascade:unsubscribe", { bareKey, eventKey });
|
|
44944
|
+
unsub();
|
|
44945
|
+
});
|
|
44946
|
+
}
|
|
44947
|
+
}
|
|
44731
44948
|
for (const binding of traitBindings) {
|
|
44732
44949
|
const ownOrbital = orbitalsByTrait?.[binding.trait.name];
|
|
44733
44950
|
const listens = binding.trait.listens ?? [];
|
|
@@ -44912,9 +45129,16 @@ function normalizeChild(child) {
|
|
|
44912
45129
|
props: { ...rest, ...normalizedChildren !== void 0 ? { children: normalizedChildren } : {} }
|
|
44913
45130
|
};
|
|
44914
45131
|
}
|
|
44915
|
-
function applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits) {
|
|
45132
|
+
function applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits, activeTraits) {
|
|
44916
45133
|
for (const eff of effects) {
|
|
44917
45134
|
if (eff.type === "render-ui" && eff.slot && eff.pattern) {
|
|
45135
|
+
if (eff.traitName && activeTraits && !activeTraits.has(eff.traitName)) {
|
|
45136
|
+
xOrbitalLog.debug("slot:off-page-trait-skipped", {
|
|
45137
|
+
sourceTrait: eff.traitName,
|
|
45138
|
+
slot: eff.slot
|
|
45139
|
+
});
|
|
45140
|
+
continue;
|
|
45141
|
+
}
|
|
44918
45142
|
const patternRecord = eff.pattern;
|
|
44919
45143
|
const { type: patternType, children, ...inlineProps } = patternRecord;
|
|
44920
45144
|
const normalizedChildren = Array.isArray(children) ? children.map((c) => normalizeChild(c)) : children;
|
|
@@ -44955,8 +45179,38 @@ function applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits) {
|
|
|
44955
45179
|
}
|
|
44956
45180
|
}
|
|
44957
45181
|
}
|
|
44958
|
-
function
|
|
45182
|
+
function collectServerActiveTraits(ir, allTraits, mountedTraitNames) {
|
|
45183
|
+
if (!ir?.pages || ir.pages.size <= 1) return void 0;
|
|
45184
|
+
const pageBound = /* @__PURE__ */ new Set();
|
|
45185
|
+
for (const page of ir.pages.values()) {
|
|
45186
|
+
const queue = page.traits.map((b) => b.trait.name).filter((n) => !!n);
|
|
45187
|
+
for (const name of queue) {
|
|
45188
|
+
if (pageBound.has(name)) continue;
|
|
45189
|
+
pageBound.add(name);
|
|
45190
|
+
const rt = allTraits.get(name);
|
|
45191
|
+
if (!rt) continue;
|
|
45192
|
+
queue.push(...ui.collectTraitRefsFromResolvedTrait(rt));
|
|
45193
|
+
}
|
|
45194
|
+
}
|
|
45195
|
+
const active = new Set(mountedTraitNames);
|
|
45196
|
+
for (const name of allTraits.keys()) {
|
|
45197
|
+
if (!pageBound.has(name)) active.add(name);
|
|
45198
|
+
}
|
|
45199
|
+
return active;
|
|
45200
|
+
}
|
|
45201
|
+
function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFallback, persistence, traitConfigsByName, orbitalsByTrait, embeddedTraits, serverActiveTraits }) {
|
|
44959
45202
|
const bridge = providers.useServerBridge();
|
|
45203
|
+
const activeTraitNames = React81.useMemo(
|
|
45204
|
+
() => new Set(traits2.map((b) => b.trait.name).filter((n) => !!n)),
|
|
45205
|
+
[traits2]
|
|
45206
|
+
);
|
|
45207
|
+
const withActiveTraits = React81.useCallback(
|
|
45208
|
+
(payload) => {
|
|
45209
|
+
if (!serverActiveTraits || serverActiveTraits.size === 0) return payload;
|
|
45210
|
+
return { ...payload ?? {}, _activeTraits: Array.from(serverActiveTraits) };
|
|
45211
|
+
},
|
|
45212
|
+
[serverActiveTraits]
|
|
45213
|
+
);
|
|
44960
45214
|
const uiSlots = context.useUISlots();
|
|
44961
45215
|
const onEventProcessed = React81.useCallback(async (event, payload, dispatchedOrbitals) => {
|
|
44962
45216
|
if (!bridge.connected || !orbitalNames?.length) return;
|
|
@@ -44968,11 +45222,11 @@ function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFa
|
|
|
44968
45222
|
dispatchedOrbitalsSize: dispatchedOrbitals?.size ?? 0
|
|
44969
45223
|
}));
|
|
44970
45224
|
for (const name of targets) {
|
|
44971
|
-
const { effects, meta } = await bridge.sendEvent(name, event, payload);
|
|
45225
|
+
const { effects, meta } = await bridge.sendEvent(name, event, withActiveTraits(payload));
|
|
44972
45226
|
recordServerResponse(name, event, meta);
|
|
44973
|
-
applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits);
|
|
45227
|
+
applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits, activeTraitNames);
|
|
44974
45228
|
}
|
|
44975
|
-
}, [bridge.connected, bridge.sendEvent, orbitalNames, uiSlots, onNavigate, embeddedTraits]);
|
|
45229
|
+
}, [bridge.connected, bridge.sendEvent, orbitalNames, uiSlots, onNavigate, embeddedTraits, activeTraitNames, withActiveTraits]);
|
|
44976
45230
|
const opts = orbitalNames ? { onEventProcessed, navigate: onNavigate, traitConfigsByName, orbitalsByTrait, embeddedTraits } : { navigate: onNavigate, persistence, traitConfigsByName, orbitalsByTrait, embeddedTraits };
|
|
44977
45231
|
const { sendEvent } = useTraitStateMachine(traits2, uiSlots, opts);
|
|
44978
45232
|
const initSentRef = React81.useRef(false);
|
|
@@ -45009,7 +45263,7 @@ function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFa
|
|
|
45009
45263
|
initSentRef.current = true;
|
|
45010
45264
|
(async () => {
|
|
45011
45265
|
for (const name of orbitalNames) {
|
|
45012
|
-
const { effects, meta } = await bridge.sendEvent(name, "INIT", {});
|
|
45266
|
+
const { effects, meta } = await bridge.sendEvent(name, "INIT", withActiveTraits({}));
|
|
45013
45267
|
recordServerResponse(name, "INIT", meta);
|
|
45014
45268
|
const effectTraces = [
|
|
45015
45269
|
{ type: "fetch", args: [], status: "executed" },
|
|
@@ -45027,10 +45281,10 @@ function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFa
|
|
|
45027
45281
|
effects: effectTraces,
|
|
45028
45282
|
timestamp: Date.now()
|
|
45029
45283
|
});
|
|
45030
|
-
applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits);
|
|
45284
|
+
applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits, activeTraitNames);
|
|
45031
45285
|
}
|
|
45032
45286
|
})();
|
|
45033
|
-
}, [bridge.connected, orbitalNames, bridge.sendEvent, uiSlots, onNavigate, embeddedTraits]);
|
|
45287
|
+
}, [bridge.connected, orbitalNames, bridge.sendEvent, uiSlots, onNavigate, embeddedTraits, activeTraitNames, withActiveTraits]);
|
|
45034
45288
|
return null;
|
|
45035
45289
|
}
|
|
45036
45290
|
function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, onNavigate, onLocalFallback, persistence }) {
|
|
@@ -45117,6 +45371,14 @@ function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, onNavi
|
|
|
45117
45371
|
}
|
|
45118
45372
|
return Array.from(set);
|
|
45119
45373
|
}, [allPageTraits, orbitalsByTrait]);
|
|
45374
|
+
const serverActiveTraits = React81.useMemo(
|
|
45375
|
+
() => collectServerActiveTraits(
|
|
45376
|
+
ir,
|
|
45377
|
+
allTraits,
|
|
45378
|
+
new Set(allPageTraits.map((b) => b.trait.name).filter((n) => !!n))
|
|
45379
|
+
),
|
|
45380
|
+
[ir, allTraits, allPageTraits]
|
|
45381
|
+
);
|
|
45120
45382
|
React81.useEffect(() => {
|
|
45121
45383
|
const traitNames = allPageTraits.map((b) => b.trait.name);
|
|
45122
45384
|
const orbitalsByTraitForPage = {};
|
|
@@ -45126,7 +45388,7 @@ function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, onNavi
|
|
|
45126
45388
|
}
|
|
45127
45389
|
xOrbitalLog.info("SchemaRunner:mount", {
|
|
45128
45390
|
pageName,
|
|
45129
|
-
traitNames,
|
|
45391
|
+
traitNames: traitNames.join(","),
|
|
45130
45392
|
orbitalsByTraitForPage,
|
|
45131
45393
|
pageOrbitalNames: pageOrbitalNames.join(",")
|
|
45132
45394
|
});
|
|
@@ -45171,6 +45433,7 @@ function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, onNavi
|
|
|
45171
45433
|
traitConfigsByName,
|
|
45172
45434
|
orbitalsByTrait,
|
|
45173
45435
|
embeddedTraits,
|
|
45436
|
+
serverActiveTraits,
|
|
45174
45437
|
onNavigate,
|
|
45175
45438
|
onLocalFallback,
|
|
45176
45439
|
persistence
|