@almadar/ui 5.121.3 → 5.121.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/avl/index.cjs +330 -67
- package/dist/avl/index.js +332 -69
- package/dist/components/index.cjs +159 -45
- package/dist/components/index.d.cts +25 -5
- package/dist/components/index.d.ts +25 -5
- package/dist/components/index.js +159 -47
- package/dist/hooks/index.cjs +31 -10
- package/dist/hooks/index.d.cts +17 -1
- package/dist/hooks/index.d.ts +17 -1
- package/dist/hooks/index.js +31 -12
- package/dist/lib/drawable/three/index.cjs +19 -10
- package/dist/lib/drawable/three/index.js +20 -11
- package/dist/lib/index.cjs +41 -13
- package/dist/lib/index.js +41 -13
- package/dist/marketing/index.cjs +29 -14
- package/dist/marketing/index.js +29 -14
- package/dist/providers/index.cjs +204 -63
- package/dist/providers/index.d.cts +33 -4
- package/dist/providers/index.d.ts +33 -4
- package/dist/providers/index.js +204 -64
- package/dist/runtime/index.cjs +330 -67
- package/dist/runtime/index.d.cts +0 -14
- package/dist/runtime/index.d.ts +0 -14
- package/dist/runtime/index.js +333 -70
- package/package.json +2 -2
- package/tailwind-preset.cjs +56 -0
- package/themes/_base.css +19 -0
package/dist/avl/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
2
2
|
import * as React90 from 'react';
|
|
3
3
|
import React90__default, { createContext, useState, useMemo, useRef, useEffect, useContext, useCallback, Suspense, useLayoutEffect, Profiler, useReducer, useSyncExternalStore, lazy, useId } from 'react';
|
|
4
|
-
import { getAllPages, OrbitalProvider, EventBusContext,
|
|
4
|
+
import { getAllPages, OrbitalProvider, EventBusContext, useTraitScopeChain, ServerBridgeProvider, VerificationProvider, EntitySchemaProvider, OrbitalThemeProvider, useServerBridge, useEntitySchema, useEntitySchemaOptional, TraitScopeProvider, useCurrentPagePath, useGameAudioContextOptional } from '@almadar/ui/providers';
|
|
5
5
|
import { createLogger, setNamespaceLevel, isLogLevelEnabled } from '@almadar/logger';
|
|
6
6
|
import ELK from 'elkjs/lib/elk.bundled.js';
|
|
7
7
|
import { MarkerType, useReactFlow, Handle, Position, getBezierPath, EdgeLabelRenderer, useNodeId, ReactFlowProvider, BaseEdge, useNodesState, useEdgesState, ReactFlow, Controls, Background, BackgroundVariant } from '@xyflow/react';
|
|
@@ -36,7 +36,7 @@ import ReactMarkdown from 'react-markdown';
|
|
|
36
36
|
import remarkGfm from 'remark-gfm';
|
|
37
37
|
import remarkMath from 'remark-math';
|
|
38
38
|
import rehypeKatex from 'rehype-katex';
|
|
39
|
-
import { FieldTypeSchema, isInlineTrait, isPageReference, buildResolvedTraitConfigs, schemaToIR, getPage, isCircuitEvent, walkSExpr,
|
|
39
|
+
import { FieldTypeSchema, isInlineTrait, isPageReference, buildResolvedTraitConfigs, schemaToIR, getPage, mergeEntityFrame, isCircuitEvent, walkSExpr, isSExpr, isEventPayloadValue } from '@almadar/core';
|
|
40
40
|
import { useDroppable, useDraggable, DndContext, DragOverlay, useSensors, useSensor, PointerSensor, KeyboardSensor, pointerWithin, rectIntersection, closestCorners } from '@dnd-kit/core';
|
|
41
41
|
import { sortableKeyboardCoordinates, useSortable, arrayMove, SortableContext, rectSortingStrategy, verticalListSortingStrategy } from '@dnd-kit/sortable';
|
|
42
42
|
import { CSS } from '@dnd-kit/utilities';
|
|
@@ -3225,9 +3225,9 @@ function getGlobalEventBus() {
|
|
|
3225
3225
|
function useEventBus() {
|
|
3226
3226
|
const context = useContext(EventBusContext);
|
|
3227
3227
|
const baseBus = context ?? getGlobalEventBus() ?? fallbackEventBus;
|
|
3228
|
-
const
|
|
3228
|
+
const chain = useTraitScopeChain();
|
|
3229
3229
|
return useMemo(() => {
|
|
3230
|
-
if (
|
|
3230
|
+
if (chain.length === 0) {
|
|
3231
3231
|
return {
|
|
3232
3232
|
...baseBus,
|
|
3233
3233
|
emit: (type, payload, source) => {
|
|
@@ -3243,22 +3243,31 @@ function useEventBus() {
|
|
|
3243
3243
|
emit: (type, payload, source) => {
|
|
3244
3244
|
if (typeof type === "string" && type.startsWith("UI:")) {
|
|
3245
3245
|
const tail = type.slice(3);
|
|
3246
|
-
const
|
|
3247
|
-
|
|
3248
|
-
|
|
3246
|
+
const isQualified = tail.includes(".");
|
|
3247
|
+
const event = isQualified ? tail.split(".").slice(2).join(".") : tail;
|
|
3248
|
+
if (!event) {
|
|
3249
|
+
baseBus.emit(type, payload, source);
|
|
3250
|
+
return;
|
|
3251
|
+
}
|
|
3252
|
+
const keys = /* @__PURE__ */ new Set();
|
|
3253
|
+
if (isQualified) keys.add(type);
|
|
3254
|
+
for (const sc of chain) {
|
|
3255
|
+
keys.add(`UI:${sc.orbital}.${sc.trait}.${event}`);
|
|
3256
|
+
}
|
|
3257
|
+
if (keys.size > 1) {
|
|
3258
|
+
scopeLog.info("emit:fan-out", {
|
|
3249
3259
|
from: type,
|
|
3250
|
-
|
|
3251
|
-
|
|
3252
|
-
scopeTrait: scope.trait
|
|
3260
|
+
keys: Array.from(keys),
|
|
3261
|
+
chainDepth: chain.length
|
|
3253
3262
|
});
|
|
3254
3263
|
}
|
|
3255
|
-
baseBus.emit(
|
|
3264
|
+
for (const key of keys) baseBus.emit(key, payload, source);
|
|
3256
3265
|
return;
|
|
3257
3266
|
}
|
|
3258
3267
|
baseBus.emit(type, payload, source);
|
|
3259
3268
|
}
|
|
3260
3269
|
};
|
|
3261
|
-
}, [baseBus,
|
|
3270
|
+
}, [baseBus, chain]);
|
|
3262
3271
|
}
|
|
3263
3272
|
function useEventListener(event, handler) {
|
|
3264
3273
|
const eventBus = useEventBus();
|
|
@@ -4615,13 +4624,13 @@ var init_Icon = __esm({
|
|
|
4615
4624
|
style
|
|
4616
4625
|
}) => {
|
|
4617
4626
|
const directIcon = typeof icon === "string" ? void 0 : icon;
|
|
4618
|
-
const effectiveName = typeof icon === "string" ? icon : name;
|
|
4627
|
+
const effectiveName = typeof icon === "string" && icon !== "" ? icon : name;
|
|
4628
|
+
const effectiveStrokeWidth = strokeWidth != null && strokeWidth > 0 ? strokeWidth : void 0;
|
|
4619
4629
|
const family = useIconFamily();
|
|
4620
4630
|
const RenderedComponent = React90__default.useMemo(() => {
|
|
4621
4631
|
if (directIcon) return null;
|
|
4622
4632
|
return effectiveName ? resolveIconForFamily(effectiveName) : null;
|
|
4623
4633
|
}, [directIcon, effectiveName, family]);
|
|
4624
|
-
const effectiveStrokeWidth = strokeWidth ?? void 0;
|
|
4625
4634
|
const inlineStyle = {
|
|
4626
4635
|
...effectiveStrokeWidth === void 0 ? { strokeWidth: "var(--icon-stroke-width, 2)" } : {},
|
|
4627
4636
|
...style
|
|
@@ -5103,6 +5112,15 @@ var init_Modal = __esm({
|
|
|
5103
5112
|
const [dragY, setDragY] = useState(0);
|
|
5104
5113
|
const dragStartY = useRef(0);
|
|
5105
5114
|
const isDragging = useRef(false);
|
|
5115
|
+
const [closing, setClosing] = useState(false);
|
|
5116
|
+
const wasOpenRef = useRef(isOpen);
|
|
5117
|
+
useEffect(() => {
|
|
5118
|
+
if (wasOpenRef.current && !isOpen) setClosing(true);
|
|
5119
|
+
wasOpenRef.current = isOpen;
|
|
5120
|
+
}, [isOpen]);
|
|
5121
|
+
const handleAnimEnd = (e) => {
|
|
5122
|
+
if (closing && e.target === e.currentTarget) setClosing(false);
|
|
5123
|
+
};
|
|
5106
5124
|
useEffect(() => {
|
|
5107
5125
|
if (isOpen) {
|
|
5108
5126
|
previousActiveElement.current = document.activeElement;
|
|
@@ -5136,7 +5154,11 @@ var init_Modal = __esm({
|
|
|
5136
5154
|
document.body.style.overflow = "";
|
|
5137
5155
|
};
|
|
5138
5156
|
}, [isOpen]);
|
|
5139
|
-
if (
|
|
5157
|
+
if (typeof document === "undefined") return null;
|
|
5158
|
+
const renderOpen = isOpen || closing;
|
|
5159
|
+
if (!renderOpen) return null;
|
|
5160
|
+
const dialogAnim = closing ? "animate-modal-out" : "animate-modal-in";
|
|
5161
|
+
const overlayAnim = closing ? "animate-overlay-out" : "animate-overlay-in";
|
|
5140
5162
|
const handleClose = () => {
|
|
5141
5163
|
if (closeEvent) eventBus.emit(`UI:${closeEvent}`, {});
|
|
5142
5164
|
onClose();
|
|
@@ -5153,7 +5175,8 @@ var init_Modal = __esm({
|
|
|
5153
5175
|
className: cn(
|
|
5154
5176
|
"fixed inset-0 z-[1000]",
|
|
5155
5177
|
"flex items-start justify-center px-4 pb-4 pt-[10vh]",
|
|
5156
|
-
"max-sm:items-stretch max-sm:p-0 max-sm:pt-0"
|
|
5178
|
+
"max-sm:items-stretch max-sm:p-0 max-sm:pt-0",
|
|
5179
|
+
overlayAnim
|
|
5157
5180
|
),
|
|
5158
5181
|
style: { backgroundColor: "rgba(0, 0, 0, 0.6)" },
|
|
5159
5182
|
onClick: handleOverlayClick,
|
|
@@ -5181,8 +5204,10 @@ var init_Modal = __esm({
|
|
|
5181
5204
|
// full height, no rounded corners, no min-width.
|
|
5182
5205
|
"max-sm:max-w-none max-sm:max-h-none max-sm:w-full max-sm:h-full max-sm:rounded-none",
|
|
5183
5206
|
lookStyles[look],
|
|
5184
|
-
className
|
|
5207
|
+
className,
|
|
5208
|
+
dialogAnim
|
|
5185
5209
|
),
|
|
5210
|
+
onAnimationEnd: handleAnimEnd,
|
|
5186
5211
|
style: dragY > 0 ? {
|
|
5187
5212
|
transform: `translateY(${dragY}px)`,
|
|
5188
5213
|
transition: isDragging.current ? "none" : "transform 200ms ease-out"
|
|
@@ -5291,6 +5316,7 @@ var init_Overlay = __esm({
|
|
|
5291
5316
|
className: cn(
|
|
5292
5317
|
"fixed inset-0 z-40",
|
|
5293
5318
|
blur && "backdrop-blur-sm",
|
|
5319
|
+
"animate-overlay-in",
|
|
5294
5320
|
className
|
|
5295
5321
|
),
|
|
5296
5322
|
style: { backgroundColor: "rgba(0, 0, 0, 0.6)" },
|
|
@@ -6703,7 +6729,7 @@ var init_Input = __esm({
|
|
|
6703
6729
|
eventBus.emit(`UI:${action}`, { value: e.currentTarget.value });
|
|
6704
6730
|
}
|
|
6705
6731
|
};
|
|
6706
|
-
const wrapField = (field) => /* @__PURE__ */ jsxs("div", { className: "w-full", children: [
|
|
6732
|
+
const wrapField = (field, fullWidth = true) => /* @__PURE__ */ jsxs("div", { className: fullWidth ? "w-full" : "w-fit", children: [
|
|
6707
6733
|
label && /* @__PURE__ */ jsx("label", { className: "block text-sm font-medium text-foreground mb-1", children: label }),
|
|
6708
6734
|
field,
|
|
6709
6735
|
(helperText || error) && /* @__PURE__ */ jsx("p", { className: cn("mt-1 text-xs", error ? "text-error" : "text-muted-foreground"), children: error ?? helperText })
|
|
@@ -6763,7 +6789,8 @@ var init_Input = __esm({
|
|
|
6763
6789
|
),
|
|
6764
6790
|
...props
|
|
6765
6791
|
}
|
|
6766
|
-
)
|
|
6792
|
+
),
|
|
6793
|
+
false
|
|
6767
6794
|
);
|
|
6768
6795
|
}
|
|
6769
6796
|
return wrapField(
|
|
@@ -9006,6 +9033,18 @@ var init_RangeSlider = __esm({
|
|
|
9006
9033
|
function easeOut(t) {
|
|
9007
9034
|
return t * (2 - t);
|
|
9008
9035
|
}
|
|
9036
|
+
function formatDisplay(value, format, decimals) {
|
|
9037
|
+
switch (format) {
|
|
9038
|
+
case "currency":
|
|
9039
|
+
return `$${value.toFixed(2)}`;
|
|
9040
|
+
case "percent":
|
|
9041
|
+
return `${Math.round(value)}%`;
|
|
9042
|
+
case "number":
|
|
9043
|
+
return value.toLocaleString();
|
|
9044
|
+
default:
|
|
9045
|
+
return value.toFixed(decimals);
|
|
9046
|
+
}
|
|
9047
|
+
}
|
|
9009
9048
|
var AnimatedCounter;
|
|
9010
9049
|
var init_AnimatedCounter = __esm({
|
|
9011
9050
|
"components/marketing/atoms/AnimatedCounter.tsx"() {
|
|
@@ -9017,6 +9056,7 @@ var init_AnimatedCounter = __esm({
|
|
|
9017
9056
|
duration = 600,
|
|
9018
9057
|
prefix,
|
|
9019
9058
|
suffix,
|
|
9059
|
+
format,
|
|
9020
9060
|
className
|
|
9021
9061
|
}) => {
|
|
9022
9062
|
const numericRaw = typeof rawValue === "number" ? rawValue : Number.parseFloat(String(rawValue ?? ""));
|
|
@@ -9032,6 +9072,10 @@ var init_AnimatedCounter = __esm({
|
|
|
9032
9072
|
setDisplayValue(to);
|
|
9033
9073
|
return;
|
|
9034
9074
|
}
|
|
9075
|
+
if (window.matchMedia?.("(prefers-reduced-motion: reduce)").matches) {
|
|
9076
|
+
setDisplayValue(to);
|
|
9077
|
+
return;
|
|
9078
|
+
}
|
|
9035
9079
|
const startTime = performance.now();
|
|
9036
9080
|
const diff = to - from;
|
|
9037
9081
|
function animate(currentTime) {
|
|
@@ -9053,7 +9097,7 @@ var init_AnimatedCounter = __esm({
|
|
|
9053
9097
|
};
|
|
9054
9098
|
}, [value, duration]);
|
|
9055
9099
|
const decimalPlaces = Number.isInteger(value) ? 0 : String(value).split(".")[1]?.length ?? 0;
|
|
9056
|
-
const formattedValue = displayValue
|
|
9100
|
+
const formattedValue = formatDisplay(displayValue, format, decimalPlaces);
|
|
9057
9101
|
return /* @__PURE__ */ jsxs(Typography, { variant: "h3", className: cn("tabular-nums", className), children: [
|
|
9058
9102
|
prefix,
|
|
9059
9103
|
formattedValue,
|
|
@@ -10332,14 +10376,29 @@ function recordTransition(trace) {
|
|
|
10332
10376
|
"pass"
|
|
10333
10377
|
);
|
|
10334
10378
|
} else {
|
|
10335
|
-
const
|
|
10336
|
-
|
|
10337
|
-
|
|
10338
|
-
|
|
10339
|
-
|
|
10340
|
-
"
|
|
10341
|
-
|
|
10379
|
+
const rendersEntityData = entry.effects.some(
|
|
10380
|
+
(e) => e.type === "render-ui" && JSON.stringify(e.args).includes("@entity.")
|
|
10381
|
+
);
|
|
10382
|
+
if (rendersEntityData) {
|
|
10383
|
+
const siblingSeeds = getState().transitions.some(
|
|
10384
|
+
(t) => t.event === "INIT" && t.effects.some(
|
|
10385
|
+
(e) => e.type === "fetch" || e.type === "set" && typeof e.args[0] === "string" && e.args[0].startsWith("@entity.")
|
|
10386
|
+
)
|
|
10342
10387
|
);
|
|
10388
|
+
if (siblingSeeds) {
|
|
10389
|
+
registerCheck(
|
|
10390
|
+
checkId,
|
|
10391
|
+
`INIT transition for "${entry.traitName}" has sibling entity-seed (shared entity)`,
|
|
10392
|
+
"pass"
|
|
10393
|
+
);
|
|
10394
|
+
} else {
|
|
10395
|
+
registerCheck(
|
|
10396
|
+
checkId,
|
|
10397
|
+
`INIT transition for "${entry.traitName}" missing fetch effect`,
|
|
10398
|
+
"fail",
|
|
10399
|
+
"Entity-bound render-ui without a fetch effect will show empty data"
|
|
10400
|
+
);
|
|
10401
|
+
}
|
|
10343
10402
|
}
|
|
10344
10403
|
}
|
|
10345
10404
|
}
|
|
@@ -11484,7 +11543,7 @@ function GameMenu({
|
|
|
11484
11543
|
logo,
|
|
11485
11544
|
className
|
|
11486
11545
|
}) {
|
|
11487
|
-
const resolvedOptions = options ?? menuItems ?? DEFAULT_MENU_OPTIONS;
|
|
11546
|
+
const resolvedOptions = (options?.length ? options : void 0) ?? (menuItems?.length ? menuItems : void 0) ?? DEFAULT_MENU_OPTIONS;
|
|
11488
11547
|
const eventBus = useEventBus();
|
|
11489
11548
|
const handleOptionClick = React90.useCallback(
|
|
11490
11549
|
(option) => {
|
|
@@ -12882,6 +12941,10 @@ function Canvas2D({
|
|
|
12882
12941
|
window.removeEventListener("keyup", onUp);
|
|
12883
12942
|
};
|
|
12884
12943
|
}, [keyMap, keyUpMap, eventBus]);
|
|
12944
|
+
useEffect(() => {
|
|
12945
|
+
if (!keyMap && !keyUpMap) return;
|
|
12946
|
+
canvasRef.current?.focus();
|
|
12947
|
+
}, [keyMap, keyUpMap]);
|
|
12885
12948
|
if (error) {
|
|
12886
12949
|
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: [
|
|
12887
12950
|
/* @__PURE__ */ jsx(Icon, { name: "alert-circle", size: "xl" }),
|
|
@@ -12930,7 +12993,7 @@ function Canvas2D({
|
|
|
12930
12993
|
onWheel: gestureHandlers.onWheel,
|
|
12931
12994
|
onContextMenu: (e) => e.preventDefault(),
|
|
12932
12995
|
className: "cursor-pointer touch-none",
|
|
12933
|
-
tabIndex: isFree ? 0 : void 0,
|
|
12996
|
+
tabIndex: isFree || keyMap || keyUpMap ? 0 : void 0,
|
|
12934
12997
|
style: {
|
|
12935
12998
|
width: viewportSize.width,
|
|
12936
12999
|
height: viewportSize.height
|
|
@@ -16354,7 +16417,8 @@ var init_LoadingState = __esm({
|
|
|
16354
16417
|
LoadingState = ({
|
|
16355
16418
|
title,
|
|
16356
16419
|
message,
|
|
16357
|
-
className
|
|
16420
|
+
className,
|
|
16421
|
+
fullPage = false
|
|
16358
16422
|
}) => {
|
|
16359
16423
|
const { t } = useTranslate();
|
|
16360
16424
|
const displayMessage = message ?? t("common.loading");
|
|
@@ -16363,7 +16427,8 @@ var init_LoadingState = __esm({
|
|
|
16363
16427
|
{
|
|
16364
16428
|
align: "center",
|
|
16365
16429
|
className: cn(
|
|
16366
|
-
"justify-center
|
|
16430
|
+
"justify-center",
|
|
16431
|
+
fullPage ? "fixed inset-0 z-[1000] py-12 bg-background/80 backdrop-blur-sm animate-overlay-in" : "py-12",
|
|
16367
16432
|
className
|
|
16368
16433
|
),
|
|
16369
16434
|
children: [
|
|
@@ -19565,7 +19630,7 @@ var init_BookCoverPage = __esm({
|
|
|
19565
19630
|
size: "lg",
|
|
19566
19631
|
action: "BOOK_START",
|
|
19567
19632
|
className: "mt-8",
|
|
19568
|
-
children: /* @__PURE__ */ jsx(Typography, { variant: "body", children: t("book.startReading") })
|
|
19633
|
+
children: /* @__PURE__ */ jsx(Typography, { variant: "body", color: "inherit", children: t("book.startReading") })
|
|
19569
19634
|
}
|
|
19570
19635
|
)
|
|
19571
19636
|
]
|
|
@@ -21877,8 +21942,9 @@ var init_Chart = __esm({
|
|
|
21877
21942
|
align: "center",
|
|
21878
21943
|
flex: true,
|
|
21879
21944
|
className: "min-w-0",
|
|
21945
|
+
style: { height: "100%" },
|
|
21880
21946
|
children: [
|
|
21881
|
-
/* @__PURE__ */ jsx(HStack, { gap: histogram ? "none" : "xs", align: "end",
|
|
21947
|
+
/* @__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) => {
|
|
21882
21948
|
const value = valueAt(s, label);
|
|
21883
21949
|
const barHeight = value / maxValue * 100;
|
|
21884
21950
|
const color = seriesColor(s, sIdx);
|
|
@@ -21891,6 +21957,8 @@ var init_Chart = __esm({
|
|
|
21891
21957
|
),
|
|
21892
21958
|
style: {
|
|
21893
21959
|
height: `${barHeight}%`,
|
|
21960
|
+
// Cap width so a lone category doesn't paint the whole plot as one solid block; narrow columns are unaffected (flex-1 binds first).
|
|
21961
|
+
...!histogram && { maxWidth: 72 },
|
|
21894
21962
|
backgroundColor: color
|
|
21895
21963
|
},
|
|
21896
21964
|
onClick: () => onPointClick?.(
|
|
@@ -21925,8 +21993,9 @@ var init_Chart = __esm({
|
|
|
21925
21993
|
align: "center",
|
|
21926
21994
|
flex: true,
|
|
21927
21995
|
className: "min-w-0",
|
|
21996
|
+
style: { height: "100%" },
|
|
21928
21997
|
children: [
|
|
21929
|
-
/* @__PURE__ */ jsx(VStack, { gap: "none", className: "w-full
|
|
21998
|
+
/* @__PURE__ */ jsx(VStack, { gap: "none", className: "w-full flex-1 min-h-0", justify: "end", children: series.map((s, sIdx) => {
|
|
21930
21999
|
const value = valueAt(s, label);
|
|
21931
22000
|
const ratio = stack === "normalize" ? total === 0 ? 0 : value / total * 100 : value / maxValue * 100;
|
|
21932
22001
|
const color = seriesColor(s, sIdx);
|
|
@@ -21971,6 +22040,7 @@ var init_Chart = __esm({
|
|
|
21971
22040
|
const innerRadius = donut ? radius * 0.6 : 0;
|
|
21972
22041
|
const center = size / 2;
|
|
21973
22042
|
const segments = useMemo(() => {
|
|
22043
|
+
if (!Number.isFinite(total) || total <= 0) return [];
|
|
21974
22044
|
let currentAngle = -Math.PI / 2;
|
|
21975
22045
|
return data.map((point, idx) => {
|
|
21976
22046
|
const angle = point.value / total * 2 * Math.PI;
|
|
@@ -21982,13 +22052,25 @@ var init_Chart = __esm({
|
|
|
21982
22052
|
const y1 = center + radius * Math.sin(startAngle);
|
|
21983
22053
|
const x2 = center + radius * Math.cos(endAngle);
|
|
21984
22054
|
const y2 = center + radius * Math.sin(endAngle);
|
|
22055
|
+
const fullCircle = angle >= 2 * Math.PI - 1e-9;
|
|
22056
|
+
const midAngle = startAngle + angle / 2;
|
|
22057
|
+
const xm = center + radius * Math.cos(midAngle);
|
|
22058
|
+
const ym = center + radius * Math.sin(midAngle);
|
|
21985
22059
|
let d;
|
|
21986
22060
|
if (innerRadius > 0) {
|
|
21987
22061
|
const ix1 = center + innerRadius * Math.cos(startAngle);
|
|
21988
22062
|
const iy1 = center + innerRadius * Math.sin(startAngle);
|
|
21989
22063
|
const ix2 = center + innerRadius * Math.cos(endAngle);
|
|
21990
22064
|
const iy2 = center + innerRadius * Math.sin(endAngle);
|
|
21991
|
-
|
|
22065
|
+
if (fullCircle) {
|
|
22066
|
+
const ixm = center + innerRadius * Math.cos(midAngle);
|
|
22067
|
+
const iym = center + innerRadius * Math.sin(midAngle);
|
|
22068
|
+
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`;
|
|
22069
|
+
} else {
|
|
22070
|
+
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`;
|
|
22071
|
+
}
|
|
22072
|
+
} else if (fullCircle) {
|
|
22073
|
+
d = `M ${center} ${center} L ${x1} ${y1} A ${radius} ${radius} 0 1 1 ${xm} ${ym} A ${radius} ${radius} 0 1 1 ${x2} ${y2} Z`;
|
|
21992
22074
|
} else {
|
|
21993
22075
|
d = `M ${center} ${center} L ${x1} ${y1} A ${radius} ${radius} 0 ${largeArc} 1 ${x2} ${y2} Z`;
|
|
21994
22076
|
}
|
|
@@ -25015,10 +25097,10 @@ function DataGrid({
|
|
|
25015
25097
|
] }),
|
|
25016
25098
|
badgeFields.length > 0 && /* @__PURE__ */ jsx(HStack, { gap: "xs", className: "flex-wrap", children: badgeFields.map((field) => {
|
|
25017
25099
|
const val = getNestedValue(itemData, field.name);
|
|
25018
|
-
if (val === void 0 || val === null) return null;
|
|
25100
|
+
if (val === void 0 || val === null || val === "") return null;
|
|
25019
25101
|
return /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "items-center", children: [
|
|
25020
25102
|
field.icon && renderIconInput(field.icon, { size: "xs" }),
|
|
25021
|
-
/* @__PURE__ */ jsx(Badge, { variant: resolveBadgeVariant(field, String(val)), children:
|
|
25103
|
+
/* @__PURE__ */ jsx(Badge, { variant: resolveBadgeVariant(field, String(val)), children: formatValue(val, field.format) })
|
|
25022
25104
|
] }, field.name);
|
|
25023
25105
|
}) })
|
|
25024
25106
|
] }),
|
|
@@ -32508,6 +32590,11 @@ var init_VoteStack = __esm({
|
|
|
32508
32590
|
{
|
|
32509
32591
|
className: cn(
|
|
32510
32592
|
"inline-flex items-center justify-center",
|
|
32593
|
+
// Shrink-wrap in stretch contexts (slot/sidecar wrappers are
|
|
32594
|
+
// flex-column with stretch alignment): without this the root spans
|
|
32595
|
+
// the full wrapper width and the count row's `w-full` turns the
|
|
32596
|
+
// compact pill into a page-wide band.
|
|
32597
|
+
"w-fit",
|
|
32511
32598
|
variant === "vertical" ? "flex-col" : "flex-row",
|
|
32512
32599
|
"rounded-sm",
|
|
32513
32600
|
"border-[length:var(--border-width)] border-border",
|
|
@@ -36004,7 +36091,7 @@ var init_Sidebar = __esm({
|
|
|
36004
36091
|
isActive ? [
|
|
36005
36092
|
"bg-primary text-primary-foreground",
|
|
36006
36093
|
"font-medium shadow-sm",
|
|
36007
|
-
"border-primary translate-x-1 -translate-y-0.5"
|
|
36094
|
+
"border-primary translate-x-1 rtl:-translate-x-1 -translate-y-0.5"
|
|
36008
36095
|
].join(" ") : [
|
|
36009
36096
|
"text-foreground",
|
|
36010
36097
|
"hover:bg-muted hover:border-border",
|
|
@@ -36014,10 +36101,10 @@ var init_Sidebar = __esm({
|
|
|
36014
36101
|
title: collapsed ? item.label : void 0,
|
|
36015
36102
|
children: [
|
|
36016
36103
|
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") })),
|
|
36017
|
-
!collapsed && /* @__PURE__ */ jsx(Typography, { variant: "body", color: isActive ? "inherit" : "primary", className: "font-medium truncate flex-1 text-
|
|
36104
|
+
!collapsed && /* @__PURE__ */ jsx(Typography, { variant: "body", color: isActive ? "inherit" : "primary", className: "font-medium truncate flex-1 text-start", children: item.label }),
|
|
36018
36105
|
!collapsed && item.badge !== void 0 && /* @__PURE__ */ jsx(Badge, { variant: "danger", size: "sm", children: item.badge }),
|
|
36019
36106
|
collapsed && /* @__PURE__ */ jsx(Box, { className: cn(
|
|
36020
|
-
"absolute
|
|
36107
|
+
"absolute start-full ms-2 px-2 py-1 text-xs opacity-0 group-hover:opacity-100",
|
|
36021
36108
|
"pointer-events-none whitespace-nowrap z-50 transition-opacity",
|
|
36022
36109
|
"bg-primary text-primary-foreground",
|
|
36023
36110
|
"border-[length:var(--border-width-thin)] border-border",
|
|
@@ -36072,7 +36159,7 @@ var init_Sidebar = __esm({
|
|
|
36072
36159
|
as: "aside",
|
|
36073
36160
|
className: cn(
|
|
36074
36161
|
"flex flex-col h-full",
|
|
36075
|
-
"bg-card border-
|
|
36162
|
+
"bg-card border-e border-border",
|
|
36076
36163
|
"transition-all duration-300 ease-in-out",
|
|
36077
36164
|
collapsed ? "w-20" : "w-64",
|
|
36078
36165
|
className
|
|
@@ -37233,7 +37320,7 @@ function resolveColor3(color, el) {
|
|
|
37233
37320
|
function truncateLabel(label) {
|
|
37234
37321
|
return label.length > MAX_LABEL_CHARS ? label.slice(0, MAX_LABEL_CHARS - 1) + "\u2026" : label;
|
|
37235
37322
|
}
|
|
37236
|
-
var GROUP_COLORS2, GROUP_GRAVITY, UNGROUPED_GRAVITY, labelMeasureCtx, MAX_LABEL_CHARS, GraphCanvas;
|
|
37323
|
+
var GROUP_COLORS2, GROUP_GRAVITY, UNGROUPED_GRAVITY, labelMeasureCtx, MAX_LABEL_CHARS, NO_NODES, NO_EDGES, NO_SIM, GraphCanvas;
|
|
37237
37324
|
var init_GraphCanvas = __esm({
|
|
37238
37325
|
"components/core/molecules/GraphCanvas.tsx"() {
|
|
37239
37326
|
"use client";
|
|
@@ -37257,11 +37344,14 @@ var init_GraphCanvas = __esm({
|
|
|
37257
37344
|
UNGROUPED_GRAVITY = 0.02;
|
|
37258
37345
|
labelMeasureCtx = null;
|
|
37259
37346
|
MAX_LABEL_CHARS = 22;
|
|
37347
|
+
NO_NODES = [];
|
|
37348
|
+
NO_EDGES = [];
|
|
37349
|
+
NO_SIM = [];
|
|
37260
37350
|
GraphCanvas = ({
|
|
37261
37351
|
title,
|
|
37262
|
-
nodes: propNodes =
|
|
37263
|
-
edges: propEdges =
|
|
37264
|
-
similarity: propSimilarity =
|
|
37352
|
+
nodes: propNodes = NO_NODES,
|
|
37353
|
+
edges: propEdges = NO_EDGES,
|
|
37354
|
+
similarity: propSimilarity = NO_SIM,
|
|
37265
37355
|
height = 400,
|
|
37266
37356
|
showLabels = true,
|
|
37267
37357
|
interactive = true,
|
|
@@ -37311,6 +37401,7 @@ var init_GraphCanvas = __esm({
|
|
|
37311
37401
|
const interactionRef = useRef({
|
|
37312
37402
|
mode: "none",
|
|
37313
37403
|
dragNodeId: null,
|
|
37404
|
+
pressedNodeId: null,
|
|
37314
37405
|
startMouse: { x: 0, y: 0 },
|
|
37315
37406
|
startOffset: { x: 0, y: 0 },
|
|
37316
37407
|
downPos: { x: 0, y: 0 }
|
|
@@ -37358,6 +37449,11 @@ var init_GraphCanvas = __esm({
|
|
|
37358
37449
|
() => [...new Set(propNodes.map((n) => n.group).filter(Boolean))],
|
|
37359
37450
|
[propNodes]
|
|
37360
37451
|
);
|
|
37452
|
+
const nodesKey = useMemo(() => propNodes.map((n) => n.id).join(""), [propNodes]);
|
|
37453
|
+
const edgesKey = useMemo(
|
|
37454
|
+
() => propEdges.map((e) => `${e.source}${e.target}`).join(""),
|
|
37455
|
+
[propEdges]
|
|
37456
|
+
);
|
|
37361
37457
|
useEffect(() => {
|
|
37362
37458
|
const canvas = canvasRef.current;
|
|
37363
37459
|
if (!canvas || propNodes.length === 0) return;
|
|
@@ -37538,7 +37634,7 @@ var init_GraphCanvas = __esm({
|
|
|
37538
37634
|
return () => {
|
|
37539
37635
|
cancelAnimationFrame(animRef.current);
|
|
37540
37636
|
};
|
|
37541
|
-
}, [
|
|
37637
|
+
}, [nodesKey, edgesKey, propSimilarity, layout, repulsion, linkDistance, nodeSpacing, showLabels]);
|
|
37542
37638
|
useEffect(() => {
|
|
37543
37639
|
const canvas = canvasRef.current;
|
|
37544
37640
|
if (!canvas) return;
|
|
@@ -37668,6 +37764,7 @@ var init_GraphCanvas = __esm({
|
|
|
37668
37764
|
const cancelSinglePointer = useCallback(() => {
|
|
37669
37765
|
interactionRef.current.mode = "none";
|
|
37670
37766
|
interactionRef.current.dragNodeId = null;
|
|
37767
|
+
interactionRef.current.pressedNodeId = null;
|
|
37671
37768
|
}, []);
|
|
37672
37769
|
const handlePointerDown = useCallback(
|
|
37673
37770
|
(e) => {
|
|
@@ -37678,6 +37775,7 @@ var init_GraphCanvas = __esm({
|
|
|
37678
37775
|
state.downPos = { x: e.clientX, y: e.clientY };
|
|
37679
37776
|
state.startMouse = { x: e.clientX, y: e.clientY };
|
|
37680
37777
|
state.startOffset = { ...offset };
|
|
37778
|
+
state.pressedNodeId = node?.id ?? null;
|
|
37681
37779
|
if (draggable && node) {
|
|
37682
37780
|
state.mode = "dragging";
|
|
37683
37781
|
state.dragNodeId = node.id;
|
|
@@ -37729,7 +37827,8 @@ var init_GraphCanvas = __esm({
|
|
|
37729
37827
|
if (moved < 4) {
|
|
37730
37828
|
const coords = toCoords(e);
|
|
37731
37829
|
if (!coords) return;
|
|
37732
|
-
const node = nodeAt(coords.graphX, coords.graphY);
|
|
37830
|
+
const node = (state.pressedNodeId ? nodesRef.current.find((n) => n.id === state.pressedNodeId) : void 0) ?? nodeAt(coords.graphX, coords.graphY);
|
|
37831
|
+
state.pressedNodeId = null;
|
|
37733
37832
|
if (node) {
|
|
37734
37833
|
if (node.badge && node.badge > 1 && onBadgeClick) {
|
|
37735
37834
|
const r2 = (node.size || 8) + (selectedNodeId === node.id ? 4 : 0);
|
|
@@ -37749,6 +37848,7 @@ var init_GraphCanvas = __esm({
|
|
|
37749
37848
|
);
|
|
37750
37849
|
const handlePointerLeave = useCallback(() => {
|
|
37751
37850
|
setHoveredNode(null);
|
|
37851
|
+
interactionRef.current.pressedNodeId = null;
|
|
37752
37852
|
}, []);
|
|
37753
37853
|
const gestureHandlers = useCanvasGestures({
|
|
37754
37854
|
canvasRef,
|
|
@@ -40700,8 +40800,17 @@ var init_MediaGallery = __esm({
|
|
|
40700
40800
|
const eventBus = useEventBus();
|
|
40701
40801
|
const { t } = useTranslate();
|
|
40702
40802
|
const [lightboxItem, setLightboxItem] = useState(null);
|
|
40803
|
+
const [failedIds, setFailedIds] = useState(/* @__PURE__ */ new Set());
|
|
40703
40804
|
const closeLightbox = useCallback(() => setLightboxItem(null), []);
|
|
40704
40805
|
useEventListener("UI:LIGHTBOX_CLOSE", closeLightbox);
|
|
40806
|
+
const handleImageError = useCallback((id) => {
|
|
40807
|
+
setFailedIds((prev) => {
|
|
40808
|
+
if (prev.has(id)) return prev;
|
|
40809
|
+
const next = new Set(prev);
|
|
40810
|
+
next.add(id);
|
|
40811
|
+
return next;
|
|
40812
|
+
});
|
|
40813
|
+
}, []);
|
|
40705
40814
|
const handleItemClick = useCallback(
|
|
40706
40815
|
(item) => {
|
|
40707
40816
|
if (selectable) {
|
|
@@ -40717,7 +40826,7 @@ var init_MediaGallery = __esm({
|
|
|
40717
40826
|
);
|
|
40718
40827
|
const entityData = Array.isArray(entity) ? entity : [];
|
|
40719
40828
|
const items = React90__default.useMemo(() => {
|
|
40720
|
-
if (propItems) return propItems;
|
|
40829
|
+
if (propItems && propItems.length > 0) return propItems;
|
|
40721
40830
|
if (entityData.length === 0) return [];
|
|
40722
40831
|
return entityData.map((record, idx) => {
|
|
40723
40832
|
return {
|
|
@@ -40800,13 +40909,14 @@ var init_MediaGallery = __esm({
|
|
|
40800
40909
|
),
|
|
40801
40910
|
onClick: () => handleItemClick(item),
|
|
40802
40911
|
children: [
|
|
40803
|
-
/* @__PURE__ */ jsx(
|
|
40912
|
+
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(
|
|
40804
40913
|
"img",
|
|
40805
40914
|
{
|
|
40806
40915
|
src: item.thumbnail || item.src,
|
|
40807
40916
|
alt: item.alt || item.caption || "",
|
|
40808
40917
|
className: "w-full h-full object-cover",
|
|
40809
|
-
loading: "lazy"
|
|
40918
|
+
loading: "lazy",
|
|
40919
|
+
onError: () => handleImageError(item.id)
|
|
40810
40920
|
}
|
|
40811
40921
|
),
|
|
40812
40922
|
/* @__PURE__ */ jsx(
|
|
@@ -44313,6 +44423,11 @@ var init_TeamOrganism = __esm({
|
|
|
44313
44423
|
TeamOrganism.displayName = "TeamOrganism";
|
|
44314
44424
|
}
|
|
44315
44425
|
});
|
|
44426
|
+
function formatDate4(value) {
|
|
44427
|
+
const d = new Date(value);
|
|
44428
|
+
if (isNaN(d.getTime())) return value;
|
|
44429
|
+
return d.toLocaleDateString(void 0, { year: "numeric", month: "short", day: "numeric" });
|
|
44430
|
+
}
|
|
44316
44431
|
var lookStyles10, STATUS_STYLES2, Timeline;
|
|
44317
44432
|
var init_Timeline = __esm({
|
|
44318
44433
|
"components/core/organisms/Timeline.tsx"() {
|
|
@@ -44440,7 +44555,7 @@ var init_Timeline = __esm({
|
|
|
44440
44555
|
/* @__PURE__ */ jsxs(VStack, { gap: "xs", className: cn("flex-1 min-w-0", !isLast && "pb-6"), children: [
|
|
44441
44556
|
/* @__PURE__ */ jsxs(HStack, { justify: "between", align: "start", wrap: true, children: [
|
|
44442
44557
|
/* @__PURE__ */ jsx(Typography, { variant: "body", weight: "semibold", children: item.title }),
|
|
44443
|
-
item.date && /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", className: "flex-shrink-0", children: item.date })
|
|
44558
|
+
item.date && /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", className: "flex-shrink-0", children: formatDate4(item.date) })
|
|
44444
44559
|
] }),
|
|
44445
44560
|
item.description && /* @__PURE__ */ jsx(Typography, { variant: "small", color: "secondary", children: item.description }),
|
|
44446
44561
|
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)) }),
|
|
@@ -45652,7 +45767,7 @@ function substituteTraitRefsDeep(value, pathKey) {
|
|
|
45652
45767
|
}
|
|
45653
45768
|
return value;
|
|
45654
45769
|
}
|
|
45655
|
-
function renderPatternProps(props, onDismiss) {
|
|
45770
|
+
function renderPatternProps(props, onDismiss, propsSchema) {
|
|
45656
45771
|
const rendered = {};
|
|
45657
45772
|
for (const [key, value] of Object.entries(props)) {
|
|
45658
45773
|
if (key === "children") {
|
|
@@ -45670,9 +45785,10 @@ function renderPatternProps(props, onDismiss) {
|
|
|
45670
45785
|
};
|
|
45671
45786
|
rendered[key] = /* @__PURE__ */ jsx(SlotContentRenderer, { content: childContent, onDismiss });
|
|
45672
45787
|
} else if (Array.isArray(value)) {
|
|
45788
|
+
const isDataArray = propsSchema?.[key]?.items?.types?.includes("object") ?? false;
|
|
45673
45789
|
rendered[key] = value.map((item, i) => {
|
|
45674
45790
|
const el = item;
|
|
45675
|
-
if (isPatternConfig(el)) {
|
|
45791
|
+
if (!isDataArray && isPatternConfig(el)) {
|
|
45676
45792
|
const nestedProps = {};
|
|
45677
45793
|
for (const [k, v] of Object.entries(el)) {
|
|
45678
45794
|
if (k !== "type") nestedProps[k] = v;
|
|
@@ -45760,14 +45876,15 @@ function SlotContentRenderer({
|
|
|
45760
45876
|
);
|
|
45761
45877
|
}
|
|
45762
45878
|
}
|
|
45763
|
-
const renderedProps = renderPatternProps(restProps, onDismiss);
|
|
45764
45879
|
const patternDef = getPatternDefinition(content.pattern);
|
|
45765
45880
|
const propsSchema = patternDef?.propsSchema;
|
|
45881
|
+
const renderedProps = renderPatternProps(restProps, onDismiss, propsSchema);
|
|
45766
45882
|
if (propsSchema) {
|
|
45767
45883
|
for (const [propKey, propValue] of Object.entries(renderedProps)) {
|
|
45768
45884
|
if (typeof propValue !== "string") continue;
|
|
45769
45885
|
const propDef = propsSchema[propKey];
|
|
45770
45886
|
if (!propDef || propDef.kind !== "callback") continue;
|
|
45887
|
+
if (propValue === "") continue;
|
|
45771
45888
|
renderedProps[propKey] = wrapCallbackForEvent(
|
|
45772
45889
|
`UI:${propValue}`,
|
|
45773
45890
|
propDef.callbackArgs,
|
|
@@ -49562,6 +49679,7 @@ function useSharedEntityStore() {
|
|
|
49562
49679
|
}
|
|
49563
49680
|
return storeRef.current;
|
|
49564
49681
|
}
|
|
49682
|
+
createContext(null);
|
|
49565
49683
|
function runTickFrame(entityId, orderedWriters, store) {
|
|
49566
49684
|
let scratch = store.getSnapshot(entityId);
|
|
49567
49685
|
for (const writer of orderedWriters) {
|
|
@@ -49659,6 +49777,11 @@ var SYNC_TICK_OPERATORS = /* @__PURE__ */ new Set([
|
|
|
49659
49777
|
"do",
|
|
49660
49778
|
"when"
|
|
49661
49779
|
]);
|
|
49780
|
+
var REACTIVE_REPAINT_PATTERN_TYPES = /* @__PURE__ */ new Set([
|
|
49781
|
+
"canvas",
|
|
49782
|
+
"game-hud",
|
|
49783
|
+
"game-shell"
|
|
49784
|
+
]);
|
|
49662
49785
|
var LIFECYCLE_EVENTS = ["INIT", "LOAD", "$MOUNT"];
|
|
49663
49786
|
function toTraitDefinition(binding) {
|
|
49664
49787
|
return {
|
|
@@ -49911,6 +50034,8 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
49911
50034
|
}, [traitStates]);
|
|
49912
50035
|
const traitSnapshotDataRef = useRef(/* @__PURE__ */ new Map());
|
|
49913
50036
|
const traitFieldStatesRef = useRef(/* @__PURE__ */ new Map());
|
|
50037
|
+
const lastCanvasRenderUiRef = useRef(/* @__PURE__ */ new Map());
|
|
50038
|
+
const executeTransitionEffectsRef = useRef(null);
|
|
49914
50039
|
useEffect(() => {
|
|
49915
50040
|
const mgr = managerRef.current;
|
|
49916
50041
|
const bindings = traitBindingsRef.current;
|
|
@@ -49951,11 +50076,9 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
49951
50076
|
bindTraitStateGetter((traitName) => {
|
|
49952
50077
|
const allStates = newManager.getAllStates();
|
|
49953
50078
|
if (allStates instanceof Map) {
|
|
49954
|
-
|
|
49955
|
-
return typeof val === "string" ? val : void 0;
|
|
50079
|
+
return allStates.get(traitName)?.currentState;
|
|
49956
50080
|
}
|
|
49957
|
-
|
|
49958
|
-
return typeof state === "string" ? state : void 0;
|
|
50081
|
+
return newManager.getState(traitName)?.currentState;
|
|
49959
50082
|
});
|
|
49960
50083
|
const snapshotUnregs = [];
|
|
49961
50084
|
for (const binding of traitBindingsRef.current) {
|
|
@@ -50040,6 +50163,15 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
50040
50163
|
const existing = pendingSlots.get(slot) || [];
|
|
50041
50164
|
existing.push({ pattern, props: props || {} });
|
|
50042
50165
|
pendingSlots.set(slot, existing);
|
|
50166
|
+
const patternType = pattern?.type;
|
|
50167
|
+
if (patternType !== void 0 && REACTIVE_REPAINT_PATTERN_TYPES.has(patternType)) {
|
|
50168
|
+
const rawForSlot = effects.filter(
|
|
50169
|
+
(e) => Array.isArray(e) && (e[0] === "render-ui" || e[0] === "render") && e[1] === slot
|
|
50170
|
+
);
|
|
50171
|
+
if (rawForSlot.length > 0) {
|
|
50172
|
+
lastCanvasRenderUiRef.current.set(traitName, rawForSlot);
|
|
50173
|
+
}
|
|
50174
|
+
}
|
|
50043
50175
|
},
|
|
50044
50176
|
clearSlot: (slot) => {
|
|
50045
50177
|
pendingSlots.set(slot, []);
|
|
@@ -50110,11 +50242,15 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
50110
50242
|
notify: clientHandlers.notify
|
|
50111
50243
|
};
|
|
50112
50244
|
}
|
|
50245
|
+
const sharedWrites = [];
|
|
50113
50246
|
const baseSet = handlers.set;
|
|
50114
50247
|
handlers = {
|
|
50115
50248
|
...handlers,
|
|
50116
50249
|
set: async (targetId, field, value) => {
|
|
50117
50250
|
if (baseSet) await baseSet(targetId, field, value);
|
|
50251
|
+
if (sharedKey !== void 0) {
|
|
50252
|
+
sharedWrites.push({ field, value });
|
|
50253
|
+
}
|
|
50118
50254
|
log11.debug("set:write", {
|
|
50119
50255
|
traitName,
|
|
50120
50256
|
field,
|
|
@@ -50190,7 +50326,10 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
50190
50326
|
});
|
|
50191
50327
|
}
|
|
50192
50328
|
if (sharedKey !== void 0) {
|
|
50193
|
-
sharedEntityStore.commit(
|
|
50329
|
+
sharedEntityStore.commit(
|
|
50330
|
+
sharedKey,
|
|
50331
|
+
mergeEntityFrame(sharedEntityStore.getSnapshot(sharedKey), sharedWrites)
|
|
50332
|
+
);
|
|
50194
50333
|
}
|
|
50195
50334
|
log11.debug("effects:executed", () => ({
|
|
50196
50335
|
traitName,
|
|
@@ -50216,6 +50355,38 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
50216
50355
|
entity: binding.linkedEntity
|
|
50217
50356
|
});
|
|
50218
50357
|
}
|
|
50358
|
+
if (pendingSlots.size === 0 && effectsCallOp(effects, SHARED_ENTITY_WRITE_OPS)) {
|
|
50359
|
+
const stashed = lastCanvasRenderUiRef.current.get(traitName);
|
|
50360
|
+
if (stashed !== void 0 && stashed.length > 0) {
|
|
50361
|
+
await executor.executeAll(stashed);
|
|
50362
|
+
for (const [slot, patterns] of pendingSlots) {
|
|
50363
|
+
flushSlot(traitName, slot, patterns, {
|
|
50364
|
+
event: flushEvent,
|
|
50365
|
+
state: previousState,
|
|
50366
|
+
entity: binding.linkedEntity
|
|
50367
|
+
});
|
|
50368
|
+
}
|
|
50369
|
+
}
|
|
50370
|
+
if (sharedKey !== void 0 && executeTransitionEffectsRef.current !== null) {
|
|
50371
|
+
for (const sibling of traitBindingsRef.current) {
|
|
50372
|
+
const siblingName = sibling.trait.name;
|
|
50373
|
+
if (siblingName === traitName) continue;
|
|
50374
|
+
if (sharedKeyByTraitNameRef.current.get(siblingName) !== sharedKey) continue;
|
|
50375
|
+
const siblingStash = lastCanvasRenderUiRef.current.get(siblingName);
|
|
50376
|
+
if (siblingStash === void 0 || siblingStash.length === 0) continue;
|
|
50377
|
+
const siblingState = traitStatesRef.current.get(siblingName)?.currentState ?? "";
|
|
50378
|
+
await executeTransitionEffectsRef.current({
|
|
50379
|
+
binding: sibling,
|
|
50380
|
+
effects: siblingStash,
|
|
50381
|
+
previousState: siblingState,
|
|
50382
|
+
newState: siblingState,
|
|
50383
|
+
flushEvent: `${flushEvent}:repaint`,
|
|
50384
|
+
syncOnly,
|
|
50385
|
+
log: log11
|
|
50386
|
+
});
|
|
50387
|
+
}
|
|
50388
|
+
}
|
|
50389
|
+
}
|
|
50219
50390
|
} catch (error) {
|
|
50220
50391
|
log11.error("effects:error", {
|
|
50221
50392
|
traitName,
|
|
@@ -50227,6 +50398,9 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
50227
50398
|
}
|
|
50228
50399
|
return emittedDuringExec;
|
|
50229
50400
|
}, [eventBus, flushSlot, sharedEntityStore]);
|
|
50401
|
+
useEffect(() => {
|
|
50402
|
+
executeTransitionEffectsRef.current = executeTransitionEffects;
|
|
50403
|
+
}, [executeTransitionEffects]);
|
|
50230
50404
|
const runTickEffects = useCallback((tick, binding) => {
|
|
50231
50405
|
const traitName = binding.trait.name;
|
|
50232
50406
|
const currentState = traitStatesRef.current.get(traitName)?.currentState ?? "";
|
|
@@ -50289,6 +50463,24 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
50289
50463
|
({ binding, tick }) => createSharedEntityWriter(binding, tick, traitStatesRef, emitFromSharedWriter)
|
|
50290
50464
|
);
|
|
50291
50465
|
runTickFrame(group.storeKey, writers, sharedEntityStore);
|
|
50466
|
+
const repaint = executeTransitionEffectsRef.current;
|
|
50467
|
+
if (repaint !== null) {
|
|
50468
|
+
for (const renderBinding of group.renderBindings) {
|
|
50469
|
+
const renderTraitName = renderBinding.trait.name;
|
|
50470
|
+
const stash = lastCanvasRenderUiRef.current.get(renderTraitName);
|
|
50471
|
+
if (stash === void 0 || stash.length === 0) continue;
|
|
50472
|
+
const renderState = traitStatesRef.current.get(renderTraitName)?.currentState ?? "";
|
|
50473
|
+
void repaint({
|
|
50474
|
+
binding: renderBinding,
|
|
50475
|
+
effects: stash,
|
|
50476
|
+
previousState: renderState,
|
|
50477
|
+
newState: renderState,
|
|
50478
|
+
flushEvent: "tick:repaint",
|
|
50479
|
+
syncOnly: true,
|
|
50480
|
+
log: sharedEntityLog
|
|
50481
|
+
});
|
|
50482
|
+
}
|
|
50483
|
+
}
|
|
50292
50484
|
};
|
|
50293
50485
|
if (interval === "frame") {
|
|
50294
50486
|
scheduler.add(0, onDue);
|
|
@@ -50338,6 +50530,13 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
50338
50530
|
entityByTrait[name] = fields;
|
|
50339
50531
|
}
|
|
50340
50532
|
}
|
|
50533
|
+
for (const binding of bindings) {
|
|
50534
|
+
const name = binding.trait.name;
|
|
50535
|
+
const sharedKey = sharedKeyByTraitNameRef.current.get(name);
|
|
50536
|
+
if (sharedKey !== void 0) {
|
|
50537
|
+
entityByTrait[name] = { ...sharedEntityStore.getSnapshot(sharedKey) };
|
|
50538
|
+
}
|
|
50539
|
+
}
|
|
50341
50540
|
const results = currentManager.sendEvent(
|
|
50342
50541
|
normalizedEvent,
|
|
50343
50542
|
payload,
|
|
@@ -50491,7 +50690,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
50491
50690
|
}
|
|
50492
50691
|
await onEventProcessed(normalizedEvent, payload, dispatchedOrbitals);
|
|
50493
50692
|
}
|
|
50494
|
-
}, [entities, eventBus]);
|
|
50693
|
+
}, [entities, eventBus, sharedEntityStore]);
|
|
50495
50694
|
const drainEventQueue = useCallback(async () => {
|
|
50496
50695
|
if (processingRef.current) return;
|
|
50497
50696
|
processingRef.current = true;
|
|
@@ -50561,6 +50760,24 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
50561
50760
|
});
|
|
50562
50761
|
}
|
|
50563
50762
|
}
|
|
50763
|
+
const bareCascadeKeys = /* @__PURE__ */ new Set();
|
|
50764
|
+
for (const binding of traitBindings) {
|
|
50765
|
+
for (const transition of binding.trait.transitions) {
|
|
50766
|
+
const eventKey = transition.event;
|
|
50767
|
+
if (LIFECYCLE_EVENTS.includes(eventKey)) continue;
|
|
50768
|
+
if (bareCascadeKeys.has(eventKey)) continue;
|
|
50769
|
+
bareCascadeKeys.add(eventKey);
|
|
50770
|
+
const bareKey = `UI:${eventKey}`;
|
|
50771
|
+
const unsub = eventBus.on(bareKey, (event) => {
|
|
50772
|
+
crossTraitLog.debug("bare-cascade:fire", { bareKey, eventKey });
|
|
50773
|
+
enqueueAndDrain(eventKey, event.payload);
|
|
50774
|
+
});
|
|
50775
|
+
unsubscribes.push(() => {
|
|
50776
|
+
crossTraitLog.debug("bare-cascade:unsubscribe", { bareKey, eventKey });
|
|
50777
|
+
unsub();
|
|
50778
|
+
});
|
|
50779
|
+
}
|
|
50780
|
+
}
|
|
50564
50781
|
for (const binding of traitBindings) {
|
|
50565
50782
|
const ownOrbital = orbitalsByTrait?.[binding.trait.name];
|
|
50566
50783
|
const listens = binding.trait.listens ?? [];
|
|
@@ -50644,9 +50861,16 @@ function normalizeChild(child) {
|
|
|
50644
50861
|
props: { ...rest, ...normalizedChildren !== void 0 ? { children: normalizedChildren } : {} }
|
|
50645
50862
|
};
|
|
50646
50863
|
}
|
|
50647
|
-
function applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits) {
|
|
50864
|
+
function applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits, activeTraits) {
|
|
50648
50865
|
for (const eff of effects) {
|
|
50649
50866
|
if (eff.type === "render-ui" && eff.slot && eff.pattern) {
|
|
50867
|
+
if (eff.traitName && activeTraits && !activeTraits.has(eff.traitName)) {
|
|
50868
|
+
xOrbitalLog.debug("slot:off-page-trait-skipped", {
|
|
50869
|
+
sourceTrait: eff.traitName,
|
|
50870
|
+
slot: eff.slot
|
|
50871
|
+
});
|
|
50872
|
+
continue;
|
|
50873
|
+
}
|
|
50650
50874
|
const patternRecord = eff.pattern;
|
|
50651
50875
|
const { type: patternType, children, ...inlineProps } = patternRecord;
|
|
50652
50876
|
const normalizedChildren = Array.isArray(children) ? children.map((c) => normalizeChild(c)) : children;
|
|
@@ -50687,8 +50911,38 @@ function applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits) {
|
|
|
50687
50911
|
}
|
|
50688
50912
|
}
|
|
50689
50913
|
}
|
|
50690
|
-
function
|
|
50914
|
+
function collectServerActiveTraits(ir, allTraits, mountedTraitNames) {
|
|
50915
|
+
if (!ir?.pages || ir.pages.size <= 1) return void 0;
|
|
50916
|
+
const pageBound = /* @__PURE__ */ new Set();
|
|
50917
|
+
for (const page of ir.pages.values()) {
|
|
50918
|
+
const queue = page.traits.map((b) => b.trait.name).filter((n) => !!n);
|
|
50919
|
+
for (const name of queue) {
|
|
50920
|
+
if (pageBound.has(name)) continue;
|
|
50921
|
+
pageBound.add(name);
|
|
50922
|
+
const rt = allTraits.get(name);
|
|
50923
|
+
if (!rt) continue;
|
|
50924
|
+
queue.push(...collectTraitRefsFromResolvedTrait(rt));
|
|
50925
|
+
}
|
|
50926
|
+
}
|
|
50927
|
+
const active = new Set(mountedTraitNames);
|
|
50928
|
+
for (const name of allTraits.keys()) {
|
|
50929
|
+
if (!pageBound.has(name)) active.add(name);
|
|
50930
|
+
}
|
|
50931
|
+
return active;
|
|
50932
|
+
}
|
|
50933
|
+
function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFallback, persistence, traitConfigsByName, orbitalsByTrait, embeddedTraits, serverActiveTraits }) {
|
|
50691
50934
|
const bridge = useServerBridge();
|
|
50935
|
+
const activeTraitNames = useMemo(
|
|
50936
|
+
() => new Set(traits2.map((b) => b.trait.name).filter((n) => !!n)),
|
|
50937
|
+
[traits2]
|
|
50938
|
+
);
|
|
50939
|
+
const withActiveTraits = useCallback(
|
|
50940
|
+
(payload) => {
|
|
50941
|
+
if (!serverActiveTraits || serverActiveTraits.size === 0) return payload;
|
|
50942
|
+
return { ...payload ?? {}, _activeTraits: Array.from(serverActiveTraits) };
|
|
50943
|
+
},
|
|
50944
|
+
[serverActiveTraits]
|
|
50945
|
+
);
|
|
50692
50946
|
const uiSlots = useUISlots();
|
|
50693
50947
|
const onEventProcessed = useCallback(async (event, payload, dispatchedOrbitals) => {
|
|
50694
50948
|
if (!bridge.connected || !orbitalNames?.length) return;
|
|
@@ -50700,11 +50954,11 @@ function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFa
|
|
|
50700
50954
|
dispatchedOrbitalsSize: dispatchedOrbitals?.size ?? 0
|
|
50701
50955
|
}));
|
|
50702
50956
|
for (const name of targets) {
|
|
50703
|
-
const { effects, meta } = await bridge.sendEvent(name, event, payload);
|
|
50957
|
+
const { effects, meta } = await bridge.sendEvent(name, event, withActiveTraits(payload));
|
|
50704
50958
|
recordServerResponse(name, event, meta);
|
|
50705
|
-
applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits);
|
|
50959
|
+
applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits, activeTraitNames);
|
|
50706
50960
|
}
|
|
50707
|
-
}, [bridge.connected, bridge.sendEvent, orbitalNames, uiSlots, onNavigate, embeddedTraits]);
|
|
50961
|
+
}, [bridge.connected, bridge.sendEvent, orbitalNames, uiSlots, onNavigate, embeddedTraits, activeTraitNames, withActiveTraits]);
|
|
50708
50962
|
const opts = orbitalNames ? { onEventProcessed, navigate: onNavigate, traitConfigsByName, orbitalsByTrait, embeddedTraits } : { navigate: onNavigate, persistence, traitConfigsByName, orbitalsByTrait, embeddedTraits };
|
|
50709
50963
|
const { sendEvent } = useTraitStateMachine(traits2, uiSlots, opts);
|
|
50710
50964
|
const initSentRef = useRef(false);
|
|
@@ -50741,7 +50995,7 @@ function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFa
|
|
|
50741
50995
|
initSentRef.current = true;
|
|
50742
50996
|
(async () => {
|
|
50743
50997
|
for (const name of orbitalNames) {
|
|
50744
|
-
const { effects, meta } = await bridge.sendEvent(name, "INIT", {});
|
|
50998
|
+
const { effects, meta } = await bridge.sendEvent(name, "INIT", withActiveTraits({}));
|
|
50745
50999
|
recordServerResponse(name, "INIT", meta);
|
|
50746
51000
|
const effectTraces = [
|
|
50747
51001
|
{ type: "fetch", args: [], status: "executed" },
|
|
@@ -50759,10 +51013,10 @@ function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFa
|
|
|
50759
51013
|
effects: effectTraces,
|
|
50760
51014
|
timestamp: Date.now()
|
|
50761
51015
|
});
|
|
50762
|
-
applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits);
|
|
51016
|
+
applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits, activeTraitNames);
|
|
50763
51017
|
}
|
|
50764
51018
|
})();
|
|
50765
|
-
}, [bridge.connected, orbitalNames, bridge.sendEvent, uiSlots, onNavigate, embeddedTraits]);
|
|
51019
|
+
}, [bridge.connected, orbitalNames, bridge.sendEvent, uiSlots, onNavigate, embeddedTraits, activeTraitNames, withActiveTraits]);
|
|
50766
51020
|
return null;
|
|
50767
51021
|
}
|
|
50768
51022
|
function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, onNavigate, onLocalFallback, persistence }) {
|
|
@@ -50849,6 +51103,14 @@ function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, onNavi
|
|
|
50849
51103
|
}
|
|
50850
51104
|
return Array.from(set);
|
|
50851
51105
|
}, [allPageTraits, orbitalsByTrait]);
|
|
51106
|
+
const serverActiveTraits = useMemo(
|
|
51107
|
+
() => collectServerActiveTraits(
|
|
51108
|
+
ir,
|
|
51109
|
+
allTraits,
|
|
51110
|
+
new Set(allPageTraits.map((b) => b.trait.name).filter((n) => !!n))
|
|
51111
|
+
),
|
|
51112
|
+
[ir, allTraits, allPageTraits]
|
|
51113
|
+
);
|
|
50852
51114
|
useEffect(() => {
|
|
50853
51115
|
const traitNames = allPageTraits.map((b) => b.trait.name);
|
|
50854
51116
|
const orbitalsByTraitForPage = {};
|
|
@@ -50858,7 +51120,7 @@ function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, onNavi
|
|
|
50858
51120
|
}
|
|
50859
51121
|
xOrbitalLog.info("SchemaRunner:mount", {
|
|
50860
51122
|
pageName,
|
|
50861
|
-
traitNames,
|
|
51123
|
+
traitNames: traitNames.join(","),
|
|
50862
51124
|
orbitalsByTraitForPage,
|
|
50863
51125
|
pageOrbitalNames: pageOrbitalNames.join(",")
|
|
50864
51126
|
});
|
|
@@ -50903,6 +51165,7 @@ function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, onNavi
|
|
|
50903
51165
|
traitConfigsByName,
|
|
50904
51166
|
orbitalsByTrait,
|
|
50905
51167
|
embeddedTraits,
|
|
51168
|
+
serverActiveTraits,
|
|
50906
51169
|
onNavigate,
|
|
50907
51170
|
onLocalFallback,
|
|
50908
51171
|
persistence
|