@almadar/ui 5.157.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 +244 -25
- package/dist/avl/index.js +244 -25
- package/dist/components/index.cjs +205 -13
- package/dist/components/index.d.cts +40 -6
- package/dist/components/index.d.ts +40 -6
- package/dist/components/index.js +205 -13
- package/dist/providers/index.cjs +212 -17
- package/dist/providers/index.d.cts +1 -1
- package/dist/providers/index.d.ts +1 -1
- package/dist/providers/index.js +212 -17
- package/dist/runtime/index.cjs +244 -25
- package/dist/runtime/index.d.cts +12 -3
- package/dist/runtime/index.d.ts +12 -3
- package/dist/runtime/index.js +244 -25
- package/package.json +4 -4
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) {
|
|
@@ -26921,7 +26945,7 @@ function fileIcon(name) {
|
|
|
26921
26945
|
return "file";
|
|
26922
26946
|
}
|
|
26923
26947
|
}
|
|
26924
|
-
var TreeNodeItem, FileTree;
|
|
26948
|
+
var TreeNodeItem, FlatTreeNodeItem, FileTree;
|
|
26925
26949
|
var init_FileTree = __esm({
|
|
26926
26950
|
"components/core/molecules/FileTree.tsx"() {
|
|
26927
26951
|
"use client";
|
|
@@ -27006,14 +27030,101 @@ var init_FileTree = __esm({
|
|
|
27006
27030
|
)) })
|
|
27007
27031
|
] });
|
|
27008
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
|
+
};
|
|
27009
27091
|
FileTree = ({
|
|
27010
27092
|
tree,
|
|
27093
|
+
items,
|
|
27011
27094
|
selectedPath,
|
|
27012
27095
|
onFileSelect,
|
|
27096
|
+
onNodeSelect,
|
|
27013
27097
|
className,
|
|
27014
27098
|
indent = 16
|
|
27015
27099
|
}) => {
|
|
27016
|
-
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;
|
|
27017
27128
|
return /* @__PURE__ */ jsx(Box, { className: `py-1 overflow-y-auto ${className ?? ""}`, role: "tree", children: tree.map((node) => /* @__PURE__ */ jsx(
|
|
27018
27129
|
TreeNodeItem,
|
|
27019
27130
|
{
|
|
@@ -28344,7 +28455,7 @@ var init_debug = __esm({
|
|
|
28344
28455
|
createLogger("almadar:ui:debug:game-state");
|
|
28345
28456
|
}
|
|
28346
28457
|
});
|
|
28347
|
-
var isRelationsDebugEnabled, RelationSelect;
|
|
28458
|
+
var isRelationsDebugEnabled, MANY_CARDINALITIES, RelationSelect;
|
|
28348
28459
|
var init_RelationSelect = __esm({
|
|
28349
28460
|
"components/core/molecules/RelationSelect.tsx"() {
|
|
28350
28461
|
"use client";
|
|
@@ -28358,6 +28469,11 @@ var init_RelationSelect = __esm({
|
|
|
28358
28469
|
init_Typography();
|
|
28359
28470
|
init_debug();
|
|
28360
28471
|
isRelationsDebugEnabled = () => isDebugEnabled();
|
|
28472
|
+
MANY_CARDINALITIES = [
|
|
28473
|
+
"many",
|
|
28474
|
+
"one-to-many",
|
|
28475
|
+
"many-to-many"
|
|
28476
|
+
];
|
|
28361
28477
|
RelationSelect = ({
|
|
28362
28478
|
value,
|
|
28363
28479
|
onChange,
|
|
@@ -30022,17 +30138,21 @@ var init_MathCanvas = __esm({
|
|
|
30022
30138
|
error
|
|
30023
30139
|
}) => {
|
|
30024
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]);
|
|
30025
30145
|
useEffect(() => {
|
|
30026
|
-
if (!
|
|
30146
|
+
if (!stableKeyMap && !stableKeyUpMap) return;
|
|
30027
30147
|
const onDown = (e) => {
|
|
30028
|
-
const ev =
|
|
30148
|
+
const ev = stableKeyMap?.[e.code];
|
|
30029
30149
|
if (ev) {
|
|
30030
30150
|
eventBus.emit(`UI:${ev}`, {});
|
|
30031
30151
|
e.preventDefault();
|
|
30032
30152
|
}
|
|
30033
30153
|
};
|
|
30034
30154
|
const onUp = (e) => {
|
|
30035
|
-
const ev =
|
|
30155
|
+
const ev = stableKeyUpMap?.[e.code];
|
|
30036
30156
|
if (ev) eventBus.emit(`UI:${ev}`, {});
|
|
30037
30157
|
};
|
|
30038
30158
|
window.addEventListener("keydown", onDown);
|
|
@@ -30041,7 +30161,7 @@ var init_MathCanvas = __esm({
|
|
|
30041
30161
|
window.removeEventListener("keydown", onDown);
|
|
30042
30162
|
window.removeEventListener("keyup", onUp);
|
|
30043
30163
|
};
|
|
30044
|
-
}, [
|
|
30164
|
+
}, [stableKeyMap, stableKeyUpMap, eventBus]);
|
|
30045
30165
|
const derivedShapes = useMemo(() => {
|
|
30046
30166
|
const out = [];
|
|
30047
30167
|
const margin = 24;
|
|
@@ -42340,6 +42460,9 @@ function determineInputType(field) {
|
|
|
42340
42460
|
if (field.type === "relation" || field.relation) {
|
|
42341
42461
|
return "relation";
|
|
42342
42462
|
}
|
|
42463
|
+
if (field.type === "array") {
|
|
42464
|
+
return "array";
|
|
42465
|
+
}
|
|
42343
42466
|
if (field.type === "enum" || field.values || getEnumOptions(field).length > 0) {
|
|
42344
42467
|
return "select";
|
|
42345
42468
|
}
|
|
@@ -42415,6 +42538,7 @@ var init_Form = __esm({
|
|
|
42415
42538
|
init_Typography();
|
|
42416
42539
|
init_Icon();
|
|
42417
42540
|
init_RelationSelect();
|
|
42541
|
+
init_TagInput();
|
|
42418
42542
|
init_UploadDropZone();
|
|
42419
42543
|
init_Alert();
|
|
42420
42544
|
init_useEventBus();
|
|
@@ -42494,7 +42618,7 @@ var init_Form = __esm({
|
|
|
42494
42618
|
values: "values" in f3 ? f3.values : void 0,
|
|
42495
42619
|
min: f3.min,
|
|
42496
42620
|
max: f3.max,
|
|
42497
|
-
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
|
|
42498
42622
|
})
|
|
42499
42623
|
);
|
|
42500
42624
|
}, [entity, fields]);
|
|
@@ -42729,7 +42853,7 @@ var init_Form = __esm({
|
|
|
42729
42853
|
values: "values" in entityField ? entityField.values : void 0,
|
|
42730
42854
|
min: entityField.min,
|
|
42731
42855
|
max: entityField.max,
|
|
42732
|
-
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
|
|
42733
42857
|
};
|
|
42734
42858
|
}
|
|
42735
42859
|
return { name: field, type: "string" };
|
|
@@ -42841,6 +42965,22 @@ var init_Form = __esm({
|
|
|
42841
42965
|
case "relation": {
|
|
42842
42966
|
const relationOptions = relationsData[fieldName] || [];
|
|
42843
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
|
+
}
|
|
42844
42984
|
return /* @__PURE__ */ jsx(
|
|
42845
42985
|
RelationSelect,
|
|
42846
42986
|
{
|
|
@@ -42855,6 +42995,18 @@ var init_Form = __esm({
|
|
|
42855
42995
|
}
|
|
42856
42996
|
);
|
|
42857
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
|
+
}
|
|
42858
43010
|
case "number":
|
|
42859
43011
|
return /* @__PURE__ */ jsx(
|
|
42860
43012
|
Input,
|
|
@@ -48423,7 +48575,10 @@ function enrichFormFields(fields, entityDef) {
|
|
|
48423
48575
|
enriched.values = entityField.enumValues;
|
|
48424
48576
|
}
|
|
48425
48577
|
if (entityField.relation) {
|
|
48426
|
-
enriched.relation =
|
|
48578
|
+
enriched.relation = {
|
|
48579
|
+
entity: entityField.relation.entity,
|
|
48580
|
+
cardinality: entityField.relation.cardinality
|
|
48581
|
+
};
|
|
48427
48582
|
}
|
|
48428
48583
|
return enriched;
|
|
48429
48584
|
}
|
|
@@ -48451,7 +48606,10 @@ function enrichFormFields(fields, entityDef) {
|
|
|
48451
48606
|
}
|
|
48452
48607
|
}
|
|
48453
48608
|
if (!obj.relation && entityField.relation) {
|
|
48454
|
-
enriched.relation =
|
|
48609
|
+
enriched.relation = {
|
|
48610
|
+
entity: entityField.relation.entity,
|
|
48611
|
+
cardinality: entityField.relation.cardinality
|
|
48612
|
+
};
|
|
48455
48613
|
}
|
|
48456
48614
|
return enriched;
|
|
48457
48615
|
}
|
|
@@ -48466,7 +48624,12 @@ function enrichDetailFields(fields, entityDef) {
|
|
|
48466
48624
|
const meta = { type: entityField.type };
|
|
48467
48625
|
const values = entityField.values ?? entityField.enumValues;
|
|
48468
48626
|
if (values && values.length > 0) meta.values = values;
|
|
48469
|
-
if (entityField.relation)
|
|
48627
|
+
if (entityField.relation) {
|
|
48628
|
+
meta.relation = {
|
|
48629
|
+
entity: entityField.relation.entity,
|
|
48630
|
+
cardinality: entityField.relation.cardinality
|
|
48631
|
+
};
|
|
48632
|
+
}
|
|
48470
48633
|
return meta;
|
|
48471
48634
|
};
|
|
48472
48635
|
return fields.map((field) => {
|
|
@@ -49020,6 +49183,32 @@ function isPlainConfigObject(value) {
|
|
|
49020
49183
|
const proto = Object.getPrototypeOf(value);
|
|
49021
49184
|
return proto === Object.prototype || proto === null;
|
|
49022
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
|
+
}
|
|
49023
49212
|
function substituteTraitRefsDeep(value, pathKey) {
|
|
49024
49213
|
if (isRenderBindingMarker(value)) return value;
|
|
49025
49214
|
if (typeof value === "string") {
|
|
@@ -49034,11 +49223,13 @@ function substituteTraitRefsDeep(value, pathKey) {
|
|
|
49034
49223
|
return value;
|
|
49035
49224
|
}
|
|
49036
49225
|
if (Array.isArray(value)) {
|
|
49226
|
+
if (!subtreeHasTraitRef(value)) return value;
|
|
49037
49227
|
return value.map(
|
|
49038
49228
|
(item, i) => substituteTraitRefsDeep(item, `${pathKey}[${i}]`)
|
|
49039
49229
|
);
|
|
49040
49230
|
}
|
|
49041
49231
|
if (typeof value === "object" && isPlainConfigObject(value)) {
|
|
49232
|
+
if (!subtreeHasTraitRef(value)) return value;
|
|
49042
49233
|
const out = {};
|
|
49043
49234
|
for (const [k, v] of Object.entries(value)) {
|
|
49044
49235
|
out[k] = substituteTraitRefsDeep(v, `${pathKey}.${k}`);
|
|
@@ -49327,7 +49518,7 @@ function UISlotRenderer({
|
|
|
49327
49518
|
}
|
|
49328
49519
|
return wrapped;
|
|
49329
49520
|
}
|
|
49330
|
-
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;
|
|
49331
49522
|
var init_UISlotRenderer = __esm({
|
|
49332
49523
|
"components/core/organisms/UISlotRenderer.tsx"() {
|
|
49333
49524
|
"use client";
|
|
@@ -49401,6 +49592,7 @@ var init_UISlotRenderer = __esm({
|
|
|
49401
49592
|
"alert",
|
|
49402
49593
|
"dialog"
|
|
49403
49594
|
]);
|
|
49595
|
+
traitRefPresenceCache = /* @__PURE__ */ new WeakMap();
|
|
49404
49596
|
UISlotRenderer.displayName = "UISlotRenderer";
|
|
49405
49597
|
}
|
|
49406
49598
|
});
|
|
@@ -49528,6 +49720,20 @@ function createClientEffectHandlers(options) {
|
|
|
49528
49720
|
})
|
|
49529
49721
|
};
|
|
49530
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
|
+
}
|
|
49531
49737
|
var lambdaLog = createLogger("almadar:ui:fn-form-lambda");
|
|
49532
49738
|
function isOperatorCall(value) {
|
|
49533
49739
|
const first = value[0];
|
|
@@ -50273,12 +50479,13 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
50273
50479
|
entityId
|
|
50274
50480
|
};
|
|
50275
50481
|
const emittedDuringExec = [];
|
|
50482
|
+
const tickName = flushEvent.startsWith("tick:") ? flushEvent.slice(5) : void 0;
|
|
50276
50483
|
const baseEmit = handlers.emit;
|
|
50277
50484
|
const trackingHandlers = {
|
|
50278
50485
|
...handlers,
|
|
50279
50486
|
emit: (event, eventPayload, source) => {
|
|
50280
50487
|
emittedDuringExec.push(event);
|
|
50281
|
-
baseEmit(event, eventPayload, source);
|
|
50488
|
+
baseEmit(event, eventPayload, tickName !== void 0 ? { ...source, tick: tickName } : source);
|
|
50282
50489
|
}
|
|
50283
50490
|
};
|
|
50284
50491
|
if (traitName === "Hero") {
|
|
@@ -50437,7 +50644,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
50437
50644
|
}
|
|
50438
50645
|
return () => scheduler.stopAll();
|
|
50439
50646
|
}, [traitBindings, runTickEffects, sharedGroups, sharedEntityStore, emitFromSharedWriter]);
|
|
50440
|
-
const processEventQueued = useCallback(async (eventKey, payload, targetTrait) => {
|
|
50647
|
+
const processEventQueued = useCallback(async (eventKey, payload, targetTrait, tick, sourceTrait) => {
|
|
50441
50648
|
const normalizedEvent = normalizeEventKey(eventKey);
|
|
50442
50649
|
const bindings = traitBindingsRef.current;
|
|
50443
50650
|
const currentManager = managerRef.current;
|
|
@@ -50626,7 +50833,11 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
50626
50833
|
if (orbital) dispatchedOrbitals.add(orbital);
|
|
50627
50834
|
}
|
|
50628
50835
|
const relayPayload = targetTrait !== void 0 ? { ...payload ?? {}, _targetTrait: targetTrait } : payload;
|
|
50629
|
-
|
|
50836
|
+
if (tick !== void 0) {
|
|
50837
|
+
void onEventProcessed(normalizedEvent, relayPayload, dispatchedOrbitals, tick, sourceTrait);
|
|
50838
|
+
} else {
|
|
50839
|
+
await onEventProcessed(normalizedEvent, relayPayload, dispatchedOrbitals);
|
|
50840
|
+
}
|
|
50630
50841
|
}
|
|
50631
50842
|
}, [entities, eventBus, sharedEntityStore]);
|
|
50632
50843
|
const drainEventQueue = useCallback(async () => {
|
|
@@ -50635,14 +50846,14 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
50635
50846
|
try {
|
|
50636
50847
|
while (eventQueueRef.current.length > 0) {
|
|
50637
50848
|
const entry = eventQueueRef.current.shift();
|
|
50638
|
-
await processEventQueued(entry.eventKey, entry.payload, entry.targetTrait);
|
|
50849
|
+
await processEventQueued(entry.eventKey, entry.payload, entry.targetTrait, entry.tick, entry.sourceTrait);
|
|
50639
50850
|
}
|
|
50640
50851
|
} finally {
|
|
50641
50852
|
processingRef.current = false;
|
|
50642
50853
|
}
|
|
50643
50854
|
}, [processEventQueued]);
|
|
50644
|
-
const enqueueAndDrain = useCallback((eventKey, payload, targetTrait) => {
|
|
50645
|
-
eventQueueRef.current
|
|
50855
|
+
const enqueueAndDrain = useCallback((eventKey, payload, targetTrait, tick, sourceTrait) => {
|
|
50856
|
+
enqueueEvent(eventQueueRef.current, { eventKey, payload, targetTrait, tick, sourceTrait });
|
|
50646
50857
|
void drainEventQueue();
|
|
50647
50858
|
}, [drainEventQueue]);
|
|
50648
50859
|
useCallback((eventKey, payload) => {
|
|
@@ -50695,7 +50906,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
50695
50906
|
crossTraitLog.debug("self:fire-server-cascade", { traitName, busKey: selfBusKey, eventKey });
|
|
50696
50907
|
}
|
|
50697
50908
|
crossTraitLog.debug("self:fire", { traitName, busKey: selfBusKey, eventKey });
|
|
50698
|
-
enqueueAndDrain(eventKey, event.payload, traitName);
|
|
50909
|
+
enqueueAndDrain(eventKey, event.payload, traitName, event.source?.tick, event.source?.trait);
|
|
50699
50910
|
});
|
|
50700
50911
|
unsubscribes.push(() => {
|
|
50701
50912
|
crossTraitLog.debug("self:unsubscribe", { traitName, busKey: selfBusKey, eventKey });
|
|
@@ -50713,7 +50924,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
50713
50924
|
const bareKey = `UI:${eventKey}`;
|
|
50714
50925
|
const unsub = eventBus.on(bareKey, (event) => {
|
|
50715
50926
|
crossTraitLog.debug("bare-cascade:fire", { bareKey, eventKey });
|
|
50716
|
-
enqueueAndDrain(eventKey, event.payload);
|
|
50927
|
+
enqueueAndDrain(eventKey, event.payload, void 0, event.source?.tick, event.source?.trait);
|
|
50717
50928
|
});
|
|
50718
50929
|
unsubscribes.push(() => {
|
|
50719
50930
|
crossTraitLog.debug("bare-cascade:unsubscribe", { bareKey, eventKey });
|
|
@@ -50747,7 +50958,9 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
50747
50958
|
enqueueAndDrain(
|
|
50748
50959
|
listen.triggers,
|
|
50749
50960
|
applyListenPayloadMapping(listen.payloadMapping, event.payload, evaluateListenPayloadExpr),
|
|
50750
|
-
binding.trait.name
|
|
50961
|
+
binding.trait.name,
|
|
50962
|
+
event.source?.tick,
|
|
50963
|
+
event.source?.trait
|
|
50751
50964
|
);
|
|
50752
50965
|
});
|
|
50753
50966
|
unsubscribes.push(() => {
|
|
@@ -51042,7 +51255,7 @@ function TraitInitializer({ traits: traits2, routeParams, orbitalNames, onNaviga
|
|
|
51042
51255
|
[serverActiveTraits]
|
|
51043
51256
|
);
|
|
51044
51257
|
const uiSlots = useUISlots();
|
|
51045
|
-
const onEventProcessed = useCallback(async (event, payload, dispatchedOrbitals) => {
|
|
51258
|
+
const onEventProcessed = useCallback(async (event, payload, dispatchedOrbitals, tick, sourceTrait) => {
|
|
51046
51259
|
if (!bridge.connected || !orbitalNames?.length) return;
|
|
51047
51260
|
const targets = dispatchedOrbitals && dispatchedOrbitals.size > 0 ? orbitalNames.filter((n) => dispatchedOrbitals.has(n)) : orbitalNames;
|
|
51048
51261
|
xOrbitalLog.debug("TraitInitializer:fanout", () => ({
|
|
@@ -51052,6 +51265,10 @@ function TraitInitializer({ traits: traits2, routeParams, orbitalNames, onNaviga
|
|
|
51052
51265
|
dispatchedOrbitalsSize: dispatchedOrbitals?.size ?? 0
|
|
51053
51266
|
}));
|
|
51054
51267
|
for (const name of targets) {
|
|
51268
|
+
if (tick !== void 0) {
|
|
51269
|
+
void bridge.sendEvent(name, event, withActiveTraits(payload), tick, sourceTrait);
|
|
51270
|
+
continue;
|
|
51271
|
+
}
|
|
51055
51272
|
const { effects, meta } = await bridge.sendEvent(name, event, withActiveTraits(payload));
|
|
51056
51273
|
recordServerResponse(name, event, meta);
|
|
51057
51274
|
applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits, activeTraitNames, onNavigateBack);
|
|
@@ -51527,11 +51744,13 @@ function BrowserPlayground({
|
|
|
51527
51744
|
unregister: async () => {
|
|
51528
51745
|
runtime.unregisterAll();
|
|
51529
51746
|
},
|
|
51530
|
-
sendEvent: async (orbitalName, event, payload) => {
|
|
51747
|
+
sendEvent: async (orbitalName, event, payload, _clientId, tick, sourceTrait) => {
|
|
51531
51748
|
await registrationReady;
|
|
51532
51749
|
return runtime.processOrbitalEvent(orbitalName, {
|
|
51533
51750
|
event,
|
|
51534
|
-
payload
|
|
51751
|
+
payload,
|
|
51752
|
+
tick,
|
|
51753
|
+
sourceTrait
|
|
51535
51754
|
// @almadar/runtime OrbitalEventResponse.clientEffects uses a wider ClientEffectTuple than
|
|
51536
51755
|
// ServerBridge's local definition — cast at this boundary (upstream fix queued).
|
|
51537
51756
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@almadar/ui",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.158.0",
|
|
4
4
|
"description": "React UI components, hooks, and providers for Almadar",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": [
|
|
@@ -118,11 +118,11 @@
|
|
|
118
118
|
"access": "public"
|
|
119
119
|
},
|
|
120
120
|
"dependencies": {
|
|
121
|
-
"@almadar/core": "^10.
|
|
121
|
+
"@almadar/core": "^10.68.0",
|
|
122
122
|
"@almadar/evaluator": "^2.41.0",
|
|
123
123
|
"@almadar/logger": "^1.11.0",
|
|
124
|
-
"@almadar/runtime": "^6.
|
|
125
|
-
"@almadar/std": "^16.
|
|
124
|
+
"@almadar/runtime": "^6.59.0",
|
|
125
|
+
"@almadar/std": "^16.184.0",
|
|
126
126
|
"@almadar/syntax": "^1.15.0",
|
|
127
127
|
"@dnd-kit/core": "^6.3.1",
|
|
128
128
|
"@dnd-kit/sortable": "^10.0.0",
|