@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/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, 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";
|
|
@@ -37253,13 +37340,18 @@ var init_GraphCanvas = __esm({
|
|
|
37253
37340
|
"var(--color-info)",
|
|
37254
37341
|
"var(--color-accent)"
|
|
37255
37342
|
];
|
|
37343
|
+
GROUP_GRAVITY = 0.3;
|
|
37344
|
+
UNGROUPED_GRAVITY = 0.02;
|
|
37256
37345
|
labelMeasureCtx = null;
|
|
37257
37346
|
MAX_LABEL_CHARS = 22;
|
|
37347
|
+
NO_NODES = [];
|
|
37348
|
+
NO_EDGES = [];
|
|
37349
|
+
NO_SIM = [];
|
|
37258
37350
|
GraphCanvas = ({
|
|
37259
37351
|
title,
|
|
37260
|
-
nodes: propNodes =
|
|
37261
|
-
edges: propEdges =
|
|
37262
|
-
similarity: propSimilarity =
|
|
37352
|
+
nodes: propNodes = NO_NODES,
|
|
37353
|
+
edges: propEdges = NO_EDGES,
|
|
37354
|
+
similarity: propSimilarity = NO_SIM,
|
|
37263
37355
|
height = 400,
|
|
37264
37356
|
showLabels = true,
|
|
37265
37357
|
interactive = true,
|
|
@@ -37309,6 +37401,7 @@ var init_GraphCanvas = __esm({
|
|
|
37309
37401
|
const interactionRef = useRef({
|
|
37310
37402
|
mode: "none",
|
|
37311
37403
|
dragNodeId: null,
|
|
37404
|
+
pressedNodeId: null,
|
|
37312
37405
|
startMouse: { x: 0, y: 0 },
|
|
37313
37406
|
startOffset: { x: 0, y: 0 },
|
|
37314
37407
|
downPos: { x: 0, y: 0 }
|
|
@@ -37356,6 +37449,11 @@ var init_GraphCanvas = __esm({
|
|
|
37356
37449
|
() => [...new Set(propNodes.map((n) => n.group).filter(Boolean))],
|
|
37357
37450
|
[propNodes]
|
|
37358
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
|
+
);
|
|
37359
37457
|
useEffect(() => {
|
|
37360
37458
|
const canvas = canvasRef.current;
|
|
37361
37459
|
if (!canvas || propNodes.length === 0) return;
|
|
@@ -37439,7 +37537,7 @@ var init_GraphCanvas = __esm({
|
|
|
37439
37537
|
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) }));
|
|
37440
37538
|
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) }));
|
|
37441
37539
|
const collideRadius = (n) => Math.max(n.size || 8, (n.labelW ?? 0) / 2) + nodeSpacing / 2;
|
|
37442
|
-
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 ?
|
|
37540
|
+
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();
|
|
37443
37541
|
for (let i = 0; i < 300; i++) simulation.tick();
|
|
37444
37542
|
const pad = nodeSpacing / 2;
|
|
37445
37543
|
const rectsOf = (n) => {
|
|
@@ -37536,7 +37634,7 @@ var init_GraphCanvas = __esm({
|
|
|
37536
37634
|
return () => {
|
|
37537
37635
|
cancelAnimationFrame(animRef.current);
|
|
37538
37636
|
};
|
|
37539
|
-
}, [
|
|
37637
|
+
}, [nodesKey, edgesKey, propSimilarity, layout, repulsion, linkDistance, nodeSpacing, showLabels]);
|
|
37540
37638
|
useEffect(() => {
|
|
37541
37639
|
const canvas = canvasRef.current;
|
|
37542
37640
|
if (!canvas) return;
|
|
@@ -37666,6 +37764,7 @@ var init_GraphCanvas = __esm({
|
|
|
37666
37764
|
const cancelSinglePointer = useCallback(() => {
|
|
37667
37765
|
interactionRef.current.mode = "none";
|
|
37668
37766
|
interactionRef.current.dragNodeId = null;
|
|
37767
|
+
interactionRef.current.pressedNodeId = null;
|
|
37669
37768
|
}, []);
|
|
37670
37769
|
const handlePointerDown = useCallback(
|
|
37671
37770
|
(e) => {
|
|
@@ -37676,6 +37775,7 @@ var init_GraphCanvas = __esm({
|
|
|
37676
37775
|
state.downPos = { x: e.clientX, y: e.clientY };
|
|
37677
37776
|
state.startMouse = { x: e.clientX, y: e.clientY };
|
|
37678
37777
|
state.startOffset = { ...offset };
|
|
37778
|
+
state.pressedNodeId = node?.id ?? null;
|
|
37679
37779
|
if (draggable && node) {
|
|
37680
37780
|
state.mode = "dragging";
|
|
37681
37781
|
state.dragNodeId = node.id;
|
|
@@ -37727,7 +37827,8 @@ var init_GraphCanvas = __esm({
|
|
|
37727
37827
|
if (moved < 4) {
|
|
37728
37828
|
const coords = toCoords(e);
|
|
37729
37829
|
if (!coords) return;
|
|
37730
|
-
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;
|
|
37731
37832
|
if (node) {
|
|
37732
37833
|
if (node.badge && node.badge > 1 && onBadgeClick) {
|
|
37733
37834
|
const r2 = (node.size || 8) + (selectedNodeId === node.id ? 4 : 0);
|
|
@@ -37747,6 +37848,7 @@ var init_GraphCanvas = __esm({
|
|
|
37747
37848
|
);
|
|
37748
37849
|
const handlePointerLeave = useCallback(() => {
|
|
37749
37850
|
setHoveredNode(null);
|
|
37851
|
+
interactionRef.current.pressedNodeId = null;
|
|
37750
37852
|
}, []);
|
|
37751
37853
|
const gestureHandlers = useCanvasGestures({
|
|
37752
37854
|
canvasRef,
|
|
@@ -40698,8 +40800,17 @@ var init_MediaGallery = __esm({
|
|
|
40698
40800
|
const eventBus = useEventBus();
|
|
40699
40801
|
const { t } = useTranslate();
|
|
40700
40802
|
const [lightboxItem, setLightboxItem] = useState(null);
|
|
40803
|
+
const [failedIds, setFailedIds] = useState(/* @__PURE__ */ new Set());
|
|
40701
40804
|
const closeLightbox = useCallback(() => setLightboxItem(null), []);
|
|
40702
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
|
+
}, []);
|
|
40703
40814
|
const handleItemClick = useCallback(
|
|
40704
40815
|
(item) => {
|
|
40705
40816
|
if (selectable) {
|
|
@@ -40715,7 +40826,7 @@ var init_MediaGallery = __esm({
|
|
|
40715
40826
|
);
|
|
40716
40827
|
const entityData = Array.isArray(entity) ? entity : [];
|
|
40717
40828
|
const items = React90__default.useMemo(() => {
|
|
40718
|
-
if (propItems) return propItems;
|
|
40829
|
+
if (propItems && propItems.length > 0) return propItems;
|
|
40719
40830
|
if (entityData.length === 0) return [];
|
|
40720
40831
|
return entityData.map((record, idx) => {
|
|
40721
40832
|
return {
|
|
@@ -40798,13 +40909,14 @@ var init_MediaGallery = __esm({
|
|
|
40798
40909
|
),
|
|
40799
40910
|
onClick: () => handleItemClick(item),
|
|
40800
40911
|
children: [
|
|
40801
|
-
/* @__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(
|
|
40802
40913
|
"img",
|
|
40803
40914
|
{
|
|
40804
40915
|
src: item.thumbnail || item.src,
|
|
40805
40916
|
alt: item.alt || item.caption || "",
|
|
40806
40917
|
className: "w-full h-full object-cover",
|
|
40807
|
-
loading: "lazy"
|
|
40918
|
+
loading: "lazy",
|
|
40919
|
+
onError: () => handleImageError(item.id)
|
|
40808
40920
|
}
|
|
40809
40921
|
),
|
|
40810
40922
|
/* @__PURE__ */ jsx(
|
|
@@ -44311,6 +44423,11 @@ var init_TeamOrganism = __esm({
|
|
|
44311
44423
|
TeamOrganism.displayName = "TeamOrganism";
|
|
44312
44424
|
}
|
|
44313
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
|
+
}
|
|
44314
44431
|
var lookStyles10, STATUS_STYLES2, Timeline;
|
|
44315
44432
|
var init_Timeline = __esm({
|
|
44316
44433
|
"components/core/organisms/Timeline.tsx"() {
|
|
@@ -44438,7 +44555,7 @@ var init_Timeline = __esm({
|
|
|
44438
44555
|
/* @__PURE__ */ jsxs(VStack, { gap: "xs", className: cn("flex-1 min-w-0", !isLast && "pb-6"), children: [
|
|
44439
44556
|
/* @__PURE__ */ jsxs(HStack, { justify: "between", align: "start", wrap: true, children: [
|
|
44440
44557
|
/* @__PURE__ */ jsx(Typography, { variant: "body", weight: "semibold", children: item.title }),
|
|
44441
|
-
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) })
|
|
44442
44559
|
] }),
|
|
44443
44560
|
item.description && /* @__PURE__ */ jsx(Typography, { variant: "small", color: "secondary", children: item.description }),
|
|
44444
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)) }),
|
|
@@ -45650,7 +45767,7 @@ function substituteTraitRefsDeep(value, pathKey) {
|
|
|
45650
45767
|
}
|
|
45651
45768
|
return value;
|
|
45652
45769
|
}
|
|
45653
|
-
function renderPatternProps(props, onDismiss) {
|
|
45770
|
+
function renderPatternProps(props, onDismiss, propsSchema) {
|
|
45654
45771
|
const rendered = {};
|
|
45655
45772
|
for (const [key, value] of Object.entries(props)) {
|
|
45656
45773
|
if (key === "children") {
|
|
@@ -45668,9 +45785,10 @@ function renderPatternProps(props, onDismiss) {
|
|
|
45668
45785
|
};
|
|
45669
45786
|
rendered[key] = /* @__PURE__ */ jsx(SlotContentRenderer, { content: childContent, onDismiss });
|
|
45670
45787
|
} else if (Array.isArray(value)) {
|
|
45788
|
+
const isDataArray = propsSchema?.[key]?.items?.types?.includes("object") ?? false;
|
|
45671
45789
|
rendered[key] = value.map((item, i) => {
|
|
45672
45790
|
const el = item;
|
|
45673
|
-
if (isPatternConfig(el)) {
|
|
45791
|
+
if (!isDataArray && isPatternConfig(el)) {
|
|
45674
45792
|
const nestedProps = {};
|
|
45675
45793
|
for (const [k, v] of Object.entries(el)) {
|
|
45676
45794
|
if (k !== "type") nestedProps[k] = v;
|
|
@@ -45758,14 +45876,15 @@ function SlotContentRenderer({
|
|
|
45758
45876
|
);
|
|
45759
45877
|
}
|
|
45760
45878
|
}
|
|
45761
|
-
const renderedProps = renderPatternProps(restProps, onDismiss);
|
|
45762
45879
|
const patternDef = getPatternDefinition(content.pattern);
|
|
45763
45880
|
const propsSchema = patternDef?.propsSchema;
|
|
45881
|
+
const renderedProps = renderPatternProps(restProps, onDismiss, propsSchema);
|
|
45764
45882
|
if (propsSchema) {
|
|
45765
45883
|
for (const [propKey, propValue] of Object.entries(renderedProps)) {
|
|
45766
45884
|
if (typeof propValue !== "string") continue;
|
|
45767
45885
|
const propDef = propsSchema[propKey];
|
|
45768
45886
|
if (!propDef || propDef.kind !== "callback") continue;
|
|
45887
|
+
if (propValue === "") continue;
|
|
45769
45888
|
renderedProps[propKey] = wrapCallbackForEvent(
|
|
45770
45889
|
`UI:${propValue}`,
|
|
45771
45890
|
propDef.callbackArgs,
|
|
@@ -49560,6 +49679,7 @@ function useSharedEntityStore() {
|
|
|
49560
49679
|
}
|
|
49561
49680
|
return storeRef.current;
|
|
49562
49681
|
}
|
|
49682
|
+
createContext(null);
|
|
49563
49683
|
function runTickFrame(entityId, orderedWriters, store) {
|
|
49564
49684
|
let scratch = store.getSnapshot(entityId);
|
|
49565
49685
|
for (const writer of orderedWriters) {
|
|
@@ -49657,6 +49777,11 @@ var SYNC_TICK_OPERATORS = /* @__PURE__ */ new Set([
|
|
|
49657
49777
|
"do",
|
|
49658
49778
|
"when"
|
|
49659
49779
|
]);
|
|
49780
|
+
var REACTIVE_REPAINT_PATTERN_TYPES = /* @__PURE__ */ new Set([
|
|
49781
|
+
"canvas",
|
|
49782
|
+
"game-hud",
|
|
49783
|
+
"game-shell"
|
|
49784
|
+
]);
|
|
49660
49785
|
var LIFECYCLE_EVENTS = ["INIT", "LOAD", "$MOUNT"];
|
|
49661
49786
|
function toTraitDefinition(binding) {
|
|
49662
49787
|
return {
|
|
@@ -49909,6 +50034,8 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
49909
50034
|
}, [traitStates]);
|
|
49910
50035
|
const traitSnapshotDataRef = useRef(/* @__PURE__ */ new Map());
|
|
49911
50036
|
const traitFieldStatesRef = useRef(/* @__PURE__ */ new Map());
|
|
50037
|
+
const lastCanvasRenderUiRef = useRef(/* @__PURE__ */ new Map());
|
|
50038
|
+
const executeTransitionEffectsRef = useRef(null);
|
|
49912
50039
|
useEffect(() => {
|
|
49913
50040
|
const mgr = managerRef.current;
|
|
49914
50041
|
const bindings = traitBindingsRef.current;
|
|
@@ -49949,11 +50076,9 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
49949
50076
|
bindTraitStateGetter((traitName) => {
|
|
49950
50077
|
const allStates = newManager.getAllStates();
|
|
49951
50078
|
if (allStates instanceof Map) {
|
|
49952
|
-
|
|
49953
|
-
return typeof val === "string" ? val : void 0;
|
|
50079
|
+
return allStates.get(traitName)?.currentState;
|
|
49954
50080
|
}
|
|
49955
|
-
|
|
49956
|
-
return typeof state === "string" ? state : void 0;
|
|
50081
|
+
return newManager.getState(traitName)?.currentState;
|
|
49957
50082
|
});
|
|
49958
50083
|
const snapshotUnregs = [];
|
|
49959
50084
|
for (const binding of traitBindingsRef.current) {
|
|
@@ -50038,6 +50163,15 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
50038
50163
|
const existing = pendingSlots.get(slot) || [];
|
|
50039
50164
|
existing.push({ pattern, props: props || {} });
|
|
50040
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
|
+
}
|
|
50041
50175
|
},
|
|
50042
50176
|
clearSlot: (slot) => {
|
|
50043
50177
|
pendingSlots.set(slot, []);
|
|
@@ -50108,11 +50242,15 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
50108
50242
|
notify: clientHandlers.notify
|
|
50109
50243
|
};
|
|
50110
50244
|
}
|
|
50245
|
+
const sharedWrites = [];
|
|
50111
50246
|
const baseSet = handlers.set;
|
|
50112
50247
|
handlers = {
|
|
50113
50248
|
...handlers,
|
|
50114
50249
|
set: async (targetId, field, value) => {
|
|
50115
50250
|
if (baseSet) await baseSet(targetId, field, value);
|
|
50251
|
+
if (sharedKey !== void 0) {
|
|
50252
|
+
sharedWrites.push({ field, value });
|
|
50253
|
+
}
|
|
50116
50254
|
log11.debug("set:write", {
|
|
50117
50255
|
traitName,
|
|
50118
50256
|
field,
|
|
@@ -50188,7 +50326,10 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
50188
50326
|
});
|
|
50189
50327
|
}
|
|
50190
50328
|
if (sharedKey !== void 0) {
|
|
50191
|
-
sharedEntityStore.commit(
|
|
50329
|
+
sharedEntityStore.commit(
|
|
50330
|
+
sharedKey,
|
|
50331
|
+
mergeEntityFrame(sharedEntityStore.getSnapshot(sharedKey), sharedWrites)
|
|
50332
|
+
);
|
|
50192
50333
|
}
|
|
50193
50334
|
log11.debug("effects:executed", () => ({
|
|
50194
50335
|
traitName,
|
|
@@ -50214,6 +50355,38 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
50214
50355
|
entity: binding.linkedEntity
|
|
50215
50356
|
});
|
|
50216
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
|
+
}
|
|
50217
50390
|
} catch (error) {
|
|
50218
50391
|
log11.error("effects:error", {
|
|
50219
50392
|
traitName,
|
|
@@ -50225,6 +50398,9 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
50225
50398
|
}
|
|
50226
50399
|
return emittedDuringExec;
|
|
50227
50400
|
}, [eventBus, flushSlot, sharedEntityStore]);
|
|
50401
|
+
useEffect(() => {
|
|
50402
|
+
executeTransitionEffectsRef.current = executeTransitionEffects;
|
|
50403
|
+
}, [executeTransitionEffects]);
|
|
50228
50404
|
const runTickEffects = useCallback((tick, binding) => {
|
|
50229
50405
|
const traitName = binding.trait.name;
|
|
50230
50406
|
const currentState = traitStatesRef.current.get(traitName)?.currentState ?? "";
|
|
@@ -50287,6 +50463,24 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
50287
50463
|
({ binding, tick }) => createSharedEntityWriter(binding, tick, traitStatesRef, emitFromSharedWriter)
|
|
50288
50464
|
);
|
|
50289
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
|
+
}
|
|
50290
50484
|
};
|
|
50291
50485
|
if (interval === "frame") {
|
|
50292
50486
|
scheduler.add(0, onDue);
|
|
@@ -50336,6 +50530,13 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
50336
50530
|
entityByTrait[name] = fields;
|
|
50337
50531
|
}
|
|
50338
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
|
+
}
|
|
50339
50540
|
const results = currentManager.sendEvent(
|
|
50340
50541
|
normalizedEvent,
|
|
50341
50542
|
payload,
|
|
@@ -50489,7 +50690,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
50489
50690
|
}
|
|
50490
50691
|
await onEventProcessed(normalizedEvent, payload, dispatchedOrbitals);
|
|
50491
50692
|
}
|
|
50492
|
-
}, [entities, eventBus]);
|
|
50693
|
+
}, [entities, eventBus, sharedEntityStore]);
|
|
50493
50694
|
const drainEventQueue = useCallback(async () => {
|
|
50494
50695
|
if (processingRef.current) return;
|
|
50495
50696
|
processingRef.current = true;
|
|
@@ -50559,6 +50760,24 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
50559
50760
|
});
|
|
50560
50761
|
}
|
|
50561
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
|
+
}
|
|
50562
50781
|
for (const binding of traitBindings) {
|
|
50563
50782
|
const ownOrbital = orbitalsByTrait?.[binding.trait.name];
|
|
50564
50783
|
const listens = binding.trait.listens ?? [];
|
|
@@ -50642,9 +50861,16 @@ function normalizeChild(child) {
|
|
|
50642
50861
|
props: { ...rest, ...normalizedChildren !== void 0 ? { children: normalizedChildren } : {} }
|
|
50643
50862
|
};
|
|
50644
50863
|
}
|
|
50645
|
-
function applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits) {
|
|
50864
|
+
function applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits, activeTraits) {
|
|
50646
50865
|
for (const eff of effects) {
|
|
50647
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
|
+
}
|
|
50648
50874
|
const patternRecord = eff.pattern;
|
|
50649
50875
|
const { type: patternType, children, ...inlineProps } = patternRecord;
|
|
50650
50876
|
const normalizedChildren = Array.isArray(children) ? children.map((c) => normalizeChild(c)) : children;
|
|
@@ -50685,8 +50911,38 @@ function applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits) {
|
|
|
50685
50911
|
}
|
|
50686
50912
|
}
|
|
50687
50913
|
}
|
|
50688
|
-
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 }) {
|
|
50689
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
|
+
);
|
|
50690
50946
|
const uiSlots = useUISlots();
|
|
50691
50947
|
const onEventProcessed = useCallback(async (event, payload, dispatchedOrbitals) => {
|
|
50692
50948
|
if (!bridge.connected || !orbitalNames?.length) return;
|
|
@@ -50698,11 +50954,11 @@ function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFa
|
|
|
50698
50954
|
dispatchedOrbitalsSize: dispatchedOrbitals?.size ?? 0
|
|
50699
50955
|
}));
|
|
50700
50956
|
for (const name of targets) {
|
|
50701
|
-
const { effects, meta } = await bridge.sendEvent(name, event, payload);
|
|
50957
|
+
const { effects, meta } = await bridge.sendEvent(name, event, withActiveTraits(payload));
|
|
50702
50958
|
recordServerResponse(name, event, meta);
|
|
50703
|
-
applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits);
|
|
50959
|
+
applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits, activeTraitNames);
|
|
50704
50960
|
}
|
|
50705
|
-
}, [bridge.connected, bridge.sendEvent, orbitalNames, uiSlots, onNavigate, embeddedTraits]);
|
|
50961
|
+
}, [bridge.connected, bridge.sendEvent, orbitalNames, uiSlots, onNavigate, embeddedTraits, activeTraitNames, withActiveTraits]);
|
|
50706
50962
|
const opts = orbitalNames ? { onEventProcessed, navigate: onNavigate, traitConfigsByName, orbitalsByTrait, embeddedTraits } : { navigate: onNavigate, persistence, traitConfigsByName, orbitalsByTrait, embeddedTraits };
|
|
50707
50963
|
const { sendEvent } = useTraitStateMachine(traits2, uiSlots, opts);
|
|
50708
50964
|
const initSentRef = useRef(false);
|
|
@@ -50739,7 +50995,7 @@ function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFa
|
|
|
50739
50995
|
initSentRef.current = true;
|
|
50740
50996
|
(async () => {
|
|
50741
50997
|
for (const name of orbitalNames) {
|
|
50742
|
-
const { effects, meta } = await bridge.sendEvent(name, "INIT", {});
|
|
50998
|
+
const { effects, meta } = await bridge.sendEvent(name, "INIT", withActiveTraits({}));
|
|
50743
50999
|
recordServerResponse(name, "INIT", meta);
|
|
50744
51000
|
const effectTraces = [
|
|
50745
51001
|
{ type: "fetch", args: [], status: "executed" },
|
|
@@ -50757,10 +51013,10 @@ function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFa
|
|
|
50757
51013
|
effects: effectTraces,
|
|
50758
51014
|
timestamp: Date.now()
|
|
50759
51015
|
});
|
|
50760
|
-
applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits);
|
|
51016
|
+
applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits, activeTraitNames);
|
|
50761
51017
|
}
|
|
50762
51018
|
})();
|
|
50763
|
-
}, [bridge.connected, orbitalNames, bridge.sendEvent, uiSlots, onNavigate, embeddedTraits]);
|
|
51019
|
+
}, [bridge.connected, orbitalNames, bridge.sendEvent, uiSlots, onNavigate, embeddedTraits, activeTraitNames, withActiveTraits]);
|
|
50764
51020
|
return null;
|
|
50765
51021
|
}
|
|
50766
51022
|
function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, onNavigate, onLocalFallback, persistence }) {
|
|
@@ -50847,6 +51103,14 @@ function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, onNavi
|
|
|
50847
51103
|
}
|
|
50848
51104
|
return Array.from(set);
|
|
50849
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
|
+
);
|
|
50850
51114
|
useEffect(() => {
|
|
50851
51115
|
const traitNames = allPageTraits.map((b) => b.trait.name);
|
|
50852
51116
|
const orbitalsByTraitForPage = {};
|
|
@@ -50856,7 +51120,7 @@ function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, onNavi
|
|
|
50856
51120
|
}
|
|
50857
51121
|
xOrbitalLog.info("SchemaRunner:mount", {
|
|
50858
51122
|
pageName,
|
|
50859
|
-
traitNames,
|
|
51123
|
+
traitNames: traitNames.join(","),
|
|
50860
51124
|
orbitalsByTraitForPage,
|
|
50861
51125
|
pageOrbitalNames: pageOrbitalNames.join(",")
|
|
50862
51126
|
});
|
|
@@ -50901,6 +51165,7 @@ function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, onNavi
|
|
|
50901
51165
|
traitConfigsByName,
|
|
50902
51166
|
orbitalsByTrait,
|
|
50903
51167
|
embeddedTraits,
|
|
51168
|
+
serverActiveTraits,
|
|
50904
51169
|
onNavigate,
|
|
50905
51170
|
onLocalFallback,
|
|
50906
51171
|
persistence
|