@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.cjs
CHANGED
|
@@ -884,11 +884,32 @@ function isPlainObject(value) {
|
|
|
884
884
|
if (typeof value === "function") return false;
|
|
885
885
|
return true;
|
|
886
886
|
}
|
|
887
|
+
function subtreeHasMarker(value) {
|
|
888
|
+
const cached = markerPresenceCache.get(value);
|
|
889
|
+
if (cached !== void 0) return cached;
|
|
890
|
+
let found = false;
|
|
891
|
+
const children = Array.isArray(value) ? value : Object.values(value);
|
|
892
|
+
for (const child of children) {
|
|
893
|
+
if (core.isRenderBindingMarker(child)) {
|
|
894
|
+
found = true;
|
|
895
|
+
break;
|
|
896
|
+
}
|
|
897
|
+
if (Array.isArray(child) || isPlainObject(child)) {
|
|
898
|
+
if (subtreeHasMarker(child)) {
|
|
899
|
+
found = true;
|
|
900
|
+
break;
|
|
901
|
+
}
|
|
902
|
+
}
|
|
903
|
+
}
|
|
904
|
+
markerPresenceCache.set(value, found);
|
|
905
|
+
return found;
|
|
906
|
+
}
|
|
887
907
|
function walkValue(value, scopeTrait, entity, config, state) {
|
|
888
908
|
if (core.isRenderBindingMarker(value)) {
|
|
889
909
|
return { resolved: resolveMarkerExpression(value.expression, entity, config, state), changed: true };
|
|
890
910
|
}
|
|
891
911
|
if (Array.isArray(value)) {
|
|
912
|
+
if (!subtreeHasMarker(value)) return { resolved: value, changed: false };
|
|
892
913
|
const out = [];
|
|
893
914
|
let changed = false;
|
|
894
915
|
for (const item of value) {
|
|
@@ -906,6 +927,7 @@ function walkValue(value, scopeTrait, entity, config, state) {
|
|
|
906
927
|
return changed ? { resolved: out, changed: true } : { resolved: value, changed: false };
|
|
907
928
|
}
|
|
908
929
|
if (isPlainObject(value)) {
|
|
930
|
+
if (!subtreeHasMarker(value)) return { resolved: value, changed: false };
|
|
909
931
|
const sourceTrait = value._sourceTrait;
|
|
910
932
|
if (typeof sourceTrait === "string" && sourceTrait !== scopeTrait) {
|
|
911
933
|
return { resolved: value, changed: false };
|
|
@@ -931,9 +953,11 @@ function resolveRenderBindingMarkers(props, scopeTrait, entity, config, state) {
|
|
|
931
953
|
}
|
|
932
954
|
return changed ? out : props;
|
|
933
955
|
}
|
|
956
|
+
var markerPresenceCache;
|
|
934
957
|
var init_resolve_render_bindings = __esm({
|
|
935
958
|
"lib/resolve-render-bindings.ts"() {
|
|
936
959
|
"use client";
|
|
960
|
+
markerPresenceCache = /* @__PURE__ */ new WeakMap();
|
|
937
961
|
}
|
|
938
962
|
});
|
|
939
963
|
function cn(...inputs) {
|
|
@@ -26995,7 +27019,7 @@ function fileIcon(name) {
|
|
|
26995
27019
|
return "file";
|
|
26996
27020
|
}
|
|
26997
27021
|
}
|
|
26998
|
-
var TreeNodeItem, FileTree;
|
|
27022
|
+
var TreeNodeItem, FlatTreeNodeItem, FileTree;
|
|
26999
27023
|
var init_FileTree = __esm({
|
|
27000
27024
|
"components/core/molecules/FileTree.tsx"() {
|
|
27001
27025
|
"use client";
|
|
@@ -27080,14 +27104,101 @@ var init_FileTree = __esm({
|
|
|
27080
27104
|
)) })
|
|
27081
27105
|
] });
|
|
27082
27106
|
};
|
|
27107
|
+
FlatTreeNodeItem = ({
|
|
27108
|
+
item,
|
|
27109
|
+
depth,
|
|
27110
|
+
indent,
|
|
27111
|
+
childrenByParent,
|
|
27112
|
+
onNodeSelect,
|
|
27113
|
+
defaultExpanded = false
|
|
27114
|
+
}) => {
|
|
27115
|
+
const [expanded, setExpanded] = React85.useState(defaultExpanded || depth < 1);
|
|
27116
|
+
const children = childrenByParent.get(item.id);
|
|
27117
|
+
const hasChildren = !!children && children.length > 0;
|
|
27118
|
+
const handleClick = React85.useCallback(() => {
|
|
27119
|
+
if (hasChildren) setExpanded((prev) => !prev);
|
|
27120
|
+
onNodeSelect?.(item.id);
|
|
27121
|
+
}, [hasChildren, item.id, onNodeSelect]);
|
|
27122
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
27123
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
27124
|
+
Box,
|
|
27125
|
+
{
|
|
27126
|
+
className: "flex items-center gap-1.5 py-0.5 px-2 cursor-pointer rounded-sm transition-colors hover:bg-muted",
|
|
27127
|
+
style: { paddingLeft: depth * indent + 8 },
|
|
27128
|
+
onClick: handleClick,
|
|
27129
|
+
role: "treeitem",
|
|
27130
|
+
"aria-expanded": hasChildren ? expanded : void 0,
|
|
27131
|
+
children: [
|
|
27132
|
+
hasChildren ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
27133
|
+
Icon,
|
|
27134
|
+
{
|
|
27135
|
+
name: expanded ? "chevron-down" : "chevron-right",
|
|
27136
|
+
size: "xs",
|
|
27137
|
+
className: "text-[var(--color-muted-foreground)] flex-shrink-0"
|
|
27138
|
+
}
|
|
27139
|
+
) : /* @__PURE__ */ jsxRuntime.jsx(Box, { style: { width: 12, flexShrink: 0 } }),
|
|
27140
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
27141
|
+
Icon,
|
|
27142
|
+
{
|
|
27143
|
+
name: item.icon ?? (hasChildren ? expanded ? "folder-open" : "folder" : "file"),
|
|
27144
|
+
size: "xs",
|
|
27145
|
+
className: hasChildren ? "text-[var(--color-warning)]" : "text-[var(--color-muted-foreground)]"
|
|
27146
|
+
}
|
|
27147
|
+
),
|
|
27148
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "caption", className: "truncate font-mono text-xs", children: item.label })
|
|
27149
|
+
]
|
|
27150
|
+
}
|
|
27151
|
+
),
|
|
27152
|
+
hasChildren && expanded && /* @__PURE__ */ jsxRuntime.jsx(Box, { role: "group", children: children.map((child) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
27153
|
+
FlatTreeNodeItem,
|
|
27154
|
+
{
|
|
27155
|
+
item: child,
|
|
27156
|
+
depth: depth + 1,
|
|
27157
|
+
indent,
|
|
27158
|
+
childrenByParent,
|
|
27159
|
+
onNodeSelect
|
|
27160
|
+
},
|
|
27161
|
+
child.id
|
|
27162
|
+
)) })
|
|
27163
|
+
] });
|
|
27164
|
+
};
|
|
27083
27165
|
FileTree = ({
|
|
27084
27166
|
tree,
|
|
27167
|
+
items,
|
|
27085
27168
|
selectedPath,
|
|
27086
27169
|
onFileSelect,
|
|
27170
|
+
onNodeSelect,
|
|
27087
27171
|
className,
|
|
27088
27172
|
indent = 16
|
|
27089
27173
|
}) => {
|
|
27090
|
-
if (
|
|
27174
|
+
if (items) {
|
|
27175
|
+
if (items.length === 0) return null;
|
|
27176
|
+
const ids = new Set(items.map((node) => node.id));
|
|
27177
|
+
const childrenByParent = /* @__PURE__ */ new Map();
|
|
27178
|
+
const roots = [];
|
|
27179
|
+
for (const item of items) {
|
|
27180
|
+
if (item.parentId && ids.has(item.parentId)) {
|
|
27181
|
+
const siblings = childrenByParent.get(item.parentId);
|
|
27182
|
+
if (siblings) siblings.push(item);
|
|
27183
|
+
else childrenByParent.set(item.parentId, [item]);
|
|
27184
|
+
} else {
|
|
27185
|
+
roots.push(item);
|
|
27186
|
+
}
|
|
27187
|
+
}
|
|
27188
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Box, { className: `py-1 overflow-y-auto ${className ?? ""}`, role: "tree", children: roots.map((item) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
27189
|
+
FlatTreeNodeItem,
|
|
27190
|
+
{
|
|
27191
|
+
item,
|
|
27192
|
+
depth: 0,
|
|
27193
|
+
indent,
|
|
27194
|
+
childrenByParent,
|
|
27195
|
+
onNodeSelect,
|
|
27196
|
+
defaultExpanded: true
|
|
27197
|
+
},
|
|
27198
|
+
item.id
|
|
27199
|
+
)) });
|
|
27200
|
+
}
|
|
27201
|
+
if (!tree || tree.length === 0) return null;
|
|
27091
27202
|
return /* @__PURE__ */ jsxRuntime.jsx(Box, { className: `py-1 overflow-y-auto ${className ?? ""}`, role: "tree", children: tree.map((node) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
27092
27203
|
TreeNodeItem,
|
|
27093
27204
|
{
|
|
@@ -28418,7 +28529,7 @@ var init_debug = __esm({
|
|
|
28418
28529
|
logger.createLogger("almadar:ui:debug:game-state");
|
|
28419
28530
|
}
|
|
28420
28531
|
});
|
|
28421
|
-
var isRelationsDebugEnabled, RelationSelect;
|
|
28532
|
+
var isRelationsDebugEnabled, MANY_CARDINALITIES, RelationSelect;
|
|
28422
28533
|
var init_RelationSelect = __esm({
|
|
28423
28534
|
"components/core/molecules/RelationSelect.tsx"() {
|
|
28424
28535
|
"use client";
|
|
@@ -28432,6 +28543,11 @@ var init_RelationSelect = __esm({
|
|
|
28432
28543
|
init_Typography();
|
|
28433
28544
|
init_debug();
|
|
28434
28545
|
isRelationsDebugEnabled = () => isDebugEnabled();
|
|
28546
|
+
MANY_CARDINALITIES = [
|
|
28547
|
+
"many",
|
|
28548
|
+
"one-to-many",
|
|
28549
|
+
"many-to-many"
|
|
28550
|
+
];
|
|
28435
28551
|
RelationSelect = ({
|
|
28436
28552
|
value,
|
|
28437
28553
|
onChange,
|
|
@@ -30096,17 +30212,21 @@ var init_MathCanvas = __esm({
|
|
|
30096
30212
|
error
|
|
30097
30213
|
}) => {
|
|
30098
30214
|
const eventBus = useEventBus();
|
|
30215
|
+
const keyMapKey = keyMap ? JSON.stringify(keyMap) : null;
|
|
30216
|
+
const keyUpMapKey = keyUpMap ? JSON.stringify(keyUpMap) : null;
|
|
30217
|
+
const stableKeyMap = React85.useMemo(() => keyMap, [keyMapKey]);
|
|
30218
|
+
const stableKeyUpMap = React85.useMemo(() => keyUpMap, [keyUpMapKey]);
|
|
30099
30219
|
React85.useEffect(() => {
|
|
30100
|
-
if (!
|
|
30220
|
+
if (!stableKeyMap && !stableKeyUpMap) return;
|
|
30101
30221
|
const onDown = (e) => {
|
|
30102
|
-
const ev =
|
|
30222
|
+
const ev = stableKeyMap?.[e.code];
|
|
30103
30223
|
if (ev) {
|
|
30104
30224
|
eventBus.emit(`UI:${ev}`, {});
|
|
30105
30225
|
e.preventDefault();
|
|
30106
30226
|
}
|
|
30107
30227
|
};
|
|
30108
30228
|
const onUp = (e) => {
|
|
30109
|
-
const ev =
|
|
30229
|
+
const ev = stableKeyUpMap?.[e.code];
|
|
30110
30230
|
if (ev) eventBus.emit(`UI:${ev}`, {});
|
|
30111
30231
|
};
|
|
30112
30232
|
window.addEventListener("keydown", onDown);
|
|
@@ -30115,7 +30235,7 @@ var init_MathCanvas = __esm({
|
|
|
30115
30235
|
window.removeEventListener("keydown", onDown);
|
|
30116
30236
|
window.removeEventListener("keyup", onUp);
|
|
30117
30237
|
};
|
|
30118
|
-
}, [
|
|
30238
|
+
}, [stableKeyMap, stableKeyUpMap, eventBus]);
|
|
30119
30239
|
const derivedShapes = React85.useMemo(() => {
|
|
30120
30240
|
const out = [];
|
|
30121
30241
|
const margin = 24;
|
|
@@ -42414,6 +42534,9 @@ function determineInputType(field) {
|
|
|
42414
42534
|
if (field.type === "relation" || field.relation) {
|
|
42415
42535
|
return "relation";
|
|
42416
42536
|
}
|
|
42537
|
+
if (field.type === "array") {
|
|
42538
|
+
return "array";
|
|
42539
|
+
}
|
|
42417
42540
|
if (field.type === "enum" || field.values || getEnumOptions(field).length > 0) {
|
|
42418
42541
|
return "select";
|
|
42419
42542
|
}
|
|
@@ -42489,6 +42612,7 @@ var init_Form = __esm({
|
|
|
42489
42612
|
init_Typography();
|
|
42490
42613
|
init_Icon();
|
|
42491
42614
|
init_RelationSelect();
|
|
42615
|
+
init_TagInput();
|
|
42492
42616
|
init_UploadDropZone();
|
|
42493
42617
|
init_Alert();
|
|
42494
42618
|
init_useEventBus();
|
|
@@ -42568,7 +42692,7 @@ var init_Form = __esm({
|
|
|
42568
42692
|
values: "values" in f3 ? f3.values : void 0,
|
|
42569
42693
|
min: f3.min,
|
|
42570
42694
|
max: f3.max,
|
|
42571
|
-
relation: "relation" in f3 ? { entity: f3.relation.entity } : void 0
|
|
42695
|
+
relation: "relation" in f3 ? { entity: f3.relation.entity, cardinality: f3.relation.cardinality } : void 0
|
|
42572
42696
|
})
|
|
42573
42697
|
);
|
|
42574
42698
|
}, [entity, fields]);
|
|
@@ -42803,7 +42927,7 @@ var init_Form = __esm({
|
|
|
42803
42927
|
values: "values" in entityField ? entityField.values : void 0,
|
|
42804
42928
|
min: entityField.min,
|
|
42805
42929
|
max: entityField.max,
|
|
42806
|
-
relation: "relation" in entityField ? { entity: entityField.relation.entity } : void 0
|
|
42930
|
+
relation: "relation" in entityField ? { entity: entityField.relation.entity, cardinality: entityField.relation.cardinality } : void 0
|
|
42807
42931
|
};
|
|
42808
42932
|
}
|
|
42809
42933
|
return { name: field, type: "string" };
|
|
@@ -42915,6 +43039,22 @@ var init_Form = __esm({
|
|
|
42915
43039
|
case "relation": {
|
|
42916
43040
|
const relationOptions = relationsData[fieldName] || [];
|
|
42917
43041
|
const relationLoading = relationsLoading[fieldName] || false;
|
|
43042
|
+
if (field.relation?.cardinality !== void 0 && MANY_CARDINALITIES.includes(field.relation.cardinality)) {
|
|
43043
|
+
const selectedValues = Array.isArray(currentValue) ? currentValue.map((v) => String(v)) : [];
|
|
43044
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
43045
|
+
Select,
|
|
43046
|
+
{
|
|
43047
|
+
...commonProps,
|
|
43048
|
+
multiple: true,
|
|
43049
|
+
searchable: true,
|
|
43050
|
+
clearable: true,
|
|
43051
|
+
options: [...relationOptions],
|
|
43052
|
+
value: selectedValues,
|
|
43053
|
+
onValueChange: (value) => handleChange(fieldName, Array.isArray(value) ? value : [value]),
|
|
43054
|
+
placeholder: field.placeholder || `Select ${label}...`
|
|
43055
|
+
}
|
|
43056
|
+
);
|
|
43057
|
+
}
|
|
42918
43058
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
42919
43059
|
RelationSelect,
|
|
42920
43060
|
{
|
|
@@ -42929,6 +43069,18 @@ var init_Form = __esm({
|
|
|
42929
43069
|
}
|
|
42930
43070
|
);
|
|
42931
43071
|
}
|
|
43072
|
+
case "array": {
|
|
43073
|
+
const arrayValue = Array.isArray(currentValue) ? currentValue.map((v) => String(v)) : currentValue != null && currentValue !== "" ? [String(currentValue)] : [];
|
|
43074
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
43075
|
+
TagInput,
|
|
43076
|
+
{
|
|
43077
|
+
placeholder: field.placeholder,
|
|
43078
|
+
disabled: isLoading,
|
|
43079
|
+
value: arrayValue,
|
|
43080
|
+
onChange: (next) => handleChange(fieldName, [...next])
|
|
43081
|
+
}
|
|
43082
|
+
);
|
|
43083
|
+
}
|
|
42932
43084
|
case "number":
|
|
42933
43085
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
42934
43086
|
Input,
|
|
@@ -48497,7 +48649,10 @@ function enrichFormFields(fields, entityDef) {
|
|
|
48497
48649
|
enriched.values = entityField.enumValues;
|
|
48498
48650
|
}
|
|
48499
48651
|
if (entityField.relation) {
|
|
48500
|
-
enriched.relation =
|
|
48652
|
+
enriched.relation = {
|
|
48653
|
+
entity: entityField.relation.entity,
|
|
48654
|
+
cardinality: entityField.relation.cardinality
|
|
48655
|
+
};
|
|
48501
48656
|
}
|
|
48502
48657
|
return enriched;
|
|
48503
48658
|
}
|
|
@@ -48525,7 +48680,10 @@ function enrichFormFields(fields, entityDef) {
|
|
|
48525
48680
|
}
|
|
48526
48681
|
}
|
|
48527
48682
|
if (!obj.relation && entityField.relation) {
|
|
48528
|
-
enriched.relation =
|
|
48683
|
+
enriched.relation = {
|
|
48684
|
+
entity: entityField.relation.entity,
|
|
48685
|
+
cardinality: entityField.relation.cardinality
|
|
48686
|
+
};
|
|
48529
48687
|
}
|
|
48530
48688
|
return enriched;
|
|
48531
48689
|
}
|
|
@@ -48540,7 +48698,12 @@ function enrichDetailFields(fields, entityDef) {
|
|
|
48540
48698
|
const meta = { type: entityField.type };
|
|
48541
48699
|
const values = entityField.values ?? entityField.enumValues;
|
|
48542
48700
|
if (values && values.length > 0) meta.values = values;
|
|
48543
|
-
if (entityField.relation)
|
|
48701
|
+
if (entityField.relation) {
|
|
48702
|
+
meta.relation = {
|
|
48703
|
+
entity: entityField.relation.entity,
|
|
48704
|
+
cardinality: entityField.relation.cardinality
|
|
48705
|
+
};
|
|
48706
|
+
}
|
|
48544
48707
|
return meta;
|
|
48545
48708
|
};
|
|
48546
48709
|
return fields.map((field) => {
|
|
@@ -49094,6 +49257,32 @@ function isPlainConfigObject(value) {
|
|
|
49094
49257
|
const proto = Object.getPrototypeOf(value);
|
|
49095
49258
|
return proto === Object.prototype || proto === null;
|
|
49096
49259
|
}
|
|
49260
|
+
function subtreeHasTraitRef(value) {
|
|
49261
|
+
const cached = traitRefPresenceCache.get(value);
|
|
49262
|
+
if (cached !== void 0) return cached;
|
|
49263
|
+
let found = false;
|
|
49264
|
+
const children = Array.isArray(value) ? value : Object.values(value);
|
|
49265
|
+
for (const child of children) {
|
|
49266
|
+
if (typeof child === "string" && TRAIT_BINDING_RE.test(child)) {
|
|
49267
|
+
found = true;
|
|
49268
|
+
break;
|
|
49269
|
+
}
|
|
49270
|
+
if (core.isRenderBindingMarker(child)) continue;
|
|
49271
|
+
if (Array.isArray(child)) {
|
|
49272
|
+
if (subtreeHasTraitRef(child)) {
|
|
49273
|
+
found = true;
|
|
49274
|
+
break;
|
|
49275
|
+
}
|
|
49276
|
+
} else if (child !== null && typeof child === "object" && isPlainConfigObject(child)) {
|
|
49277
|
+
if (subtreeHasTraitRef(child)) {
|
|
49278
|
+
found = true;
|
|
49279
|
+
break;
|
|
49280
|
+
}
|
|
49281
|
+
}
|
|
49282
|
+
}
|
|
49283
|
+
traitRefPresenceCache.set(value, found);
|
|
49284
|
+
return found;
|
|
49285
|
+
}
|
|
49097
49286
|
function substituteTraitRefsDeep(value, pathKey) {
|
|
49098
49287
|
if (core.isRenderBindingMarker(value)) return value;
|
|
49099
49288
|
if (typeof value === "string") {
|
|
@@ -49108,11 +49297,13 @@ function substituteTraitRefsDeep(value, pathKey) {
|
|
|
49108
49297
|
return value;
|
|
49109
49298
|
}
|
|
49110
49299
|
if (Array.isArray(value)) {
|
|
49300
|
+
if (!subtreeHasTraitRef(value)) return value;
|
|
49111
49301
|
return value.map(
|
|
49112
49302
|
(item, i) => substituteTraitRefsDeep(item, `${pathKey}[${i}]`)
|
|
49113
49303
|
);
|
|
49114
49304
|
}
|
|
49115
49305
|
if (typeof value === "object" && isPlainConfigObject(value)) {
|
|
49306
|
+
if (!subtreeHasTraitRef(value)) return value;
|
|
49116
49307
|
const out = {};
|
|
49117
49308
|
for (const [k, v] of Object.entries(value)) {
|
|
49118
49309
|
out[k] = substituteTraitRefsDeep(v, `${pathKey}.${k}`);
|
|
@@ -49401,7 +49592,7 @@ function UISlotRenderer({
|
|
|
49401
49592
|
}
|
|
49402
49593
|
return wrapped;
|
|
49403
49594
|
}
|
|
49404
|
-
var scopeWrapLog, TRAIT_BINDING_RE, SuspenseConfigContext, SlotContainedContext, SLOT_SKELETON_MAP, SELF_OVERLAY_PATTERNS, CONTENT_NODE_SLOTS, PATTERNS_WITH_CHILDREN;
|
|
49595
|
+
var scopeWrapLog, TRAIT_BINDING_RE, SuspenseConfigContext, SlotContainedContext, SLOT_SKELETON_MAP, SELF_OVERLAY_PATTERNS, CONTENT_NODE_SLOTS, PATTERNS_WITH_CHILDREN, traitRefPresenceCache;
|
|
49405
49596
|
var init_UISlotRenderer = __esm({
|
|
49406
49597
|
"components/core/organisms/UISlotRenderer.tsx"() {
|
|
49407
49598
|
"use client";
|
|
@@ -49475,6 +49666,7 @@ var init_UISlotRenderer = __esm({
|
|
|
49475
49666
|
"alert",
|
|
49476
49667
|
"dialog"
|
|
49477
49668
|
]);
|
|
49669
|
+
traitRefPresenceCache = /* @__PURE__ */ new WeakMap();
|
|
49478
49670
|
UISlotRenderer.displayName = "UISlotRenderer";
|
|
49479
49671
|
}
|
|
49480
49672
|
});
|
|
@@ -49602,6 +49794,20 @@ function createClientEffectHandlers(options) {
|
|
|
49602
49794
|
})
|
|
49603
49795
|
};
|
|
49604
49796
|
}
|
|
49797
|
+
|
|
49798
|
+
// lib/event-queue-coalesce.ts
|
|
49799
|
+
function enqueueEvent(queue, entry) {
|
|
49800
|
+
if (entry.tick !== void 0) {
|
|
49801
|
+
const pending = queue.find(
|
|
49802
|
+
(e) => e.tick !== void 0 && e.eventKey === entry.eventKey && e.targetTrait === entry.targetTrait
|
|
49803
|
+
);
|
|
49804
|
+
if (pending !== void 0) {
|
|
49805
|
+
pending.payload = entry.payload;
|
|
49806
|
+
return;
|
|
49807
|
+
}
|
|
49808
|
+
}
|
|
49809
|
+
queue.push(entry);
|
|
49810
|
+
}
|
|
49605
49811
|
var lambdaLog = logger.createLogger("almadar:ui:fn-form-lambda");
|
|
49606
49812
|
function isOperatorCall(value) {
|
|
49607
49813
|
const first = value[0];
|
|
@@ -50347,12 +50553,13 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
50347
50553
|
entityId
|
|
50348
50554
|
};
|
|
50349
50555
|
const emittedDuringExec = [];
|
|
50556
|
+
const tickName = flushEvent.startsWith("tick:") ? flushEvent.slice(5) : void 0;
|
|
50350
50557
|
const baseEmit = handlers.emit;
|
|
50351
50558
|
const trackingHandlers = {
|
|
50352
50559
|
...handlers,
|
|
50353
50560
|
emit: (event, eventPayload, source) => {
|
|
50354
50561
|
emittedDuringExec.push(event);
|
|
50355
|
-
baseEmit(event, eventPayload, source);
|
|
50562
|
+
baseEmit(event, eventPayload, tickName !== void 0 ? { ...source, tick: tickName } : source);
|
|
50356
50563
|
}
|
|
50357
50564
|
};
|
|
50358
50565
|
if (traitName === "Hero") {
|
|
@@ -50511,7 +50718,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
50511
50718
|
}
|
|
50512
50719
|
return () => scheduler.stopAll();
|
|
50513
50720
|
}, [traitBindings, runTickEffects, sharedGroups, sharedEntityStore, emitFromSharedWriter]);
|
|
50514
|
-
const processEventQueued = React85.useCallback(async (eventKey, payload, targetTrait) => {
|
|
50721
|
+
const processEventQueued = React85.useCallback(async (eventKey, payload, targetTrait, tick, sourceTrait) => {
|
|
50515
50722
|
const normalizedEvent = normalizeEventKey(eventKey);
|
|
50516
50723
|
const bindings = traitBindingsRef.current;
|
|
50517
50724
|
const currentManager = managerRef.current;
|
|
@@ -50700,7 +50907,11 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
50700
50907
|
if (orbital) dispatchedOrbitals.add(orbital);
|
|
50701
50908
|
}
|
|
50702
50909
|
const relayPayload = targetTrait !== void 0 ? { ...payload ?? {}, _targetTrait: targetTrait } : payload;
|
|
50703
|
-
|
|
50910
|
+
if (tick !== void 0) {
|
|
50911
|
+
void onEventProcessed(normalizedEvent, relayPayload, dispatchedOrbitals, tick, sourceTrait);
|
|
50912
|
+
} else {
|
|
50913
|
+
await onEventProcessed(normalizedEvent, relayPayload, dispatchedOrbitals);
|
|
50914
|
+
}
|
|
50704
50915
|
}
|
|
50705
50916
|
}, [entities, eventBus, sharedEntityStore]);
|
|
50706
50917
|
const drainEventQueue = React85.useCallback(async () => {
|
|
@@ -50709,14 +50920,14 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
50709
50920
|
try {
|
|
50710
50921
|
while (eventQueueRef.current.length > 0) {
|
|
50711
50922
|
const entry = eventQueueRef.current.shift();
|
|
50712
|
-
await processEventQueued(entry.eventKey, entry.payload, entry.targetTrait);
|
|
50923
|
+
await processEventQueued(entry.eventKey, entry.payload, entry.targetTrait, entry.tick, entry.sourceTrait);
|
|
50713
50924
|
}
|
|
50714
50925
|
} finally {
|
|
50715
50926
|
processingRef.current = false;
|
|
50716
50927
|
}
|
|
50717
50928
|
}, [processEventQueued]);
|
|
50718
|
-
const enqueueAndDrain = React85.useCallback((eventKey, payload, targetTrait) => {
|
|
50719
|
-
eventQueueRef.current
|
|
50929
|
+
const enqueueAndDrain = React85.useCallback((eventKey, payload, targetTrait, tick, sourceTrait) => {
|
|
50930
|
+
enqueueEvent(eventQueueRef.current, { eventKey, payload, targetTrait, tick, sourceTrait });
|
|
50720
50931
|
void drainEventQueue();
|
|
50721
50932
|
}, [drainEventQueue]);
|
|
50722
50933
|
React85.useCallback((eventKey, payload) => {
|
|
@@ -50769,7 +50980,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
50769
50980
|
crossTraitLog.debug("self:fire-server-cascade", { traitName, busKey: selfBusKey, eventKey });
|
|
50770
50981
|
}
|
|
50771
50982
|
crossTraitLog.debug("self:fire", { traitName, busKey: selfBusKey, eventKey });
|
|
50772
|
-
enqueueAndDrain(eventKey, event.payload, traitName);
|
|
50983
|
+
enqueueAndDrain(eventKey, event.payload, traitName, event.source?.tick, event.source?.trait);
|
|
50773
50984
|
});
|
|
50774
50985
|
unsubscribes.push(() => {
|
|
50775
50986
|
crossTraitLog.debug("self:unsubscribe", { traitName, busKey: selfBusKey, eventKey });
|
|
@@ -50787,7 +50998,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
50787
50998
|
const bareKey = `UI:${eventKey}`;
|
|
50788
50999
|
const unsub = eventBus.on(bareKey, (event) => {
|
|
50789
51000
|
crossTraitLog.debug("bare-cascade:fire", { bareKey, eventKey });
|
|
50790
|
-
enqueueAndDrain(eventKey, event.payload);
|
|
51001
|
+
enqueueAndDrain(eventKey, event.payload, void 0, event.source?.tick, event.source?.trait);
|
|
50791
51002
|
});
|
|
50792
51003
|
unsubscribes.push(() => {
|
|
50793
51004
|
crossTraitLog.debug("bare-cascade:unsubscribe", { bareKey, eventKey });
|
|
@@ -50821,7 +51032,9 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
50821
51032
|
enqueueAndDrain(
|
|
50822
51033
|
listen.triggers,
|
|
50823
51034
|
core.applyListenPayloadMapping(listen.payloadMapping, event.payload, evaluator.evaluateListenPayloadExpr),
|
|
50824
|
-
binding.trait.name
|
|
51035
|
+
binding.trait.name,
|
|
51036
|
+
event.source?.tick,
|
|
51037
|
+
event.source?.trait
|
|
50825
51038
|
);
|
|
50826
51039
|
});
|
|
50827
51040
|
unsubscribes.push(() => {
|
|
@@ -51116,7 +51329,7 @@ function TraitInitializer({ traits: traits2, routeParams, orbitalNames, onNaviga
|
|
|
51116
51329
|
[serverActiveTraits]
|
|
51117
51330
|
);
|
|
51118
51331
|
const uiSlots = context.useUISlots();
|
|
51119
|
-
const onEventProcessed = React85.useCallback(async (event, payload, dispatchedOrbitals) => {
|
|
51332
|
+
const onEventProcessed = React85.useCallback(async (event, payload, dispatchedOrbitals, tick, sourceTrait) => {
|
|
51120
51333
|
if (!bridge.connected || !orbitalNames?.length) return;
|
|
51121
51334
|
const targets = dispatchedOrbitals && dispatchedOrbitals.size > 0 ? orbitalNames.filter((n) => dispatchedOrbitals.has(n)) : orbitalNames;
|
|
51122
51335
|
xOrbitalLog.debug("TraitInitializer:fanout", () => ({
|
|
@@ -51126,6 +51339,10 @@ function TraitInitializer({ traits: traits2, routeParams, orbitalNames, onNaviga
|
|
|
51126
51339
|
dispatchedOrbitalsSize: dispatchedOrbitals?.size ?? 0
|
|
51127
51340
|
}));
|
|
51128
51341
|
for (const name of targets) {
|
|
51342
|
+
if (tick !== void 0) {
|
|
51343
|
+
void bridge.sendEvent(name, event, withActiveTraits(payload), tick, sourceTrait);
|
|
51344
|
+
continue;
|
|
51345
|
+
}
|
|
51129
51346
|
const { effects, meta } = await bridge.sendEvent(name, event, withActiveTraits(payload));
|
|
51130
51347
|
recordServerResponse(name, event, meta);
|
|
51131
51348
|
applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits, activeTraitNames, onNavigateBack);
|
|
@@ -51601,11 +51818,13 @@ function BrowserPlayground({
|
|
|
51601
51818
|
unregister: async () => {
|
|
51602
51819
|
runtime.unregisterAll();
|
|
51603
51820
|
},
|
|
51604
|
-
sendEvent: async (orbitalName, event, payload) => {
|
|
51821
|
+
sendEvent: async (orbitalName, event, payload, _clientId, tick, sourceTrait) => {
|
|
51605
51822
|
await registrationReady;
|
|
51606
51823
|
return runtime.processOrbitalEvent(orbitalName, {
|
|
51607
51824
|
event,
|
|
51608
|
-
payload
|
|
51825
|
+
payload,
|
|
51826
|
+
tick,
|
|
51827
|
+
sourceTrait
|
|
51609
51828
|
// @almadar/runtime OrbitalEventResponse.clientEffects uses a wider ClientEffectTuple than
|
|
51610
51829
|
// ServerBridge's local definition — cast at this boundary (upstream fix queued).
|
|
51611
51830
|
});
|
package/dist/runtime/index.d.cts
CHANGED
|
@@ -5,8 +5,8 @@ import * as _almadar_runtime from '@almadar/runtime';
|
|
|
5
5
|
import { TraitState, EffectHandlers } from '@almadar/runtime';
|
|
6
6
|
import '../useEventBus-Ckr4wqW3.cjs';
|
|
7
7
|
import { c as useUISlots } from '../UISlotContext-BlRDbHDy.cjs';
|
|
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.cjs';
|
|
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.cjs';
|
|
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.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;
|