@almadar/ui 5.158.0 → 5.159.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,7 +360,16 @@ function isPlainObject(value) {
360
360
  if (typeof value === "function") return false;
361
361
  return true;
362
362
  }
363
+ function isEvaluatorResolvedData(value) {
364
+ return evaluatorResolvedData.has(value);
365
+ }
366
+ function brandResolved(value) {
367
+ if (value !== null && typeof value === "object" && !React87__namespace.default.isValidElement(value) && !(value instanceof Date)) {
368
+ resolvedMarkerFree.add(value);
369
+ }
370
+ }
363
371
  function subtreeHasMarker(value) {
372
+ if (resolvedMarkerFree.has(value)) return false;
364
373
  const cached = markerPresenceCache.get(value);
365
374
  if (cached !== void 0) return cached;
366
375
  let found = false;
@@ -382,10 +391,23 @@ function subtreeHasMarker(value) {
382
391
  }
383
392
  function walkValue(value, scopeTrait, entity, config, state) {
384
393
  if (core.isRenderBindingMarker(value)) {
385
- return { resolved: resolveMarkerExpression(value.expression, entity, config, state), changed: true };
394
+ const cached = markerResolutionCache.get(value);
395
+ if (cached !== void 0 && cached.entity === entity && cached.config === config && cached.state === state) {
396
+ return { resolved: cached.resolved, changed: false };
397
+ }
398
+ const resolved = resolveMarkerExpression(value.expression, entity, config, state);
399
+ markerResolutionCache.set(value, { entity, config, state, resolved });
400
+ if (resolved !== null && typeof resolved === "object" && !React87__namespace.default.isValidElement(resolved) && !(resolved instanceof Date)) {
401
+ resolvedMarkerFree.add(resolved);
402
+ evaluatorResolvedData.add(resolved);
403
+ }
404
+ return { resolved, changed: true };
386
405
  }
387
406
  if (Array.isArray(value)) {
388
- if (!subtreeHasMarker(value)) return { resolved: value, changed: false };
407
+ if (!subtreeHasMarker(value)) {
408
+ brandResolved(value);
409
+ return { resolved: value, changed: false };
410
+ }
389
411
  const out = [];
390
412
  let changed = false;
391
413
  for (const item of value) {
@@ -400,10 +422,14 @@ function walkValue(value, scopeTrait, entity, config, state) {
400
422
  out.push(resolved);
401
423
  if (itemChanged) changed = true;
402
424
  }
425
+ brandResolved(out);
403
426
  return changed ? { resolved: out, changed: true } : { resolved: value, changed: false };
404
427
  }
405
428
  if (isPlainObject(value)) {
406
- if (!subtreeHasMarker(value)) return { resolved: value, changed: false };
429
+ if (!subtreeHasMarker(value)) {
430
+ brandResolved(value);
431
+ return { resolved: value, changed: false };
432
+ }
407
433
  const sourceTrait = value._sourceTrait;
408
434
  if (typeof sourceTrait === "string" && sourceTrait !== scopeTrait) {
409
435
  return { resolved: value, changed: false };
@@ -415,11 +441,13 @@ function walkValue(value, scopeTrait, entity, config, state) {
415
441
  out[key] = resolved;
416
442
  if (itemChanged) changed = true;
417
443
  }
444
+ brandResolved(out);
418
445
  return changed ? { resolved: out, changed: true } : { resolved: value, changed: false };
419
446
  }
420
447
  return { resolved: value, changed: false };
421
448
  }
422
449
  function resolveRenderBindingMarkers(props, scopeTrait, entity, config, state) {
450
+ if (resolvedMarkerFree.has(props)) return props;
423
451
  const out = {};
424
452
  let changed = false;
425
453
  for (const [key, value] of Object.entries(props)) {
@@ -427,13 +455,17 @@ function resolveRenderBindingMarkers(props, scopeTrait, entity, config, state) {
427
455
  out[key] = resolved;
428
456
  if (propChanged) changed = true;
429
457
  }
458
+ brandResolved(out);
430
459
  return changed ? out : props;
431
460
  }
432
- var markerPresenceCache;
461
+ var markerPresenceCache, markerResolutionCache, resolvedMarkerFree, evaluatorResolvedData;
433
462
  var init_resolve_render_bindings = __esm({
434
463
  "lib/resolve-render-bindings.ts"() {
435
464
  "use client";
436
465
  markerPresenceCache = /* @__PURE__ */ new WeakMap();
466
+ markerResolutionCache = /* @__PURE__ */ new WeakMap();
467
+ resolvedMarkerFree = /* @__PURE__ */ new WeakSet();
468
+ evaluatorResolvedData = /* @__PURE__ */ new WeakSet();
437
469
  }
438
470
  });
439
471
  function cn(...inputs) {
@@ -11867,6 +11899,10 @@ var init_molecules = __esm({
11867
11899
  init_puzzleObject();
11868
11900
  }
11869
11901
  });
11902
+ var init_perf = __esm({
11903
+ "lib/perf.ts"() {
11904
+ }
11905
+ });
11870
11906
  function themeBodyFont(el) {
11871
11907
  if (typeof getComputedStyle !== "function") return "system-ui, sans-serif";
11872
11908
  const v = getComputedStyle(el).getPropertyValue("--font-family-body").trim();
@@ -12215,6 +12251,7 @@ var init_LearningCanvas = __esm({
12215
12251
  "components/learning/atoms/LearningCanvas.tsx"() {
12216
12252
  "use client";
12217
12253
  init_cn();
12254
+ init_perf();
12218
12255
  init_useEventBus();
12219
12256
  DASH_PATTERNS = { dashed: [6, 4], dotted: [2, 3] };
12220
12257
  TRACE_SERIES_COLORS = ["#2563eb", "#dc2626", "#16a34a", "#f59e0b"];
@@ -12258,6 +12295,7 @@ var init_LearningCanvas = __esm({
12258
12295
  return [...shapes, ...traceOut, ...readoutOut];
12259
12296
  }, [shapes, traces, readouts, width, height]);
12260
12297
  const draw = React87.useCallback(() => {
12298
+ const _perfT = ui.perfStart("learningcanvas:paint");
12261
12299
  const canvas = canvasRef.current;
12262
12300
  if (!canvas) return;
12263
12301
  const ctx = canvas.getContext("2d");
@@ -12279,6 +12317,7 @@ var init_LearningCanvas = __esm({
12279
12317
  for (const shape of derivedShapes) {
12280
12318
  if (shape.type === "text") drawShape(ctx, shape, width, height, derivedShapes);
12281
12319
  }
12320
+ ui.perfEnd("learningcanvas:paint", _perfT);
12282
12321
  }, [width, height, backgroundColor, derivedShapes]);
12283
12322
  React87.useEffect(() => {
12284
12323
  draw();
@@ -30683,6 +30722,7 @@ var init_MathCanvas = __esm({
30683
30722
  "components/learning/molecules/MathCanvas.tsx"() {
30684
30723
  "use client";
30685
30724
  init_useEventBus();
30725
+ init_perf();
30686
30726
  init_atoms();
30687
30727
  init_Stack();
30688
30728
  init_LearningCanvas();
@@ -30748,6 +30788,7 @@ var init_MathCanvas = __esm({
30748
30788
  };
30749
30789
  }, [stableKeyMap, stableKeyUpMap, eventBus]);
30750
30790
  const derivedShapes = React87.useMemo(() => {
30791
+ const _perfT = ui.perfStart("mathcanvas:derive");
30751
30792
  const out = [];
30752
30793
  const margin = 24;
30753
30794
  const plotW = width - margin * 2;
@@ -30991,6 +31032,7 @@ var init_MathCanvas = __esm({
30991
31032
  }
30992
31033
  }
30993
31034
  out.push(...shapes);
31035
+ ui.perfEnd("mathcanvas:derive", _perfT);
30994
31036
  return out;
30995
31037
  }, [
30996
31038
  width,
@@ -32254,12 +32296,12 @@ var init_MapView = __esm({
32254
32296
  shadowSize: [41, 41]
32255
32297
  });
32256
32298
  L.Marker.prototype.options.icon = defaultIcon;
32257
- const { useEffect: useEffect67, useRef: useRef64, useCallback: useCallback97, useState: useState95 } = React87__namespace.default;
32299
+ const { useEffect: useEffect67, useRef: useRef65, useCallback: useCallback97, useState: useState95 } = React87__namespace.default;
32258
32300
  const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
32259
32301
  const { useEventBus: useEventBus2 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
32260
32302
  function MapUpdater({ centerLat, centerLng, zoom }) {
32261
32303
  const map = useMap();
32262
- const prevRef = useRef64({ centerLat, centerLng, zoom });
32304
+ const prevRef = useRef65({ centerLat, centerLng, zoom });
32263
32305
  useEffect67(() => {
32264
32306
  const prev = prevRef.current;
32265
32307
  if (prev.centerLat !== centerLat || prev.centerLng !== centerLng || prev.zoom !== zoom) {
@@ -37344,7 +37386,7 @@ var init_RichBlockEditor = __esm({
37344
37386
  {
37345
37387
  variant: "bordered",
37346
37388
  padding: "none",
37347
- className: cn("flex flex-col", className),
37389
+ className: cn("flex flex-col text-card-foreground", className),
37348
37390
  children: [
37349
37391
  enableBlocks && showToolbar && !readOnly && /* @__PURE__ */ jsxRuntime.jsx(
37350
37392
  Box,
@@ -42572,6 +42614,7 @@ var init_DetailPanel = __esm({
42572
42614
  "use client";
42573
42615
  init_atoms();
42574
42616
  init_Box();
42617
+ init_Input();
42575
42618
  init_Stack();
42576
42619
  init_SimpleGrid();
42577
42620
  init_Menu();
@@ -42587,6 +42630,7 @@ var init_DetailPanel = __esm({
42587
42630
  ReactMarkdown2 = React87.lazy(() => import('react-markdown'));
42588
42631
  DetailPanel = ({
42589
42632
  title: propTitle,
42633
+ onTitleCommit,
42590
42634
  subtitle,
42591
42635
  status,
42592
42636
  avatar,
@@ -42608,6 +42652,7 @@ var init_DetailPanel = __esm({
42608
42652
  }) => {
42609
42653
  const eventBus = useEventBus();
42610
42654
  const { t } = hooks.useTranslate();
42655
+ const [titleDraft, setTitleDraft] = React87__namespace.default.useState(null);
42611
42656
  const isFieldDefArray = (arr) => {
42612
42657
  if (!arr || arr.length === 0) return false;
42613
42658
  const first = arr[0];
@@ -42828,6 +42873,50 @@ var init_DetailPanel = __esm({
42828
42873
  }),
42829
42874
  status && /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: status.variant ?? "default", children: status.label })
42830
42875
  ] });
42876
+ const commitTitle = () => {
42877
+ if (!onTitleCommit) return;
42878
+ const next = (titleDraft ?? "").trim();
42879
+ setTitleDraft(null);
42880
+ if (!next || next === title) return;
42881
+ onTitleCommit(next, normalizedData?.id !== void 0 ? String(normalizedData.id) : "");
42882
+ };
42883
+ const titleNode = onTitleCommit && titleDraft !== null ? /* @__PURE__ */ jsxRuntime.jsx(
42884
+ Input,
42885
+ {
42886
+ value: titleDraft,
42887
+ autoFocus: true,
42888
+ "aria-label": t("common.title"),
42889
+ className: "h-auto py-1 text-3xl font-bold tracking-tight",
42890
+ onChange: (e) => setTitleDraft(e.target.value),
42891
+ onBlur: commitTitle,
42892
+ onKeyDown: (e) => {
42893
+ if (e.key === "Enter") {
42894
+ e.preventDefault();
42895
+ commitTitle();
42896
+ } else if (e.key === "Escape") {
42897
+ e.preventDefault();
42898
+ setTitleDraft(null);
42899
+ }
42900
+ },
42901
+ "data-testid": "detail-title-input"
42902
+ }
42903
+ ) : onTitleCommit ? /* @__PURE__ */ jsxRuntime.jsx(
42904
+ Box,
42905
+ {
42906
+ role: "button",
42907
+ tabIndex: 0,
42908
+ className: "cursor-text rounded px-1 -mx-1 transition-colors hover:bg-muted/40",
42909
+ onClick: () => setTitleDraft(title ?? ""),
42910
+ onKeyDown: (e) => {
42911
+ if (e.key === "Enter" || e.key === " ") {
42912
+ e.preventDefault();
42913
+ setTitleDraft(title ?? "");
42914
+ }
42915
+ },
42916
+ "data-testid": "detail-title-editable",
42917
+ children: /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "h2", weight: "bold", children: title || "Details" })
42918
+ }
42919
+ ) : /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "h2", weight: "bold", children: title || "Details" });
42831
42920
  const content = /* @__PURE__ */ jsxRuntime.jsx(Card, { variant: "elevated", children: /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "md", className: "p-6", children: [
42832
42921
  /* @__PURE__ */ jsxRuntime.jsxs(HStack, { justify: "between", align: "start", gap: "md", children: [
42833
42922
  /* @__PURE__ */ jsxRuntime.jsxs(HStack, { align: "start", gap: "sm", className: "min-w-0", children: [
@@ -42847,7 +42936,7 @@ var init_DetailPanel = __esm({
42847
42936
  avatar,
42848
42937
  /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "xs", className: "min-w-0", children: [
42849
42938
  /* @__PURE__ */ jsxRuntime.jsxs(HStack, { align: "center", gap: "sm", wrap: true, children: [
42850
- /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "h2", weight: "bold", children: title || "Details" }),
42939
+ titleNode,
42851
42940
  statusBadges
42852
42941
  ] }),
42853
42942
  subtitle && /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", color: "secondary", children: subtitle })
@@ -43408,7 +43497,7 @@ var init_Form = __esm({
43408
43497
  });
43409
43498
  debug(
43410
43499
  "forms",
43411
- `Calculation triggered: ${calc.variableName} = ${value}`
43500
+ `Calculation triggered: ${calc.variableName} = ${String(value)}`
43412
43501
  );
43413
43502
  }
43414
43503
  });
@@ -49888,6 +49977,7 @@ function isPlainConfigObject(value) {
49888
49977
  return proto === Object.prototype || proto === null;
49889
49978
  }
49890
49979
  function subtreeHasTraitRef(value) {
49980
+ if (isEvaluatorResolvedData(value)) return false;
49891
49981
  const cached = traitRefPresenceCache.get(value);
49892
49982
  if (cached !== void 0) return cached;
49893
49983
  let found = false;
@@ -49960,6 +50050,10 @@ function renderPatternProps(props, onDismiss, propsSchema) {
49960
50050
  };
49961
50051
  rendered[key] = /* @__PURE__ */ jsxRuntime.jsx(SlotContentRenderer, { content: childContent, onDismiss });
49962
50052
  } else if (Array.isArray(value)) {
50053
+ if (!isEvaluatorResolvedData(value) && value.some((el) => isPatternConfig(el))) ; else if (!subtreeHasTraitRef(value)) {
50054
+ rendered[key] = value;
50055
+ continue;
50056
+ }
49963
50057
  const isDataArray = propsSchema?.[key]?.items?.types?.includes("object") ?? false;
49964
50058
  rendered[key] = value.map((item, i) => {
49965
50059
  const el = item;
@@ -51401,6 +51495,53 @@ function useNavigationId2() {
51401
51495
 
51402
51496
  // providers/ServerBridge.tsx
51403
51497
  init_useEventBus();
51498
+
51499
+ // lib/tick-send-relay.ts
51500
+ function createTickSendRelay(send) {
51501
+ const lanes = /* @__PURE__ */ new Map();
51502
+ const flush = (key, lane) => {
51503
+ const next = lane.pending;
51504
+ lane.pending = void 0;
51505
+ if (next === void 0) {
51506
+ lane.inFlight = false;
51507
+ return;
51508
+ }
51509
+ lane.inFlight = true;
51510
+ void send(key, next).catch(() => void 0).then(() => flush(key, lane));
51511
+ };
51512
+ return {
51513
+ send(key, value) {
51514
+ const lane = lanes.get(key) ?? { inFlight: false };
51515
+ lanes.set(key, lane);
51516
+ if (lane.inFlight) {
51517
+ lane.pending = value;
51518
+ return;
51519
+ }
51520
+ lane.pending = value;
51521
+ flush(key, lane);
51522
+ },
51523
+ clear() {
51524
+ for (const lane of lanes.values()) {
51525
+ lane.pending = void 0;
51526
+ }
51527
+ }
51528
+ };
51529
+ }
51530
+
51531
+ // lib/command-send-pump.ts
51532
+ function createCommandSendPump() {
51533
+ let tail = Promise.resolve();
51534
+ return {
51535
+ enqueue(job) {
51536
+ const result = tail.then(job);
51537
+ tail = result.then(
51538
+ () => void 0,
51539
+ () => void 0
51540
+ );
51541
+ return result;
51542
+ }
51543
+ };
51544
+ }
51404
51545
  var xOrbitalLog = logger.createLogger("almadar:runtime:cross-orbital");
51405
51546
  var serverBridgeLog = logger.createLogger("almadar:ui:server-bridge");
51406
51547
  function reEmitServerEvent(eventBus, emitted, origin) {
@@ -51535,99 +51676,118 @@ function ServerBridgeProvider({
51535
51676
  async () => transport.unregister(),
51536
51677
  [transport]
51537
51678
  );
51679
+ const tickRelay = React87.useMemo(
51680
+ () => createTickSendRelay(async (_key, snap) => {
51681
+ await transport.sendEvent(snap.orbitalName, snap.event, snap.payload, getTabClientId(), snap.tick, snap.sourceTrait);
51682
+ }),
51683
+ [transport]
51684
+ );
51685
+ React87.useEffect(() => () => tickRelay.clear(), [tickRelay]);
51686
+ const commandPump = React87.useMemo(createCommandSendPump, []);
51687
+ const disposedRef = React87.useRef(false);
51688
+ React87.useEffect(() => {
51689
+ disposedRef.current = false;
51690
+ return () => {
51691
+ disposedRef.current = true;
51692
+ };
51693
+ }, []);
51538
51694
  const sendEvent = React87.useCallback(async (orbitalName, event, payload, tick, sourceTrait) => {
51539
51695
  const emptyMeta = { success: false, clientEffects: 0, dataEntities: {}, emittedEvents: [] };
51540
51696
  if (!connected) return { effects: [], meta: emptyMeta };
51541
- try {
51542
- const result = await transport.sendEvent(orbitalName, event, payload, getTabClientId(), tick, sourceTrait);
51543
- const effects = [];
51544
- if (tick !== void 0) {
51545
- return { effects, meta: { ...emptyMeta, success: !!result.success, error: result.error } };
51546
- }
51547
- const responseData = result.data || {};
51548
- const dataEntities = {};
51549
- for (const [entityName, records] of Object.entries(responseData)) {
51550
- dataEntities[entityName] = Array.isArray(records) ? records.length : 0;
51551
- }
51552
- const meta = {
51553
- success: !!result.success,
51554
- clientEffects: result.clientEffects?.length ?? 0,
51555
- dataEntities,
51556
- data: responseData,
51557
- emittedEvents: result.emittedEvents?.map((e) => e.event) ?? [],
51558
- error: result.error
51559
- };
51560
- if (result.success) {
51561
- const tagged = result.clientEffectsByTrait;
51562
- const tuples = tagged ? tagged.map((entry) => ({ effect: entry.effect, traitName: entry.traitName })) : (result.clientEffects ?? []).map((eff) => ({ effect: eff }));
51563
- for (const { effect, traitName } of tuples) {
51564
- const effectType = effect[0];
51565
- if (effectType === "render-ui") {
51566
- const slot = effect[1];
51567
- const pattern = effect[2];
51568
- effects.push({
51569
- type: "render-ui",
51570
- slot,
51571
- pattern: pattern !== null && typeof pattern === "object" ? pattern : void 0,
51572
- traitName
51573
- });
51574
- } else if (effectType === "navigate") {
51575
- const route = effect[1];
51576
- const rawParams = effect[2];
51577
- const rawOptions = effect[3];
51578
- const optionsObj = rawOptions !== null && rawOptions !== void 0 && typeof rawOptions === "object" && !Array.isArray(rawOptions) ? rawOptions : void 0;
51579
- const crumb = typeof optionsObj?.crumb === "string" ? optionsObj.crumb : void 0;
51580
- effects.push({
51581
- type: "navigate",
51582
- route,
51583
- params: rawParams !== null && rawParams !== void 0 && typeof rawParams === "object" && !Array.isArray(rawParams) ? rawParams : void 0,
51584
- crumb,
51585
- traitName
51586
- });
51587
- } else if (effectType === "navigate-back") {
51588
- effects.push({ type: "navigate-back", traitName });
51589
- } else if (effectType === "notify") {
51590
- const message = effect[1];
51591
- effects.push({ type: "notify", message: typeof message === "string" ? message : void 0, traitName });
51592
- }
51593
- }
51594
- if (result.emittedEvents) {
51595
- for (const emitted of result.emittedEvents) {
51596
- if (emitted.event === event) continue;
51597
- reEmitServerEvent(
51598
- eventBus,
51599
- { ...emitted, source: { ...emitted.source, dispatched: true } },
51600
- orbitalName
51601
- );
51697
+ if (tick !== void 0) {
51698
+ tickRelay.send(`${orbitalName}:${event}`, { orbitalName, event, payload, tick, sourceTrait });
51699
+ return { effects: [], meta: { ...emptyMeta, success: true } };
51700
+ }
51701
+ return commandPump.enqueue(async () => {
51702
+ if (disposedRef.current) return { effects: [], meta: emptyMeta };
51703
+ try {
51704
+ const result = await transport.sendEvent(orbitalName, event, payload, getTabClientId(), tick, sourceTrait);
51705
+ const effects = [];
51706
+ const responseData = result.data || {};
51707
+ const dataEntities = {};
51708
+ for (const [entityName, records] of Object.entries(responseData)) {
51709
+ dataEntities[entityName] = Array.isArray(records) ? records.length : 0;
51710
+ }
51711
+ const meta = {
51712
+ success: !!result.success,
51713
+ clientEffects: result.clientEffects?.length ?? 0,
51714
+ dataEntities,
51715
+ data: responseData,
51716
+ emittedEvents: result.emittedEvents?.map((e) => e.event) ?? [],
51717
+ error: result.error
51718
+ };
51719
+ if (result.success) {
51720
+ const tagged = result.clientEffectsByTrait;
51721
+ const tuples = tagged ? tagged.map((entry) => ({ effect: entry.effect, traitName: entry.traitName })) : (result.clientEffects ?? []).map((eff) => ({ effect: eff }));
51722
+ for (const { effect, traitName } of tuples) {
51723
+ const effectType = effect[0];
51724
+ if (effectType === "render-ui") {
51725
+ const slot = effect[1];
51726
+ const pattern = effect[2];
51727
+ effects.push({
51728
+ type: "render-ui",
51729
+ slot,
51730
+ pattern: pattern !== null && typeof pattern === "object" ? pattern : void 0,
51731
+ traitName
51732
+ });
51733
+ } else if (effectType === "navigate") {
51734
+ const route = effect[1];
51735
+ const rawParams = effect[2];
51736
+ const rawOptions = effect[3];
51737
+ const optionsObj = rawOptions !== null && rawOptions !== void 0 && typeof rawOptions === "object" && !Array.isArray(rawOptions) ? rawOptions : void 0;
51738
+ const crumb = typeof optionsObj?.crumb === "string" ? optionsObj.crumb : void 0;
51739
+ effects.push({
51740
+ type: "navigate",
51741
+ route,
51742
+ params: rawParams !== null && rawParams !== void 0 && typeof rawParams === "object" && !Array.isArray(rawParams) ? rawParams : void 0,
51743
+ crumb,
51744
+ traitName
51745
+ });
51746
+ } else if (effectType === "navigate-back") {
51747
+ effects.push({ type: "navigate-back", traitName });
51748
+ } else if (effectType === "notify") {
51749
+ const message = effect[1];
51750
+ effects.push({ type: "notify", message: typeof message === "string" ? message : void 0, traitName });
51751
+ }
51752
+ }
51753
+ if (result.emittedEvents) {
51754
+ for (const emitted of result.emittedEvents) {
51755
+ if (emitted.event === event) continue;
51756
+ reEmitServerEvent(
51757
+ eventBus,
51758
+ { ...emitted, source: { ...emitted.source, dispatched: true } },
51759
+ orbitalName
51760
+ );
51761
+ }
51602
51762
  }
51763
+ } else if (result.error) {
51764
+ xOrbitalLog.warn("response:fail", {
51765
+ orbital: orbitalName,
51766
+ event,
51767
+ error: result.error
51768
+ });
51603
51769
  }
51604
- } else if (result.error) {
51605
- xOrbitalLog.warn("response:fail", {
51606
- orbital: orbitalName,
51607
- event,
51608
- error: result.error
51609
- });
51610
- }
51611
- return { effects, meta };
51612
- } catch (err) {
51613
- const msg = err instanceof Error ? err.message : String(err);
51614
- if (err instanceof TypeError) {
51615
- xOrbitalLog.warn("response:network", {
51616
- orbital: orbitalName,
51617
- event,
51618
- error: msg,
51619
- reason: "peer endpoint unreachable (expected in standalone single-orbital mode)"
51620
- });
51621
- } else {
51622
- xOrbitalLog.error("response:network", {
51623
- orbital: orbitalName,
51624
- event,
51625
- error: msg
51626
- });
51770
+ return { effects, meta };
51771
+ } catch (err) {
51772
+ const msg = err instanceof Error ? err.message : String(err);
51773
+ if (err instanceof TypeError) {
51774
+ xOrbitalLog.warn("response:network", {
51775
+ orbital: orbitalName,
51776
+ event,
51777
+ error: msg,
51778
+ reason: "peer endpoint unreachable (expected in standalone single-orbital mode)"
51779
+ });
51780
+ } else {
51781
+ xOrbitalLog.error("response:network", {
51782
+ orbital: orbitalName,
51783
+ event,
51784
+ error: msg
51785
+ });
51786
+ }
51787
+ return { effects: [], meta: { ...emptyMeta, error: msg } };
51627
51788
  }
51628
- return { effects: [], meta: { ...emptyMeta, error: msg } };
51629
- }
51630
- }, [connected, transport, eventBus]);
51789
+ });
51790
+ }, [connected, transport, eventBus, tickRelay, commandPump]);
51631
51791
  React87.useEffect(() => {
51632
51792
  if (!schema) return;
51633
51793
  let cancelled = false;
@@ -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-Bn3ePJQC.cjs';
6
+ export { o as EntityBindingContext, E as EntityBindingSource, a as EntitySchemaContextValue, b as EntitySchemaProvider, c as EntitySchemaProviderProps, p as SendEventResult, d as ServerBridgeContextValue, e as ServerBridgeProvider, q as ServerBridgeProviderProps, S as ServerBridgeTransport, f as ServerClientEffect, r as ServerResponseMeta, T as TraitContext, g as TraitContextValue, h as TraitInstance, i as TraitProvider, j as TraitProviderProps, s as useEntityBindingSnapshot, u as useEntitySchema, k as useEntitySchemaOptional, l as useServerBridge, m as useTrait, n as useTraitContext } from '../EntityBindingContext-0Evn_LcT.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-Bn3ePJQC.js';
6
+ export { o as EntityBindingContext, E as EntityBindingSource, a as EntitySchemaContextValue, b as EntitySchemaProvider, c as EntitySchemaProviderProps, p as SendEventResult, d as ServerBridgeContextValue, e as ServerBridgeProvider, q as ServerBridgeProviderProps, S as ServerBridgeTransport, f as ServerClientEffect, r as ServerResponseMeta, T as TraitContext, g as TraitContextValue, h as TraitInstance, i as TraitProvider, j as TraitProviderProps, s as useEntityBindingSnapshot, u as useEntitySchema, k as useEntitySchemaOptional, l as useServerBridge, m as useTrait, n as useTraitContext } from '../EntityBindingContext-0Evn_LcT.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';