@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.
@@ -360,11 +360,32 @@ function isPlainObject(value) {
360
360
  if (typeof value === "function") return false;
361
361
  return true;
362
362
  }
363
+ function subtreeHasMarker(value) {
364
+ const cached = markerPresenceCache.get(value);
365
+ if (cached !== void 0) return cached;
366
+ let found = false;
367
+ const children = Array.isArray(value) ? value : Object.values(value);
368
+ for (const child of children) {
369
+ if (core.isRenderBindingMarker(child)) {
370
+ found = true;
371
+ break;
372
+ }
373
+ if (Array.isArray(child) || isPlainObject(child)) {
374
+ if (subtreeHasMarker(child)) {
375
+ found = true;
376
+ break;
377
+ }
378
+ }
379
+ }
380
+ markerPresenceCache.set(value, found);
381
+ return found;
382
+ }
363
383
  function walkValue(value, scopeTrait, entity, config, state) {
364
384
  if (core.isRenderBindingMarker(value)) {
365
385
  return { resolved: resolveMarkerExpression(value.expression, entity, config, state), changed: true };
366
386
  }
367
387
  if (Array.isArray(value)) {
388
+ if (!subtreeHasMarker(value)) return { resolved: value, changed: false };
368
389
  const out = [];
369
390
  let changed = false;
370
391
  for (const item of value) {
@@ -382,6 +403,7 @@ function walkValue(value, scopeTrait, entity, config, state) {
382
403
  return changed ? { resolved: out, changed: true } : { resolved: value, changed: false };
383
404
  }
384
405
  if (isPlainObject(value)) {
406
+ if (!subtreeHasMarker(value)) return { resolved: value, changed: false };
385
407
  const sourceTrait = value._sourceTrait;
386
408
  if (typeof sourceTrait === "string" && sourceTrait !== scopeTrait) {
387
409
  return { resolved: value, changed: false };
@@ -407,9 +429,11 @@ function resolveRenderBindingMarkers(props, scopeTrait, entity, config, state) {
407
429
  }
408
430
  return changed ? out : props;
409
431
  }
432
+ var markerPresenceCache;
410
433
  var init_resolve_render_bindings = __esm({
411
434
  "lib/resolve-render-bindings.ts"() {
412
435
  "use client";
436
+ markerPresenceCache = /* @__PURE__ */ new WeakMap();
413
437
  }
414
438
  });
415
439
  function cn(...inputs) {
@@ -12036,6 +12060,8 @@ function drawShape(ctx, shape, width, height, allShapes) {
12036
12060
  case "path": {
12037
12061
  if (!shape.path) break;
12038
12062
  const p = new Path2D(shape.path);
12063
+ ctx.lineJoin = "round";
12064
+ ctx.lineCap = "round";
12039
12065
  if (fill) {
12040
12066
  ctx.fillStyle = fill;
12041
12067
  ctx.fill(p);
@@ -12244,7 +12270,7 @@ var init_LearningCanvas = __esm({
12244
12270
  ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
12245
12271
  ctx.clearRect(0, 0, width, height);
12246
12272
  if (backgroundColor) {
12247
- ctx.fillStyle = backgroundColor;
12273
+ ctx.fillStyle = resolveColor2(backgroundColor, ctx, backgroundColor);
12248
12274
  ctx.fillRect(0, 0, width, height);
12249
12275
  }
12250
12276
  for (const shape of derivedShapes) {
@@ -27440,7 +27466,7 @@ function fileIcon(name) {
27440
27466
  return "file";
27441
27467
  }
27442
27468
  }
27443
- var TreeNodeItem, FileTree;
27469
+ var TreeNodeItem, FlatTreeNodeItem, FileTree;
27444
27470
  var init_FileTree = __esm({
27445
27471
  "components/core/molecules/FileTree.tsx"() {
27446
27472
  "use client";
@@ -27525,14 +27551,101 @@ var init_FileTree = __esm({
27525
27551
  )) })
27526
27552
  ] });
27527
27553
  };
27554
+ FlatTreeNodeItem = ({
27555
+ item,
27556
+ depth,
27557
+ indent,
27558
+ childrenByParent,
27559
+ onNodeSelect,
27560
+ defaultExpanded = false
27561
+ }) => {
27562
+ const [expanded, setExpanded] = React87.useState(defaultExpanded || depth < 1);
27563
+ const children = childrenByParent.get(item.id);
27564
+ const hasChildren = !!children && children.length > 0;
27565
+ const handleClick = React87.useCallback(() => {
27566
+ if (hasChildren) setExpanded((prev) => !prev);
27567
+ onNodeSelect?.(item.id);
27568
+ }, [hasChildren, item.id, onNodeSelect]);
27569
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
27570
+ /* @__PURE__ */ jsxRuntime.jsxs(
27571
+ Box,
27572
+ {
27573
+ className: "flex items-center gap-1.5 py-0.5 px-2 cursor-pointer rounded-sm transition-colors hover:bg-muted",
27574
+ style: { paddingLeft: depth * indent + 8 },
27575
+ onClick: handleClick,
27576
+ role: "treeitem",
27577
+ "aria-expanded": hasChildren ? expanded : void 0,
27578
+ children: [
27579
+ hasChildren ? /* @__PURE__ */ jsxRuntime.jsx(
27580
+ Icon,
27581
+ {
27582
+ name: expanded ? "chevron-down" : "chevron-right",
27583
+ size: "xs",
27584
+ className: "text-[var(--color-muted-foreground)] flex-shrink-0"
27585
+ }
27586
+ ) : /* @__PURE__ */ jsxRuntime.jsx(Box, { style: { width: 12, flexShrink: 0 } }),
27587
+ /* @__PURE__ */ jsxRuntime.jsx(
27588
+ Icon,
27589
+ {
27590
+ name: item.icon ?? (hasChildren ? expanded ? "folder-open" : "folder" : "file"),
27591
+ size: "xs",
27592
+ className: hasChildren ? "text-[var(--color-warning)]" : "text-[var(--color-muted-foreground)]"
27593
+ }
27594
+ ),
27595
+ /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "caption", className: "truncate font-mono text-xs", children: item.label })
27596
+ ]
27597
+ }
27598
+ ),
27599
+ hasChildren && expanded && /* @__PURE__ */ jsxRuntime.jsx(Box, { role: "group", children: children.map((child) => /* @__PURE__ */ jsxRuntime.jsx(
27600
+ FlatTreeNodeItem,
27601
+ {
27602
+ item: child,
27603
+ depth: depth + 1,
27604
+ indent,
27605
+ childrenByParent,
27606
+ onNodeSelect
27607
+ },
27608
+ child.id
27609
+ )) })
27610
+ ] });
27611
+ };
27528
27612
  FileTree = ({
27529
27613
  tree,
27614
+ items,
27530
27615
  selectedPath,
27531
27616
  onFileSelect,
27617
+ onNodeSelect,
27532
27618
  className,
27533
27619
  indent = 16
27534
27620
  }) => {
27535
- if (tree.length === 0) return null;
27621
+ if (items) {
27622
+ if (items.length === 0) return null;
27623
+ const ids = new Set(items.map((node) => node.id));
27624
+ const childrenByParent = /* @__PURE__ */ new Map();
27625
+ const roots = [];
27626
+ for (const item of items) {
27627
+ if (item.parentId && ids.has(item.parentId)) {
27628
+ const siblings = childrenByParent.get(item.parentId);
27629
+ if (siblings) siblings.push(item);
27630
+ else childrenByParent.set(item.parentId, [item]);
27631
+ } else {
27632
+ roots.push(item);
27633
+ }
27634
+ }
27635
+ return /* @__PURE__ */ jsxRuntime.jsx(Box, { className: `py-1 overflow-y-auto ${className ?? ""}`, role: "tree", children: roots.map((item) => /* @__PURE__ */ jsxRuntime.jsx(
27636
+ FlatTreeNodeItem,
27637
+ {
27638
+ item,
27639
+ depth: 0,
27640
+ indent,
27641
+ childrenByParent,
27642
+ onNodeSelect,
27643
+ defaultExpanded: true
27644
+ },
27645
+ item.id
27646
+ )) });
27647
+ }
27648
+ if (!tree || tree.length === 0) return null;
27536
27649
  return /* @__PURE__ */ jsxRuntime.jsx(Box, { className: `py-1 overflow-y-auto ${className ?? ""}`, role: "tree", children: tree.map((node) => /* @__PURE__ */ jsxRuntime.jsx(
27537
27650
  TreeNodeItem,
27538
27651
  {
@@ -28927,7 +29040,7 @@ var init_debug = __esm({
28927
29040
  logger.createLogger("almadar:ui:debug:game-state");
28928
29041
  }
28929
29042
  });
28930
- var isRelationsDebugEnabled, RelationSelect;
29043
+ var isRelationsDebugEnabled, MANY_CARDINALITIES, RelationSelect;
28931
29044
  var init_RelationSelect = __esm({
28932
29045
  "components/core/molecules/RelationSelect.tsx"() {
28933
29046
  "use client";
@@ -28941,6 +29054,11 @@ var init_RelationSelect = __esm({
28941
29054
  init_Typography();
28942
29055
  init_debug();
28943
29056
  isRelationsDebugEnabled = () => isDebugEnabled();
29057
+ MANY_CARDINALITIES = [
29058
+ "many",
29059
+ "one-to-many",
29060
+ "many-to-many"
29061
+ ];
28944
29062
  RelationSelect = ({
28945
29063
  value,
28946
29064
  onChange,
@@ -30580,6 +30698,9 @@ var init_MathCanvas = __esm({
30580
30698
  showAxes = true,
30581
30699
  showGrid = true,
30582
30700
  gridStep = 1,
30701
+ backgroundColor,
30702
+ gridColor = "var(--color-border, #9ca3af)",
30703
+ axisColor = "var(--color-muted-foreground, #374151)",
30583
30704
  showTickLabels = false,
30584
30705
  showCurveLabels = false,
30585
30706
  curves = [],
@@ -30602,17 +30723,21 @@ var init_MathCanvas = __esm({
30602
30723
  error
30603
30724
  }) => {
30604
30725
  const eventBus = useEventBus();
30726
+ const keyMapKey = keyMap ? JSON.stringify(keyMap) : null;
30727
+ const keyUpMapKey = keyUpMap ? JSON.stringify(keyUpMap) : null;
30728
+ const stableKeyMap = React87.useMemo(() => keyMap, [keyMapKey]);
30729
+ const stableKeyUpMap = React87.useMemo(() => keyUpMap, [keyUpMapKey]);
30605
30730
  React87.useEffect(() => {
30606
- if (!keyMap && !keyUpMap) return;
30731
+ if (!stableKeyMap && !stableKeyUpMap) return;
30607
30732
  const onDown = (e) => {
30608
- const ev = keyMap?.[e.code];
30733
+ const ev = stableKeyMap?.[e.code];
30609
30734
  if (ev) {
30610
30735
  eventBus.emit(`UI:${ev}`, {});
30611
30736
  e.preventDefault();
30612
30737
  }
30613
30738
  };
30614
30739
  const onUp = (e) => {
30615
- const ev = keyUpMap?.[e.code];
30740
+ const ev = stableKeyUpMap?.[e.code];
30616
30741
  if (ev) eventBus.emit(`UI:${ev}`, {});
30617
30742
  };
30618
30743
  window.addEventListener("keydown", onDown);
@@ -30621,7 +30746,7 @@ var init_MathCanvas = __esm({
30621
30746
  window.removeEventListener("keydown", onDown);
30622
30747
  window.removeEventListener("keyup", onUp);
30623
30748
  };
30624
- }, [keyMap, keyUpMap, eventBus]);
30749
+ }, [stableKeyMap, stableKeyUpMap, eventBus]);
30625
30750
  const derivedShapes = React87.useMemo(() => {
30626
30751
  const out = [];
30627
30752
  const margin = 24;
@@ -30634,11 +30759,11 @@ var init_MathCanvas = __esm({
30634
30759
  if (showGrid) {
30635
30760
  for (let x = Math.ceil(xMin / gridStep) * gridStep; x <= xMax; x += gridStep) {
30636
30761
  const px = mapX(x);
30637
- out.push({ type: "line", x1: px, y1: margin, x2: px, y2: height - margin, color: "#9ca3af", opacity: 0.35, lineWidth: 1 });
30762
+ out.push({ type: "line", x1: px, y1: margin, x2: px, y2: height - margin, color: gridColor, opacity: 0.35, lineWidth: 1 });
30638
30763
  }
30639
30764
  for (let y = Math.ceil(yMin / gridStep) * gridStep; y <= yMax; y += gridStep) {
30640
30765
  const py = mapY(y);
30641
- out.push({ type: "line", x1: margin, y1: py, x2: width - margin, y2: py, color: "#9ca3af", opacity: 0.35, lineWidth: 1 });
30766
+ out.push({ type: "line", x1: margin, y1: py, x2: width - margin, y2: py, color: gridColor, opacity: 0.35, lineWidth: 1 });
30642
30767
  }
30643
30768
  }
30644
30769
  if (showTickLabels) {
@@ -30709,8 +30834,8 @@ var init_MathCanvas = __esm({
30709
30834
  });
30710
30835
  }
30711
30836
  if (showAxes) {
30712
- out.push({ type: "line", x1: margin, y1: xAxisY, x2: width - margin, y2: xAxisY, color: "#374151", lineWidth: 2 });
30713
- out.push({ type: "line", x1: yAxisX, y1: margin, x2: yAxisX, y2: height - margin, color: "#374151", lineWidth: 2 });
30837
+ out.push({ type: "line", x1: margin, y1: xAxisY, x2: width - margin, y2: xAxisY, color: axisColor, lineWidth: 2 });
30838
+ out.push({ type: "line", x1: yAxisX, y1: margin, x2: yAxisX, y2: height - margin, color: axisColor, lineWidth: 2 });
30714
30839
  }
30715
30840
  for (const guide of guides) {
30716
30841
  const color = guide.color ?? "#9ca3af";
@@ -30733,23 +30858,36 @@ var init_MathCanvas = __esm({
30733
30858
  }
30734
30859
  for (const curve of curves) {
30735
30860
  if (!curve.samples || curve.samples.length < 2) continue;
30861
+ let d = "";
30862
+ let penDown = false;
30736
30863
  let lastInRange;
30737
30864
  for (let i = 1; i < curve.samples.length; i++) {
30738
30865
  const a = curve.samples[i - 1];
30739
30866
  const b = curve.samples[i];
30740
- if (a.x < xMin || a.x > xMax || b.x < xMin || b.x > xMax) continue;
30741
- out.push({
30742
- type: "line",
30743
- x1: mapX(a.x),
30744
- y1: mapY(a.y),
30745
- x2: mapX(b.x),
30746
- y2: mapY(b.y),
30747
- color: curve.color ?? "#2563eb",
30748
- lineWidth: 2,
30749
- dash: curve.dash
30750
- });
30751
- lastInRange = b;
30752
- }
30867
+ if (a.x < xMin && b.x < xMin || a.x > xMax && b.x > xMax) {
30868
+ penDown = false;
30869
+ continue;
30870
+ }
30871
+ const clip = (p, q, xLim) => {
30872
+ const t = q.x === p.x ? 0 : (xLim - p.x) / (q.x - p.x);
30873
+ return { x: xLim, y: p.y + t * (q.y - p.y) };
30874
+ };
30875
+ const ca = a.x < xMin ? clip(a, b, xMin) : a.x > xMax ? clip(a, b, xMax) : a;
30876
+ const cb = b.x < xMin ? clip(a, b, xMin) : b.x > xMax ? clip(a, b, xMax) : b;
30877
+ const pax = mapX(ca.x);
30878
+ const pay = mapY(ca.y);
30879
+ d += `${penDown ? "L" : "M"} ${pax} ${pay} L ${mapX(cb.x)} ${mapY(cb.y)} `;
30880
+ penDown = true;
30881
+ if (b.x >= xMin && b.x <= xMax) lastInRange = b;
30882
+ }
30883
+ if (!d) continue;
30884
+ out.push({
30885
+ type: "path",
30886
+ path: d,
30887
+ color: curve.color ?? "#2563eb",
30888
+ lineWidth: 2,
30889
+ dash: curve.dash
30890
+ });
30753
30891
  if (showCurveLabels && curve.label && lastInRange) {
30754
30892
  out.push({
30755
30893
  type: "text",
@@ -30864,6 +31002,8 @@ var init_MathCanvas = __esm({
30864
31002
  showAxes,
30865
31003
  showGrid,
30866
31004
  gridStep,
31005
+ gridColor,
31006
+ axisColor,
30867
31007
  showTickLabels,
30868
31008
  showCurveLabels,
30869
31009
  curves,
@@ -30883,6 +31023,7 @@ var init_MathCanvas = __esm({
30883
31023
  {
30884
31024
  width,
30885
31025
  height,
31026
+ backgroundColor,
30886
31027
  shapes: derivedShapes,
30887
31028
  readouts,
30888
31029
  traces,
@@ -43042,6 +43183,9 @@ function determineInputType(field) {
43042
43183
  if (field.type === "relation" || field.relation) {
43043
43184
  return "relation";
43044
43185
  }
43186
+ if (field.type === "array") {
43187
+ return "array";
43188
+ }
43045
43189
  if (field.type === "enum" || field.values || getEnumOptions(field).length > 0) {
43046
43190
  return "select";
43047
43191
  }
@@ -43117,6 +43261,7 @@ var init_Form = __esm({
43117
43261
  init_Typography();
43118
43262
  init_Icon();
43119
43263
  init_RelationSelect();
43264
+ init_TagInput();
43120
43265
  init_UploadDropZone();
43121
43266
  init_Alert();
43122
43267
  init_useEventBus();
@@ -43196,7 +43341,7 @@ var init_Form = __esm({
43196
43341
  values: "values" in f3 ? f3.values : void 0,
43197
43342
  min: f3.min,
43198
43343
  max: f3.max,
43199
- relation: "relation" in f3 ? { entity: f3.relation.entity } : void 0
43344
+ relation: "relation" in f3 ? { entity: f3.relation.entity, cardinality: f3.relation.cardinality } : void 0
43200
43345
  })
43201
43346
  );
43202
43347
  }, [entity, fields]);
@@ -43431,7 +43576,7 @@ var init_Form = __esm({
43431
43576
  values: "values" in entityField ? entityField.values : void 0,
43432
43577
  min: entityField.min,
43433
43578
  max: entityField.max,
43434
- relation: "relation" in entityField ? { entity: entityField.relation.entity } : void 0
43579
+ relation: "relation" in entityField ? { entity: entityField.relation.entity, cardinality: entityField.relation.cardinality } : void 0
43435
43580
  };
43436
43581
  }
43437
43582
  return { name: field, type: "string" };
@@ -43543,6 +43688,22 @@ var init_Form = __esm({
43543
43688
  case "relation": {
43544
43689
  const relationOptions = relationsData[fieldName] || [];
43545
43690
  const relationLoading = relationsLoading[fieldName] || false;
43691
+ if (field.relation?.cardinality !== void 0 && MANY_CARDINALITIES.includes(field.relation.cardinality)) {
43692
+ const selectedValues = Array.isArray(currentValue) ? currentValue.map((v) => String(v)) : [];
43693
+ return /* @__PURE__ */ jsxRuntime.jsx(
43694
+ Select,
43695
+ {
43696
+ ...commonProps,
43697
+ multiple: true,
43698
+ searchable: true,
43699
+ clearable: true,
43700
+ options: [...relationOptions],
43701
+ value: selectedValues,
43702
+ onValueChange: (value) => handleChange(fieldName, Array.isArray(value) ? value : [value]),
43703
+ placeholder: field.placeholder || `Select ${label}...`
43704
+ }
43705
+ );
43706
+ }
43546
43707
  return /* @__PURE__ */ jsxRuntime.jsx(
43547
43708
  RelationSelect,
43548
43709
  {
@@ -43557,6 +43718,18 @@ var init_Form = __esm({
43557
43718
  }
43558
43719
  );
43559
43720
  }
43721
+ case "array": {
43722
+ const arrayValue = Array.isArray(currentValue) ? currentValue.map((v) => String(v)) : currentValue != null && currentValue !== "" ? [String(currentValue)] : [];
43723
+ return /* @__PURE__ */ jsxRuntime.jsx(
43724
+ TagInput,
43725
+ {
43726
+ placeholder: field.placeholder,
43727
+ disabled: isLoading,
43728
+ value: arrayValue,
43729
+ onChange: (next) => handleChange(fieldName, [...next])
43730
+ }
43731
+ );
43732
+ }
43560
43733
  case "number":
43561
43734
  return /* @__PURE__ */ jsxRuntime.jsx(
43562
43735
  Input,
@@ -49106,7 +49279,10 @@ function enrichFormFields(fields, entityDef) {
49106
49279
  enriched.values = entityField.enumValues;
49107
49280
  }
49108
49281
  if (entityField.relation) {
49109
- enriched.relation = entityField.relation.entity;
49282
+ enriched.relation = {
49283
+ entity: entityField.relation.entity,
49284
+ cardinality: entityField.relation.cardinality
49285
+ };
49110
49286
  }
49111
49287
  return enriched;
49112
49288
  }
@@ -49134,7 +49310,10 @@ function enrichFormFields(fields, entityDef) {
49134
49310
  }
49135
49311
  }
49136
49312
  if (!obj.relation && entityField.relation) {
49137
- enriched.relation = entityField.relation.entity;
49313
+ enriched.relation = {
49314
+ entity: entityField.relation.entity,
49315
+ cardinality: entityField.relation.cardinality
49316
+ };
49138
49317
  }
49139
49318
  return enriched;
49140
49319
  }
@@ -49149,7 +49328,12 @@ function enrichDetailFields(fields, entityDef) {
49149
49328
  const meta = { type: entityField.type };
49150
49329
  const values = entityField.values ?? entityField.enumValues;
49151
49330
  if (values && values.length > 0) meta.values = values;
49152
- if (entityField.relation) meta.relation = entityField.relation.entity;
49331
+ if (entityField.relation) {
49332
+ meta.relation = {
49333
+ entity: entityField.relation.entity,
49334
+ cardinality: entityField.relation.cardinality
49335
+ };
49336
+ }
49153
49337
  return meta;
49154
49338
  };
49155
49339
  return fields.map((field) => {
@@ -49703,6 +49887,32 @@ function isPlainConfigObject(value) {
49703
49887
  const proto = Object.getPrototypeOf(value);
49704
49888
  return proto === Object.prototype || proto === null;
49705
49889
  }
49890
+ function subtreeHasTraitRef(value) {
49891
+ const cached = traitRefPresenceCache.get(value);
49892
+ if (cached !== void 0) return cached;
49893
+ let found = false;
49894
+ const children = Array.isArray(value) ? value : Object.values(value);
49895
+ for (const child of children) {
49896
+ if (typeof child === "string" && TRAIT_BINDING_RE.test(child)) {
49897
+ found = true;
49898
+ break;
49899
+ }
49900
+ if (core.isRenderBindingMarker(child)) continue;
49901
+ if (Array.isArray(child)) {
49902
+ if (subtreeHasTraitRef(child)) {
49903
+ found = true;
49904
+ break;
49905
+ }
49906
+ } else if (child !== null && typeof child === "object" && isPlainConfigObject(child)) {
49907
+ if (subtreeHasTraitRef(child)) {
49908
+ found = true;
49909
+ break;
49910
+ }
49911
+ }
49912
+ }
49913
+ traitRefPresenceCache.set(value, found);
49914
+ return found;
49915
+ }
49706
49916
  function substituteTraitRefsDeep(value, pathKey) {
49707
49917
  if (core.isRenderBindingMarker(value)) return value;
49708
49918
  if (typeof value === "string") {
@@ -49717,11 +49927,13 @@ function substituteTraitRefsDeep(value, pathKey) {
49717
49927
  return value;
49718
49928
  }
49719
49929
  if (Array.isArray(value)) {
49930
+ if (!subtreeHasTraitRef(value)) return value;
49720
49931
  return value.map(
49721
49932
  (item, i) => substituteTraitRefsDeep(item, `${pathKey}[${i}]`)
49722
49933
  );
49723
49934
  }
49724
49935
  if (typeof value === "object" && isPlainConfigObject(value)) {
49936
+ if (!subtreeHasTraitRef(value)) return value;
49725
49937
  const out = {};
49726
49938
  for (const [k, v] of Object.entries(value)) {
49727
49939
  out[k] = substituteTraitRefsDeep(v, `${pathKey}.${k}`);
@@ -50010,7 +50222,7 @@ function UISlotRenderer({
50010
50222
  }
50011
50223
  return wrapped;
50012
50224
  }
50013
- var scopeWrapLog, TRAIT_BINDING_RE, SuspenseConfigContext, SlotContainedContext, SLOT_SKELETON_MAP, SELF_OVERLAY_PATTERNS, CONTENT_NODE_SLOTS, PATTERNS_WITH_CHILDREN;
50225
+ var scopeWrapLog, TRAIT_BINDING_RE, SuspenseConfigContext, SlotContainedContext, SLOT_SKELETON_MAP, SELF_OVERLAY_PATTERNS, CONTENT_NODE_SLOTS, PATTERNS_WITH_CHILDREN, traitRefPresenceCache;
50014
50226
  var init_UISlotRenderer = __esm({
50015
50227
  "components/core/organisms/UISlotRenderer.tsx"() {
50016
50228
  "use client";
@@ -50084,6 +50296,7 @@ var init_UISlotRenderer = __esm({
50084
50296
  "alert",
50085
50297
  "dialog"
50086
50298
  ]);
50299
+ traitRefPresenceCache = /* @__PURE__ */ new WeakMap();
50087
50300
  UISlotRenderer.displayName = "UISlotRenderer";
50088
50301
  }
50089
50302
  });
@@ -51276,8 +51489,8 @@ function createHttpTransport(serverUrl) {
51276
51489
  } catch {
51277
51490
  }
51278
51491
  },
51279
- sendEvent: async (orbitalName, event, payload, clientId) => {
51280
- const body = { event, payload, clientId };
51492
+ sendEvent: async (orbitalName, event, payload, clientId, tick, sourceTrait) => {
51493
+ const body = { event, payload, clientId, tick, sourceTrait };
51281
51494
  const res = await fetch(`${serverUrl}/${orbitalName}/events`, {
51282
51495
  method: "POST",
51283
51496
  headers: { "Content-Type": "application/json" },
@@ -51322,12 +51535,15 @@ function ServerBridgeProvider({
51322
51535
  async () => transport.unregister(),
51323
51536
  [transport]
51324
51537
  );
51325
- const sendEvent = React87.useCallback(async (orbitalName, event, payload) => {
51538
+ const sendEvent = React87.useCallback(async (orbitalName, event, payload, tick, sourceTrait) => {
51326
51539
  const emptyMeta = { success: false, clientEffects: 0, dataEntities: {}, emittedEvents: [] };
51327
51540
  if (!connected) return { effects: [], meta: emptyMeta };
51328
51541
  try {
51329
- const result = await transport.sendEvent(orbitalName, event, payload, getTabClientId());
51542
+ const result = await transport.sendEvent(orbitalName, event, payload, getTabClientId(), tick, sourceTrait);
51330
51543
  const effects = [];
51544
+ if (tick !== void 0) {
51545
+ return { effects, meta: { ...emptyMeta, success: !!result.success, error: result.error } };
51546
+ }
51331
51547
  const responseData = result.data || {};
51332
51548
  const dataEntities = {};
51333
51549
  for (const [entityName, records] of Object.entries(responseData)) {
@@ -3,7 +3,7 @@ import { EntityRow, SExpr } from '@almadar/core';
3
3
  export { ANONYMOUS_USER } from '@almadar/core';
4
4
  import { U as UIThemeDefinition, j as UserData } from '../UserContext-g_LcDiGN.cjs';
5
5
  export { a as CurrentPagePathContext, b as CurrentPagePathProvider, c as CurrentPagePathProviderProps, d as DesignThemeProvider, O as OrbitalThemeProvider, e as OrbitalThemeProviderProps, h as UserContext, i as UserContextValue, k as UserProvider, l as UserProviderProps, u as useCurrentPagePath, m as useDesignTheme, n as useHasPermission, o as useHasRole, q as useUser, r as useUserForEvaluation } from '../UserContext-g_LcDiGN.cjs';
6
- export { E as EntityBindingContext, a as EntityBindingSource, b as EntitySchemaContextValue, c as EntitySchemaProvider, d as EntitySchemaProviderProps, S as SendEventResult, e as ServerBridgeContextValue, f as ServerBridgeProvider, g as ServerBridgeProviderProps, h as ServerBridgeTransport, i as ServerClientEffect, j as ServerResponseMeta, T as TraitContext, k as TraitContextValue, l as TraitInstance, m as TraitProvider, n as TraitProviderProps, u as useEntityBindingSnapshot, o as useEntitySchema, p as useEntitySchemaOptional, q as useServerBridge, r as useTrait, s as useTraitContext } from '../EntityBindingContext-BfZGeDfX.cjs';
6
+ export { E as EntityBindingContext, a as EntityBindingSource, b as EntitySchemaContextValue, c as EntitySchemaProvider, d as EntitySchemaProviderProps, S as SendEventResult, e as ServerBridgeContextValue, f as ServerBridgeProvider, g as ServerBridgeProviderProps, h as ServerBridgeTransport, i as ServerClientEffect, j as ServerResponseMeta, T as TraitContext, k as TraitContextValue, l as TraitInstance, m as TraitProvider, n as TraitProviderProps, u as useEntityBindingSnapshot, o as useEntitySchema, p as useEntitySchemaOptional, q as useServerBridge, r as useTrait, s as useTraitContext } from '../EntityBindingContext-Bn3ePJQC.cjs';
7
7
  import { j as UseOfflineExecutorResult, U as UseOfflineExecutorOptions } from '../offline-executor-QUdKOj7f.cjs';
8
8
  export { c as NavigationContextValue, d as NavigationProvider, e as NavigationProviderProps, f as NavigationState, k as comparePathSpecificity, m as extractRouteParams, n as findPageByName, o as findPageByPath, p as getAllPages, q as getDefaultPage, r as matchPath, s as matchPathAmong, t as pathMatches, u as useActivePage, v as useInitPayload, w as useNavigateTo, x as useNavigation, y as useNavigationId, z as useNavigationState } from '../offline-executor-QUdKOj7f.cjs';
9
9
  import { E as EventBusContextType } from '../event-bus-types-Bl78kokd.cjs';
@@ -3,7 +3,7 @@ import { EntityRow, SExpr } from '@almadar/core';
3
3
  export { ANONYMOUS_USER } from '@almadar/core';
4
4
  import { U as UIThemeDefinition, j as UserData } from '../UserContext-g_LcDiGN.js';
5
5
  export { a as CurrentPagePathContext, b as CurrentPagePathProvider, c as CurrentPagePathProviderProps, d as DesignThemeProvider, O as OrbitalThemeProvider, e as OrbitalThemeProviderProps, h as UserContext, i as UserContextValue, k as UserProvider, l as UserProviderProps, u as useCurrentPagePath, m as useDesignTheme, n as useHasPermission, o as useHasRole, q as useUser, r as useUserForEvaluation } from '../UserContext-g_LcDiGN.js';
6
- export { E as EntityBindingContext, a as EntityBindingSource, b as EntitySchemaContextValue, c as EntitySchemaProvider, d as EntitySchemaProviderProps, S as SendEventResult, e as ServerBridgeContextValue, f as ServerBridgeProvider, g as ServerBridgeProviderProps, h as ServerBridgeTransport, i as ServerClientEffect, j as ServerResponseMeta, T as TraitContext, k as TraitContextValue, l as TraitInstance, m as TraitProvider, n as TraitProviderProps, u as useEntityBindingSnapshot, o as useEntitySchema, p as useEntitySchemaOptional, q as useServerBridge, r as useTrait, s as useTraitContext } from '../EntityBindingContext-BfZGeDfX.js';
6
+ export { E as EntityBindingContext, a as EntityBindingSource, b as EntitySchemaContextValue, c as EntitySchemaProvider, d as EntitySchemaProviderProps, S as SendEventResult, e as ServerBridgeContextValue, f as ServerBridgeProvider, g as ServerBridgeProviderProps, h as ServerBridgeTransport, i as ServerClientEffect, j as ServerResponseMeta, T as TraitContext, k as TraitContextValue, l as TraitInstance, m as TraitProvider, n as TraitProviderProps, u as useEntityBindingSnapshot, o as useEntitySchema, p as useEntitySchemaOptional, q as useServerBridge, r as useTrait, s as useTraitContext } from '../EntityBindingContext-Bn3ePJQC.js';
7
7
  import { j as UseOfflineExecutorResult, U as UseOfflineExecutorOptions } from '../offline-executor-QUdKOj7f.js';
8
8
  export { c as NavigationContextValue, d as NavigationProvider, e as NavigationProviderProps, f as NavigationState, k as comparePathSpecificity, m as extractRouteParams, n as findPageByName, o as findPageByPath, p as getAllPages, q as getDefaultPage, r as matchPath, s as matchPathAmong, t as pathMatches, u as useActivePage, v as useInitPayload, w as useNavigateTo, x as useNavigation, y as useNavigationId, z as useNavigationState } from '../offline-executor-QUdKOj7f.js';
9
9
  import { E as EventBusContextType } from '../event-bus-types-Bl78kokd.js';