@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.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, 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";
|
|
@@ -34750,13 +34837,18 @@ var init_GraphCanvas = __esm({
|
|
|
34750
34837
|
"var(--color-info)",
|
|
34751
34838
|
"var(--color-accent)"
|
|
34752
34839
|
];
|
|
34840
|
+
GROUP_GRAVITY = 0.3;
|
|
34841
|
+
UNGROUPED_GRAVITY = 0.02;
|
|
34753
34842
|
labelMeasureCtx = null;
|
|
34754
34843
|
MAX_LABEL_CHARS = 22;
|
|
34844
|
+
NO_NODES = [];
|
|
34845
|
+
NO_EDGES = [];
|
|
34846
|
+
NO_SIM = [];
|
|
34755
34847
|
GraphCanvas = ({
|
|
34756
34848
|
title,
|
|
34757
|
-
nodes: propNodes =
|
|
34758
|
-
edges: propEdges =
|
|
34759
|
-
similarity: propSimilarity =
|
|
34849
|
+
nodes: propNodes = NO_NODES,
|
|
34850
|
+
edges: propEdges = NO_EDGES,
|
|
34851
|
+
similarity: propSimilarity = NO_SIM,
|
|
34760
34852
|
height = 400,
|
|
34761
34853
|
showLabels = true,
|
|
34762
34854
|
interactive = true,
|
|
@@ -34806,6 +34898,7 @@ var init_GraphCanvas = __esm({
|
|
|
34806
34898
|
const interactionRef = useRef({
|
|
34807
34899
|
mode: "none",
|
|
34808
34900
|
dragNodeId: null,
|
|
34901
|
+
pressedNodeId: null,
|
|
34809
34902
|
startMouse: { x: 0, y: 0 },
|
|
34810
34903
|
startOffset: { x: 0, y: 0 },
|
|
34811
34904
|
downPos: { x: 0, y: 0 }
|
|
@@ -34853,6 +34946,11 @@ var init_GraphCanvas = __esm({
|
|
|
34853
34946
|
() => [...new Set(propNodes.map((n) => n.group).filter(Boolean))],
|
|
34854
34947
|
[propNodes]
|
|
34855
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
|
+
);
|
|
34856
34954
|
useEffect(() => {
|
|
34857
34955
|
const canvas = canvasRef.current;
|
|
34858
34956
|
if (!canvas || propNodes.length === 0) return;
|
|
@@ -34936,7 +35034,7 @@ var init_GraphCanvas = __esm({
|
|
|
34936
35034
|
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) }));
|
|
34937
35035
|
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) }));
|
|
34938
35036
|
const collideRadius = (n) => Math.max(n.size || 8, (n.labelW ?? 0) / 2) + nodeSpacing / 2;
|
|
34939
|
-
const simulation = forceSimulation(simNodes).force("edge", forceLink(edgeLinks).id((d) => d.id).distance((l) => linkDistance * (0.35 + (1 - l.weight) * 0.3)).strength(0.9)).force("similarity", forceLink(simLinks).id((d) => d.id).distance((l) => linkDistance * (1.35 - 0.55 * l.weight)).strength(0.03)).force("charge", forceManyBody().strength(-repulsion * 0.5)).force("collide", forceCollide().radius(collideRadius).strength(0.9)).force("x", forceX((n) => groupTarget.get(n.group ?? "")?.x ?? w / 2).strength((n) => multiCluster && n.group ?
|
|
35037
|
+
const simulation = forceSimulation(simNodes).force("edge", forceLink(edgeLinks).id((d) => d.id).distance((l) => linkDistance * (0.35 + (1 - l.weight) * 0.3)).strength(0.9)).force("similarity", forceLink(simLinks).id((d) => d.id).distance((l) => linkDistance * (1.35 - 0.55 * l.weight)).strength(0.03)).force("charge", forceManyBody().strength(-repulsion * 0.5)).force("collide", forceCollide().radius(collideRadius).strength(0.9)).force("x", forceX((n) => groupTarget.get(n.group ?? "")?.x ?? w / 2).strength((n) => multiCluster && n.group ? GROUP_GRAVITY : UNGROUPED_GRAVITY)).force("y", forceY((n) => groupTarget.get(n.group ?? "")?.y ?? h / 2).strength((n) => multiCluster && n.group ? GROUP_GRAVITY : UNGROUPED_GRAVITY)).stop();
|
|
34940
35038
|
for (let i = 0; i < 300; i++) simulation.tick();
|
|
34941
35039
|
const pad = nodeSpacing / 2;
|
|
34942
35040
|
const rectsOf = (n) => {
|
|
@@ -35033,7 +35131,7 @@ var init_GraphCanvas = __esm({
|
|
|
35033
35131
|
return () => {
|
|
35034
35132
|
cancelAnimationFrame(animRef.current);
|
|
35035
35133
|
};
|
|
35036
|
-
}, [
|
|
35134
|
+
}, [nodesKey, edgesKey, propSimilarity, layout, repulsion, linkDistance, nodeSpacing, showLabels]);
|
|
35037
35135
|
useEffect(() => {
|
|
35038
35136
|
const canvas = canvasRef.current;
|
|
35039
35137
|
if (!canvas) return;
|
|
@@ -35163,6 +35261,7 @@ var init_GraphCanvas = __esm({
|
|
|
35163
35261
|
const cancelSinglePointer = useCallback(() => {
|
|
35164
35262
|
interactionRef.current.mode = "none";
|
|
35165
35263
|
interactionRef.current.dragNodeId = null;
|
|
35264
|
+
interactionRef.current.pressedNodeId = null;
|
|
35166
35265
|
}, []);
|
|
35167
35266
|
const handlePointerDown = useCallback(
|
|
35168
35267
|
(e) => {
|
|
@@ -35173,6 +35272,7 @@ var init_GraphCanvas = __esm({
|
|
|
35173
35272
|
state.downPos = { x: e.clientX, y: e.clientY };
|
|
35174
35273
|
state.startMouse = { x: e.clientX, y: e.clientY };
|
|
35175
35274
|
state.startOffset = { ...offset };
|
|
35275
|
+
state.pressedNodeId = node?.id ?? null;
|
|
35176
35276
|
if (draggable && node) {
|
|
35177
35277
|
state.mode = "dragging";
|
|
35178
35278
|
state.dragNodeId = node.id;
|
|
@@ -35224,7 +35324,8 @@ var init_GraphCanvas = __esm({
|
|
|
35224
35324
|
if (moved < 4) {
|
|
35225
35325
|
const coords = toCoords(e);
|
|
35226
35326
|
if (!coords) return;
|
|
35227
|
-
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;
|
|
35228
35329
|
if (node) {
|
|
35229
35330
|
if (node.badge && node.badge > 1 && onBadgeClick) {
|
|
35230
35331
|
const r = (node.size || 8) + (selectedNodeId === node.id ? 4 : 0);
|
|
@@ -35244,6 +35345,7 @@ var init_GraphCanvas = __esm({
|
|
|
35244
35345
|
);
|
|
35245
35346
|
const handlePointerLeave = useCallback(() => {
|
|
35246
35347
|
setHoveredNode(null);
|
|
35348
|
+
interactionRef.current.pressedNodeId = null;
|
|
35247
35349
|
}, []);
|
|
35248
35350
|
const gestureHandlers = useCanvasGestures({
|
|
35249
35351
|
canvasRef,
|
|
@@ -38195,8 +38297,17 @@ var init_MediaGallery = __esm({
|
|
|
38195
38297
|
const eventBus = useEventBus();
|
|
38196
38298
|
const { t } = useTranslate();
|
|
38197
38299
|
const [lightboxItem, setLightboxItem] = useState(null);
|
|
38300
|
+
const [failedIds, setFailedIds] = useState(/* @__PURE__ */ new Set());
|
|
38198
38301
|
const closeLightbox = useCallback(() => setLightboxItem(null), []);
|
|
38199
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
|
+
}, []);
|
|
38200
38311
|
const handleItemClick = useCallback(
|
|
38201
38312
|
(item) => {
|
|
38202
38313
|
if (selectable) {
|
|
@@ -38212,7 +38323,7 @@ var init_MediaGallery = __esm({
|
|
|
38212
38323
|
);
|
|
38213
38324
|
const entityData = Array.isArray(entity) ? entity : [];
|
|
38214
38325
|
const items = React81__default.useMemo(() => {
|
|
38215
|
-
if (propItems) return propItems;
|
|
38326
|
+
if (propItems && propItems.length > 0) return propItems;
|
|
38216
38327
|
if (entityData.length === 0) return [];
|
|
38217
38328
|
return entityData.map((record, idx) => {
|
|
38218
38329
|
return {
|
|
@@ -38295,13 +38406,14 @@ var init_MediaGallery = __esm({
|
|
|
38295
38406
|
),
|
|
38296
38407
|
onClick: () => handleItemClick(item),
|
|
38297
38408
|
children: [
|
|
38298
|
-
/* @__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(
|
|
38299
38410
|
"img",
|
|
38300
38411
|
{
|
|
38301
38412
|
src: item.thumbnail || item.src,
|
|
38302
38413
|
alt: item.alt || item.caption || "",
|
|
38303
38414
|
className: "w-full h-full object-cover",
|
|
38304
|
-
loading: "lazy"
|
|
38415
|
+
loading: "lazy",
|
|
38416
|
+
onError: () => handleImageError(item.id)
|
|
38305
38417
|
}
|
|
38306
38418
|
),
|
|
38307
38419
|
/* @__PURE__ */ jsx(
|
|
@@ -41808,6 +41920,11 @@ var init_TeamOrganism = __esm({
|
|
|
41808
41920
|
TeamOrganism.displayName = "TeamOrganism";
|
|
41809
41921
|
}
|
|
41810
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
|
+
}
|
|
41811
41928
|
var lookStyles10, STATUS_STYLES2, Timeline;
|
|
41812
41929
|
var init_Timeline = __esm({
|
|
41813
41930
|
"components/core/organisms/Timeline.tsx"() {
|
|
@@ -41935,7 +42052,7 @@ var init_Timeline = __esm({
|
|
|
41935
42052
|
/* @__PURE__ */ jsxs(VStack, { gap: "xs", className: cn("flex-1 min-w-0", !isLast && "pb-6"), children: [
|
|
41936
42053
|
/* @__PURE__ */ jsxs(HStack, { justify: "between", align: "start", wrap: true, children: [
|
|
41937
42054
|
/* @__PURE__ */ jsx(Typography, { variant: "body", weight: "semibold", children: item.title }),
|
|
41938
|
-
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) })
|
|
41939
42056
|
] }),
|
|
41940
42057
|
item.description && /* @__PURE__ */ jsx(Typography, { variant: "small", color: "secondary", children: item.description }),
|
|
41941
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)) }),
|
|
@@ -43147,7 +43264,7 @@ function substituteTraitRefsDeep(value, pathKey) {
|
|
|
43147
43264
|
}
|
|
43148
43265
|
return value;
|
|
43149
43266
|
}
|
|
43150
|
-
function renderPatternProps(props, onDismiss) {
|
|
43267
|
+
function renderPatternProps(props, onDismiss, propsSchema) {
|
|
43151
43268
|
const rendered = {};
|
|
43152
43269
|
for (const [key, value] of Object.entries(props)) {
|
|
43153
43270
|
if (key === "children") {
|
|
@@ -43165,9 +43282,10 @@ function renderPatternProps(props, onDismiss) {
|
|
|
43165
43282
|
};
|
|
43166
43283
|
rendered[key] = /* @__PURE__ */ jsx(SlotContentRenderer, { content: childContent, onDismiss });
|
|
43167
43284
|
} else if (Array.isArray(value)) {
|
|
43285
|
+
const isDataArray = propsSchema?.[key]?.items?.types?.includes("object") ?? false;
|
|
43168
43286
|
rendered[key] = value.map((item, i) => {
|
|
43169
43287
|
const el = item;
|
|
43170
|
-
if (isPatternConfig(el)) {
|
|
43288
|
+
if (!isDataArray && isPatternConfig(el)) {
|
|
43171
43289
|
const nestedProps = {};
|
|
43172
43290
|
for (const [k, v] of Object.entries(el)) {
|
|
43173
43291
|
if (k !== "type") nestedProps[k] = v;
|
|
@@ -43255,14 +43373,15 @@ function SlotContentRenderer({
|
|
|
43255
43373
|
);
|
|
43256
43374
|
}
|
|
43257
43375
|
}
|
|
43258
|
-
const renderedProps = renderPatternProps(restProps, onDismiss);
|
|
43259
43376
|
const patternDef = getPatternDefinition(content.pattern);
|
|
43260
43377
|
const propsSchema = patternDef?.propsSchema;
|
|
43378
|
+
const renderedProps = renderPatternProps(restProps, onDismiss, propsSchema);
|
|
43261
43379
|
if (propsSchema) {
|
|
43262
43380
|
for (const [propKey, propValue] of Object.entries(renderedProps)) {
|
|
43263
43381
|
if (typeof propValue !== "string") continue;
|
|
43264
43382
|
const propDef = propsSchema[propKey];
|
|
43265
43383
|
if (!propDef || propDef.kind !== "callback") continue;
|
|
43384
|
+
if (propValue === "") continue;
|
|
43266
43385
|
renderedProps[propKey] = wrapCallbackForEvent(
|
|
43267
43386
|
`UI:${propValue}`,
|
|
43268
43387
|
propDef.callbackArgs,
|
|
@@ -43545,6 +43664,7 @@ function useSharedEntityStore() {
|
|
|
43545
43664
|
}
|
|
43546
43665
|
return storeRef.current;
|
|
43547
43666
|
}
|
|
43667
|
+
createContext(null);
|
|
43548
43668
|
function runTickFrame(entityId, orderedWriters, store) {
|
|
43549
43669
|
let scratch = store.getSnapshot(entityId);
|
|
43550
43670
|
for (const writer of orderedWriters) {
|
|
@@ -43780,6 +43900,11 @@ var SYNC_TICK_OPERATORS = /* @__PURE__ */ new Set([
|
|
|
43780
43900
|
"do",
|
|
43781
43901
|
"when"
|
|
43782
43902
|
]);
|
|
43903
|
+
var REACTIVE_REPAINT_PATTERN_TYPES = /* @__PURE__ */ new Set([
|
|
43904
|
+
"canvas",
|
|
43905
|
+
"game-hud",
|
|
43906
|
+
"game-shell"
|
|
43907
|
+
]);
|
|
43783
43908
|
var LIFECYCLE_EVENTS = ["INIT", "LOAD", "$MOUNT"];
|
|
43784
43909
|
function toTraitDefinition(binding) {
|
|
43785
43910
|
return {
|
|
@@ -44032,6 +44157,8 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
44032
44157
|
}, [traitStates]);
|
|
44033
44158
|
const traitSnapshotDataRef = useRef(/* @__PURE__ */ new Map());
|
|
44034
44159
|
const traitFieldStatesRef = useRef(/* @__PURE__ */ new Map());
|
|
44160
|
+
const lastCanvasRenderUiRef = useRef(/* @__PURE__ */ new Map());
|
|
44161
|
+
const executeTransitionEffectsRef = useRef(null);
|
|
44035
44162
|
useEffect(() => {
|
|
44036
44163
|
const mgr = managerRef.current;
|
|
44037
44164
|
const bindings = traitBindingsRef.current;
|
|
@@ -44072,11 +44199,9 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
44072
44199
|
bindTraitStateGetter((traitName) => {
|
|
44073
44200
|
const allStates = newManager.getAllStates();
|
|
44074
44201
|
if (allStates instanceof Map) {
|
|
44075
|
-
|
|
44076
|
-
return typeof val === "string" ? val : void 0;
|
|
44202
|
+
return allStates.get(traitName)?.currentState;
|
|
44077
44203
|
}
|
|
44078
|
-
|
|
44079
|
-
return typeof state === "string" ? state : void 0;
|
|
44204
|
+
return newManager.getState(traitName)?.currentState;
|
|
44080
44205
|
});
|
|
44081
44206
|
const snapshotUnregs = [];
|
|
44082
44207
|
for (const binding of traitBindingsRef.current) {
|
|
@@ -44161,6 +44286,15 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
44161
44286
|
const existing = pendingSlots.get(slot) || [];
|
|
44162
44287
|
existing.push({ pattern, props: props || {} });
|
|
44163
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
|
+
}
|
|
44164
44298
|
},
|
|
44165
44299
|
clearSlot: (slot) => {
|
|
44166
44300
|
pendingSlots.set(slot, []);
|
|
@@ -44231,11 +44365,15 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
44231
44365
|
notify: clientHandlers.notify
|
|
44232
44366
|
};
|
|
44233
44367
|
}
|
|
44368
|
+
const sharedWrites = [];
|
|
44234
44369
|
const baseSet = handlers.set;
|
|
44235
44370
|
handlers = {
|
|
44236
44371
|
...handlers,
|
|
44237
44372
|
set: async (targetId, field, value) => {
|
|
44238
44373
|
if (baseSet) await baseSet(targetId, field, value);
|
|
44374
|
+
if (sharedKey !== void 0) {
|
|
44375
|
+
sharedWrites.push({ field, value });
|
|
44376
|
+
}
|
|
44239
44377
|
log9.debug("set:write", {
|
|
44240
44378
|
traitName,
|
|
44241
44379
|
field,
|
|
@@ -44311,7 +44449,10 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
44311
44449
|
});
|
|
44312
44450
|
}
|
|
44313
44451
|
if (sharedKey !== void 0) {
|
|
44314
|
-
sharedEntityStore.commit(
|
|
44452
|
+
sharedEntityStore.commit(
|
|
44453
|
+
sharedKey,
|
|
44454
|
+
mergeEntityFrame(sharedEntityStore.getSnapshot(sharedKey), sharedWrites)
|
|
44455
|
+
);
|
|
44315
44456
|
}
|
|
44316
44457
|
log9.debug("effects:executed", () => ({
|
|
44317
44458
|
traitName,
|
|
@@ -44337,6 +44478,38 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
44337
44478
|
entity: binding.linkedEntity
|
|
44338
44479
|
});
|
|
44339
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
|
+
}
|
|
44340
44513
|
} catch (error) {
|
|
44341
44514
|
log9.error("effects:error", {
|
|
44342
44515
|
traitName,
|
|
@@ -44348,6 +44521,9 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
44348
44521
|
}
|
|
44349
44522
|
return emittedDuringExec;
|
|
44350
44523
|
}, [eventBus, flushSlot, sharedEntityStore]);
|
|
44524
|
+
useEffect(() => {
|
|
44525
|
+
executeTransitionEffectsRef.current = executeTransitionEffects;
|
|
44526
|
+
}, [executeTransitionEffects]);
|
|
44351
44527
|
const runTickEffects = useCallback((tick, binding) => {
|
|
44352
44528
|
const traitName = binding.trait.name;
|
|
44353
44529
|
const currentState = traitStatesRef.current.get(traitName)?.currentState ?? "";
|
|
@@ -44410,6 +44586,24 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
44410
44586
|
({ binding, tick }) => createSharedEntityWriter(binding, tick, traitStatesRef, emitFromSharedWriter)
|
|
44411
44587
|
);
|
|
44412
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
|
+
}
|
|
44413
44607
|
};
|
|
44414
44608
|
if (interval === "frame") {
|
|
44415
44609
|
scheduler.add(0, onDue);
|
|
@@ -44459,6 +44653,13 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
44459
44653
|
entityByTrait[name] = fields;
|
|
44460
44654
|
}
|
|
44461
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
|
+
}
|
|
44462
44663
|
const results = currentManager.sendEvent(
|
|
44463
44664
|
normalizedEvent,
|
|
44464
44665
|
payload,
|
|
@@ -44612,7 +44813,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
44612
44813
|
}
|
|
44613
44814
|
await onEventProcessed(normalizedEvent, payload, dispatchedOrbitals);
|
|
44614
44815
|
}
|
|
44615
|
-
}, [entities, eventBus]);
|
|
44816
|
+
}, [entities, eventBus, sharedEntityStore]);
|
|
44616
44817
|
const drainEventQueue = useCallback(async () => {
|
|
44617
44818
|
if (processingRef.current) return;
|
|
44618
44819
|
processingRef.current = true;
|
|
@@ -44682,6 +44883,24 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
44682
44883
|
});
|
|
44683
44884
|
}
|
|
44684
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
|
+
}
|
|
44685
44904
|
for (const binding of traitBindings) {
|
|
44686
44905
|
const ownOrbital = orbitalsByTrait?.[binding.trait.name];
|
|
44687
44906
|
const listens = binding.trait.listens ?? [];
|
|
@@ -44866,9 +45085,16 @@ function normalizeChild(child) {
|
|
|
44866
45085
|
props: { ...rest, ...normalizedChildren !== void 0 ? { children: normalizedChildren } : {} }
|
|
44867
45086
|
};
|
|
44868
45087
|
}
|
|
44869
|
-
function applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits) {
|
|
45088
|
+
function applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits, activeTraits) {
|
|
44870
45089
|
for (const eff of effects) {
|
|
44871
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
|
+
}
|
|
44872
45098
|
const patternRecord = eff.pattern;
|
|
44873
45099
|
const { type: patternType, children, ...inlineProps } = patternRecord;
|
|
44874
45100
|
const normalizedChildren = Array.isArray(children) ? children.map((c) => normalizeChild(c)) : children;
|
|
@@ -44909,8 +45135,38 @@ function applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits) {
|
|
|
44909
45135
|
}
|
|
44910
45136
|
}
|
|
44911
45137
|
}
|
|
44912
|
-
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 }) {
|
|
44913
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
|
+
);
|
|
44914
45170
|
const uiSlots = useUISlots();
|
|
44915
45171
|
const onEventProcessed = useCallback(async (event, payload, dispatchedOrbitals) => {
|
|
44916
45172
|
if (!bridge.connected || !orbitalNames?.length) return;
|
|
@@ -44922,11 +45178,11 @@ function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFa
|
|
|
44922
45178
|
dispatchedOrbitalsSize: dispatchedOrbitals?.size ?? 0
|
|
44923
45179
|
}));
|
|
44924
45180
|
for (const name of targets) {
|
|
44925
|
-
const { effects, meta } = await bridge.sendEvent(name, event, payload);
|
|
45181
|
+
const { effects, meta } = await bridge.sendEvent(name, event, withActiveTraits(payload));
|
|
44926
45182
|
recordServerResponse(name, event, meta);
|
|
44927
|
-
applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits);
|
|
45183
|
+
applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits, activeTraitNames);
|
|
44928
45184
|
}
|
|
44929
|
-
}, [bridge.connected, bridge.sendEvent, orbitalNames, uiSlots, onNavigate, embeddedTraits]);
|
|
45185
|
+
}, [bridge.connected, bridge.sendEvent, orbitalNames, uiSlots, onNavigate, embeddedTraits, activeTraitNames, withActiveTraits]);
|
|
44930
45186
|
const opts = orbitalNames ? { onEventProcessed, navigate: onNavigate, traitConfigsByName, orbitalsByTrait, embeddedTraits } : { navigate: onNavigate, persistence, traitConfigsByName, orbitalsByTrait, embeddedTraits };
|
|
44931
45187
|
const { sendEvent } = useTraitStateMachine(traits2, uiSlots, opts);
|
|
44932
45188
|
const initSentRef = useRef(false);
|
|
@@ -44963,7 +45219,7 @@ function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFa
|
|
|
44963
45219
|
initSentRef.current = true;
|
|
44964
45220
|
(async () => {
|
|
44965
45221
|
for (const name of orbitalNames) {
|
|
44966
|
-
const { effects, meta } = await bridge.sendEvent(name, "INIT", {});
|
|
45222
|
+
const { effects, meta } = await bridge.sendEvent(name, "INIT", withActiveTraits({}));
|
|
44967
45223
|
recordServerResponse(name, "INIT", meta);
|
|
44968
45224
|
const effectTraces = [
|
|
44969
45225
|
{ type: "fetch", args: [], status: "executed" },
|
|
@@ -44981,10 +45237,10 @@ function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFa
|
|
|
44981
45237
|
effects: effectTraces,
|
|
44982
45238
|
timestamp: Date.now()
|
|
44983
45239
|
});
|
|
44984
|
-
applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits);
|
|
45240
|
+
applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits, activeTraitNames);
|
|
44985
45241
|
}
|
|
44986
45242
|
})();
|
|
44987
|
-
}, [bridge.connected, orbitalNames, bridge.sendEvent, uiSlots, onNavigate, embeddedTraits]);
|
|
45243
|
+
}, [bridge.connected, orbitalNames, bridge.sendEvent, uiSlots, onNavigate, embeddedTraits, activeTraitNames, withActiveTraits]);
|
|
44988
45244
|
return null;
|
|
44989
45245
|
}
|
|
44990
45246
|
function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, onNavigate, onLocalFallback, persistence }) {
|
|
@@ -45071,6 +45327,14 @@ function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, onNavi
|
|
|
45071
45327
|
}
|
|
45072
45328
|
return Array.from(set);
|
|
45073
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
|
+
);
|
|
45074
45338
|
useEffect(() => {
|
|
45075
45339
|
const traitNames = allPageTraits.map((b) => b.trait.name);
|
|
45076
45340
|
const orbitalsByTraitForPage = {};
|
|
@@ -45080,7 +45344,7 @@ function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, onNavi
|
|
|
45080
45344
|
}
|
|
45081
45345
|
xOrbitalLog.info("SchemaRunner:mount", {
|
|
45082
45346
|
pageName,
|
|
45083
|
-
traitNames,
|
|
45347
|
+
traitNames: traitNames.join(","),
|
|
45084
45348
|
orbitalsByTraitForPage,
|
|
45085
45349
|
pageOrbitalNames: pageOrbitalNames.join(",")
|
|
45086
45350
|
});
|
|
@@ -45125,6 +45389,7 @@ function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, onNavi
|
|
|
45125
45389
|
traitConfigsByName,
|
|
45126
45390
|
orbitalsByTrait,
|
|
45127
45391
|
embeddedTraits,
|
|
45392
|
+
serverActiveTraits,
|
|
45128
45393
|
onNavigate,
|
|
45129
45394
|
onLocalFallback,
|
|
45130
45395
|
persistence
|