@almadar/ui 5.121.2 → 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 +333 -68
- package/dist/avl/index.js +335 -70
- package/dist/components/index.cjs +162 -46
- package/dist/components/index.d.cts +25 -5
- package/dist/components/index.d.ts +25 -5
- package/dist/components/index.js +162 -48
- 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 +207 -64
- package/dist/providers/index.d.cts +33 -4
- package/dist/providers/index.d.ts +33 -4
- package/dist/providers/index.js +207 -65
- package/dist/runtime/index.cjs +333 -68
- package/dist/runtime/index.d.cts +0 -14
- package/dist/runtime/index.d.ts +0 -14
- package/dist/runtime/index.js +336 -71
- 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, 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";
|
|
@@ -34794,13 +34881,18 @@ var init_GraphCanvas = __esm({
|
|
|
34794
34881
|
"var(--color-info)",
|
|
34795
34882
|
"var(--color-accent)"
|
|
34796
34883
|
];
|
|
34884
|
+
GROUP_GRAVITY = 0.3;
|
|
34885
|
+
UNGROUPED_GRAVITY = 0.02;
|
|
34797
34886
|
labelMeasureCtx = null;
|
|
34798
34887
|
MAX_LABEL_CHARS = 22;
|
|
34888
|
+
NO_NODES = [];
|
|
34889
|
+
NO_EDGES = [];
|
|
34890
|
+
NO_SIM = [];
|
|
34799
34891
|
GraphCanvas = ({
|
|
34800
34892
|
title,
|
|
34801
|
-
nodes: propNodes =
|
|
34802
|
-
edges: propEdges =
|
|
34803
|
-
similarity: propSimilarity =
|
|
34893
|
+
nodes: propNodes = NO_NODES,
|
|
34894
|
+
edges: propEdges = NO_EDGES,
|
|
34895
|
+
similarity: propSimilarity = NO_SIM,
|
|
34804
34896
|
height = 400,
|
|
34805
34897
|
showLabels = true,
|
|
34806
34898
|
interactive = true,
|
|
@@ -34850,6 +34942,7 @@ var init_GraphCanvas = __esm({
|
|
|
34850
34942
|
const interactionRef = React81.useRef({
|
|
34851
34943
|
mode: "none",
|
|
34852
34944
|
dragNodeId: null,
|
|
34945
|
+
pressedNodeId: null,
|
|
34853
34946
|
startMouse: { x: 0, y: 0 },
|
|
34854
34947
|
startOffset: { x: 0, y: 0 },
|
|
34855
34948
|
downPos: { x: 0, y: 0 }
|
|
@@ -34897,6 +34990,11 @@ var init_GraphCanvas = __esm({
|
|
|
34897
34990
|
() => [...new Set(propNodes.map((n) => n.group).filter(Boolean))],
|
|
34898
34991
|
[propNodes]
|
|
34899
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
|
+
);
|
|
34900
34998
|
React81.useEffect(() => {
|
|
34901
34999
|
const canvas = canvasRef.current;
|
|
34902
35000
|
if (!canvas || propNodes.length === 0) return;
|
|
@@ -34980,7 +35078,7 @@ var init_GraphCanvas = __esm({
|
|
|
34980
35078
|
const edgeLinks = propEdges.filter((e) => present.has(e.source) && present.has(e.target)).map((e) => ({ source: e.source, target: e.target, weight: clamp01(e.weight ?? 1) }));
|
|
34981
35079
|
const simLinks = activeSimilarity.filter((p) => present.has(p.source) && present.has(p.target)).map((p) => ({ source: p.source, target: p.target, weight: clamp01(p.weight) }));
|
|
34982
35080
|
const collideRadius = (n) => Math.max(n.size || 8, (n.labelW ?? 0) / 2) + nodeSpacing / 2;
|
|
34983
|
-
const simulation = d3Force.forceSimulation(simNodes).force("edge", d3Force.forceLink(edgeLinks).id((d) => d.id).distance((l) => linkDistance * (0.35 + (1 - l.weight) * 0.3)).strength(0.9)).force("similarity", d3Force.forceLink(simLinks).id((d) => d.id).distance((l) => linkDistance * (1.35 - 0.55 * l.weight)).strength(0.03)).force("charge", d3Force.forceManyBody().strength(-repulsion * 0.5)).force("collide", d3Force.forceCollide().radius(collideRadius).strength(0.9)).force("x", d3Force.forceX((n) => groupTarget.get(n.group ?? "")?.x ?? w / 2).strength((n) => multiCluster && n.group ?
|
|
35081
|
+
const simulation = d3Force.forceSimulation(simNodes).force("edge", d3Force.forceLink(edgeLinks).id((d) => d.id).distance((l) => linkDistance * (0.35 + (1 - l.weight) * 0.3)).strength(0.9)).force("similarity", d3Force.forceLink(simLinks).id((d) => d.id).distance((l) => linkDistance * (1.35 - 0.55 * l.weight)).strength(0.03)).force("charge", d3Force.forceManyBody().strength(-repulsion * 0.5)).force("collide", d3Force.forceCollide().radius(collideRadius).strength(0.9)).force("x", d3Force.forceX((n) => groupTarget.get(n.group ?? "")?.x ?? w / 2).strength((n) => multiCluster && n.group ? GROUP_GRAVITY : UNGROUPED_GRAVITY)).force("y", d3Force.forceY((n) => groupTarget.get(n.group ?? "")?.y ?? h / 2).strength((n) => multiCluster && n.group ? GROUP_GRAVITY : UNGROUPED_GRAVITY)).stop();
|
|
34984
35082
|
for (let i = 0; i < 300; i++) simulation.tick();
|
|
34985
35083
|
const pad = nodeSpacing / 2;
|
|
34986
35084
|
const rectsOf = (n) => {
|
|
@@ -35077,7 +35175,7 @@ var init_GraphCanvas = __esm({
|
|
|
35077
35175
|
return () => {
|
|
35078
35176
|
cancelAnimationFrame(animRef.current);
|
|
35079
35177
|
};
|
|
35080
|
-
}, [
|
|
35178
|
+
}, [nodesKey, edgesKey, propSimilarity, layout, repulsion, linkDistance, nodeSpacing, showLabels]);
|
|
35081
35179
|
React81.useEffect(() => {
|
|
35082
35180
|
const canvas = canvasRef.current;
|
|
35083
35181
|
if (!canvas) return;
|
|
@@ -35207,6 +35305,7 @@ var init_GraphCanvas = __esm({
|
|
|
35207
35305
|
const cancelSinglePointer = React81.useCallback(() => {
|
|
35208
35306
|
interactionRef.current.mode = "none";
|
|
35209
35307
|
interactionRef.current.dragNodeId = null;
|
|
35308
|
+
interactionRef.current.pressedNodeId = null;
|
|
35210
35309
|
}, []);
|
|
35211
35310
|
const handlePointerDown = React81.useCallback(
|
|
35212
35311
|
(e) => {
|
|
@@ -35217,6 +35316,7 @@ var init_GraphCanvas = __esm({
|
|
|
35217
35316
|
state.downPos = { x: e.clientX, y: e.clientY };
|
|
35218
35317
|
state.startMouse = { x: e.clientX, y: e.clientY };
|
|
35219
35318
|
state.startOffset = { ...offset };
|
|
35319
|
+
state.pressedNodeId = node?.id ?? null;
|
|
35220
35320
|
if (draggable && node) {
|
|
35221
35321
|
state.mode = "dragging";
|
|
35222
35322
|
state.dragNodeId = node.id;
|
|
@@ -35268,7 +35368,8 @@ var init_GraphCanvas = __esm({
|
|
|
35268
35368
|
if (moved < 4) {
|
|
35269
35369
|
const coords = toCoords(e);
|
|
35270
35370
|
if (!coords) return;
|
|
35271
|
-
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;
|
|
35272
35373
|
if (node) {
|
|
35273
35374
|
if (node.badge && node.badge > 1 && onBadgeClick) {
|
|
35274
35375
|
const r = (node.size || 8) + (selectedNodeId === node.id ? 4 : 0);
|
|
@@ -35288,6 +35389,7 @@ var init_GraphCanvas = __esm({
|
|
|
35288
35389
|
);
|
|
35289
35390
|
const handlePointerLeave = React81.useCallback(() => {
|
|
35290
35391
|
setHoveredNode(null);
|
|
35392
|
+
interactionRef.current.pressedNodeId = null;
|
|
35291
35393
|
}, []);
|
|
35292
35394
|
const gestureHandlers = useCanvasGestures({
|
|
35293
35395
|
canvasRef,
|
|
@@ -38239,8 +38341,17 @@ var init_MediaGallery = __esm({
|
|
|
38239
38341
|
const eventBus = useEventBus();
|
|
38240
38342
|
const { t } = hooks.useTranslate();
|
|
38241
38343
|
const [lightboxItem, setLightboxItem] = React81.useState(null);
|
|
38344
|
+
const [failedIds, setFailedIds] = React81.useState(/* @__PURE__ */ new Set());
|
|
38242
38345
|
const closeLightbox = React81.useCallback(() => setLightboxItem(null), []);
|
|
38243
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
|
+
}, []);
|
|
38244
38355
|
const handleItemClick = React81.useCallback(
|
|
38245
38356
|
(item) => {
|
|
38246
38357
|
if (selectable) {
|
|
@@ -38256,7 +38367,7 @@ var init_MediaGallery = __esm({
|
|
|
38256
38367
|
);
|
|
38257
38368
|
const entityData = Array.isArray(entity) ? entity : [];
|
|
38258
38369
|
const items = React81__namespace.default.useMemo(() => {
|
|
38259
|
-
if (propItems) return propItems;
|
|
38370
|
+
if (propItems && propItems.length > 0) return propItems;
|
|
38260
38371
|
if (entityData.length === 0) return [];
|
|
38261
38372
|
return entityData.map((record, idx) => {
|
|
38262
38373
|
return {
|
|
@@ -38339,13 +38450,14 @@ var init_MediaGallery = __esm({
|
|
|
38339
38450
|
),
|
|
38340
38451
|
onClick: () => handleItemClick(item),
|
|
38341
38452
|
children: [
|
|
38342
|
-
/* @__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(
|
|
38343
38454
|
"img",
|
|
38344
38455
|
{
|
|
38345
38456
|
src: item.thumbnail || item.src,
|
|
38346
38457
|
alt: item.alt || item.caption || "",
|
|
38347
38458
|
className: "w-full h-full object-cover",
|
|
38348
|
-
loading: "lazy"
|
|
38459
|
+
loading: "lazy",
|
|
38460
|
+
onError: () => handleImageError(item.id)
|
|
38349
38461
|
}
|
|
38350
38462
|
),
|
|
38351
38463
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -41852,6 +41964,11 @@ var init_TeamOrganism = __esm({
|
|
|
41852
41964
|
TeamOrganism.displayName = "TeamOrganism";
|
|
41853
41965
|
}
|
|
41854
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
|
+
}
|
|
41855
41972
|
var lookStyles10, STATUS_STYLES2, Timeline;
|
|
41856
41973
|
var init_Timeline = __esm({
|
|
41857
41974
|
"components/core/organisms/Timeline.tsx"() {
|
|
@@ -41979,7 +42096,7 @@ var init_Timeline = __esm({
|
|
|
41979
42096
|
/* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "xs", className: cn("flex-1 min-w-0", !isLast && "pb-6"), children: [
|
|
41980
42097
|
/* @__PURE__ */ jsxRuntime.jsxs(HStack, { justify: "between", align: "start", wrap: true, children: [
|
|
41981
42098
|
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", weight: "semibold", children: item.title }),
|
|
41982
|
-
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) })
|
|
41983
42100
|
] }),
|
|
41984
42101
|
item.description && /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", color: "secondary", children: item.description }),
|
|
41985
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)) }),
|
|
@@ -43191,7 +43308,7 @@ function substituteTraitRefsDeep(value, pathKey) {
|
|
|
43191
43308
|
}
|
|
43192
43309
|
return value;
|
|
43193
43310
|
}
|
|
43194
|
-
function renderPatternProps(props, onDismiss) {
|
|
43311
|
+
function renderPatternProps(props, onDismiss, propsSchema) {
|
|
43195
43312
|
const rendered = {};
|
|
43196
43313
|
for (const [key, value] of Object.entries(props)) {
|
|
43197
43314
|
if (key === "children") {
|
|
@@ -43209,9 +43326,10 @@ function renderPatternProps(props, onDismiss) {
|
|
|
43209
43326
|
};
|
|
43210
43327
|
rendered[key] = /* @__PURE__ */ jsxRuntime.jsx(SlotContentRenderer, { content: childContent, onDismiss });
|
|
43211
43328
|
} else if (Array.isArray(value)) {
|
|
43329
|
+
const isDataArray = propsSchema?.[key]?.items?.types?.includes("object") ?? false;
|
|
43212
43330
|
rendered[key] = value.map((item, i) => {
|
|
43213
43331
|
const el = item;
|
|
43214
|
-
if (isPatternConfig(el)) {
|
|
43332
|
+
if (!isDataArray && isPatternConfig(el)) {
|
|
43215
43333
|
const nestedProps = {};
|
|
43216
43334
|
for (const [k, v] of Object.entries(el)) {
|
|
43217
43335
|
if (k !== "type") nestedProps[k] = v;
|
|
@@ -43299,14 +43417,15 @@ function SlotContentRenderer({
|
|
|
43299
43417
|
);
|
|
43300
43418
|
}
|
|
43301
43419
|
}
|
|
43302
|
-
const renderedProps = renderPatternProps(restProps, onDismiss);
|
|
43303
43420
|
const patternDef = patterns.getPatternDefinition(content.pattern);
|
|
43304
43421
|
const propsSchema = patternDef?.propsSchema;
|
|
43422
|
+
const renderedProps = renderPatternProps(restProps, onDismiss, propsSchema);
|
|
43305
43423
|
if (propsSchema) {
|
|
43306
43424
|
for (const [propKey, propValue] of Object.entries(renderedProps)) {
|
|
43307
43425
|
if (typeof propValue !== "string") continue;
|
|
43308
43426
|
const propDef = propsSchema[propKey];
|
|
43309
43427
|
if (!propDef || propDef.kind !== "callback") continue;
|
|
43428
|
+
if (propValue === "") continue;
|
|
43310
43429
|
renderedProps[propKey] = ui.wrapCallbackForEvent(
|
|
43311
43430
|
`UI:${propValue}`,
|
|
43312
43431
|
propDef.callbackArgs,
|
|
@@ -43589,6 +43708,7 @@ function useSharedEntityStore() {
|
|
|
43589
43708
|
}
|
|
43590
43709
|
return storeRef.current;
|
|
43591
43710
|
}
|
|
43711
|
+
React81.createContext(null);
|
|
43592
43712
|
function runTickFrame(entityId, orderedWriters, store) {
|
|
43593
43713
|
let scratch = store.getSnapshot(entityId);
|
|
43594
43714
|
for (const writer of orderedWriters) {
|
|
@@ -43824,6 +43944,11 @@ var SYNC_TICK_OPERATORS = /* @__PURE__ */ new Set([
|
|
|
43824
43944
|
"do",
|
|
43825
43945
|
"when"
|
|
43826
43946
|
]);
|
|
43947
|
+
var REACTIVE_REPAINT_PATTERN_TYPES = /* @__PURE__ */ new Set([
|
|
43948
|
+
"canvas",
|
|
43949
|
+
"game-hud",
|
|
43950
|
+
"game-shell"
|
|
43951
|
+
]);
|
|
43827
43952
|
var LIFECYCLE_EVENTS = ["INIT", "LOAD", "$MOUNT"];
|
|
43828
43953
|
function toTraitDefinition(binding) {
|
|
43829
43954
|
return {
|
|
@@ -44076,6 +44201,8 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
44076
44201
|
}, [traitStates]);
|
|
44077
44202
|
const traitSnapshotDataRef = React81.useRef(/* @__PURE__ */ new Map());
|
|
44078
44203
|
const traitFieldStatesRef = React81.useRef(/* @__PURE__ */ new Map());
|
|
44204
|
+
const lastCanvasRenderUiRef = React81.useRef(/* @__PURE__ */ new Map());
|
|
44205
|
+
const executeTransitionEffectsRef = React81.useRef(null);
|
|
44079
44206
|
React81.useEffect(() => {
|
|
44080
44207
|
const mgr = managerRef.current;
|
|
44081
44208
|
const bindings = traitBindingsRef.current;
|
|
@@ -44116,11 +44243,9 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
44116
44243
|
bindTraitStateGetter((traitName) => {
|
|
44117
44244
|
const allStates = newManager.getAllStates();
|
|
44118
44245
|
if (allStates instanceof Map) {
|
|
44119
|
-
|
|
44120
|
-
return typeof val === "string" ? val : void 0;
|
|
44246
|
+
return allStates.get(traitName)?.currentState;
|
|
44121
44247
|
}
|
|
44122
|
-
|
|
44123
|
-
return typeof state === "string" ? state : void 0;
|
|
44248
|
+
return newManager.getState(traitName)?.currentState;
|
|
44124
44249
|
});
|
|
44125
44250
|
const snapshotUnregs = [];
|
|
44126
44251
|
for (const binding of traitBindingsRef.current) {
|
|
@@ -44205,6 +44330,15 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
44205
44330
|
const existing = pendingSlots.get(slot) || [];
|
|
44206
44331
|
existing.push({ pattern, props: props || {} });
|
|
44207
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
|
+
}
|
|
44208
44342
|
},
|
|
44209
44343
|
clearSlot: (slot) => {
|
|
44210
44344
|
pendingSlots.set(slot, []);
|
|
@@ -44275,11 +44409,15 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
44275
44409
|
notify: clientHandlers.notify
|
|
44276
44410
|
};
|
|
44277
44411
|
}
|
|
44412
|
+
const sharedWrites = [];
|
|
44278
44413
|
const baseSet = handlers.set;
|
|
44279
44414
|
handlers = {
|
|
44280
44415
|
...handlers,
|
|
44281
44416
|
set: async (targetId, field, value) => {
|
|
44282
44417
|
if (baseSet) await baseSet(targetId, field, value);
|
|
44418
|
+
if (sharedKey !== void 0) {
|
|
44419
|
+
sharedWrites.push({ field, value });
|
|
44420
|
+
}
|
|
44283
44421
|
log9.debug("set:write", {
|
|
44284
44422
|
traitName,
|
|
44285
44423
|
field,
|
|
@@ -44355,7 +44493,10 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
44355
44493
|
});
|
|
44356
44494
|
}
|
|
44357
44495
|
if (sharedKey !== void 0) {
|
|
44358
|
-
sharedEntityStore.commit(
|
|
44496
|
+
sharedEntityStore.commit(
|
|
44497
|
+
sharedKey,
|
|
44498
|
+
core.mergeEntityFrame(sharedEntityStore.getSnapshot(sharedKey), sharedWrites)
|
|
44499
|
+
);
|
|
44359
44500
|
}
|
|
44360
44501
|
log9.debug("effects:executed", () => ({
|
|
44361
44502
|
traitName,
|
|
@@ -44381,6 +44522,38 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
44381
44522
|
entity: binding.linkedEntity
|
|
44382
44523
|
});
|
|
44383
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
|
+
}
|
|
44384
44557
|
} catch (error) {
|
|
44385
44558
|
log9.error("effects:error", {
|
|
44386
44559
|
traitName,
|
|
@@ -44392,6 +44565,9 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
44392
44565
|
}
|
|
44393
44566
|
return emittedDuringExec;
|
|
44394
44567
|
}, [eventBus, flushSlot, sharedEntityStore]);
|
|
44568
|
+
React81.useEffect(() => {
|
|
44569
|
+
executeTransitionEffectsRef.current = executeTransitionEffects;
|
|
44570
|
+
}, [executeTransitionEffects]);
|
|
44395
44571
|
const runTickEffects = React81.useCallback((tick, binding) => {
|
|
44396
44572
|
const traitName = binding.trait.name;
|
|
44397
44573
|
const currentState = traitStatesRef.current.get(traitName)?.currentState ?? "";
|
|
@@ -44454,6 +44630,24 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
44454
44630
|
({ binding, tick }) => createSharedEntityWriter(binding, tick, traitStatesRef, emitFromSharedWriter)
|
|
44455
44631
|
);
|
|
44456
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
|
+
}
|
|
44457
44651
|
};
|
|
44458
44652
|
if (interval === "frame") {
|
|
44459
44653
|
scheduler.add(0, onDue);
|
|
@@ -44503,6 +44697,13 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
44503
44697
|
entityByTrait[name] = fields;
|
|
44504
44698
|
}
|
|
44505
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
|
+
}
|
|
44506
44707
|
const results = currentManager.sendEvent(
|
|
44507
44708
|
normalizedEvent,
|
|
44508
44709
|
payload,
|
|
@@ -44656,7 +44857,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
44656
44857
|
}
|
|
44657
44858
|
await onEventProcessed(normalizedEvent, payload, dispatchedOrbitals);
|
|
44658
44859
|
}
|
|
44659
|
-
}, [entities, eventBus]);
|
|
44860
|
+
}, [entities, eventBus, sharedEntityStore]);
|
|
44660
44861
|
const drainEventQueue = React81.useCallback(async () => {
|
|
44661
44862
|
if (processingRef.current) return;
|
|
44662
44863
|
processingRef.current = true;
|
|
@@ -44726,6 +44927,24 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
44726
44927
|
});
|
|
44727
44928
|
}
|
|
44728
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
|
+
}
|
|
44729
44948
|
for (const binding of traitBindings) {
|
|
44730
44949
|
const ownOrbital = orbitalsByTrait?.[binding.trait.name];
|
|
44731
44950
|
const listens = binding.trait.listens ?? [];
|
|
@@ -44910,9 +45129,16 @@ function normalizeChild(child) {
|
|
|
44910
45129
|
props: { ...rest, ...normalizedChildren !== void 0 ? { children: normalizedChildren } : {} }
|
|
44911
45130
|
};
|
|
44912
45131
|
}
|
|
44913
|
-
function applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits) {
|
|
45132
|
+
function applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits, activeTraits) {
|
|
44914
45133
|
for (const eff of effects) {
|
|
44915
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
|
+
}
|
|
44916
45142
|
const patternRecord = eff.pattern;
|
|
44917
45143
|
const { type: patternType, children, ...inlineProps } = patternRecord;
|
|
44918
45144
|
const normalizedChildren = Array.isArray(children) ? children.map((c) => normalizeChild(c)) : children;
|
|
@@ -44953,8 +45179,38 @@ function applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits) {
|
|
|
44953
45179
|
}
|
|
44954
45180
|
}
|
|
44955
45181
|
}
|
|
44956
|
-
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 }) {
|
|
44957
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
|
+
);
|
|
44958
45214
|
const uiSlots = context.useUISlots();
|
|
44959
45215
|
const onEventProcessed = React81.useCallback(async (event, payload, dispatchedOrbitals) => {
|
|
44960
45216
|
if (!bridge.connected || !orbitalNames?.length) return;
|
|
@@ -44966,11 +45222,11 @@ function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFa
|
|
|
44966
45222
|
dispatchedOrbitalsSize: dispatchedOrbitals?.size ?? 0
|
|
44967
45223
|
}));
|
|
44968
45224
|
for (const name of targets) {
|
|
44969
|
-
const { effects, meta } = await bridge.sendEvent(name, event, payload);
|
|
45225
|
+
const { effects, meta } = await bridge.sendEvent(name, event, withActiveTraits(payload));
|
|
44970
45226
|
recordServerResponse(name, event, meta);
|
|
44971
|
-
applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits);
|
|
45227
|
+
applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits, activeTraitNames);
|
|
44972
45228
|
}
|
|
44973
|
-
}, [bridge.connected, bridge.sendEvent, orbitalNames, uiSlots, onNavigate, embeddedTraits]);
|
|
45229
|
+
}, [bridge.connected, bridge.sendEvent, orbitalNames, uiSlots, onNavigate, embeddedTraits, activeTraitNames, withActiveTraits]);
|
|
44974
45230
|
const opts = orbitalNames ? { onEventProcessed, navigate: onNavigate, traitConfigsByName, orbitalsByTrait, embeddedTraits } : { navigate: onNavigate, persistence, traitConfigsByName, orbitalsByTrait, embeddedTraits };
|
|
44975
45231
|
const { sendEvent } = useTraitStateMachine(traits2, uiSlots, opts);
|
|
44976
45232
|
const initSentRef = React81.useRef(false);
|
|
@@ -45007,7 +45263,7 @@ function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFa
|
|
|
45007
45263
|
initSentRef.current = true;
|
|
45008
45264
|
(async () => {
|
|
45009
45265
|
for (const name of orbitalNames) {
|
|
45010
|
-
const { effects, meta } = await bridge.sendEvent(name, "INIT", {});
|
|
45266
|
+
const { effects, meta } = await bridge.sendEvent(name, "INIT", withActiveTraits({}));
|
|
45011
45267
|
recordServerResponse(name, "INIT", meta);
|
|
45012
45268
|
const effectTraces = [
|
|
45013
45269
|
{ type: "fetch", args: [], status: "executed" },
|
|
@@ -45025,10 +45281,10 @@ function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFa
|
|
|
45025
45281
|
effects: effectTraces,
|
|
45026
45282
|
timestamp: Date.now()
|
|
45027
45283
|
});
|
|
45028
|
-
applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits);
|
|
45284
|
+
applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits, activeTraitNames);
|
|
45029
45285
|
}
|
|
45030
45286
|
})();
|
|
45031
|
-
}, [bridge.connected, orbitalNames, bridge.sendEvent, uiSlots, onNavigate, embeddedTraits]);
|
|
45287
|
+
}, [bridge.connected, orbitalNames, bridge.sendEvent, uiSlots, onNavigate, embeddedTraits, activeTraitNames, withActiveTraits]);
|
|
45032
45288
|
return null;
|
|
45033
45289
|
}
|
|
45034
45290
|
function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, onNavigate, onLocalFallback, persistence }) {
|
|
@@ -45115,6 +45371,14 @@ function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, onNavi
|
|
|
45115
45371
|
}
|
|
45116
45372
|
return Array.from(set);
|
|
45117
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
|
+
);
|
|
45118
45382
|
React81.useEffect(() => {
|
|
45119
45383
|
const traitNames = allPageTraits.map((b) => b.trait.name);
|
|
45120
45384
|
const orbitalsByTraitForPage = {};
|
|
@@ -45124,7 +45388,7 @@ function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, onNavi
|
|
|
45124
45388
|
}
|
|
45125
45389
|
xOrbitalLog.info("SchemaRunner:mount", {
|
|
45126
45390
|
pageName,
|
|
45127
|
-
traitNames,
|
|
45391
|
+
traitNames: traitNames.join(","),
|
|
45128
45392
|
orbitalsByTraitForPage,
|
|
45129
45393
|
pageOrbitalNames: pageOrbitalNames.join(",")
|
|
45130
45394
|
});
|
|
@@ -45169,6 +45433,7 @@ function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, onNavi
|
|
|
45169
45433
|
traitConfigsByName,
|
|
45170
45434
|
orbitalsByTrait,
|
|
45171
45435
|
embeddedTraits,
|
|
45436
|
+
serverActiveTraits,
|
|
45172
45437
|
onNavigate,
|
|
45173
45438
|
onLocalFallback,
|
|
45174
45439
|
persistence
|