@almadar/ui 5.156.0 → 5.158.0
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/{EntityBindingContext-BfZGeDfX.d.cts → EntityBindingContext-Bn3ePJQC.d.cts} +6 -2
- package/dist/{EntityBindingContext-BfZGeDfX.d.ts → EntityBindingContext-Bn3ePJQC.d.ts} +6 -2
- package/dist/avl/index.cjs +283 -43
- package/dist/avl/index.js +283 -43
- package/dist/components/index.cjs +249 -33
- package/dist/components/index.d.cts +46 -6
- package/dist/components/index.d.ts +46 -6
- package/dist/components/index.js +250 -34
- package/dist/providers/index.cjs +251 -35
- package/dist/providers/index.d.cts +1 -1
- package/dist/providers/index.d.ts +1 -1
- package/dist/providers/index.js +251 -35
- package/dist/runtime/index.cjs +283 -43
- package/dist/runtime/index.d.cts +12 -3
- package/dist/runtime/index.d.ts +12 -3
- package/dist/runtime/index.js +283 -43
- package/package.json +4 -4
package/dist/runtime/index.d.ts
CHANGED
|
@@ -5,8 +5,8 @@ import * as _almadar_runtime from '@almadar/runtime';
|
|
|
5
5
|
import { TraitState, EffectHandlers } from '@almadar/runtime';
|
|
6
6
|
import '../useEventBus-CQWyAWpK.js';
|
|
7
7
|
import { c as useUISlots } from '../UISlotContext-CB89mv7N.js';
|
|
8
|
-
import { a as EntityBindingSource, h as ServerBridgeTransport } from '../EntityBindingContext-
|
|
9
|
-
export { b as EntitySchemaContextValue, c as EntitySchemaProvider, d as EntitySchemaProviderProps, e as ServerBridgeContextValue, f as ServerBridgeProvider, i as ServerClientEffect, T as TraitContext, k as TraitContextValue, l as TraitInstance, m as TraitProvider, n as TraitProviderProps, o as useEntitySchema, p as useEntitySchemaOptional, q as useServerBridge, r as useTrait, s as useTraitContext } from '../EntityBindingContext-
|
|
8
|
+
import { a as EntityBindingSource, h as ServerBridgeTransport } from '../EntityBindingContext-Bn3ePJQC.js';
|
|
9
|
+
export { b as EntitySchemaContextValue, c as EntitySchemaProvider, d as EntitySchemaProviderProps, e as ServerBridgeContextValue, f as ServerBridgeProvider, i as ServerClientEffect, T as TraitContext, k as TraitContextValue, l as TraitInstance, m as TraitProvider, n as TraitProviderProps, o as useEntitySchema, p as useEntitySchemaOptional, q as useServerBridge, r as useTrait, s as useTraitContext } from '../EntityBindingContext-Bn3ePJQC.js';
|
|
10
10
|
import { PerfEntry } from '@almadar/runtime/ui';
|
|
11
11
|
export { PERF_NAMESPACE, PerfEntry, PreparedPreviewSchema, adjustSchemaForMockData, buildMockData, clearPerf, perfEnd, perfStart, perfTime, prepareSchemaForPreview, wrapCallbackForEvent } from '@almadar/runtime/ui';
|
|
12
12
|
import React__default, { ProfilerOnRenderCallback } from 'react';
|
|
@@ -39,7 +39,16 @@ interface UseTraitStateMachineOptions {
|
|
|
39
39
|
* set means no local transition matched — leave the legacy fallback to
|
|
40
40
|
* the consumer.
|
|
41
41
|
*/
|
|
42
|
-
onEventProcessed?: (eventKey: string, payload?: EventPayload, dispatchedOrbitals?: Set<string
|
|
42
|
+
onEventProcessed?: (eventKey: string, payload?: EventPayload, dispatchedOrbitals?: Set<string>,
|
|
43
|
+
/**
|
|
44
|
+
* Broadcast-class marker (T6): when set, the entry is a tick's
|
|
45
|
+
* latest-state broadcast — the drain does NOT await the server
|
|
46
|
+
* fan-out, and the bridge discards the response (nobody reads a
|
|
47
|
+
* broadcast response; applying a stale one would clobber newer
|
|
48
|
+
* local state). `sourceTrait` is the emitting trait, for the
|
|
49
|
+
* server relay's BusEventSource.
|
|
50
|
+
*/
|
|
51
|
+
tick?: string, sourceTrait?: string) => void | Promise<void>;
|
|
43
52
|
/** Router navigate function for navigate effects. `crumb` labels the
|
|
44
53
|
* target page's navigation-stack entry (from the effect's options). */
|
|
45
54
|
navigate?: (path: string, params?: Record<string, string>, crumb?: string) => void;
|
package/dist/runtime/index.js
CHANGED
|
@@ -810,11 +810,32 @@ function isPlainObject(value) {
|
|
|
810
810
|
if (typeof value === "function") return false;
|
|
811
811
|
return true;
|
|
812
812
|
}
|
|
813
|
+
function subtreeHasMarker(value) {
|
|
814
|
+
const cached = markerPresenceCache.get(value);
|
|
815
|
+
if (cached !== void 0) return cached;
|
|
816
|
+
let found = false;
|
|
817
|
+
const children = Array.isArray(value) ? value : Object.values(value);
|
|
818
|
+
for (const child of children) {
|
|
819
|
+
if (isRenderBindingMarker(child)) {
|
|
820
|
+
found = true;
|
|
821
|
+
break;
|
|
822
|
+
}
|
|
823
|
+
if (Array.isArray(child) || isPlainObject(child)) {
|
|
824
|
+
if (subtreeHasMarker(child)) {
|
|
825
|
+
found = true;
|
|
826
|
+
break;
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
}
|
|
830
|
+
markerPresenceCache.set(value, found);
|
|
831
|
+
return found;
|
|
832
|
+
}
|
|
813
833
|
function walkValue(value, scopeTrait, entity, config, state) {
|
|
814
834
|
if (isRenderBindingMarker(value)) {
|
|
815
835
|
return { resolved: resolveMarkerExpression(value.expression, entity, config, state), changed: true };
|
|
816
836
|
}
|
|
817
837
|
if (Array.isArray(value)) {
|
|
838
|
+
if (!subtreeHasMarker(value)) return { resolved: value, changed: false };
|
|
818
839
|
const out = [];
|
|
819
840
|
let changed = false;
|
|
820
841
|
for (const item of value) {
|
|
@@ -832,6 +853,7 @@ function walkValue(value, scopeTrait, entity, config, state) {
|
|
|
832
853
|
return changed ? { resolved: out, changed: true } : { resolved: value, changed: false };
|
|
833
854
|
}
|
|
834
855
|
if (isPlainObject(value)) {
|
|
856
|
+
if (!subtreeHasMarker(value)) return { resolved: value, changed: false };
|
|
835
857
|
const sourceTrait = value._sourceTrait;
|
|
836
858
|
if (typeof sourceTrait === "string" && sourceTrait !== scopeTrait) {
|
|
837
859
|
return { resolved: value, changed: false };
|
|
@@ -857,9 +879,11 @@ function resolveRenderBindingMarkers(props, scopeTrait, entity, config, state) {
|
|
|
857
879
|
}
|
|
858
880
|
return changed ? out : props;
|
|
859
881
|
}
|
|
882
|
+
var markerPresenceCache;
|
|
860
883
|
var init_resolve_render_bindings = __esm({
|
|
861
884
|
"lib/resolve-render-bindings.ts"() {
|
|
862
885
|
"use client";
|
|
886
|
+
markerPresenceCache = /* @__PURE__ */ new WeakMap();
|
|
863
887
|
}
|
|
864
888
|
});
|
|
865
889
|
function cn(...inputs) {
|
|
@@ -12029,6 +12053,8 @@ function drawShape(ctx, shape, width, height, allShapes) {
|
|
|
12029
12053
|
case "path": {
|
|
12030
12054
|
if (!shape.path) break;
|
|
12031
12055
|
const p = new Path2D(shape.path);
|
|
12056
|
+
ctx.lineJoin = "round";
|
|
12057
|
+
ctx.lineCap = "round";
|
|
12032
12058
|
if (fill) {
|
|
12033
12059
|
ctx.fillStyle = fill;
|
|
12034
12060
|
ctx.fill(p);
|
|
@@ -12237,7 +12263,7 @@ var init_LearningCanvas = __esm({
|
|
|
12237
12263
|
ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
|
|
12238
12264
|
ctx.clearRect(0, 0, width, height);
|
|
12239
12265
|
if (backgroundColor) {
|
|
12240
|
-
ctx.fillStyle = backgroundColor;
|
|
12266
|
+
ctx.fillStyle = resolveColor2(backgroundColor, ctx, backgroundColor);
|
|
12241
12267
|
ctx.fillRect(0, 0, width, height);
|
|
12242
12268
|
}
|
|
12243
12269
|
for (const shape of derivedShapes) {
|
|
@@ -26919,7 +26945,7 @@ function fileIcon(name) {
|
|
|
26919
26945
|
return "file";
|
|
26920
26946
|
}
|
|
26921
26947
|
}
|
|
26922
|
-
var TreeNodeItem, FileTree;
|
|
26948
|
+
var TreeNodeItem, FlatTreeNodeItem, FileTree;
|
|
26923
26949
|
var init_FileTree = __esm({
|
|
26924
26950
|
"components/core/molecules/FileTree.tsx"() {
|
|
26925
26951
|
"use client";
|
|
@@ -27004,14 +27030,101 @@ var init_FileTree = __esm({
|
|
|
27004
27030
|
)) })
|
|
27005
27031
|
] });
|
|
27006
27032
|
};
|
|
27033
|
+
FlatTreeNodeItem = ({
|
|
27034
|
+
item,
|
|
27035
|
+
depth,
|
|
27036
|
+
indent,
|
|
27037
|
+
childrenByParent,
|
|
27038
|
+
onNodeSelect,
|
|
27039
|
+
defaultExpanded = false
|
|
27040
|
+
}) => {
|
|
27041
|
+
const [expanded, setExpanded] = useState(defaultExpanded || depth < 1);
|
|
27042
|
+
const children = childrenByParent.get(item.id);
|
|
27043
|
+
const hasChildren = !!children && children.length > 0;
|
|
27044
|
+
const handleClick = useCallback(() => {
|
|
27045
|
+
if (hasChildren) setExpanded((prev) => !prev);
|
|
27046
|
+
onNodeSelect?.(item.id);
|
|
27047
|
+
}, [hasChildren, item.id, onNodeSelect]);
|
|
27048
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
27049
|
+
/* @__PURE__ */ jsxs(
|
|
27050
|
+
Box,
|
|
27051
|
+
{
|
|
27052
|
+
className: "flex items-center gap-1.5 py-0.5 px-2 cursor-pointer rounded-sm transition-colors hover:bg-muted",
|
|
27053
|
+
style: { paddingLeft: depth * indent + 8 },
|
|
27054
|
+
onClick: handleClick,
|
|
27055
|
+
role: "treeitem",
|
|
27056
|
+
"aria-expanded": hasChildren ? expanded : void 0,
|
|
27057
|
+
children: [
|
|
27058
|
+
hasChildren ? /* @__PURE__ */ jsx(
|
|
27059
|
+
Icon,
|
|
27060
|
+
{
|
|
27061
|
+
name: expanded ? "chevron-down" : "chevron-right",
|
|
27062
|
+
size: "xs",
|
|
27063
|
+
className: "text-[var(--color-muted-foreground)] flex-shrink-0"
|
|
27064
|
+
}
|
|
27065
|
+
) : /* @__PURE__ */ jsx(Box, { style: { width: 12, flexShrink: 0 } }),
|
|
27066
|
+
/* @__PURE__ */ jsx(
|
|
27067
|
+
Icon,
|
|
27068
|
+
{
|
|
27069
|
+
name: item.icon ?? (hasChildren ? expanded ? "folder-open" : "folder" : "file"),
|
|
27070
|
+
size: "xs",
|
|
27071
|
+
className: hasChildren ? "text-[var(--color-warning)]" : "text-[var(--color-muted-foreground)]"
|
|
27072
|
+
}
|
|
27073
|
+
),
|
|
27074
|
+
/* @__PURE__ */ jsx(Typography, { variant: "caption", className: "truncate font-mono text-xs", children: item.label })
|
|
27075
|
+
]
|
|
27076
|
+
}
|
|
27077
|
+
),
|
|
27078
|
+
hasChildren && expanded && /* @__PURE__ */ jsx(Box, { role: "group", children: children.map((child) => /* @__PURE__ */ jsx(
|
|
27079
|
+
FlatTreeNodeItem,
|
|
27080
|
+
{
|
|
27081
|
+
item: child,
|
|
27082
|
+
depth: depth + 1,
|
|
27083
|
+
indent,
|
|
27084
|
+
childrenByParent,
|
|
27085
|
+
onNodeSelect
|
|
27086
|
+
},
|
|
27087
|
+
child.id
|
|
27088
|
+
)) })
|
|
27089
|
+
] });
|
|
27090
|
+
};
|
|
27007
27091
|
FileTree = ({
|
|
27008
27092
|
tree,
|
|
27093
|
+
items,
|
|
27009
27094
|
selectedPath,
|
|
27010
27095
|
onFileSelect,
|
|
27096
|
+
onNodeSelect,
|
|
27011
27097
|
className,
|
|
27012
27098
|
indent = 16
|
|
27013
27099
|
}) => {
|
|
27014
|
-
if (
|
|
27100
|
+
if (items) {
|
|
27101
|
+
if (items.length === 0) return null;
|
|
27102
|
+
const ids = new Set(items.map((node) => node.id));
|
|
27103
|
+
const childrenByParent = /* @__PURE__ */ new Map();
|
|
27104
|
+
const roots = [];
|
|
27105
|
+
for (const item of items) {
|
|
27106
|
+
if (item.parentId && ids.has(item.parentId)) {
|
|
27107
|
+
const siblings = childrenByParent.get(item.parentId);
|
|
27108
|
+
if (siblings) siblings.push(item);
|
|
27109
|
+
else childrenByParent.set(item.parentId, [item]);
|
|
27110
|
+
} else {
|
|
27111
|
+
roots.push(item);
|
|
27112
|
+
}
|
|
27113
|
+
}
|
|
27114
|
+
return /* @__PURE__ */ jsx(Box, { className: `py-1 overflow-y-auto ${className ?? ""}`, role: "tree", children: roots.map((item) => /* @__PURE__ */ jsx(
|
|
27115
|
+
FlatTreeNodeItem,
|
|
27116
|
+
{
|
|
27117
|
+
item,
|
|
27118
|
+
depth: 0,
|
|
27119
|
+
indent,
|
|
27120
|
+
childrenByParent,
|
|
27121
|
+
onNodeSelect,
|
|
27122
|
+
defaultExpanded: true
|
|
27123
|
+
},
|
|
27124
|
+
item.id
|
|
27125
|
+
)) });
|
|
27126
|
+
}
|
|
27127
|
+
if (!tree || tree.length === 0) return null;
|
|
27015
27128
|
return /* @__PURE__ */ jsx(Box, { className: `py-1 overflow-y-auto ${className ?? ""}`, role: "tree", children: tree.map((node) => /* @__PURE__ */ jsx(
|
|
27016
27129
|
TreeNodeItem,
|
|
27017
27130
|
{
|
|
@@ -28342,7 +28455,7 @@ var init_debug = __esm({
|
|
|
28342
28455
|
createLogger("almadar:ui:debug:game-state");
|
|
28343
28456
|
}
|
|
28344
28457
|
});
|
|
28345
|
-
var isRelationsDebugEnabled, RelationSelect;
|
|
28458
|
+
var isRelationsDebugEnabled, MANY_CARDINALITIES, RelationSelect;
|
|
28346
28459
|
var init_RelationSelect = __esm({
|
|
28347
28460
|
"components/core/molecules/RelationSelect.tsx"() {
|
|
28348
28461
|
"use client";
|
|
@@ -28356,6 +28469,11 @@ var init_RelationSelect = __esm({
|
|
|
28356
28469
|
init_Typography();
|
|
28357
28470
|
init_debug();
|
|
28358
28471
|
isRelationsDebugEnabled = () => isDebugEnabled();
|
|
28472
|
+
MANY_CARDINALITIES = [
|
|
28473
|
+
"many",
|
|
28474
|
+
"one-to-many",
|
|
28475
|
+
"many-to-many"
|
|
28476
|
+
];
|
|
28359
28477
|
RelationSelect = ({
|
|
28360
28478
|
value,
|
|
28361
28479
|
onChange,
|
|
@@ -29995,6 +30113,9 @@ var init_MathCanvas = __esm({
|
|
|
29995
30113
|
showAxes = true,
|
|
29996
30114
|
showGrid = true,
|
|
29997
30115
|
gridStep = 1,
|
|
30116
|
+
backgroundColor,
|
|
30117
|
+
gridColor = "var(--color-border, #9ca3af)",
|
|
30118
|
+
axisColor = "var(--color-muted-foreground, #374151)",
|
|
29998
30119
|
showTickLabels = false,
|
|
29999
30120
|
showCurveLabels = false,
|
|
30000
30121
|
curves = [],
|
|
@@ -30017,17 +30138,21 @@ var init_MathCanvas = __esm({
|
|
|
30017
30138
|
error
|
|
30018
30139
|
}) => {
|
|
30019
30140
|
const eventBus = useEventBus();
|
|
30141
|
+
const keyMapKey = keyMap ? JSON.stringify(keyMap) : null;
|
|
30142
|
+
const keyUpMapKey = keyUpMap ? JSON.stringify(keyUpMap) : null;
|
|
30143
|
+
const stableKeyMap = useMemo(() => keyMap, [keyMapKey]);
|
|
30144
|
+
const stableKeyUpMap = useMemo(() => keyUpMap, [keyUpMapKey]);
|
|
30020
30145
|
useEffect(() => {
|
|
30021
|
-
if (!
|
|
30146
|
+
if (!stableKeyMap && !stableKeyUpMap) return;
|
|
30022
30147
|
const onDown = (e) => {
|
|
30023
|
-
const ev =
|
|
30148
|
+
const ev = stableKeyMap?.[e.code];
|
|
30024
30149
|
if (ev) {
|
|
30025
30150
|
eventBus.emit(`UI:${ev}`, {});
|
|
30026
30151
|
e.preventDefault();
|
|
30027
30152
|
}
|
|
30028
30153
|
};
|
|
30029
30154
|
const onUp = (e) => {
|
|
30030
|
-
const ev =
|
|
30155
|
+
const ev = stableKeyUpMap?.[e.code];
|
|
30031
30156
|
if (ev) eventBus.emit(`UI:${ev}`, {});
|
|
30032
30157
|
};
|
|
30033
30158
|
window.addEventListener("keydown", onDown);
|
|
@@ -30036,7 +30161,7 @@ var init_MathCanvas = __esm({
|
|
|
30036
30161
|
window.removeEventListener("keydown", onDown);
|
|
30037
30162
|
window.removeEventListener("keyup", onUp);
|
|
30038
30163
|
};
|
|
30039
|
-
}, [
|
|
30164
|
+
}, [stableKeyMap, stableKeyUpMap, eventBus]);
|
|
30040
30165
|
const derivedShapes = useMemo(() => {
|
|
30041
30166
|
const out = [];
|
|
30042
30167
|
const margin = 24;
|
|
@@ -30049,11 +30174,11 @@ var init_MathCanvas = __esm({
|
|
|
30049
30174
|
if (showGrid) {
|
|
30050
30175
|
for (let x = Math.ceil(xMin / gridStep) * gridStep; x <= xMax; x += gridStep) {
|
|
30051
30176
|
const px = mapX(x);
|
|
30052
|
-
out.push({ type: "line", x1: px, y1: margin, x2: px, y2: height - margin, color:
|
|
30177
|
+
out.push({ type: "line", x1: px, y1: margin, x2: px, y2: height - margin, color: gridColor, opacity: 0.35, lineWidth: 1 });
|
|
30053
30178
|
}
|
|
30054
30179
|
for (let y = Math.ceil(yMin / gridStep) * gridStep; y <= yMax; y += gridStep) {
|
|
30055
30180
|
const py = mapY(y);
|
|
30056
|
-
out.push({ type: "line", x1: margin, y1: py, x2: width - margin, y2: py, color:
|
|
30181
|
+
out.push({ type: "line", x1: margin, y1: py, x2: width - margin, y2: py, color: gridColor, opacity: 0.35, lineWidth: 1 });
|
|
30057
30182
|
}
|
|
30058
30183
|
}
|
|
30059
30184
|
if (showTickLabels) {
|
|
@@ -30124,8 +30249,8 @@ var init_MathCanvas = __esm({
|
|
|
30124
30249
|
});
|
|
30125
30250
|
}
|
|
30126
30251
|
if (showAxes) {
|
|
30127
|
-
out.push({ type: "line", x1: margin, y1: xAxisY, x2: width - margin, y2: xAxisY, color:
|
|
30128
|
-
out.push({ type: "line", x1: yAxisX, y1: margin, x2: yAxisX, y2: height - margin, color:
|
|
30252
|
+
out.push({ type: "line", x1: margin, y1: xAxisY, x2: width - margin, y2: xAxisY, color: axisColor, lineWidth: 2 });
|
|
30253
|
+
out.push({ type: "line", x1: yAxisX, y1: margin, x2: yAxisX, y2: height - margin, color: axisColor, lineWidth: 2 });
|
|
30129
30254
|
}
|
|
30130
30255
|
for (const guide of guides) {
|
|
30131
30256
|
const color = guide.color ?? "#9ca3af";
|
|
@@ -30148,23 +30273,36 @@ var init_MathCanvas = __esm({
|
|
|
30148
30273
|
}
|
|
30149
30274
|
for (const curve of curves) {
|
|
30150
30275
|
if (!curve.samples || curve.samples.length < 2) continue;
|
|
30276
|
+
let d = "";
|
|
30277
|
+
let penDown = false;
|
|
30151
30278
|
let lastInRange;
|
|
30152
30279
|
for (let i = 1; i < curve.samples.length; i++) {
|
|
30153
30280
|
const a = curve.samples[i - 1];
|
|
30154
30281
|
const b = curve.samples[i];
|
|
30155
|
-
if (a.x < xMin
|
|
30156
|
-
|
|
30157
|
-
|
|
30158
|
-
|
|
30159
|
-
|
|
30160
|
-
|
|
30161
|
-
|
|
30162
|
-
|
|
30163
|
-
|
|
30164
|
-
|
|
30165
|
-
|
|
30166
|
-
|
|
30167
|
-
|
|
30282
|
+
if (a.x < xMin && b.x < xMin || a.x > xMax && b.x > xMax) {
|
|
30283
|
+
penDown = false;
|
|
30284
|
+
continue;
|
|
30285
|
+
}
|
|
30286
|
+
const clip = (p, q, xLim) => {
|
|
30287
|
+
const t = q.x === p.x ? 0 : (xLim - p.x) / (q.x - p.x);
|
|
30288
|
+
return { x: xLim, y: p.y + t * (q.y - p.y) };
|
|
30289
|
+
};
|
|
30290
|
+
const ca = a.x < xMin ? clip(a, b, xMin) : a.x > xMax ? clip(a, b, xMax) : a;
|
|
30291
|
+
const cb = b.x < xMin ? clip(a, b, xMin) : b.x > xMax ? clip(a, b, xMax) : b;
|
|
30292
|
+
const pax = mapX(ca.x);
|
|
30293
|
+
const pay = mapY(ca.y);
|
|
30294
|
+
d += `${penDown ? "L" : "M"} ${pax} ${pay} L ${mapX(cb.x)} ${mapY(cb.y)} `;
|
|
30295
|
+
penDown = true;
|
|
30296
|
+
if (b.x >= xMin && b.x <= xMax) lastInRange = b;
|
|
30297
|
+
}
|
|
30298
|
+
if (!d) continue;
|
|
30299
|
+
out.push({
|
|
30300
|
+
type: "path",
|
|
30301
|
+
path: d,
|
|
30302
|
+
color: curve.color ?? "#2563eb",
|
|
30303
|
+
lineWidth: 2,
|
|
30304
|
+
dash: curve.dash
|
|
30305
|
+
});
|
|
30168
30306
|
if (showCurveLabels && curve.label && lastInRange) {
|
|
30169
30307
|
out.push({
|
|
30170
30308
|
type: "text",
|
|
@@ -30279,6 +30417,8 @@ var init_MathCanvas = __esm({
|
|
|
30279
30417
|
showAxes,
|
|
30280
30418
|
showGrid,
|
|
30281
30419
|
gridStep,
|
|
30420
|
+
gridColor,
|
|
30421
|
+
axisColor,
|
|
30282
30422
|
showTickLabels,
|
|
30283
30423
|
showCurveLabels,
|
|
30284
30424
|
curves,
|
|
@@ -30298,6 +30438,7 @@ var init_MathCanvas = __esm({
|
|
|
30298
30438
|
{
|
|
30299
30439
|
width,
|
|
30300
30440
|
height,
|
|
30441
|
+
backgroundColor,
|
|
30301
30442
|
shapes: derivedShapes,
|
|
30302
30443
|
readouts,
|
|
30303
30444
|
traces,
|
|
@@ -42319,6 +42460,9 @@ function determineInputType(field) {
|
|
|
42319
42460
|
if (field.type === "relation" || field.relation) {
|
|
42320
42461
|
return "relation";
|
|
42321
42462
|
}
|
|
42463
|
+
if (field.type === "array") {
|
|
42464
|
+
return "array";
|
|
42465
|
+
}
|
|
42322
42466
|
if (field.type === "enum" || field.values || getEnumOptions(field).length > 0) {
|
|
42323
42467
|
return "select";
|
|
42324
42468
|
}
|
|
@@ -42394,6 +42538,7 @@ var init_Form = __esm({
|
|
|
42394
42538
|
init_Typography();
|
|
42395
42539
|
init_Icon();
|
|
42396
42540
|
init_RelationSelect();
|
|
42541
|
+
init_TagInput();
|
|
42397
42542
|
init_UploadDropZone();
|
|
42398
42543
|
init_Alert();
|
|
42399
42544
|
init_useEventBus();
|
|
@@ -42473,7 +42618,7 @@ var init_Form = __esm({
|
|
|
42473
42618
|
values: "values" in f3 ? f3.values : void 0,
|
|
42474
42619
|
min: f3.min,
|
|
42475
42620
|
max: f3.max,
|
|
42476
|
-
relation: "relation" in f3 ? { entity: f3.relation.entity } : void 0
|
|
42621
|
+
relation: "relation" in f3 ? { entity: f3.relation.entity, cardinality: f3.relation.cardinality } : void 0
|
|
42477
42622
|
})
|
|
42478
42623
|
);
|
|
42479
42624
|
}, [entity, fields]);
|
|
@@ -42708,7 +42853,7 @@ var init_Form = __esm({
|
|
|
42708
42853
|
values: "values" in entityField ? entityField.values : void 0,
|
|
42709
42854
|
min: entityField.min,
|
|
42710
42855
|
max: entityField.max,
|
|
42711
|
-
relation: "relation" in entityField ? { entity: entityField.relation.entity } : void 0
|
|
42856
|
+
relation: "relation" in entityField ? { entity: entityField.relation.entity, cardinality: entityField.relation.cardinality } : void 0
|
|
42712
42857
|
};
|
|
42713
42858
|
}
|
|
42714
42859
|
return { name: field, type: "string" };
|
|
@@ -42820,6 +42965,22 @@ var init_Form = __esm({
|
|
|
42820
42965
|
case "relation": {
|
|
42821
42966
|
const relationOptions = relationsData[fieldName] || [];
|
|
42822
42967
|
const relationLoading = relationsLoading[fieldName] || false;
|
|
42968
|
+
if (field.relation?.cardinality !== void 0 && MANY_CARDINALITIES.includes(field.relation.cardinality)) {
|
|
42969
|
+
const selectedValues = Array.isArray(currentValue) ? currentValue.map((v) => String(v)) : [];
|
|
42970
|
+
return /* @__PURE__ */ jsx(
|
|
42971
|
+
Select,
|
|
42972
|
+
{
|
|
42973
|
+
...commonProps,
|
|
42974
|
+
multiple: true,
|
|
42975
|
+
searchable: true,
|
|
42976
|
+
clearable: true,
|
|
42977
|
+
options: [...relationOptions],
|
|
42978
|
+
value: selectedValues,
|
|
42979
|
+
onValueChange: (value) => handleChange(fieldName, Array.isArray(value) ? value : [value]),
|
|
42980
|
+
placeholder: field.placeholder || `Select ${label}...`
|
|
42981
|
+
}
|
|
42982
|
+
);
|
|
42983
|
+
}
|
|
42823
42984
|
return /* @__PURE__ */ jsx(
|
|
42824
42985
|
RelationSelect,
|
|
42825
42986
|
{
|
|
@@ -42834,6 +42995,18 @@ var init_Form = __esm({
|
|
|
42834
42995
|
}
|
|
42835
42996
|
);
|
|
42836
42997
|
}
|
|
42998
|
+
case "array": {
|
|
42999
|
+
const arrayValue = Array.isArray(currentValue) ? currentValue.map((v) => String(v)) : currentValue != null && currentValue !== "" ? [String(currentValue)] : [];
|
|
43000
|
+
return /* @__PURE__ */ jsx(
|
|
43001
|
+
TagInput,
|
|
43002
|
+
{
|
|
43003
|
+
placeholder: field.placeholder,
|
|
43004
|
+
disabled: isLoading,
|
|
43005
|
+
value: arrayValue,
|
|
43006
|
+
onChange: (next) => handleChange(fieldName, [...next])
|
|
43007
|
+
}
|
|
43008
|
+
);
|
|
43009
|
+
}
|
|
42837
43010
|
case "number":
|
|
42838
43011
|
return /* @__PURE__ */ jsx(
|
|
42839
43012
|
Input,
|
|
@@ -48402,7 +48575,10 @@ function enrichFormFields(fields, entityDef) {
|
|
|
48402
48575
|
enriched.values = entityField.enumValues;
|
|
48403
48576
|
}
|
|
48404
48577
|
if (entityField.relation) {
|
|
48405
|
-
enriched.relation =
|
|
48578
|
+
enriched.relation = {
|
|
48579
|
+
entity: entityField.relation.entity,
|
|
48580
|
+
cardinality: entityField.relation.cardinality
|
|
48581
|
+
};
|
|
48406
48582
|
}
|
|
48407
48583
|
return enriched;
|
|
48408
48584
|
}
|
|
@@ -48430,7 +48606,10 @@ function enrichFormFields(fields, entityDef) {
|
|
|
48430
48606
|
}
|
|
48431
48607
|
}
|
|
48432
48608
|
if (!obj.relation && entityField.relation) {
|
|
48433
|
-
enriched.relation =
|
|
48609
|
+
enriched.relation = {
|
|
48610
|
+
entity: entityField.relation.entity,
|
|
48611
|
+
cardinality: entityField.relation.cardinality
|
|
48612
|
+
};
|
|
48434
48613
|
}
|
|
48435
48614
|
return enriched;
|
|
48436
48615
|
}
|
|
@@ -48445,7 +48624,12 @@ function enrichDetailFields(fields, entityDef) {
|
|
|
48445
48624
|
const meta = { type: entityField.type };
|
|
48446
48625
|
const values = entityField.values ?? entityField.enumValues;
|
|
48447
48626
|
if (values && values.length > 0) meta.values = values;
|
|
48448
|
-
if (entityField.relation)
|
|
48627
|
+
if (entityField.relation) {
|
|
48628
|
+
meta.relation = {
|
|
48629
|
+
entity: entityField.relation.entity,
|
|
48630
|
+
cardinality: entityField.relation.cardinality
|
|
48631
|
+
};
|
|
48632
|
+
}
|
|
48449
48633
|
return meta;
|
|
48450
48634
|
};
|
|
48451
48635
|
return fields.map((field) => {
|
|
@@ -48999,6 +49183,32 @@ function isPlainConfigObject(value) {
|
|
|
48999
49183
|
const proto = Object.getPrototypeOf(value);
|
|
49000
49184
|
return proto === Object.prototype || proto === null;
|
|
49001
49185
|
}
|
|
49186
|
+
function subtreeHasTraitRef(value) {
|
|
49187
|
+
const cached = traitRefPresenceCache.get(value);
|
|
49188
|
+
if (cached !== void 0) return cached;
|
|
49189
|
+
let found = false;
|
|
49190
|
+
const children = Array.isArray(value) ? value : Object.values(value);
|
|
49191
|
+
for (const child of children) {
|
|
49192
|
+
if (typeof child === "string" && TRAIT_BINDING_RE.test(child)) {
|
|
49193
|
+
found = true;
|
|
49194
|
+
break;
|
|
49195
|
+
}
|
|
49196
|
+
if (isRenderBindingMarker(child)) continue;
|
|
49197
|
+
if (Array.isArray(child)) {
|
|
49198
|
+
if (subtreeHasTraitRef(child)) {
|
|
49199
|
+
found = true;
|
|
49200
|
+
break;
|
|
49201
|
+
}
|
|
49202
|
+
} else if (child !== null && typeof child === "object" && isPlainConfigObject(child)) {
|
|
49203
|
+
if (subtreeHasTraitRef(child)) {
|
|
49204
|
+
found = true;
|
|
49205
|
+
break;
|
|
49206
|
+
}
|
|
49207
|
+
}
|
|
49208
|
+
}
|
|
49209
|
+
traitRefPresenceCache.set(value, found);
|
|
49210
|
+
return found;
|
|
49211
|
+
}
|
|
49002
49212
|
function substituteTraitRefsDeep(value, pathKey) {
|
|
49003
49213
|
if (isRenderBindingMarker(value)) return value;
|
|
49004
49214
|
if (typeof value === "string") {
|
|
@@ -49013,11 +49223,13 @@ function substituteTraitRefsDeep(value, pathKey) {
|
|
|
49013
49223
|
return value;
|
|
49014
49224
|
}
|
|
49015
49225
|
if (Array.isArray(value)) {
|
|
49226
|
+
if (!subtreeHasTraitRef(value)) return value;
|
|
49016
49227
|
return value.map(
|
|
49017
49228
|
(item, i) => substituteTraitRefsDeep(item, `${pathKey}[${i}]`)
|
|
49018
49229
|
);
|
|
49019
49230
|
}
|
|
49020
49231
|
if (typeof value === "object" && isPlainConfigObject(value)) {
|
|
49232
|
+
if (!subtreeHasTraitRef(value)) return value;
|
|
49021
49233
|
const out = {};
|
|
49022
49234
|
for (const [k, v] of Object.entries(value)) {
|
|
49023
49235
|
out[k] = substituteTraitRefsDeep(v, `${pathKey}.${k}`);
|
|
@@ -49306,7 +49518,7 @@ function UISlotRenderer({
|
|
|
49306
49518
|
}
|
|
49307
49519
|
return wrapped;
|
|
49308
49520
|
}
|
|
49309
|
-
var scopeWrapLog, TRAIT_BINDING_RE, SuspenseConfigContext, SlotContainedContext, SLOT_SKELETON_MAP, SELF_OVERLAY_PATTERNS, CONTENT_NODE_SLOTS, PATTERNS_WITH_CHILDREN;
|
|
49521
|
+
var scopeWrapLog, TRAIT_BINDING_RE, SuspenseConfigContext, SlotContainedContext, SLOT_SKELETON_MAP, SELF_OVERLAY_PATTERNS, CONTENT_NODE_SLOTS, PATTERNS_WITH_CHILDREN, traitRefPresenceCache;
|
|
49310
49522
|
var init_UISlotRenderer = __esm({
|
|
49311
49523
|
"components/core/organisms/UISlotRenderer.tsx"() {
|
|
49312
49524
|
"use client";
|
|
@@ -49380,6 +49592,7 @@ var init_UISlotRenderer = __esm({
|
|
|
49380
49592
|
"alert",
|
|
49381
49593
|
"dialog"
|
|
49382
49594
|
]);
|
|
49595
|
+
traitRefPresenceCache = /* @__PURE__ */ new WeakMap();
|
|
49383
49596
|
UISlotRenderer.displayName = "UISlotRenderer";
|
|
49384
49597
|
}
|
|
49385
49598
|
});
|
|
@@ -49507,6 +49720,20 @@ function createClientEffectHandlers(options) {
|
|
|
49507
49720
|
})
|
|
49508
49721
|
};
|
|
49509
49722
|
}
|
|
49723
|
+
|
|
49724
|
+
// lib/event-queue-coalesce.ts
|
|
49725
|
+
function enqueueEvent(queue, entry) {
|
|
49726
|
+
if (entry.tick !== void 0) {
|
|
49727
|
+
const pending = queue.find(
|
|
49728
|
+
(e) => e.tick !== void 0 && e.eventKey === entry.eventKey && e.targetTrait === entry.targetTrait
|
|
49729
|
+
);
|
|
49730
|
+
if (pending !== void 0) {
|
|
49731
|
+
pending.payload = entry.payload;
|
|
49732
|
+
return;
|
|
49733
|
+
}
|
|
49734
|
+
}
|
|
49735
|
+
queue.push(entry);
|
|
49736
|
+
}
|
|
49510
49737
|
var lambdaLog = createLogger("almadar:ui:fn-form-lambda");
|
|
49511
49738
|
function isOperatorCall(value) {
|
|
49512
49739
|
const first = value[0];
|
|
@@ -50252,12 +50479,13 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
50252
50479
|
entityId
|
|
50253
50480
|
};
|
|
50254
50481
|
const emittedDuringExec = [];
|
|
50482
|
+
const tickName = flushEvent.startsWith("tick:") ? flushEvent.slice(5) : void 0;
|
|
50255
50483
|
const baseEmit = handlers.emit;
|
|
50256
50484
|
const trackingHandlers = {
|
|
50257
50485
|
...handlers,
|
|
50258
50486
|
emit: (event, eventPayload, source) => {
|
|
50259
50487
|
emittedDuringExec.push(event);
|
|
50260
|
-
baseEmit(event, eventPayload, source);
|
|
50488
|
+
baseEmit(event, eventPayload, tickName !== void 0 ? { ...source, tick: tickName } : source);
|
|
50261
50489
|
}
|
|
50262
50490
|
};
|
|
50263
50491
|
if (traitName === "Hero") {
|
|
@@ -50416,7 +50644,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
50416
50644
|
}
|
|
50417
50645
|
return () => scheduler.stopAll();
|
|
50418
50646
|
}, [traitBindings, runTickEffects, sharedGroups, sharedEntityStore, emitFromSharedWriter]);
|
|
50419
|
-
const processEventQueued = useCallback(async (eventKey, payload, targetTrait) => {
|
|
50647
|
+
const processEventQueued = useCallback(async (eventKey, payload, targetTrait, tick, sourceTrait) => {
|
|
50420
50648
|
const normalizedEvent = normalizeEventKey(eventKey);
|
|
50421
50649
|
const bindings = traitBindingsRef.current;
|
|
50422
50650
|
const currentManager = managerRef.current;
|
|
@@ -50605,7 +50833,11 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
50605
50833
|
if (orbital) dispatchedOrbitals.add(orbital);
|
|
50606
50834
|
}
|
|
50607
50835
|
const relayPayload = targetTrait !== void 0 ? { ...payload ?? {}, _targetTrait: targetTrait } : payload;
|
|
50608
|
-
|
|
50836
|
+
if (tick !== void 0) {
|
|
50837
|
+
void onEventProcessed(normalizedEvent, relayPayload, dispatchedOrbitals, tick, sourceTrait);
|
|
50838
|
+
} else {
|
|
50839
|
+
await onEventProcessed(normalizedEvent, relayPayload, dispatchedOrbitals);
|
|
50840
|
+
}
|
|
50609
50841
|
}
|
|
50610
50842
|
}, [entities, eventBus, sharedEntityStore]);
|
|
50611
50843
|
const drainEventQueue = useCallback(async () => {
|
|
@@ -50614,14 +50846,14 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
50614
50846
|
try {
|
|
50615
50847
|
while (eventQueueRef.current.length > 0) {
|
|
50616
50848
|
const entry = eventQueueRef.current.shift();
|
|
50617
|
-
await processEventQueued(entry.eventKey, entry.payload, entry.targetTrait);
|
|
50849
|
+
await processEventQueued(entry.eventKey, entry.payload, entry.targetTrait, entry.tick, entry.sourceTrait);
|
|
50618
50850
|
}
|
|
50619
50851
|
} finally {
|
|
50620
50852
|
processingRef.current = false;
|
|
50621
50853
|
}
|
|
50622
50854
|
}, [processEventQueued]);
|
|
50623
|
-
const enqueueAndDrain = useCallback((eventKey, payload, targetTrait) => {
|
|
50624
|
-
eventQueueRef.current
|
|
50855
|
+
const enqueueAndDrain = useCallback((eventKey, payload, targetTrait, tick, sourceTrait) => {
|
|
50856
|
+
enqueueEvent(eventQueueRef.current, { eventKey, payload, targetTrait, tick, sourceTrait });
|
|
50625
50857
|
void drainEventQueue();
|
|
50626
50858
|
}, [drainEventQueue]);
|
|
50627
50859
|
useCallback((eventKey, payload) => {
|
|
@@ -50674,7 +50906,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
50674
50906
|
crossTraitLog.debug("self:fire-server-cascade", { traitName, busKey: selfBusKey, eventKey });
|
|
50675
50907
|
}
|
|
50676
50908
|
crossTraitLog.debug("self:fire", { traitName, busKey: selfBusKey, eventKey });
|
|
50677
|
-
enqueueAndDrain(eventKey, event.payload, traitName);
|
|
50909
|
+
enqueueAndDrain(eventKey, event.payload, traitName, event.source?.tick, event.source?.trait);
|
|
50678
50910
|
});
|
|
50679
50911
|
unsubscribes.push(() => {
|
|
50680
50912
|
crossTraitLog.debug("self:unsubscribe", { traitName, busKey: selfBusKey, eventKey });
|
|
@@ -50692,7 +50924,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
50692
50924
|
const bareKey = `UI:${eventKey}`;
|
|
50693
50925
|
const unsub = eventBus.on(bareKey, (event) => {
|
|
50694
50926
|
crossTraitLog.debug("bare-cascade:fire", { bareKey, eventKey });
|
|
50695
|
-
enqueueAndDrain(eventKey, event.payload);
|
|
50927
|
+
enqueueAndDrain(eventKey, event.payload, void 0, event.source?.tick, event.source?.trait);
|
|
50696
50928
|
});
|
|
50697
50929
|
unsubscribes.push(() => {
|
|
50698
50930
|
crossTraitLog.debug("bare-cascade:unsubscribe", { bareKey, eventKey });
|
|
@@ -50726,7 +50958,9 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
50726
50958
|
enqueueAndDrain(
|
|
50727
50959
|
listen.triggers,
|
|
50728
50960
|
applyListenPayloadMapping(listen.payloadMapping, event.payload, evaluateListenPayloadExpr),
|
|
50729
|
-
binding.trait.name
|
|
50961
|
+
binding.trait.name,
|
|
50962
|
+
event.source?.tick,
|
|
50963
|
+
event.source?.trait
|
|
50730
50964
|
);
|
|
50731
50965
|
});
|
|
50732
50966
|
unsubscribes.push(() => {
|
|
@@ -51021,7 +51255,7 @@ function TraitInitializer({ traits: traits2, routeParams, orbitalNames, onNaviga
|
|
|
51021
51255
|
[serverActiveTraits]
|
|
51022
51256
|
);
|
|
51023
51257
|
const uiSlots = useUISlots();
|
|
51024
|
-
const onEventProcessed = useCallback(async (event, payload, dispatchedOrbitals) => {
|
|
51258
|
+
const onEventProcessed = useCallback(async (event, payload, dispatchedOrbitals, tick, sourceTrait) => {
|
|
51025
51259
|
if (!bridge.connected || !orbitalNames?.length) return;
|
|
51026
51260
|
const targets = dispatchedOrbitals && dispatchedOrbitals.size > 0 ? orbitalNames.filter((n) => dispatchedOrbitals.has(n)) : orbitalNames;
|
|
51027
51261
|
xOrbitalLog.debug("TraitInitializer:fanout", () => ({
|
|
@@ -51031,6 +51265,10 @@ function TraitInitializer({ traits: traits2, routeParams, orbitalNames, onNaviga
|
|
|
51031
51265
|
dispatchedOrbitalsSize: dispatchedOrbitals?.size ?? 0
|
|
51032
51266
|
}));
|
|
51033
51267
|
for (const name of targets) {
|
|
51268
|
+
if (tick !== void 0) {
|
|
51269
|
+
void bridge.sendEvent(name, event, withActiveTraits(payload), tick, sourceTrait);
|
|
51270
|
+
continue;
|
|
51271
|
+
}
|
|
51034
51272
|
const { effects, meta } = await bridge.sendEvent(name, event, withActiveTraits(payload));
|
|
51035
51273
|
recordServerResponse(name, event, meta);
|
|
51036
51274
|
applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits, activeTraitNames, onNavigateBack);
|
|
@@ -51506,11 +51744,13 @@ function BrowserPlayground({
|
|
|
51506
51744
|
unregister: async () => {
|
|
51507
51745
|
runtime.unregisterAll();
|
|
51508
51746
|
},
|
|
51509
|
-
sendEvent: async (orbitalName, event, payload) => {
|
|
51747
|
+
sendEvent: async (orbitalName, event, payload, _clientId, tick, sourceTrait) => {
|
|
51510
51748
|
await registrationReady;
|
|
51511
51749
|
return runtime.processOrbitalEvent(orbitalName, {
|
|
51512
51750
|
event,
|
|
51513
|
-
payload
|
|
51751
|
+
payload,
|
|
51752
|
+
tick,
|
|
51753
|
+
sourceTrait
|
|
51514
51754
|
// @almadar/runtime OrbitalEventResponse.clientEffects uses a wider ClientEffectTuple than
|
|
51515
51755
|
// ServerBridge's local definition — cast at this boundary (upstream fix queued).
|
|
51516
51756
|
});
|