@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.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as React81 from 'react';
|
|
2
|
-
import React81__default, { useContext, useMemo, useRef, useEffect, useCallback, Suspense, useState,
|
|
3
|
-
import { EventBusContext,
|
|
2
|
+
import React81__default, { createContext, useContext, useMemo, useRef, useEffect, useCallback, Suspense, useState, useSyncExternalStore, lazy, useLayoutEffect, useId } from 'react';
|
|
3
|
+
import { EventBusContext, useTraitScopeChain, useEntitySchemaOptional, useEntitySchema, getAllPages, OrbitalProvider, TraitScopeProvider, ServerBridgeProvider, useCurrentPagePath, useGameAudioContextOptional, VerificationProvider, EntitySchemaProvider, OrbitalThemeProvider, useServerBridge } from '@almadar/ui/providers';
|
|
4
4
|
export { EntitySchemaProvider, ServerBridgeProvider, TraitContext, TraitProvider, useEntitySchema, useEntitySchemaOptional, useServerBridge, useTrait, useTraitContext } from '@almadar/ui/providers';
|
|
5
5
|
import { createLogger, setNamespaceLevel, isLogLevelEnabled } from '@almadar/logger';
|
|
6
6
|
import { clsx } from 'clsx';
|
|
@@ -39,7 +39,7 @@ import ReactMarkdown from 'react-markdown';
|
|
|
39
39
|
import remarkGfm from 'remark-gfm';
|
|
40
40
|
import remarkMath from 'remark-math';
|
|
41
41
|
import rehypeKatex from 'rehype-katex';
|
|
42
|
-
import { isCircuitEvent, schemaToIR, getPage, clearSchemaCache as clearSchemaCache$1, walkSExpr, buildResolvedTraitConfigs,
|
|
42
|
+
import { mergeEntityFrame, isCircuitEvent, schemaToIR, getPage, clearSchemaCache as clearSchemaCache$1, walkSExpr, buildResolvedTraitConfigs, isInlineTrait, isSExpr, isEventPayloadValue } from '@almadar/core';
|
|
43
43
|
import { DndContext, pointerWithin, rectIntersection, closestCorners, useSensors, useSensor, PointerSensor, KeyboardSensor, useDroppable } from '@dnd-kit/core';
|
|
44
44
|
import { useSortable, arrayMove, sortableKeyboardCoordinates, SortableContext, rectSortingStrategy, verticalListSortingStrategy } from '@dnd-kit/sortable';
|
|
45
45
|
import { CSS } from '@dnd-kit/utilities';
|
|
@@ -98,9 +98,9 @@ function getGlobalEventBus() {
|
|
|
98
98
|
function useEventBus() {
|
|
99
99
|
const context = useContext(EventBusContext);
|
|
100
100
|
const baseBus = context ?? getGlobalEventBus() ?? fallbackEventBus;
|
|
101
|
-
const
|
|
101
|
+
const chain = useTraitScopeChain();
|
|
102
102
|
return useMemo(() => {
|
|
103
|
-
if (
|
|
103
|
+
if (chain.length === 0) {
|
|
104
104
|
return {
|
|
105
105
|
...baseBus,
|
|
106
106
|
emit: (type, payload, source) => {
|
|
@@ -116,22 +116,31 @@ function useEventBus() {
|
|
|
116
116
|
emit: (type, payload, source) => {
|
|
117
117
|
if (typeof type === "string" && type.startsWith("UI:")) {
|
|
118
118
|
const tail = type.slice(3);
|
|
119
|
-
const
|
|
120
|
-
|
|
121
|
-
|
|
119
|
+
const isQualified = tail.includes(".");
|
|
120
|
+
const event = isQualified ? tail.split(".").slice(2).join(".") : tail;
|
|
121
|
+
if (!event) {
|
|
122
|
+
baseBus.emit(type, payload, source);
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
const keys = /* @__PURE__ */ new Set();
|
|
126
|
+
if (isQualified) keys.add(type);
|
|
127
|
+
for (const sc of chain) {
|
|
128
|
+
keys.add(`UI:${sc.orbital}.${sc.trait}.${event}`);
|
|
129
|
+
}
|
|
130
|
+
if (keys.size > 1) {
|
|
131
|
+
scopeLog.info("emit:fan-out", {
|
|
122
132
|
from: type,
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
scopeTrait: scope.trait
|
|
133
|
+
keys: Array.from(keys),
|
|
134
|
+
chainDepth: chain.length
|
|
126
135
|
});
|
|
127
136
|
}
|
|
128
|
-
baseBus.emit(
|
|
137
|
+
for (const key of keys) baseBus.emit(key, payload, source);
|
|
129
138
|
return;
|
|
130
139
|
}
|
|
131
140
|
baseBus.emit(type, payload, source);
|
|
132
141
|
}
|
|
133
142
|
};
|
|
134
|
-
}, [baseBus,
|
|
143
|
+
}, [baseBus, chain]);
|
|
135
144
|
}
|
|
136
145
|
function useEventListener(event, handler) {
|
|
137
146
|
const eventBus = useEventBus();
|
|
@@ -1148,13 +1157,13 @@ var init_Icon = __esm({
|
|
|
1148
1157
|
style
|
|
1149
1158
|
}) => {
|
|
1150
1159
|
const directIcon = typeof icon === "string" ? void 0 : icon;
|
|
1151
|
-
const effectiveName = typeof icon === "string" ? icon : name;
|
|
1160
|
+
const effectiveName = typeof icon === "string" && icon !== "" ? icon : name;
|
|
1161
|
+
const effectiveStrokeWidth = strokeWidth != null && strokeWidth > 0 ? strokeWidth : void 0;
|
|
1152
1162
|
const family = useIconFamily();
|
|
1153
1163
|
const RenderedComponent = React81__default.useMemo(() => {
|
|
1154
1164
|
if (directIcon) return null;
|
|
1155
1165
|
return effectiveName ? resolveIconForFamily(effectiveName) : null;
|
|
1156
1166
|
}, [directIcon, effectiveName, family]);
|
|
1157
|
-
const effectiveStrokeWidth = strokeWidth ?? void 0;
|
|
1158
1167
|
const inlineStyle = {
|
|
1159
1168
|
...effectiveStrokeWidth === void 0 ? { strokeWidth: "var(--icon-stroke-width, 2)" } : {},
|
|
1160
1169
|
...style
|
|
@@ -1754,6 +1763,15 @@ var init_Modal = __esm({
|
|
|
1754
1763
|
const [dragY, setDragY] = useState(0);
|
|
1755
1764
|
const dragStartY = useRef(0);
|
|
1756
1765
|
const isDragging = useRef(false);
|
|
1766
|
+
const [closing, setClosing] = useState(false);
|
|
1767
|
+
const wasOpenRef = useRef(isOpen);
|
|
1768
|
+
useEffect(() => {
|
|
1769
|
+
if (wasOpenRef.current && !isOpen) setClosing(true);
|
|
1770
|
+
wasOpenRef.current = isOpen;
|
|
1771
|
+
}, [isOpen]);
|
|
1772
|
+
const handleAnimEnd = (e) => {
|
|
1773
|
+
if (closing && e.target === e.currentTarget) setClosing(false);
|
|
1774
|
+
};
|
|
1757
1775
|
useEffect(() => {
|
|
1758
1776
|
if (isOpen) {
|
|
1759
1777
|
previousActiveElement.current = document.activeElement;
|
|
@@ -1787,7 +1805,11 @@ var init_Modal = __esm({
|
|
|
1787
1805
|
document.body.style.overflow = "";
|
|
1788
1806
|
};
|
|
1789
1807
|
}, [isOpen]);
|
|
1790
|
-
if (
|
|
1808
|
+
if (typeof document === "undefined") return null;
|
|
1809
|
+
const renderOpen = isOpen || closing;
|
|
1810
|
+
if (!renderOpen) return null;
|
|
1811
|
+
const dialogAnim = closing ? "animate-modal-out" : "animate-modal-in";
|
|
1812
|
+
const overlayAnim = closing ? "animate-overlay-out" : "animate-overlay-in";
|
|
1791
1813
|
const handleClose = () => {
|
|
1792
1814
|
if (closeEvent) eventBus.emit(`UI:${closeEvent}`, {});
|
|
1793
1815
|
onClose();
|
|
@@ -1804,7 +1826,8 @@ var init_Modal = __esm({
|
|
|
1804
1826
|
className: cn(
|
|
1805
1827
|
"fixed inset-0 z-[1000]",
|
|
1806
1828
|
"flex items-start justify-center px-4 pb-4 pt-[10vh]",
|
|
1807
|
-
"max-sm:items-stretch max-sm:p-0 max-sm:pt-0"
|
|
1829
|
+
"max-sm:items-stretch max-sm:p-0 max-sm:pt-0",
|
|
1830
|
+
overlayAnim
|
|
1808
1831
|
),
|
|
1809
1832
|
style: { backgroundColor: "rgba(0, 0, 0, 0.6)" },
|
|
1810
1833
|
onClick: handleOverlayClick,
|
|
@@ -1832,8 +1855,10 @@ var init_Modal = __esm({
|
|
|
1832
1855
|
// full height, no rounded corners, no min-width.
|
|
1833
1856
|
"max-sm:max-w-none max-sm:max-h-none max-sm:w-full max-sm:h-full max-sm:rounded-none",
|
|
1834
1857
|
lookStyles[look],
|
|
1835
|
-
className
|
|
1858
|
+
className,
|
|
1859
|
+
dialogAnim
|
|
1836
1860
|
),
|
|
1861
|
+
onAnimationEnd: handleAnimEnd,
|
|
1837
1862
|
style: dragY > 0 ? {
|
|
1838
1863
|
transform: `translateY(${dragY}px)`,
|
|
1839
1864
|
transition: isDragging.current ? "none" : "transform 200ms ease-out"
|
|
@@ -1942,6 +1967,7 @@ var init_Overlay = __esm({
|
|
|
1942
1967
|
className: cn(
|
|
1943
1968
|
"fixed inset-0 z-40",
|
|
1944
1969
|
blur && "backdrop-blur-sm",
|
|
1970
|
+
"animate-overlay-in",
|
|
1945
1971
|
className
|
|
1946
1972
|
),
|
|
1947
1973
|
style: { backgroundColor: "rgba(0, 0, 0, 0.6)" },
|
|
@@ -3354,7 +3380,7 @@ var init_Input = __esm({
|
|
|
3354
3380
|
eventBus.emit(`UI:${action}`, { value: e.currentTarget.value });
|
|
3355
3381
|
}
|
|
3356
3382
|
};
|
|
3357
|
-
const wrapField = (field) => /* @__PURE__ */ jsxs("div", { className: "w-full", children: [
|
|
3383
|
+
const wrapField = (field, fullWidth = true) => /* @__PURE__ */ jsxs("div", { className: fullWidth ? "w-full" : "w-fit", children: [
|
|
3358
3384
|
label && /* @__PURE__ */ jsx("label", { className: "block text-sm font-medium text-foreground mb-1", children: label }),
|
|
3359
3385
|
field,
|
|
3360
3386
|
(helperText || error) && /* @__PURE__ */ jsx("p", { className: cn("mt-1 text-xs", error ? "text-error" : "text-muted-foreground"), children: error ?? helperText })
|
|
@@ -3414,7 +3440,8 @@ var init_Input = __esm({
|
|
|
3414
3440
|
),
|
|
3415
3441
|
...props
|
|
3416
3442
|
}
|
|
3417
|
-
)
|
|
3443
|
+
),
|
|
3444
|
+
false
|
|
3418
3445
|
);
|
|
3419
3446
|
}
|
|
3420
3447
|
return wrapField(
|
|
@@ -5742,6 +5769,18 @@ var init_RangeSlider = __esm({
|
|
|
5742
5769
|
function easeOut(t) {
|
|
5743
5770
|
return t * (2 - t);
|
|
5744
5771
|
}
|
|
5772
|
+
function formatDisplay(value, format, decimals) {
|
|
5773
|
+
switch (format) {
|
|
5774
|
+
case "currency":
|
|
5775
|
+
return `$${value.toFixed(2)}`;
|
|
5776
|
+
case "percent":
|
|
5777
|
+
return `${Math.round(value)}%`;
|
|
5778
|
+
case "number":
|
|
5779
|
+
return value.toLocaleString();
|
|
5780
|
+
default:
|
|
5781
|
+
return value.toFixed(decimals);
|
|
5782
|
+
}
|
|
5783
|
+
}
|
|
5745
5784
|
var AnimatedCounter;
|
|
5746
5785
|
var init_AnimatedCounter = __esm({
|
|
5747
5786
|
"components/marketing/atoms/AnimatedCounter.tsx"() {
|
|
@@ -5753,6 +5792,7 @@ var init_AnimatedCounter = __esm({
|
|
|
5753
5792
|
duration = 600,
|
|
5754
5793
|
prefix,
|
|
5755
5794
|
suffix,
|
|
5795
|
+
format,
|
|
5756
5796
|
className
|
|
5757
5797
|
}) => {
|
|
5758
5798
|
const numericRaw = typeof rawValue === "number" ? rawValue : Number.parseFloat(String(rawValue ?? ""));
|
|
@@ -5768,6 +5808,10 @@ var init_AnimatedCounter = __esm({
|
|
|
5768
5808
|
setDisplayValue(to);
|
|
5769
5809
|
return;
|
|
5770
5810
|
}
|
|
5811
|
+
if (window.matchMedia?.("(prefers-reduced-motion: reduce)").matches) {
|
|
5812
|
+
setDisplayValue(to);
|
|
5813
|
+
return;
|
|
5814
|
+
}
|
|
5771
5815
|
const startTime = performance.now();
|
|
5772
5816
|
const diff = to - from;
|
|
5773
5817
|
function animate(currentTime) {
|
|
@@ -5789,7 +5833,7 @@ var init_AnimatedCounter = __esm({
|
|
|
5789
5833
|
};
|
|
5790
5834
|
}, [value, duration]);
|
|
5791
5835
|
const decimalPlaces = Number.isInteger(value) ? 0 : String(value).split(".")[1]?.length ?? 0;
|
|
5792
|
-
const formattedValue = displayValue
|
|
5836
|
+
const formattedValue = formatDisplay(displayValue, format, decimalPlaces);
|
|
5793
5837
|
return /* @__PURE__ */ jsxs(Typography, { variant: "h3", className: cn("tabular-nums", className), children: [
|
|
5794
5838
|
prefix,
|
|
5795
5839
|
formattedValue,
|
|
@@ -7033,14 +7077,29 @@ function recordTransition(trace) {
|
|
|
7033
7077
|
"pass"
|
|
7034
7078
|
);
|
|
7035
7079
|
} else {
|
|
7036
|
-
const
|
|
7037
|
-
|
|
7038
|
-
|
|
7039
|
-
|
|
7040
|
-
|
|
7041
|
-
"
|
|
7042
|
-
|
|
7080
|
+
const rendersEntityData = entry.effects.some(
|
|
7081
|
+
(e) => e.type === "render-ui" && JSON.stringify(e.args).includes("@entity.")
|
|
7082
|
+
);
|
|
7083
|
+
if (rendersEntityData) {
|
|
7084
|
+
const siblingSeeds = getState().transitions.some(
|
|
7085
|
+
(t) => t.event === "INIT" && t.effects.some(
|
|
7086
|
+
(e) => e.type === "fetch" || e.type === "set" && typeof e.args[0] === "string" && e.args[0].startsWith("@entity.")
|
|
7087
|
+
)
|
|
7043
7088
|
);
|
|
7089
|
+
if (siblingSeeds) {
|
|
7090
|
+
registerCheck(
|
|
7091
|
+
checkId,
|
|
7092
|
+
`INIT transition for "${entry.traitName}" has sibling entity-seed (shared entity)`,
|
|
7093
|
+
"pass"
|
|
7094
|
+
);
|
|
7095
|
+
} else {
|
|
7096
|
+
registerCheck(
|
|
7097
|
+
checkId,
|
|
7098
|
+
`INIT transition for "${entry.traitName}" missing fetch effect`,
|
|
7099
|
+
"fail",
|
|
7100
|
+
"Entity-bound render-ui without a fetch effect will show empty data"
|
|
7101
|
+
);
|
|
7102
|
+
}
|
|
7044
7103
|
}
|
|
7045
7104
|
}
|
|
7046
7105
|
}
|
|
@@ -8185,7 +8244,7 @@ function GameMenu({
|
|
|
8185
8244
|
logo,
|
|
8186
8245
|
className
|
|
8187
8246
|
}) {
|
|
8188
|
-
const resolvedOptions = options ?? menuItems ?? DEFAULT_MENU_OPTIONS;
|
|
8247
|
+
const resolvedOptions = (options?.length ? options : void 0) ?? (menuItems?.length ? menuItems : void 0) ?? DEFAULT_MENU_OPTIONS;
|
|
8189
8248
|
const eventBus = useEventBus();
|
|
8190
8249
|
const handleOptionClick = React81.useCallback(
|
|
8191
8250
|
(option) => {
|
|
@@ -9476,6 +9535,10 @@ function Canvas2D({
|
|
|
9476
9535
|
window.removeEventListener("keyup", onUp);
|
|
9477
9536
|
};
|
|
9478
9537
|
}, [keyMap, keyUpMap, eventBus]);
|
|
9538
|
+
useEffect(() => {
|
|
9539
|
+
if (!keyMap && !keyUpMap) return;
|
|
9540
|
+
canvasRef.current?.focus();
|
|
9541
|
+
}, [keyMap, keyUpMap]);
|
|
9479
9542
|
if (error) {
|
|
9480
9543
|
return /* @__PURE__ */ jsx(Box, { className: cn("flex items-center justify-center w-full h-full bg-[var(--color-card)] rounded-container", className), children: /* @__PURE__ */ jsxs(Stack, { direction: "vertical", gap: "md", align: "center", children: [
|
|
9481
9544
|
/* @__PURE__ */ jsx(Icon, { name: "alert-circle", size: "xl" }),
|
|
@@ -9524,7 +9587,7 @@ function Canvas2D({
|
|
|
9524
9587
|
onWheel: gestureHandlers.onWheel,
|
|
9525
9588
|
onContextMenu: (e) => e.preventDefault(),
|
|
9526
9589
|
className: "cursor-pointer touch-none",
|
|
9527
|
-
tabIndex: isFree ? 0 : void 0,
|
|
9590
|
+
tabIndex: isFree || keyMap || keyUpMap ? 0 : void 0,
|
|
9528
9591
|
style: {
|
|
9529
9592
|
width: viewportSize.width,
|
|
9530
9593
|
height: viewportSize.height
|
|
@@ -13775,7 +13838,8 @@ var init_LoadingState = __esm({
|
|
|
13775
13838
|
LoadingState = ({
|
|
13776
13839
|
title,
|
|
13777
13840
|
message,
|
|
13778
|
-
className
|
|
13841
|
+
className,
|
|
13842
|
+
fullPage = false
|
|
13779
13843
|
}) => {
|
|
13780
13844
|
const { t } = useTranslate();
|
|
13781
13845
|
const displayMessage = message ?? t("common.loading");
|
|
@@ -13784,7 +13848,8 @@ var init_LoadingState = __esm({
|
|
|
13784
13848
|
{
|
|
13785
13849
|
align: "center",
|
|
13786
13850
|
className: cn(
|
|
13787
|
-
"justify-center
|
|
13851
|
+
"justify-center",
|
|
13852
|
+
fullPage ? "fixed inset-0 z-[1000] py-12 bg-background/80 backdrop-blur-sm animate-overlay-in" : "py-12",
|
|
13788
13853
|
className
|
|
13789
13854
|
),
|
|
13790
13855
|
children: [
|
|
@@ -16936,7 +17001,7 @@ var init_BookCoverPage = __esm({
|
|
|
16936
17001
|
size: "lg",
|
|
16937
17002
|
action: "BOOK_START",
|
|
16938
17003
|
className: "mt-8",
|
|
16939
|
-
children: /* @__PURE__ */ jsx(Typography, { variant: "body", children: t("book.startReading") })
|
|
17004
|
+
children: /* @__PURE__ */ jsx(Typography, { variant: "body", color: "inherit", children: t("book.startReading") })
|
|
16940
17005
|
}
|
|
16941
17006
|
)
|
|
16942
17007
|
]
|
|
@@ -19181,8 +19246,9 @@ var init_Chart = __esm({
|
|
|
19181
19246
|
align: "center",
|
|
19182
19247
|
flex: true,
|
|
19183
19248
|
className: "min-w-0",
|
|
19249
|
+
style: { height: "100%" },
|
|
19184
19250
|
children: [
|
|
19185
|
-
/* @__PURE__ */ jsx(HStack, { gap: histogram ? "none" : "xs", align: "end",
|
|
19251
|
+
/* @__PURE__ */ 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) => {
|
|
19186
19252
|
const value = valueAt(s, label);
|
|
19187
19253
|
const barHeight = value / maxValue * 100;
|
|
19188
19254
|
const color = seriesColor(s, sIdx);
|
|
@@ -19195,6 +19261,8 @@ var init_Chart = __esm({
|
|
|
19195
19261
|
),
|
|
19196
19262
|
style: {
|
|
19197
19263
|
height: `${barHeight}%`,
|
|
19264
|
+
// Cap width so a lone category doesn't paint the whole plot as one solid block; narrow columns are unaffected (flex-1 binds first).
|
|
19265
|
+
...!histogram && { maxWidth: 72 },
|
|
19198
19266
|
backgroundColor: color
|
|
19199
19267
|
},
|
|
19200
19268
|
onClick: () => onPointClick?.(
|
|
@@ -19229,8 +19297,9 @@ var init_Chart = __esm({
|
|
|
19229
19297
|
align: "center",
|
|
19230
19298
|
flex: true,
|
|
19231
19299
|
className: "min-w-0",
|
|
19300
|
+
style: { height: "100%" },
|
|
19232
19301
|
children: [
|
|
19233
|
-
/* @__PURE__ */ jsx(VStack, { gap: "none", className: "w-full
|
|
19302
|
+
/* @__PURE__ */ jsx(VStack, { gap: "none", className: "w-full flex-1 min-h-0", justify: "end", children: series.map((s, sIdx) => {
|
|
19234
19303
|
const value = valueAt(s, label);
|
|
19235
19304
|
const ratio = stack === "normalize" ? total === 0 ? 0 : value / total * 100 : value / maxValue * 100;
|
|
19236
19305
|
const color = seriesColor(s, sIdx);
|
|
@@ -19275,6 +19344,7 @@ var init_Chart = __esm({
|
|
|
19275
19344
|
const innerRadius = donut ? radius * 0.6 : 0;
|
|
19276
19345
|
const center = size / 2;
|
|
19277
19346
|
const segments = useMemo(() => {
|
|
19347
|
+
if (!Number.isFinite(total) || total <= 0) return [];
|
|
19278
19348
|
let currentAngle = -Math.PI / 2;
|
|
19279
19349
|
return data.map((point, idx) => {
|
|
19280
19350
|
const angle = point.value / total * 2 * Math.PI;
|
|
@@ -19286,13 +19356,25 @@ var init_Chart = __esm({
|
|
|
19286
19356
|
const y1 = center + radius * Math.sin(startAngle);
|
|
19287
19357
|
const x2 = center + radius * Math.cos(endAngle);
|
|
19288
19358
|
const y2 = center + radius * Math.sin(endAngle);
|
|
19359
|
+
const fullCircle = angle >= 2 * Math.PI - 1e-9;
|
|
19360
|
+
const midAngle = startAngle + angle / 2;
|
|
19361
|
+
const xm = center + radius * Math.cos(midAngle);
|
|
19362
|
+
const ym = center + radius * Math.sin(midAngle);
|
|
19289
19363
|
let d;
|
|
19290
19364
|
if (innerRadius > 0) {
|
|
19291
19365
|
const ix1 = center + innerRadius * Math.cos(startAngle);
|
|
19292
19366
|
const iy1 = center + innerRadius * Math.sin(startAngle);
|
|
19293
19367
|
const ix2 = center + innerRadius * Math.cos(endAngle);
|
|
19294
19368
|
const iy2 = center + innerRadius * Math.sin(endAngle);
|
|
19295
|
-
|
|
19369
|
+
if (fullCircle) {
|
|
19370
|
+
const ixm = center + innerRadius * Math.cos(midAngle);
|
|
19371
|
+
const iym = center + innerRadius * Math.sin(midAngle);
|
|
19372
|
+
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`;
|
|
19373
|
+
} else {
|
|
19374
|
+
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`;
|
|
19375
|
+
}
|
|
19376
|
+
} else if (fullCircle) {
|
|
19377
|
+
d = `M ${center} ${center} L ${x1} ${y1} A ${radius} ${radius} 0 1 1 ${xm} ${ym} A ${radius} ${radius} 0 1 1 ${x2} ${y2} Z`;
|
|
19296
19378
|
} else {
|
|
19297
19379
|
d = `M ${center} ${center} L ${x1} ${y1} A ${radius} ${radius} 0 ${largeArc} 1 ${x2} ${y2} Z`;
|
|
19298
19380
|
}
|
|
@@ -22305,10 +22387,10 @@ function DataGrid({
|
|
|
22305
22387
|
] }),
|
|
22306
22388
|
badgeFields.length > 0 && /* @__PURE__ */ jsx(HStack, { gap: "xs", className: "flex-wrap", children: badgeFields.map((field) => {
|
|
22307
22389
|
const val = getNestedValue(itemData, field.name);
|
|
22308
|
-
if (val === void 0 || val === null) return null;
|
|
22390
|
+
if (val === void 0 || val === null || val === "") return null;
|
|
22309
22391
|
return /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "items-center", children: [
|
|
22310
22392
|
field.icon && renderIconInput(field.icon, { size: "xs" }),
|
|
22311
|
-
/* @__PURE__ */ jsx(Badge, { variant: resolveBadgeVariant(field, String(val)), children:
|
|
22393
|
+
/* @__PURE__ */ jsx(Badge, { variant: resolveBadgeVariant(field, String(val)), children: formatValue(val, field.format) })
|
|
22312
22394
|
] }, field.name);
|
|
22313
22395
|
}) })
|
|
22314
22396
|
] }),
|
|
@@ -29596,6 +29678,11 @@ var init_VoteStack = __esm({
|
|
|
29596
29678
|
{
|
|
29597
29679
|
className: cn(
|
|
29598
29680
|
"inline-flex items-center justify-center",
|
|
29681
|
+
// Shrink-wrap in stretch contexts (slot/sidecar wrappers are
|
|
29682
|
+
// flex-column with stretch alignment): without this the root spans
|
|
29683
|
+
// the full wrapper width and the count row's `w-full` turns the
|
|
29684
|
+
// compact pill into a page-wide band.
|
|
29685
|
+
"w-fit",
|
|
29599
29686
|
variant === "vertical" ? "flex-col" : "flex-row",
|
|
29600
29687
|
"rounded-sm",
|
|
29601
29688
|
"border-[length:var(--border-width)] border-border",
|
|
@@ -33501,7 +33588,7 @@ var init_Sidebar = __esm({
|
|
|
33501
33588
|
isActive ? [
|
|
33502
33589
|
"bg-primary text-primary-foreground",
|
|
33503
33590
|
"font-medium shadow-sm",
|
|
33504
|
-
"border-primary translate-x-1 -translate-y-0.5"
|
|
33591
|
+
"border-primary translate-x-1 rtl:-translate-x-1 -translate-y-0.5"
|
|
33505
33592
|
].join(" ") : [
|
|
33506
33593
|
"text-foreground",
|
|
33507
33594
|
"hover:bg-muted hover:border-border",
|
|
@@ -33511,10 +33598,10 @@ var init_Sidebar = __esm({
|
|
|
33511
33598
|
title: collapsed ? item.label : void 0,
|
|
33512
33599
|
children: [
|
|
33513
33600
|
item.icon && (typeof item.icon === "string" ? /* @__PURE__ */ jsx(Icon, { name: item.icon, size: "sm", className: cn("min-w-[20px] flex-shrink-0", isActive && "text-primary-foreground") }) : /* @__PURE__ */ jsx(Icon, { icon: item.icon, size: "sm", className: cn("min-w-[20px] flex-shrink-0", isActive && "text-primary-foreground") })),
|
|
33514
|
-
!collapsed && /* @__PURE__ */ jsx(Typography, { variant: "body", color: isActive ? "inherit" : "primary", className: "font-medium truncate flex-1 text-
|
|
33601
|
+
!collapsed && /* @__PURE__ */ jsx(Typography, { variant: "body", color: isActive ? "inherit" : "primary", className: "font-medium truncate flex-1 text-start", children: item.label }),
|
|
33515
33602
|
!collapsed && item.badge !== void 0 && /* @__PURE__ */ jsx(Badge, { variant: "danger", size: "sm", children: item.badge }),
|
|
33516
33603
|
collapsed && /* @__PURE__ */ jsx(Box, { className: cn(
|
|
33517
|
-
"absolute
|
|
33604
|
+
"absolute start-full ms-2 px-2 py-1 text-xs opacity-0 group-hover:opacity-100",
|
|
33518
33605
|
"pointer-events-none whitespace-nowrap z-50 transition-opacity",
|
|
33519
33606
|
"bg-primary text-primary-foreground",
|
|
33520
33607
|
"border-[length:var(--border-width-thin)] border-border",
|
|
@@ -33569,7 +33656,7 @@ var init_Sidebar = __esm({
|
|
|
33569
33656
|
as: "aside",
|
|
33570
33657
|
className: cn(
|
|
33571
33658
|
"flex flex-col h-full",
|
|
33572
|
-
"bg-card border-
|
|
33659
|
+
"bg-card border-e border-border",
|
|
33573
33660
|
"transition-all duration-300 ease-in-out",
|
|
33574
33661
|
collapsed ? "w-20" : "w-64",
|
|
33575
33662
|
className
|
|
@@ -34730,7 +34817,7 @@ function resolveColor3(color, el) {
|
|
|
34730
34817
|
function truncateLabel(label) {
|
|
34731
34818
|
return label.length > MAX_LABEL_CHARS ? label.slice(0, MAX_LABEL_CHARS - 1) + "\u2026" : label;
|
|
34732
34819
|
}
|
|
34733
|
-
var GROUP_COLORS2, GROUP_GRAVITY, UNGROUPED_GRAVITY, labelMeasureCtx, MAX_LABEL_CHARS, GraphCanvas;
|
|
34820
|
+
var GROUP_COLORS2, GROUP_GRAVITY, UNGROUPED_GRAVITY, labelMeasureCtx, MAX_LABEL_CHARS, NO_NODES, NO_EDGES, NO_SIM, GraphCanvas;
|
|
34734
34821
|
var init_GraphCanvas = __esm({
|
|
34735
34822
|
"components/core/molecules/GraphCanvas.tsx"() {
|
|
34736
34823
|
"use client";
|
|
@@ -34754,11 +34841,14 @@ var init_GraphCanvas = __esm({
|
|
|
34754
34841
|
UNGROUPED_GRAVITY = 0.02;
|
|
34755
34842
|
labelMeasureCtx = null;
|
|
34756
34843
|
MAX_LABEL_CHARS = 22;
|
|
34844
|
+
NO_NODES = [];
|
|
34845
|
+
NO_EDGES = [];
|
|
34846
|
+
NO_SIM = [];
|
|
34757
34847
|
GraphCanvas = ({
|
|
34758
34848
|
title,
|
|
34759
|
-
nodes: propNodes =
|
|
34760
|
-
edges: propEdges =
|
|
34761
|
-
similarity: propSimilarity =
|
|
34849
|
+
nodes: propNodes = NO_NODES,
|
|
34850
|
+
edges: propEdges = NO_EDGES,
|
|
34851
|
+
similarity: propSimilarity = NO_SIM,
|
|
34762
34852
|
height = 400,
|
|
34763
34853
|
showLabels = true,
|
|
34764
34854
|
interactive = true,
|
|
@@ -34808,6 +34898,7 @@ var init_GraphCanvas = __esm({
|
|
|
34808
34898
|
const interactionRef = useRef({
|
|
34809
34899
|
mode: "none",
|
|
34810
34900
|
dragNodeId: null,
|
|
34901
|
+
pressedNodeId: null,
|
|
34811
34902
|
startMouse: { x: 0, y: 0 },
|
|
34812
34903
|
startOffset: { x: 0, y: 0 },
|
|
34813
34904
|
downPos: { x: 0, y: 0 }
|
|
@@ -34855,6 +34946,11 @@ var init_GraphCanvas = __esm({
|
|
|
34855
34946
|
() => [...new Set(propNodes.map((n) => n.group).filter(Boolean))],
|
|
34856
34947
|
[propNodes]
|
|
34857
34948
|
);
|
|
34949
|
+
const nodesKey = useMemo(() => propNodes.map((n) => n.id).join(""), [propNodes]);
|
|
34950
|
+
const edgesKey = useMemo(
|
|
34951
|
+
() => propEdges.map((e) => `${e.source}${e.target}`).join(""),
|
|
34952
|
+
[propEdges]
|
|
34953
|
+
);
|
|
34858
34954
|
useEffect(() => {
|
|
34859
34955
|
const canvas = canvasRef.current;
|
|
34860
34956
|
if (!canvas || propNodes.length === 0) return;
|
|
@@ -35035,7 +35131,7 @@ var init_GraphCanvas = __esm({
|
|
|
35035
35131
|
return () => {
|
|
35036
35132
|
cancelAnimationFrame(animRef.current);
|
|
35037
35133
|
};
|
|
35038
|
-
}, [
|
|
35134
|
+
}, [nodesKey, edgesKey, propSimilarity, layout, repulsion, linkDistance, nodeSpacing, showLabels]);
|
|
35039
35135
|
useEffect(() => {
|
|
35040
35136
|
const canvas = canvasRef.current;
|
|
35041
35137
|
if (!canvas) return;
|
|
@@ -35165,6 +35261,7 @@ var init_GraphCanvas = __esm({
|
|
|
35165
35261
|
const cancelSinglePointer = useCallback(() => {
|
|
35166
35262
|
interactionRef.current.mode = "none";
|
|
35167
35263
|
interactionRef.current.dragNodeId = null;
|
|
35264
|
+
interactionRef.current.pressedNodeId = null;
|
|
35168
35265
|
}, []);
|
|
35169
35266
|
const handlePointerDown = useCallback(
|
|
35170
35267
|
(e) => {
|
|
@@ -35175,6 +35272,7 @@ var init_GraphCanvas = __esm({
|
|
|
35175
35272
|
state.downPos = { x: e.clientX, y: e.clientY };
|
|
35176
35273
|
state.startMouse = { x: e.clientX, y: e.clientY };
|
|
35177
35274
|
state.startOffset = { ...offset };
|
|
35275
|
+
state.pressedNodeId = node?.id ?? null;
|
|
35178
35276
|
if (draggable && node) {
|
|
35179
35277
|
state.mode = "dragging";
|
|
35180
35278
|
state.dragNodeId = node.id;
|
|
@@ -35226,7 +35324,8 @@ var init_GraphCanvas = __esm({
|
|
|
35226
35324
|
if (moved < 4) {
|
|
35227
35325
|
const coords = toCoords(e);
|
|
35228
35326
|
if (!coords) return;
|
|
35229
|
-
const node = nodeAt(coords.graphX, coords.graphY);
|
|
35327
|
+
const node = (state.pressedNodeId ? nodesRef.current.find((n) => n.id === state.pressedNodeId) : void 0) ?? nodeAt(coords.graphX, coords.graphY);
|
|
35328
|
+
state.pressedNodeId = null;
|
|
35230
35329
|
if (node) {
|
|
35231
35330
|
if (node.badge && node.badge > 1 && onBadgeClick) {
|
|
35232
35331
|
const r = (node.size || 8) + (selectedNodeId === node.id ? 4 : 0);
|
|
@@ -35246,6 +35345,7 @@ var init_GraphCanvas = __esm({
|
|
|
35246
35345
|
);
|
|
35247
35346
|
const handlePointerLeave = useCallback(() => {
|
|
35248
35347
|
setHoveredNode(null);
|
|
35348
|
+
interactionRef.current.pressedNodeId = null;
|
|
35249
35349
|
}, []);
|
|
35250
35350
|
const gestureHandlers = useCanvasGestures({
|
|
35251
35351
|
canvasRef,
|
|
@@ -38197,8 +38297,17 @@ var init_MediaGallery = __esm({
|
|
|
38197
38297
|
const eventBus = useEventBus();
|
|
38198
38298
|
const { t } = useTranslate();
|
|
38199
38299
|
const [lightboxItem, setLightboxItem] = useState(null);
|
|
38300
|
+
const [failedIds, setFailedIds] = useState(/* @__PURE__ */ new Set());
|
|
38200
38301
|
const closeLightbox = useCallback(() => setLightboxItem(null), []);
|
|
38201
38302
|
useEventListener("UI:LIGHTBOX_CLOSE", closeLightbox);
|
|
38303
|
+
const handleImageError = useCallback((id) => {
|
|
38304
|
+
setFailedIds((prev) => {
|
|
38305
|
+
if (prev.has(id)) return prev;
|
|
38306
|
+
const next = new Set(prev);
|
|
38307
|
+
next.add(id);
|
|
38308
|
+
return next;
|
|
38309
|
+
});
|
|
38310
|
+
}, []);
|
|
38202
38311
|
const handleItemClick = useCallback(
|
|
38203
38312
|
(item) => {
|
|
38204
38313
|
if (selectable) {
|
|
@@ -38214,7 +38323,7 @@ var init_MediaGallery = __esm({
|
|
|
38214
38323
|
);
|
|
38215
38324
|
const entityData = Array.isArray(entity) ? entity : [];
|
|
38216
38325
|
const items = React81__default.useMemo(() => {
|
|
38217
|
-
if (propItems) return propItems;
|
|
38326
|
+
if (propItems && propItems.length > 0) return propItems;
|
|
38218
38327
|
if (entityData.length === 0) return [];
|
|
38219
38328
|
return entityData.map((record, idx) => {
|
|
38220
38329
|
return {
|
|
@@ -38297,13 +38406,14 @@ var init_MediaGallery = __esm({
|
|
|
38297
38406
|
),
|
|
38298
38407
|
onClick: () => handleItemClick(item),
|
|
38299
38408
|
children: [
|
|
38300
|
-
/* @__PURE__ */ jsx(
|
|
38409
|
+
failedIds.has(item.id) ? /* @__PURE__ */ jsx(Box, { className: "w-full h-full flex items-center justify-center bg-muted text-muted-foreground", children: /* @__PURE__ */ jsx(Icon, { icon: Image$1, size: "lg" }) }) : /* @__PURE__ */ jsx(
|
|
38301
38410
|
"img",
|
|
38302
38411
|
{
|
|
38303
38412
|
src: item.thumbnail || item.src,
|
|
38304
38413
|
alt: item.alt || item.caption || "",
|
|
38305
38414
|
className: "w-full h-full object-cover",
|
|
38306
|
-
loading: "lazy"
|
|
38415
|
+
loading: "lazy",
|
|
38416
|
+
onError: () => handleImageError(item.id)
|
|
38307
38417
|
}
|
|
38308
38418
|
),
|
|
38309
38419
|
/* @__PURE__ */ jsx(
|
|
@@ -41810,6 +41920,11 @@ var init_TeamOrganism = __esm({
|
|
|
41810
41920
|
TeamOrganism.displayName = "TeamOrganism";
|
|
41811
41921
|
}
|
|
41812
41922
|
});
|
|
41923
|
+
function formatDate4(value) {
|
|
41924
|
+
const d = new Date(value);
|
|
41925
|
+
if (isNaN(d.getTime())) return value;
|
|
41926
|
+
return d.toLocaleDateString(void 0, { year: "numeric", month: "short", day: "numeric" });
|
|
41927
|
+
}
|
|
41813
41928
|
var lookStyles10, STATUS_STYLES2, Timeline;
|
|
41814
41929
|
var init_Timeline = __esm({
|
|
41815
41930
|
"components/core/organisms/Timeline.tsx"() {
|
|
@@ -41937,7 +42052,7 @@ var init_Timeline = __esm({
|
|
|
41937
42052
|
/* @__PURE__ */ jsxs(VStack, { gap: "xs", className: cn("flex-1 min-w-0", !isLast && "pb-6"), children: [
|
|
41938
42053
|
/* @__PURE__ */ jsxs(HStack, { justify: "between", align: "start", wrap: true, children: [
|
|
41939
42054
|
/* @__PURE__ */ jsx(Typography, { variant: "body", weight: "semibold", children: item.title }),
|
|
41940
|
-
item.date && /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", className: "flex-shrink-0", children: item.date })
|
|
42055
|
+
item.date && /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", className: "flex-shrink-0", children: formatDate4(item.date) })
|
|
41941
42056
|
] }),
|
|
41942
42057
|
item.description && /* @__PURE__ */ jsx(Typography, { variant: "small", color: "secondary", children: item.description }),
|
|
41943
42058
|
item.tags && item.tags.length > 0 && /* @__PURE__ */ jsx(HStack, { gap: "xs", wrap: true, children: item.tags.map((tag, tagIdx) => /* @__PURE__ */ jsx(Badge, { variant: "default", children: tag }, tagIdx)) }),
|
|
@@ -43149,7 +43264,7 @@ function substituteTraitRefsDeep(value, pathKey) {
|
|
|
43149
43264
|
}
|
|
43150
43265
|
return value;
|
|
43151
43266
|
}
|
|
43152
|
-
function renderPatternProps(props, onDismiss) {
|
|
43267
|
+
function renderPatternProps(props, onDismiss, propsSchema) {
|
|
43153
43268
|
const rendered = {};
|
|
43154
43269
|
for (const [key, value] of Object.entries(props)) {
|
|
43155
43270
|
if (key === "children") {
|
|
@@ -43167,9 +43282,10 @@ function renderPatternProps(props, onDismiss) {
|
|
|
43167
43282
|
};
|
|
43168
43283
|
rendered[key] = /* @__PURE__ */ jsx(SlotContentRenderer, { content: childContent, onDismiss });
|
|
43169
43284
|
} else if (Array.isArray(value)) {
|
|
43285
|
+
const isDataArray = propsSchema?.[key]?.items?.types?.includes("object") ?? false;
|
|
43170
43286
|
rendered[key] = value.map((item, i) => {
|
|
43171
43287
|
const el = item;
|
|
43172
|
-
if (isPatternConfig(el)) {
|
|
43288
|
+
if (!isDataArray && isPatternConfig(el)) {
|
|
43173
43289
|
const nestedProps = {};
|
|
43174
43290
|
for (const [k, v] of Object.entries(el)) {
|
|
43175
43291
|
if (k !== "type") nestedProps[k] = v;
|
|
@@ -43257,14 +43373,15 @@ function SlotContentRenderer({
|
|
|
43257
43373
|
);
|
|
43258
43374
|
}
|
|
43259
43375
|
}
|
|
43260
|
-
const renderedProps = renderPatternProps(restProps, onDismiss);
|
|
43261
43376
|
const patternDef = getPatternDefinition(content.pattern);
|
|
43262
43377
|
const propsSchema = patternDef?.propsSchema;
|
|
43378
|
+
const renderedProps = renderPatternProps(restProps, onDismiss, propsSchema);
|
|
43263
43379
|
if (propsSchema) {
|
|
43264
43380
|
for (const [propKey, propValue] of Object.entries(renderedProps)) {
|
|
43265
43381
|
if (typeof propValue !== "string") continue;
|
|
43266
43382
|
const propDef = propsSchema[propKey];
|
|
43267
43383
|
if (!propDef || propDef.kind !== "callback") continue;
|
|
43384
|
+
if (propValue === "") continue;
|
|
43268
43385
|
renderedProps[propKey] = wrapCallbackForEvent(
|
|
43269
43386
|
`UI:${propValue}`,
|
|
43270
43387
|
propDef.callbackArgs,
|
|
@@ -43547,6 +43664,7 @@ function useSharedEntityStore() {
|
|
|
43547
43664
|
}
|
|
43548
43665
|
return storeRef.current;
|
|
43549
43666
|
}
|
|
43667
|
+
createContext(null);
|
|
43550
43668
|
function runTickFrame(entityId, orderedWriters, store) {
|
|
43551
43669
|
let scratch = store.getSnapshot(entityId);
|
|
43552
43670
|
for (const writer of orderedWriters) {
|
|
@@ -43782,6 +43900,11 @@ var SYNC_TICK_OPERATORS = /* @__PURE__ */ new Set([
|
|
|
43782
43900
|
"do",
|
|
43783
43901
|
"when"
|
|
43784
43902
|
]);
|
|
43903
|
+
var REACTIVE_REPAINT_PATTERN_TYPES = /* @__PURE__ */ new Set([
|
|
43904
|
+
"canvas",
|
|
43905
|
+
"game-hud",
|
|
43906
|
+
"game-shell"
|
|
43907
|
+
]);
|
|
43785
43908
|
var LIFECYCLE_EVENTS = ["INIT", "LOAD", "$MOUNT"];
|
|
43786
43909
|
function toTraitDefinition(binding) {
|
|
43787
43910
|
return {
|
|
@@ -44034,6 +44157,8 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
44034
44157
|
}, [traitStates]);
|
|
44035
44158
|
const traitSnapshotDataRef = useRef(/* @__PURE__ */ new Map());
|
|
44036
44159
|
const traitFieldStatesRef = useRef(/* @__PURE__ */ new Map());
|
|
44160
|
+
const lastCanvasRenderUiRef = useRef(/* @__PURE__ */ new Map());
|
|
44161
|
+
const executeTransitionEffectsRef = useRef(null);
|
|
44037
44162
|
useEffect(() => {
|
|
44038
44163
|
const mgr = managerRef.current;
|
|
44039
44164
|
const bindings = traitBindingsRef.current;
|
|
@@ -44074,11 +44199,9 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
44074
44199
|
bindTraitStateGetter((traitName) => {
|
|
44075
44200
|
const allStates = newManager.getAllStates();
|
|
44076
44201
|
if (allStates instanceof Map) {
|
|
44077
|
-
|
|
44078
|
-
return typeof val === "string" ? val : void 0;
|
|
44202
|
+
return allStates.get(traitName)?.currentState;
|
|
44079
44203
|
}
|
|
44080
|
-
|
|
44081
|
-
return typeof state === "string" ? state : void 0;
|
|
44204
|
+
return newManager.getState(traitName)?.currentState;
|
|
44082
44205
|
});
|
|
44083
44206
|
const snapshotUnregs = [];
|
|
44084
44207
|
for (const binding of traitBindingsRef.current) {
|
|
@@ -44163,6 +44286,15 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
44163
44286
|
const existing = pendingSlots.get(slot) || [];
|
|
44164
44287
|
existing.push({ pattern, props: props || {} });
|
|
44165
44288
|
pendingSlots.set(slot, existing);
|
|
44289
|
+
const patternType = pattern?.type;
|
|
44290
|
+
if (patternType !== void 0 && REACTIVE_REPAINT_PATTERN_TYPES.has(patternType)) {
|
|
44291
|
+
const rawForSlot = effects.filter(
|
|
44292
|
+
(e) => Array.isArray(e) && (e[0] === "render-ui" || e[0] === "render") && e[1] === slot
|
|
44293
|
+
);
|
|
44294
|
+
if (rawForSlot.length > 0) {
|
|
44295
|
+
lastCanvasRenderUiRef.current.set(traitName, rawForSlot);
|
|
44296
|
+
}
|
|
44297
|
+
}
|
|
44166
44298
|
},
|
|
44167
44299
|
clearSlot: (slot) => {
|
|
44168
44300
|
pendingSlots.set(slot, []);
|
|
@@ -44233,11 +44365,15 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
44233
44365
|
notify: clientHandlers.notify
|
|
44234
44366
|
};
|
|
44235
44367
|
}
|
|
44368
|
+
const sharedWrites = [];
|
|
44236
44369
|
const baseSet = handlers.set;
|
|
44237
44370
|
handlers = {
|
|
44238
44371
|
...handlers,
|
|
44239
44372
|
set: async (targetId, field, value) => {
|
|
44240
44373
|
if (baseSet) await baseSet(targetId, field, value);
|
|
44374
|
+
if (sharedKey !== void 0) {
|
|
44375
|
+
sharedWrites.push({ field, value });
|
|
44376
|
+
}
|
|
44241
44377
|
log9.debug("set:write", {
|
|
44242
44378
|
traitName,
|
|
44243
44379
|
field,
|
|
@@ -44313,7 +44449,10 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
44313
44449
|
});
|
|
44314
44450
|
}
|
|
44315
44451
|
if (sharedKey !== void 0) {
|
|
44316
|
-
sharedEntityStore.commit(
|
|
44452
|
+
sharedEntityStore.commit(
|
|
44453
|
+
sharedKey,
|
|
44454
|
+
mergeEntityFrame(sharedEntityStore.getSnapshot(sharedKey), sharedWrites)
|
|
44455
|
+
);
|
|
44317
44456
|
}
|
|
44318
44457
|
log9.debug("effects:executed", () => ({
|
|
44319
44458
|
traitName,
|
|
@@ -44339,6 +44478,38 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
44339
44478
|
entity: binding.linkedEntity
|
|
44340
44479
|
});
|
|
44341
44480
|
}
|
|
44481
|
+
if (pendingSlots.size === 0 && effectsCallOp(effects, SHARED_ENTITY_WRITE_OPS)) {
|
|
44482
|
+
const stashed = lastCanvasRenderUiRef.current.get(traitName);
|
|
44483
|
+
if (stashed !== void 0 && stashed.length > 0) {
|
|
44484
|
+
await executor.executeAll(stashed);
|
|
44485
|
+
for (const [slot, patterns] of pendingSlots) {
|
|
44486
|
+
flushSlot(traitName, slot, patterns, {
|
|
44487
|
+
event: flushEvent,
|
|
44488
|
+
state: previousState,
|
|
44489
|
+
entity: binding.linkedEntity
|
|
44490
|
+
});
|
|
44491
|
+
}
|
|
44492
|
+
}
|
|
44493
|
+
if (sharedKey !== void 0 && executeTransitionEffectsRef.current !== null) {
|
|
44494
|
+
for (const sibling of traitBindingsRef.current) {
|
|
44495
|
+
const siblingName = sibling.trait.name;
|
|
44496
|
+
if (siblingName === traitName) continue;
|
|
44497
|
+
if (sharedKeyByTraitNameRef.current.get(siblingName) !== sharedKey) continue;
|
|
44498
|
+
const siblingStash = lastCanvasRenderUiRef.current.get(siblingName);
|
|
44499
|
+
if (siblingStash === void 0 || siblingStash.length === 0) continue;
|
|
44500
|
+
const siblingState = traitStatesRef.current.get(siblingName)?.currentState ?? "";
|
|
44501
|
+
await executeTransitionEffectsRef.current({
|
|
44502
|
+
binding: sibling,
|
|
44503
|
+
effects: siblingStash,
|
|
44504
|
+
previousState: siblingState,
|
|
44505
|
+
newState: siblingState,
|
|
44506
|
+
flushEvent: `${flushEvent}:repaint`,
|
|
44507
|
+
syncOnly,
|
|
44508
|
+
log: log9
|
|
44509
|
+
});
|
|
44510
|
+
}
|
|
44511
|
+
}
|
|
44512
|
+
}
|
|
44342
44513
|
} catch (error) {
|
|
44343
44514
|
log9.error("effects:error", {
|
|
44344
44515
|
traitName,
|
|
@@ -44350,6 +44521,9 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
44350
44521
|
}
|
|
44351
44522
|
return emittedDuringExec;
|
|
44352
44523
|
}, [eventBus, flushSlot, sharedEntityStore]);
|
|
44524
|
+
useEffect(() => {
|
|
44525
|
+
executeTransitionEffectsRef.current = executeTransitionEffects;
|
|
44526
|
+
}, [executeTransitionEffects]);
|
|
44353
44527
|
const runTickEffects = useCallback((tick, binding) => {
|
|
44354
44528
|
const traitName = binding.trait.name;
|
|
44355
44529
|
const currentState = traitStatesRef.current.get(traitName)?.currentState ?? "";
|
|
@@ -44412,6 +44586,24 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
44412
44586
|
({ binding, tick }) => createSharedEntityWriter(binding, tick, traitStatesRef, emitFromSharedWriter)
|
|
44413
44587
|
);
|
|
44414
44588
|
runTickFrame(group.storeKey, writers, sharedEntityStore);
|
|
44589
|
+
const repaint = executeTransitionEffectsRef.current;
|
|
44590
|
+
if (repaint !== null) {
|
|
44591
|
+
for (const renderBinding of group.renderBindings) {
|
|
44592
|
+
const renderTraitName = renderBinding.trait.name;
|
|
44593
|
+
const stash = lastCanvasRenderUiRef.current.get(renderTraitName);
|
|
44594
|
+
if (stash === void 0 || stash.length === 0) continue;
|
|
44595
|
+
const renderState = traitStatesRef.current.get(renderTraitName)?.currentState ?? "";
|
|
44596
|
+
void repaint({
|
|
44597
|
+
binding: renderBinding,
|
|
44598
|
+
effects: stash,
|
|
44599
|
+
previousState: renderState,
|
|
44600
|
+
newState: renderState,
|
|
44601
|
+
flushEvent: "tick:repaint",
|
|
44602
|
+
syncOnly: true,
|
|
44603
|
+
log: sharedEntityLog
|
|
44604
|
+
});
|
|
44605
|
+
}
|
|
44606
|
+
}
|
|
44415
44607
|
};
|
|
44416
44608
|
if (interval === "frame") {
|
|
44417
44609
|
scheduler.add(0, onDue);
|
|
@@ -44461,6 +44653,13 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
44461
44653
|
entityByTrait[name] = fields;
|
|
44462
44654
|
}
|
|
44463
44655
|
}
|
|
44656
|
+
for (const binding of bindings) {
|
|
44657
|
+
const name = binding.trait.name;
|
|
44658
|
+
const sharedKey = sharedKeyByTraitNameRef.current.get(name);
|
|
44659
|
+
if (sharedKey !== void 0) {
|
|
44660
|
+
entityByTrait[name] = { ...sharedEntityStore.getSnapshot(sharedKey) };
|
|
44661
|
+
}
|
|
44662
|
+
}
|
|
44464
44663
|
const results = currentManager.sendEvent(
|
|
44465
44664
|
normalizedEvent,
|
|
44466
44665
|
payload,
|
|
@@ -44614,7 +44813,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
44614
44813
|
}
|
|
44615
44814
|
await onEventProcessed(normalizedEvent, payload, dispatchedOrbitals);
|
|
44616
44815
|
}
|
|
44617
|
-
}, [entities, eventBus]);
|
|
44816
|
+
}, [entities, eventBus, sharedEntityStore]);
|
|
44618
44817
|
const drainEventQueue = useCallback(async () => {
|
|
44619
44818
|
if (processingRef.current) return;
|
|
44620
44819
|
processingRef.current = true;
|
|
@@ -44684,6 +44883,24 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
44684
44883
|
});
|
|
44685
44884
|
}
|
|
44686
44885
|
}
|
|
44886
|
+
const bareCascadeKeys = /* @__PURE__ */ new Set();
|
|
44887
|
+
for (const binding of traitBindings) {
|
|
44888
|
+
for (const transition of binding.trait.transitions) {
|
|
44889
|
+
const eventKey = transition.event;
|
|
44890
|
+
if (LIFECYCLE_EVENTS.includes(eventKey)) continue;
|
|
44891
|
+
if (bareCascadeKeys.has(eventKey)) continue;
|
|
44892
|
+
bareCascadeKeys.add(eventKey);
|
|
44893
|
+
const bareKey = `UI:${eventKey}`;
|
|
44894
|
+
const unsub = eventBus.on(bareKey, (event) => {
|
|
44895
|
+
crossTraitLog.debug("bare-cascade:fire", { bareKey, eventKey });
|
|
44896
|
+
enqueueAndDrain(eventKey, event.payload);
|
|
44897
|
+
});
|
|
44898
|
+
unsubscribes.push(() => {
|
|
44899
|
+
crossTraitLog.debug("bare-cascade:unsubscribe", { bareKey, eventKey });
|
|
44900
|
+
unsub();
|
|
44901
|
+
});
|
|
44902
|
+
}
|
|
44903
|
+
}
|
|
44687
44904
|
for (const binding of traitBindings) {
|
|
44688
44905
|
const ownOrbital = orbitalsByTrait?.[binding.trait.name];
|
|
44689
44906
|
const listens = binding.trait.listens ?? [];
|
|
@@ -44868,9 +45085,16 @@ function normalizeChild(child) {
|
|
|
44868
45085
|
props: { ...rest, ...normalizedChildren !== void 0 ? { children: normalizedChildren } : {} }
|
|
44869
45086
|
};
|
|
44870
45087
|
}
|
|
44871
|
-
function applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits) {
|
|
45088
|
+
function applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits, activeTraits) {
|
|
44872
45089
|
for (const eff of effects) {
|
|
44873
45090
|
if (eff.type === "render-ui" && eff.slot && eff.pattern) {
|
|
45091
|
+
if (eff.traitName && activeTraits && !activeTraits.has(eff.traitName)) {
|
|
45092
|
+
xOrbitalLog.debug("slot:off-page-trait-skipped", {
|
|
45093
|
+
sourceTrait: eff.traitName,
|
|
45094
|
+
slot: eff.slot
|
|
45095
|
+
});
|
|
45096
|
+
continue;
|
|
45097
|
+
}
|
|
44874
45098
|
const patternRecord = eff.pattern;
|
|
44875
45099
|
const { type: patternType, children, ...inlineProps } = patternRecord;
|
|
44876
45100
|
const normalizedChildren = Array.isArray(children) ? children.map((c) => normalizeChild(c)) : children;
|
|
@@ -44911,8 +45135,38 @@ function applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits) {
|
|
|
44911
45135
|
}
|
|
44912
45136
|
}
|
|
44913
45137
|
}
|
|
44914
|
-
function
|
|
45138
|
+
function collectServerActiveTraits(ir, allTraits, mountedTraitNames) {
|
|
45139
|
+
if (!ir?.pages || ir.pages.size <= 1) return void 0;
|
|
45140
|
+
const pageBound = /* @__PURE__ */ new Set();
|
|
45141
|
+
for (const page of ir.pages.values()) {
|
|
45142
|
+
const queue = page.traits.map((b) => b.trait.name).filter((n) => !!n);
|
|
45143
|
+
for (const name of queue) {
|
|
45144
|
+
if (pageBound.has(name)) continue;
|
|
45145
|
+
pageBound.add(name);
|
|
45146
|
+
const rt = allTraits.get(name);
|
|
45147
|
+
if (!rt) continue;
|
|
45148
|
+
queue.push(...collectTraitRefsFromResolvedTrait(rt));
|
|
45149
|
+
}
|
|
45150
|
+
}
|
|
45151
|
+
const active = new Set(mountedTraitNames);
|
|
45152
|
+
for (const name of allTraits.keys()) {
|
|
45153
|
+
if (!pageBound.has(name)) active.add(name);
|
|
45154
|
+
}
|
|
45155
|
+
return active;
|
|
45156
|
+
}
|
|
45157
|
+
function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFallback, persistence, traitConfigsByName, orbitalsByTrait, embeddedTraits, serverActiveTraits }) {
|
|
44915
45158
|
const bridge = useServerBridge();
|
|
45159
|
+
const activeTraitNames = useMemo(
|
|
45160
|
+
() => new Set(traits2.map((b) => b.trait.name).filter((n) => !!n)),
|
|
45161
|
+
[traits2]
|
|
45162
|
+
);
|
|
45163
|
+
const withActiveTraits = useCallback(
|
|
45164
|
+
(payload) => {
|
|
45165
|
+
if (!serverActiveTraits || serverActiveTraits.size === 0) return payload;
|
|
45166
|
+
return { ...payload ?? {}, _activeTraits: Array.from(serverActiveTraits) };
|
|
45167
|
+
},
|
|
45168
|
+
[serverActiveTraits]
|
|
45169
|
+
);
|
|
44916
45170
|
const uiSlots = useUISlots();
|
|
44917
45171
|
const onEventProcessed = useCallback(async (event, payload, dispatchedOrbitals) => {
|
|
44918
45172
|
if (!bridge.connected || !orbitalNames?.length) return;
|
|
@@ -44924,11 +45178,11 @@ function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFa
|
|
|
44924
45178
|
dispatchedOrbitalsSize: dispatchedOrbitals?.size ?? 0
|
|
44925
45179
|
}));
|
|
44926
45180
|
for (const name of targets) {
|
|
44927
|
-
const { effects, meta } = await bridge.sendEvent(name, event, payload);
|
|
45181
|
+
const { effects, meta } = await bridge.sendEvent(name, event, withActiveTraits(payload));
|
|
44928
45182
|
recordServerResponse(name, event, meta);
|
|
44929
|
-
applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits);
|
|
45183
|
+
applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits, activeTraitNames);
|
|
44930
45184
|
}
|
|
44931
|
-
}, [bridge.connected, bridge.sendEvent, orbitalNames, uiSlots, onNavigate, embeddedTraits]);
|
|
45185
|
+
}, [bridge.connected, bridge.sendEvent, orbitalNames, uiSlots, onNavigate, embeddedTraits, activeTraitNames, withActiveTraits]);
|
|
44932
45186
|
const opts = orbitalNames ? { onEventProcessed, navigate: onNavigate, traitConfigsByName, orbitalsByTrait, embeddedTraits } : { navigate: onNavigate, persistence, traitConfigsByName, orbitalsByTrait, embeddedTraits };
|
|
44933
45187
|
const { sendEvent } = useTraitStateMachine(traits2, uiSlots, opts);
|
|
44934
45188
|
const initSentRef = useRef(false);
|
|
@@ -44965,7 +45219,7 @@ function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFa
|
|
|
44965
45219
|
initSentRef.current = true;
|
|
44966
45220
|
(async () => {
|
|
44967
45221
|
for (const name of orbitalNames) {
|
|
44968
|
-
const { effects, meta } = await bridge.sendEvent(name, "INIT", {});
|
|
45222
|
+
const { effects, meta } = await bridge.sendEvent(name, "INIT", withActiveTraits({}));
|
|
44969
45223
|
recordServerResponse(name, "INIT", meta);
|
|
44970
45224
|
const effectTraces = [
|
|
44971
45225
|
{ type: "fetch", args: [], status: "executed" },
|
|
@@ -44983,10 +45237,10 @@ function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFa
|
|
|
44983
45237
|
effects: effectTraces,
|
|
44984
45238
|
timestamp: Date.now()
|
|
44985
45239
|
});
|
|
44986
|
-
applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits);
|
|
45240
|
+
applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits, activeTraitNames);
|
|
44987
45241
|
}
|
|
44988
45242
|
})();
|
|
44989
|
-
}, [bridge.connected, orbitalNames, bridge.sendEvent, uiSlots, onNavigate, embeddedTraits]);
|
|
45243
|
+
}, [bridge.connected, orbitalNames, bridge.sendEvent, uiSlots, onNavigate, embeddedTraits, activeTraitNames, withActiveTraits]);
|
|
44990
45244
|
return null;
|
|
44991
45245
|
}
|
|
44992
45246
|
function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, onNavigate, onLocalFallback, persistence }) {
|
|
@@ -45073,6 +45327,14 @@ function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, onNavi
|
|
|
45073
45327
|
}
|
|
45074
45328
|
return Array.from(set);
|
|
45075
45329
|
}, [allPageTraits, orbitalsByTrait]);
|
|
45330
|
+
const serverActiveTraits = useMemo(
|
|
45331
|
+
() => collectServerActiveTraits(
|
|
45332
|
+
ir,
|
|
45333
|
+
allTraits,
|
|
45334
|
+
new Set(allPageTraits.map((b) => b.trait.name).filter((n) => !!n))
|
|
45335
|
+
),
|
|
45336
|
+
[ir, allTraits, allPageTraits]
|
|
45337
|
+
);
|
|
45076
45338
|
useEffect(() => {
|
|
45077
45339
|
const traitNames = allPageTraits.map((b) => b.trait.name);
|
|
45078
45340
|
const orbitalsByTraitForPage = {};
|
|
@@ -45082,7 +45344,7 @@ function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, onNavi
|
|
|
45082
45344
|
}
|
|
45083
45345
|
xOrbitalLog.info("SchemaRunner:mount", {
|
|
45084
45346
|
pageName,
|
|
45085
|
-
traitNames,
|
|
45347
|
+
traitNames: traitNames.join(","),
|
|
45086
45348
|
orbitalsByTraitForPage,
|
|
45087
45349
|
pageOrbitalNames: pageOrbitalNames.join(",")
|
|
45088
45350
|
});
|
|
@@ -45127,6 +45389,7 @@ function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, onNavi
|
|
|
45127
45389
|
traitConfigsByName,
|
|
45128
45390
|
orbitalsByTrait,
|
|
45129
45391
|
embeddedTraits,
|
|
45392
|
+
serverActiveTraits,
|
|
45130
45393
|
onNavigate,
|
|
45131
45394
|
onLocalFallback,
|
|
45132
45395
|
persistence
|