@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/avl/index.cjs
CHANGED
|
@@ -4664,11 +4664,32 @@ function isPlainObject(value) {
|
|
|
4664
4664
|
if (typeof value === "function") return false;
|
|
4665
4665
|
return true;
|
|
4666
4666
|
}
|
|
4667
|
+
function subtreeHasMarker(value) {
|
|
4668
|
+
const cached = markerPresenceCache.get(value);
|
|
4669
|
+
if (cached !== void 0) return cached;
|
|
4670
|
+
let found = false;
|
|
4671
|
+
const children = Array.isArray(value) ? value : Object.values(value);
|
|
4672
|
+
for (const child of children) {
|
|
4673
|
+
if (core.isRenderBindingMarker(child)) {
|
|
4674
|
+
found = true;
|
|
4675
|
+
break;
|
|
4676
|
+
}
|
|
4677
|
+
if (Array.isArray(child) || isPlainObject(child)) {
|
|
4678
|
+
if (subtreeHasMarker(child)) {
|
|
4679
|
+
found = true;
|
|
4680
|
+
break;
|
|
4681
|
+
}
|
|
4682
|
+
}
|
|
4683
|
+
}
|
|
4684
|
+
markerPresenceCache.set(value, found);
|
|
4685
|
+
return found;
|
|
4686
|
+
}
|
|
4667
4687
|
function walkValue(value, scopeTrait, entity, config, state) {
|
|
4668
4688
|
if (core.isRenderBindingMarker(value)) {
|
|
4669
4689
|
return { resolved: resolveMarkerExpression(value.expression, entity, config, state), changed: true };
|
|
4670
4690
|
}
|
|
4671
4691
|
if (Array.isArray(value)) {
|
|
4692
|
+
if (!subtreeHasMarker(value)) return { resolved: value, changed: false };
|
|
4672
4693
|
const out = [];
|
|
4673
4694
|
let changed = false;
|
|
4674
4695
|
for (const item of value) {
|
|
@@ -4686,6 +4707,7 @@ function walkValue(value, scopeTrait, entity, config, state) {
|
|
|
4686
4707
|
return changed ? { resolved: out, changed: true } : { resolved: value, changed: false };
|
|
4687
4708
|
}
|
|
4688
4709
|
if (isPlainObject(value)) {
|
|
4710
|
+
if (!subtreeHasMarker(value)) return { resolved: value, changed: false };
|
|
4689
4711
|
const sourceTrait = value._sourceTrait;
|
|
4690
4712
|
if (typeof sourceTrait === "string" && sourceTrait !== scopeTrait) {
|
|
4691
4713
|
return { resolved: value, changed: false };
|
|
@@ -4711,9 +4733,11 @@ function resolveRenderBindingMarkers(props, scopeTrait, entity, config, state) {
|
|
|
4711
4733
|
}
|
|
4712
4734
|
return changed ? out : props;
|
|
4713
4735
|
}
|
|
4736
|
+
var markerPresenceCache;
|
|
4714
4737
|
var init_resolve_render_bindings = __esm({
|
|
4715
4738
|
"lib/resolve-render-bindings.ts"() {
|
|
4716
4739
|
"use client";
|
|
4740
|
+
markerPresenceCache = /* @__PURE__ */ new WeakMap();
|
|
4717
4741
|
}
|
|
4718
4742
|
});
|
|
4719
4743
|
function getCurrentIconFamily() {
|
|
@@ -15511,6 +15535,8 @@ function drawShape(ctx, shape, width, height, allShapes) {
|
|
|
15511
15535
|
case "path": {
|
|
15512
15536
|
if (!shape.path) break;
|
|
15513
15537
|
const p = new Path2D(shape.path);
|
|
15538
|
+
ctx.lineJoin = "round";
|
|
15539
|
+
ctx.lineCap = "round";
|
|
15514
15540
|
if (fill) {
|
|
15515
15541
|
ctx.fillStyle = fill;
|
|
15516
15542
|
ctx.fill(p);
|
|
@@ -15719,7 +15745,7 @@ var init_LearningCanvas = __esm({
|
|
|
15719
15745
|
ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
|
|
15720
15746
|
ctx.clearRect(0, 0, width, height);
|
|
15721
15747
|
if (backgroundColor) {
|
|
15722
|
-
ctx.fillStyle = backgroundColor;
|
|
15748
|
+
ctx.fillStyle = resolveColor2(backgroundColor, ctx, backgroundColor);
|
|
15723
15749
|
ctx.fillRect(0, 0, width, height);
|
|
15724
15750
|
}
|
|
15725
15751
|
for (const shape of derivedShapes) {
|
|
@@ -29705,7 +29731,7 @@ function fileIcon(name) {
|
|
|
29705
29731
|
return "file";
|
|
29706
29732
|
}
|
|
29707
29733
|
}
|
|
29708
|
-
var TreeNodeItem, FileTree;
|
|
29734
|
+
var TreeNodeItem, FlatTreeNodeItem, FileTree;
|
|
29709
29735
|
var init_FileTree = __esm({
|
|
29710
29736
|
"components/core/molecules/FileTree.tsx"() {
|
|
29711
29737
|
"use client";
|
|
@@ -29790,14 +29816,101 @@ var init_FileTree = __esm({
|
|
|
29790
29816
|
)) })
|
|
29791
29817
|
] });
|
|
29792
29818
|
};
|
|
29819
|
+
FlatTreeNodeItem = ({
|
|
29820
|
+
item,
|
|
29821
|
+
depth,
|
|
29822
|
+
indent,
|
|
29823
|
+
childrenByParent,
|
|
29824
|
+
onNodeSelect,
|
|
29825
|
+
defaultExpanded = false
|
|
29826
|
+
}) => {
|
|
29827
|
+
const [expanded, setExpanded] = React94.useState(defaultExpanded || depth < 1);
|
|
29828
|
+
const children = childrenByParent.get(item.id);
|
|
29829
|
+
const hasChildren = !!children && children.length > 0;
|
|
29830
|
+
const handleClick = React94.useCallback(() => {
|
|
29831
|
+
if (hasChildren) setExpanded((prev) => !prev);
|
|
29832
|
+
onNodeSelect?.(item.id);
|
|
29833
|
+
}, [hasChildren, item.id, onNodeSelect]);
|
|
29834
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
29835
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
29836
|
+
Box,
|
|
29837
|
+
{
|
|
29838
|
+
className: "flex items-center gap-1.5 py-0.5 px-2 cursor-pointer rounded-sm transition-colors hover:bg-muted",
|
|
29839
|
+
style: { paddingLeft: depth * indent + 8 },
|
|
29840
|
+
onClick: handleClick,
|
|
29841
|
+
role: "treeitem",
|
|
29842
|
+
"aria-expanded": hasChildren ? expanded : void 0,
|
|
29843
|
+
children: [
|
|
29844
|
+
hasChildren ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
29845
|
+
Icon,
|
|
29846
|
+
{
|
|
29847
|
+
name: expanded ? "chevron-down" : "chevron-right",
|
|
29848
|
+
size: "xs",
|
|
29849
|
+
className: "text-[var(--color-muted-foreground)] flex-shrink-0"
|
|
29850
|
+
}
|
|
29851
|
+
) : /* @__PURE__ */ jsxRuntime.jsx(Box, { style: { width: 12, flexShrink: 0 } }),
|
|
29852
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
29853
|
+
Icon,
|
|
29854
|
+
{
|
|
29855
|
+
name: item.icon ?? (hasChildren ? expanded ? "folder-open" : "folder" : "file"),
|
|
29856
|
+
size: "xs",
|
|
29857
|
+
className: hasChildren ? "text-[var(--color-warning)]" : "text-[var(--color-muted-foreground)]"
|
|
29858
|
+
}
|
|
29859
|
+
),
|
|
29860
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "caption", className: "truncate font-mono text-xs", children: item.label })
|
|
29861
|
+
]
|
|
29862
|
+
}
|
|
29863
|
+
),
|
|
29864
|
+
hasChildren && expanded && /* @__PURE__ */ jsxRuntime.jsx(Box, { role: "group", children: children.map((child) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
29865
|
+
FlatTreeNodeItem,
|
|
29866
|
+
{
|
|
29867
|
+
item: child,
|
|
29868
|
+
depth: depth + 1,
|
|
29869
|
+
indent,
|
|
29870
|
+
childrenByParent,
|
|
29871
|
+
onNodeSelect
|
|
29872
|
+
},
|
|
29873
|
+
child.id
|
|
29874
|
+
)) })
|
|
29875
|
+
] });
|
|
29876
|
+
};
|
|
29793
29877
|
FileTree = ({
|
|
29794
29878
|
tree,
|
|
29879
|
+
items,
|
|
29795
29880
|
selectedPath,
|
|
29796
29881
|
onFileSelect,
|
|
29882
|
+
onNodeSelect,
|
|
29797
29883
|
className,
|
|
29798
29884
|
indent = 16
|
|
29799
29885
|
}) => {
|
|
29800
|
-
if (
|
|
29886
|
+
if (items) {
|
|
29887
|
+
if (items.length === 0) return null;
|
|
29888
|
+
const ids = new Set(items.map((node) => node.id));
|
|
29889
|
+
const childrenByParent = /* @__PURE__ */ new Map();
|
|
29890
|
+
const roots = [];
|
|
29891
|
+
for (const item of items) {
|
|
29892
|
+
if (item.parentId && ids.has(item.parentId)) {
|
|
29893
|
+
const siblings = childrenByParent.get(item.parentId);
|
|
29894
|
+
if (siblings) siblings.push(item);
|
|
29895
|
+
else childrenByParent.set(item.parentId, [item]);
|
|
29896
|
+
} else {
|
|
29897
|
+
roots.push(item);
|
|
29898
|
+
}
|
|
29899
|
+
}
|
|
29900
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Box, { className: `py-1 overflow-y-auto ${className ?? ""}`, role: "tree", children: roots.map((item) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
29901
|
+
FlatTreeNodeItem,
|
|
29902
|
+
{
|
|
29903
|
+
item,
|
|
29904
|
+
depth: 0,
|
|
29905
|
+
indent,
|
|
29906
|
+
childrenByParent,
|
|
29907
|
+
onNodeSelect,
|
|
29908
|
+
defaultExpanded: true
|
|
29909
|
+
},
|
|
29910
|
+
item.id
|
|
29911
|
+
)) });
|
|
29912
|
+
}
|
|
29913
|
+
if (!tree || tree.length === 0) return null;
|
|
29801
29914
|
return /* @__PURE__ */ jsxRuntime.jsx(Box, { className: `py-1 overflow-y-auto ${className ?? ""}`, role: "tree", children: tree.map((node) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
29802
29915
|
TreeNodeItem,
|
|
29803
29916
|
{
|
|
@@ -31192,7 +31305,7 @@ var init_debug = __esm({
|
|
|
31192
31305
|
logger.createLogger("almadar:ui:debug:game-state");
|
|
31193
31306
|
}
|
|
31194
31307
|
});
|
|
31195
|
-
var isRelationsDebugEnabled, RelationSelect;
|
|
31308
|
+
var isRelationsDebugEnabled, MANY_CARDINALITIES, RelationSelect;
|
|
31196
31309
|
var init_RelationSelect = __esm({
|
|
31197
31310
|
"components/core/molecules/RelationSelect.tsx"() {
|
|
31198
31311
|
"use client";
|
|
@@ -31206,6 +31319,11 @@ var init_RelationSelect = __esm({
|
|
|
31206
31319
|
init_Typography();
|
|
31207
31320
|
init_debug();
|
|
31208
31321
|
isRelationsDebugEnabled = () => isDebugEnabled();
|
|
31322
|
+
MANY_CARDINALITIES = [
|
|
31323
|
+
"many",
|
|
31324
|
+
"one-to-many",
|
|
31325
|
+
"many-to-many"
|
|
31326
|
+
];
|
|
31209
31327
|
RelationSelect = ({
|
|
31210
31328
|
value,
|
|
31211
31329
|
onChange,
|
|
@@ -32845,6 +32963,9 @@ var init_MathCanvas = __esm({
|
|
|
32845
32963
|
showAxes = true,
|
|
32846
32964
|
showGrid = true,
|
|
32847
32965
|
gridStep = 1,
|
|
32966
|
+
backgroundColor,
|
|
32967
|
+
gridColor = "var(--color-border, #9ca3af)",
|
|
32968
|
+
axisColor = "var(--color-muted-foreground, #374151)",
|
|
32848
32969
|
showTickLabels = false,
|
|
32849
32970
|
showCurveLabels = false,
|
|
32850
32971
|
curves = [],
|
|
@@ -32867,17 +32988,21 @@ var init_MathCanvas = __esm({
|
|
|
32867
32988
|
error
|
|
32868
32989
|
}) => {
|
|
32869
32990
|
const eventBus = useEventBus();
|
|
32991
|
+
const keyMapKey = keyMap ? JSON.stringify(keyMap) : null;
|
|
32992
|
+
const keyUpMapKey = keyUpMap ? JSON.stringify(keyUpMap) : null;
|
|
32993
|
+
const stableKeyMap = React94.useMemo(() => keyMap, [keyMapKey]);
|
|
32994
|
+
const stableKeyUpMap = React94.useMemo(() => keyUpMap, [keyUpMapKey]);
|
|
32870
32995
|
React94.useEffect(() => {
|
|
32871
|
-
if (!
|
|
32996
|
+
if (!stableKeyMap && !stableKeyUpMap) return;
|
|
32872
32997
|
const onDown = (e) => {
|
|
32873
|
-
const ev =
|
|
32998
|
+
const ev = stableKeyMap?.[e.code];
|
|
32874
32999
|
if (ev) {
|
|
32875
33000
|
eventBus.emit(`UI:${ev}`, {});
|
|
32876
33001
|
e.preventDefault();
|
|
32877
33002
|
}
|
|
32878
33003
|
};
|
|
32879
33004
|
const onUp = (e) => {
|
|
32880
|
-
const ev =
|
|
33005
|
+
const ev = stableKeyUpMap?.[e.code];
|
|
32881
33006
|
if (ev) eventBus.emit(`UI:${ev}`, {});
|
|
32882
33007
|
};
|
|
32883
33008
|
window.addEventListener("keydown", onDown);
|
|
@@ -32886,7 +33011,7 @@ var init_MathCanvas = __esm({
|
|
|
32886
33011
|
window.removeEventListener("keydown", onDown);
|
|
32887
33012
|
window.removeEventListener("keyup", onUp);
|
|
32888
33013
|
};
|
|
32889
|
-
}, [
|
|
33014
|
+
}, [stableKeyMap, stableKeyUpMap, eventBus]);
|
|
32890
33015
|
const derivedShapes = React94.useMemo(() => {
|
|
32891
33016
|
const out = [];
|
|
32892
33017
|
const margin = 24;
|
|
@@ -32899,11 +33024,11 @@ var init_MathCanvas = __esm({
|
|
|
32899
33024
|
if (showGrid) {
|
|
32900
33025
|
for (let x = Math.ceil(xMin / gridStep) * gridStep; x <= xMax; x += gridStep) {
|
|
32901
33026
|
const px = mapX(x);
|
|
32902
|
-
out.push({ type: "line", x1: px, y1: margin, x2: px, y2: height - margin, color:
|
|
33027
|
+
out.push({ type: "line", x1: px, y1: margin, x2: px, y2: height - margin, color: gridColor, opacity: 0.35, lineWidth: 1 });
|
|
32903
33028
|
}
|
|
32904
33029
|
for (let y = Math.ceil(yMin / gridStep) * gridStep; y <= yMax; y += gridStep) {
|
|
32905
33030
|
const py = mapY(y);
|
|
32906
|
-
out.push({ type: "line", x1: margin, y1: py, x2: width - margin, y2: py, color:
|
|
33031
|
+
out.push({ type: "line", x1: margin, y1: py, x2: width - margin, y2: py, color: gridColor, opacity: 0.35, lineWidth: 1 });
|
|
32907
33032
|
}
|
|
32908
33033
|
}
|
|
32909
33034
|
if (showTickLabels) {
|
|
@@ -32974,8 +33099,8 @@ var init_MathCanvas = __esm({
|
|
|
32974
33099
|
});
|
|
32975
33100
|
}
|
|
32976
33101
|
if (showAxes) {
|
|
32977
|
-
out.push({ type: "line", x1: margin, y1: xAxisY, x2: width - margin, y2: xAxisY, color:
|
|
32978
|
-
out.push({ type: "line", x1: yAxisX, y1: margin, x2: yAxisX, y2: height - margin, color:
|
|
33102
|
+
out.push({ type: "line", x1: margin, y1: xAxisY, x2: width - margin, y2: xAxisY, color: axisColor, lineWidth: 2 });
|
|
33103
|
+
out.push({ type: "line", x1: yAxisX, y1: margin, x2: yAxisX, y2: height - margin, color: axisColor, lineWidth: 2 });
|
|
32979
33104
|
}
|
|
32980
33105
|
for (const guide of guides) {
|
|
32981
33106
|
const color = guide.color ?? "#9ca3af";
|
|
@@ -32998,23 +33123,36 @@ var init_MathCanvas = __esm({
|
|
|
32998
33123
|
}
|
|
32999
33124
|
for (const curve of curves) {
|
|
33000
33125
|
if (!curve.samples || curve.samples.length < 2) continue;
|
|
33126
|
+
let d = "";
|
|
33127
|
+
let penDown = false;
|
|
33001
33128
|
let lastInRange;
|
|
33002
33129
|
for (let i = 1; i < curve.samples.length; i++) {
|
|
33003
33130
|
const a = curve.samples[i - 1];
|
|
33004
33131
|
const b = curve.samples[i];
|
|
33005
|
-
if (a.x < xMin
|
|
33006
|
-
|
|
33007
|
-
|
|
33008
|
-
|
|
33009
|
-
|
|
33010
|
-
|
|
33011
|
-
|
|
33012
|
-
|
|
33013
|
-
|
|
33014
|
-
|
|
33015
|
-
|
|
33016
|
-
|
|
33017
|
-
|
|
33132
|
+
if (a.x < xMin && b.x < xMin || a.x > xMax && b.x > xMax) {
|
|
33133
|
+
penDown = false;
|
|
33134
|
+
continue;
|
|
33135
|
+
}
|
|
33136
|
+
const clip = (p, q, xLim) => {
|
|
33137
|
+
const t = q.x === p.x ? 0 : (xLim - p.x) / (q.x - p.x);
|
|
33138
|
+
return { x: xLim, y: p.y + t * (q.y - p.y) };
|
|
33139
|
+
};
|
|
33140
|
+
const ca = a.x < xMin ? clip(a, b, xMin) : a.x > xMax ? clip(a, b, xMax) : a;
|
|
33141
|
+
const cb = b.x < xMin ? clip(a, b, xMin) : b.x > xMax ? clip(a, b, xMax) : b;
|
|
33142
|
+
const pax = mapX(ca.x);
|
|
33143
|
+
const pay = mapY(ca.y);
|
|
33144
|
+
d += `${penDown ? "L" : "M"} ${pax} ${pay} L ${mapX(cb.x)} ${mapY(cb.y)} `;
|
|
33145
|
+
penDown = true;
|
|
33146
|
+
if (b.x >= xMin && b.x <= xMax) lastInRange = b;
|
|
33147
|
+
}
|
|
33148
|
+
if (!d) continue;
|
|
33149
|
+
out.push({
|
|
33150
|
+
type: "path",
|
|
33151
|
+
path: d,
|
|
33152
|
+
color: curve.color ?? "#2563eb",
|
|
33153
|
+
lineWidth: 2,
|
|
33154
|
+
dash: curve.dash
|
|
33155
|
+
});
|
|
33018
33156
|
if (showCurveLabels && curve.label && lastInRange) {
|
|
33019
33157
|
out.push({
|
|
33020
33158
|
type: "text",
|
|
@@ -33129,6 +33267,8 @@ var init_MathCanvas = __esm({
|
|
|
33129
33267
|
showAxes,
|
|
33130
33268
|
showGrid,
|
|
33131
33269
|
gridStep,
|
|
33270
|
+
gridColor,
|
|
33271
|
+
axisColor,
|
|
33132
33272
|
showTickLabels,
|
|
33133
33273
|
showCurveLabels,
|
|
33134
33274
|
curves,
|
|
@@ -33148,6 +33288,7 @@ var init_MathCanvas = __esm({
|
|
|
33148
33288
|
{
|
|
33149
33289
|
width,
|
|
33150
33290
|
height,
|
|
33291
|
+
backgroundColor,
|
|
33151
33292
|
shapes: derivedShapes,
|
|
33152
33293
|
readouts,
|
|
33153
33294
|
traces,
|
|
@@ -44898,6 +45039,9 @@ function determineInputType(field) {
|
|
|
44898
45039
|
if (field.type === "relation" || field.relation) {
|
|
44899
45040
|
return "relation";
|
|
44900
45041
|
}
|
|
45042
|
+
if (field.type === "array") {
|
|
45043
|
+
return "array";
|
|
45044
|
+
}
|
|
44901
45045
|
if (field.type === "enum" || field.values || getEnumOptions(field).length > 0) {
|
|
44902
45046
|
return "select";
|
|
44903
45047
|
}
|
|
@@ -44973,6 +45117,7 @@ var init_Form = __esm({
|
|
|
44973
45117
|
init_Typography();
|
|
44974
45118
|
init_Icon();
|
|
44975
45119
|
init_RelationSelect();
|
|
45120
|
+
init_TagInput();
|
|
44976
45121
|
init_UploadDropZone();
|
|
44977
45122
|
init_Alert();
|
|
44978
45123
|
init_useEventBus();
|
|
@@ -45052,7 +45197,7 @@ var init_Form = __esm({
|
|
|
45052
45197
|
values: "values" in f3 ? f3.values : void 0,
|
|
45053
45198
|
min: f3.min,
|
|
45054
45199
|
max: f3.max,
|
|
45055
|
-
relation: "relation" in f3 ? { entity: f3.relation.entity } : void 0
|
|
45200
|
+
relation: "relation" in f3 ? { entity: f3.relation.entity, cardinality: f3.relation.cardinality } : void 0
|
|
45056
45201
|
})
|
|
45057
45202
|
);
|
|
45058
45203
|
}, [entity, fields]);
|
|
@@ -45287,7 +45432,7 @@ var init_Form = __esm({
|
|
|
45287
45432
|
values: "values" in entityField ? entityField.values : void 0,
|
|
45288
45433
|
min: entityField.min,
|
|
45289
45434
|
max: entityField.max,
|
|
45290
|
-
relation: "relation" in entityField ? { entity: entityField.relation.entity } : void 0
|
|
45435
|
+
relation: "relation" in entityField ? { entity: entityField.relation.entity, cardinality: entityField.relation.cardinality } : void 0
|
|
45291
45436
|
};
|
|
45292
45437
|
}
|
|
45293
45438
|
return { name: field, type: "string" };
|
|
@@ -45399,6 +45544,22 @@ var init_Form = __esm({
|
|
|
45399
45544
|
case "relation": {
|
|
45400
45545
|
const relationOptions = relationsData[fieldName] || [];
|
|
45401
45546
|
const relationLoading = relationsLoading[fieldName] || false;
|
|
45547
|
+
if (field.relation?.cardinality !== void 0 && MANY_CARDINALITIES.includes(field.relation.cardinality)) {
|
|
45548
|
+
const selectedValues = Array.isArray(currentValue) ? currentValue.map((v) => String(v)) : [];
|
|
45549
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
45550
|
+
Select,
|
|
45551
|
+
{
|
|
45552
|
+
...commonProps,
|
|
45553
|
+
multiple: true,
|
|
45554
|
+
searchable: true,
|
|
45555
|
+
clearable: true,
|
|
45556
|
+
options: [...relationOptions],
|
|
45557
|
+
value: selectedValues,
|
|
45558
|
+
onValueChange: (value) => handleChange(fieldName, Array.isArray(value) ? value : [value]),
|
|
45559
|
+
placeholder: field.placeholder || `Select ${label}...`
|
|
45560
|
+
}
|
|
45561
|
+
);
|
|
45562
|
+
}
|
|
45402
45563
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
45403
45564
|
RelationSelect,
|
|
45404
45565
|
{
|
|
@@ -45413,6 +45574,18 @@ var init_Form = __esm({
|
|
|
45413
45574
|
}
|
|
45414
45575
|
);
|
|
45415
45576
|
}
|
|
45577
|
+
case "array": {
|
|
45578
|
+
const arrayValue = Array.isArray(currentValue) ? currentValue.map((v) => String(v)) : currentValue != null && currentValue !== "" ? [String(currentValue)] : [];
|
|
45579
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
45580
|
+
TagInput,
|
|
45581
|
+
{
|
|
45582
|
+
placeholder: field.placeholder,
|
|
45583
|
+
disabled: isLoading,
|
|
45584
|
+
value: arrayValue,
|
|
45585
|
+
onChange: (next) => handleChange(fieldName, [...next])
|
|
45586
|
+
}
|
|
45587
|
+
);
|
|
45588
|
+
}
|
|
45416
45589
|
case "number":
|
|
45417
45590
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
45418
45591
|
Input,
|
|
@@ -50981,7 +51154,10 @@ function enrichFormFields(fields, entityDef) {
|
|
|
50981
51154
|
enriched.values = entityField.enumValues;
|
|
50982
51155
|
}
|
|
50983
51156
|
if (entityField.relation) {
|
|
50984
|
-
enriched.relation =
|
|
51157
|
+
enriched.relation = {
|
|
51158
|
+
entity: entityField.relation.entity,
|
|
51159
|
+
cardinality: entityField.relation.cardinality
|
|
51160
|
+
};
|
|
50985
51161
|
}
|
|
50986
51162
|
return enriched;
|
|
50987
51163
|
}
|
|
@@ -51009,7 +51185,10 @@ function enrichFormFields(fields, entityDef) {
|
|
|
51009
51185
|
}
|
|
51010
51186
|
}
|
|
51011
51187
|
if (!obj.relation && entityField.relation) {
|
|
51012
|
-
enriched.relation =
|
|
51188
|
+
enriched.relation = {
|
|
51189
|
+
entity: entityField.relation.entity,
|
|
51190
|
+
cardinality: entityField.relation.cardinality
|
|
51191
|
+
};
|
|
51013
51192
|
}
|
|
51014
51193
|
return enriched;
|
|
51015
51194
|
}
|
|
@@ -51024,7 +51203,12 @@ function enrichDetailFields(fields, entityDef) {
|
|
|
51024
51203
|
const meta = { type: entityField.type };
|
|
51025
51204
|
const values = entityField.values ?? entityField.enumValues;
|
|
51026
51205
|
if (values && values.length > 0) meta.values = values;
|
|
51027
|
-
if (entityField.relation)
|
|
51206
|
+
if (entityField.relation) {
|
|
51207
|
+
meta.relation = {
|
|
51208
|
+
entity: entityField.relation.entity,
|
|
51209
|
+
cardinality: entityField.relation.cardinality
|
|
51210
|
+
};
|
|
51211
|
+
}
|
|
51028
51212
|
return meta;
|
|
51029
51213
|
};
|
|
51030
51214
|
return fields.map((field) => {
|
|
@@ -51578,6 +51762,32 @@ function isPlainConfigObject(value) {
|
|
|
51578
51762
|
const proto = Object.getPrototypeOf(value);
|
|
51579
51763
|
return proto === Object.prototype || proto === null;
|
|
51580
51764
|
}
|
|
51765
|
+
function subtreeHasTraitRef(value) {
|
|
51766
|
+
const cached = traitRefPresenceCache.get(value);
|
|
51767
|
+
if (cached !== void 0) return cached;
|
|
51768
|
+
let found = false;
|
|
51769
|
+
const children = Array.isArray(value) ? value : Object.values(value);
|
|
51770
|
+
for (const child of children) {
|
|
51771
|
+
if (typeof child === "string" && TRAIT_BINDING_RE.test(child)) {
|
|
51772
|
+
found = true;
|
|
51773
|
+
break;
|
|
51774
|
+
}
|
|
51775
|
+
if (core.isRenderBindingMarker(child)) continue;
|
|
51776
|
+
if (Array.isArray(child)) {
|
|
51777
|
+
if (subtreeHasTraitRef(child)) {
|
|
51778
|
+
found = true;
|
|
51779
|
+
break;
|
|
51780
|
+
}
|
|
51781
|
+
} else if (child !== null && typeof child === "object" && isPlainConfigObject(child)) {
|
|
51782
|
+
if (subtreeHasTraitRef(child)) {
|
|
51783
|
+
found = true;
|
|
51784
|
+
break;
|
|
51785
|
+
}
|
|
51786
|
+
}
|
|
51787
|
+
}
|
|
51788
|
+
traitRefPresenceCache.set(value, found);
|
|
51789
|
+
return found;
|
|
51790
|
+
}
|
|
51581
51791
|
function substituteTraitRefsDeep(value, pathKey) {
|
|
51582
51792
|
if (core.isRenderBindingMarker(value)) return value;
|
|
51583
51793
|
if (typeof value === "string") {
|
|
@@ -51592,11 +51802,13 @@ function substituteTraitRefsDeep(value, pathKey) {
|
|
|
51592
51802
|
return value;
|
|
51593
51803
|
}
|
|
51594
51804
|
if (Array.isArray(value)) {
|
|
51805
|
+
if (!subtreeHasTraitRef(value)) return value;
|
|
51595
51806
|
return value.map(
|
|
51596
51807
|
(item, i) => substituteTraitRefsDeep(item, `${pathKey}[${i}]`)
|
|
51597
51808
|
);
|
|
51598
51809
|
}
|
|
51599
51810
|
if (typeof value === "object" && isPlainConfigObject(value)) {
|
|
51811
|
+
if (!subtreeHasTraitRef(value)) return value;
|
|
51600
51812
|
const out = {};
|
|
51601
51813
|
for (const [k, v] of Object.entries(value)) {
|
|
51602
51814
|
out[k] = substituteTraitRefsDeep(v, `${pathKey}.${k}`);
|
|
@@ -51885,7 +52097,7 @@ function UISlotRenderer({
|
|
|
51885
52097
|
}
|
|
51886
52098
|
return wrapped;
|
|
51887
52099
|
}
|
|
51888
|
-
var scopeWrapLog, TRAIT_BINDING_RE, SuspenseConfigContext, SlotContainedContext, SLOT_SKELETON_MAP, SELF_OVERLAY_PATTERNS, CONTENT_NODE_SLOTS, PATTERNS_WITH_CHILDREN;
|
|
52100
|
+
var scopeWrapLog, TRAIT_BINDING_RE, SuspenseConfigContext, SlotContainedContext, SLOT_SKELETON_MAP, SELF_OVERLAY_PATTERNS, CONTENT_NODE_SLOTS, PATTERNS_WITH_CHILDREN, traitRefPresenceCache;
|
|
51889
52101
|
var init_UISlotRenderer = __esm({
|
|
51890
52102
|
"components/core/organisms/UISlotRenderer.tsx"() {
|
|
51891
52103
|
"use client";
|
|
@@ -51959,6 +52171,7 @@ var init_UISlotRenderer = __esm({
|
|
|
51959
52171
|
"alert",
|
|
51960
52172
|
"dialog"
|
|
51961
52173
|
]);
|
|
52174
|
+
traitRefPresenceCache = /* @__PURE__ */ new WeakMap();
|
|
51962
52175
|
UISlotRenderer.displayName = "UISlotRenderer";
|
|
51963
52176
|
}
|
|
51964
52177
|
});
|
|
@@ -55633,6 +55846,20 @@ function createClientEffectHandlers(options) {
|
|
|
55633
55846
|
};
|
|
55634
55847
|
}
|
|
55635
55848
|
|
|
55849
|
+
// lib/event-queue-coalesce.ts
|
|
55850
|
+
function enqueueEvent(queue, entry) {
|
|
55851
|
+
if (entry.tick !== void 0) {
|
|
55852
|
+
const pending = queue.find(
|
|
55853
|
+
(e) => e.tick !== void 0 && e.eventKey === entry.eventKey && e.targetTrait === entry.targetTrait
|
|
55854
|
+
);
|
|
55855
|
+
if (pending !== void 0) {
|
|
55856
|
+
pending.payload = entry.payload;
|
|
55857
|
+
return;
|
|
55858
|
+
}
|
|
55859
|
+
}
|
|
55860
|
+
queue.push(entry);
|
|
55861
|
+
}
|
|
55862
|
+
|
|
55636
55863
|
// hooks/useTraitStateMachine.ts
|
|
55637
55864
|
init_traitRegistry();
|
|
55638
55865
|
init_verificationRegistry();
|
|
@@ -56207,12 +56434,13 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
56207
56434
|
entityId
|
|
56208
56435
|
};
|
|
56209
56436
|
const emittedDuringExec = [];
|
|
56437
|
+
const tickName = flushEvent.startsWith("tick:") ? flushEvent.slice(5) : void 0;
|
|
56210
56438
|
const baseEmit = handlers.emit;
|
|
56211
56439
|
const trackingHandlers = {
|
|
56212
56440
|
...handlers,
|
|
56213
56441
|
emit: (event, eventPayload, source) => {
|
|
56214
56442
|
emittedDuringExec.push(event);
|
|
56215
|
-
baseEmit(event, eventPayload, source);
|
|
56443
|
+
baseEmit(event, eventPayload, tickName !== void 0 ? { ...source, tick: tickName } : source);
|
|
56216
56444
|
}
|
|
56217
56445
|
};
|
|
56218
56446
|
if (traitName === "Hero") {
|
|
@@ -56371,7 +56599,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
56371
56599
|
}
|
|
56372
56600
|
return () => scheduler.stopAll();
|
|
56373
56601
|
}, [traitBindings, runTickEffects, sharedGroups, sharedEntityStore, emitFromSharedWriter]);
|
|
56374
|
-
const processEventQueued = React94.useCallback(async (eventKey, payload, targetTrait) => {
|
|
56602
|
+
const processEventQueued = React94.useCallback(async (eventKey, payload, targetTrait, tick, sourceTrait) => {
|
|
56375
56603
|
const normalizedEvent = normalizeEventKey(eventKey);
|
|
56376
56604
|
const bindings = traitBindingsRef.current;
|
|
56377
56605
|
const currentManager = managerRef.current;
|
|
@@ -56560,7 +56788,11 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
56560
56788
|
if (orbital) dispatchedOrbitals.add(orbital);
|
|
56561
56789
|
}
|
|
56562
56790
|
const relayPayload = targetTrait !== void 0 ? { ...payload ?? {}, _targetTrait: targetTrait } : payload;
|
|
56563
|
-
|
|
56791
|
+
if (tick !== void 0) {
|
|
56792
|
+
void onEventProcessed(normalizedEvent, relayPayload, dispatchedOrbitals, tick, sourceTrait);
|
|
56793
|
+
} else {
|
|
56794
|
+
await onEventProcessed(normalizedEvent, relayPayload, dispatchedOrbitals);
|
|
56795
|
+
}
|
|
56564
56796
|
}
|
|
56565
56797
|
}, [entities, eventBus, sharedEntityStore]);
|
|
56566
56798
|
const drainEventQueue = React94.useCallback(async () => {
|
|
@@ -56569,14 +56801,14 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
56569
56801
|
try {
|
|
56570
56802
|
while (eventQueueRef.current.length > 0) {
|
|
56571
56803
|
const entry = eventQueueRef.current.shift();
|
|
56572
|
-
await processEventQueued(entry.eventKey, entry.payload, entry.targetTrait);
|
|
56804
|
+
await processEventQueued(entry.eventKey, entry.payload, entry.targetTrait, entry.tick, entry.sourceTrait);
|
|
56573
56805
|
}
|
|
56574
56806
|
} finally {
|
|
56575
56807
|
processingRef.current = false;
|
|
56576
56808
|
}
|
|
56577
56809
|
}, [processEventQueued]);
|
|
56578
|
-
const enqueueAndDrain = React94.useCallback((eventKey, payload, targetTrait) => {
|
|
56579
|
-
eventQueueRef.current
|
|
56810
|
+
const enqueueAndDrain = React94.useCallback((eventKey, payload, targetTrait, tick, sourceTrait) => {
|
|
56811
|
+
enqueueEvent(eventQueueRef.current, { eventKey, payload, targetTrait, tick, sourceTrait });
|
|
56580
56812
|
void drainEventQueue();
|
|
56581
56813
|
}, [drainEventQueue]);
|
|
56582
56814
|
React94.useCallback((eventKey, payload) => {
|
|
@@ -56629,7 +56861,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
56629
56861
|
crossTraitLog.debug("self:fire-server-cascade", { traitName, busKey: selfBusKey, eventKey });
|
|
56630
56862
|
}
|
|
56631
56863
|
crossTraitLog.debug("self:fire", { traitName, busKey: selfBusKey, eventKey });
|
|
56632
|
-
enqueueAndDrain(eventKey, event.payload, traitName);
|
|
56864
|
+
enqueueAndDrain(eventKey, event.payload, traitName, event.source?.tick, event.source?.trait);
|
|
56633
56865
|
});
|
|
56634
56866
|
unsubscribes.push(() => {
|
|
56635
56867
|
crossTraitLog.debug("self:unsubscribe", { traitName, busKey: selfBusKey, eventKey });
|
|
@@ -56647,7 +56879,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
56647
56879
|
const bareKey = `UI:${eventKey}`;
|
|
56648
56880
|
const unsub = eventBus.on(bareKey, (event) => {
|
|
56649
56881
|
crossTraitLog.debug("bare-cascade:fire", { bareKey, eventKey });
|
|
56650
|
-
enqueueAndDrain(eventKey, event.payload);
|
|
56882
|
+
enqueueAndDrain(eventKey, event.payload, void 0, event.source?.tick, event.source?.trait);
|
|
56651
56883
|
});
|
|
56652
56884
|
unsubscribes.push(() => {
|
|
56653
56885
|
crossTraitLog.debug("bare-cascade:unsubscribe", { bareKey, eventKey });
|
|
@@ -56681,7 +56913,9 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
56681
56913
|
enqueueAndDrain(
|
|
56682
56914
|
listen.triggers,
|
|
56683
56915
|
core.applyListenPayloadMapping(listen.payloadMapping, event.payload, evaluator.evaluateListenPayloadExpr),
|
|
56684
|
-
binding.trait.name
|
|
56916
|
+
binding.trait.name,
|
|
56917
|
+
event.source?.tick,
|
|
56918
|
+
event.source?.trait
|
|
56685
56919
|
);
|
|
56686
56920
|
});
|
|
56687
56921
|
unsubscribes.push(() => {
|
|
@@ -56873,7 +57107,7 @@ function TraitInitializer({ traits: traits2, routeParams, orbitalNames, onNaviga
|
|
|
56873
57107
|
[serverActiveTraits]
|
|
56874
57108
|
);
|
|
56875
57109
|
const uiSlots = context.useUISlots();
|
|
56876
|
-
const onEventProcessed = React94.useCallback(async (event, payload, dispatchedOrbitals) => {
|
|
57110
|
+
const onEventProcessed = React94.useCallback(async (event, payload, dispatchedOrbitals, tick, sourceTrait) => {
|
|
56877
57111
|
if (!bridge.connected || !orbitalNames?.length) return;
|
|
56878
57112
|
const targets = dispatchedOrbitals && dispatchedOrbitals.size > 0 ? orbitalNames.filter((n) => dispatchedOrbitals.has(n)) : orbitalNames;
|
|
56879
57113
|
xOrbitalLog.debug("TraitInitializer:fanout", () => ({
|
|
@@ -56883,6 +57117,10 @@ function TraitInitializer({ traits: traits2, routeParams, orbitalNames, onNaviga
|
|
|
56883
57117
|
dispatchedOrbitalsSize: dispatchedOrbitals?.size ?? 0
|
|
56884
57118
|
}));
|
|
56885
57119
|
for (const name of targets) {
|
|
57120
|
+
if (tick !== void 0) {
|
|
57121
|
+
void bridge.sendEvent(name, event, withActiveTraits(payload), tick, sourceTrait);
|
|
57122
|
+
continue;
|
|
57123
|
+
}
|
|
56886
57124
|
const { effects, meta } = await bridge.sendEvent(name, event, withActiveTraits(payload));
|
|
56887
57125
|
recordServerResponse(name, event, meta);
|
|
56888
57126
|
applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits, activeTraitNames, onNavigateBack);
|
|
@@ -57358,11 +57596,13 @@ function BrowserPlayground({
|
|
|
57358
57596
|
unregister: async () => {
|
|
57359
57597
|
runtime.unregisterAll();
|
|
57360
57598
|
},
|
|
57361
|
-
sendEvent: async (orbitalName, event, payload) => {
|
|
57599
|
+
sendEvent: async (orbitalName, event, payload, _clientId, tick, sourceTrait) => {
|
|
57362
57600
|
await registrationReady;
|
|
57363
57601
|
return runtime.processOrbitalEvent(orbitalName, {
|
|
57364
57602
|
event,
|
|
57365
|
-
payload
|
|
57603
|
+
payload,
|
|
57604
|
+
tick,
|
|
57605
|
+
sourceTrait
|
|
57366
57606
|
// @almadar/runtime OrbitalEventResponse.clientEffects uses a wider ClientEffectTuple than
|
|
57367
57607
|
// ServerBridge's local definition — cast at this boundary (upstream fix queued).
|
|
57368
57608
|
});
|