@almadar/ui 3.8.2 → 3.9.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.
@@ -22166,10 +22166,7 @@ var init_DataList = __esm({
22166
22166
  HStack,
22167
22167
  {
22168
22168
  gap: "xs",
22169
- className: cn(
22170
- "flex-shrink-0 transition-opacity duration-200",
22171
- "opacity-0 group-hover:opacity-100"
22172
- ),
22169
+ className: "flex-shrink-0",
22173
22170
  children: itemActions.map((action, idx) => /* @__PURE__ */ jsxRuntime.jsxs(
22174
22171
  Button,
22175
22172
  {
@@ -22259,33 +22256,23 @@ var init_DataList = __esm({
22259
22256
  ] }, field.name);
22260
22257
  })
22261
22258
  ] }),
22262
- itemActions && itemActions.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
22263
- HStack,
22259
+ itemActions && itemActions.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(HStack, { gap: "xs", className: "flex-shrink-0", children: itemActions.map((action, idx) => /* @__PURE__ */ jsxRuntime.jsxs(
22260
+ Button,
22264
22261
  {
22265
- gap: "xs",
22262
+ variant: action.variant ?? "ghost",
22263
+ size: "sm",
22264
+ onClick: handleActionClick(action, itemData),
22265
+ "data-testid": `action-${action.event}`,
22266
22266
  className: cn(
22267
- "flex-shrink-0 transition-opacity duration-200",
22268
- "opacity-0 group-hover:opacity-100"
22267
+ action.variant === "danger" && "text-error hover:bg-error/10"
22269
22268
  ),
22270
- children: itemActions.map((action, idx) => /* @__PURE__ */ jsxRuntime.jsxs(
22271
- Button,
22272
- {
22273
- variant: action.variant ?? "ghost",
22274
- size: "sm",
22275
- onClick: handleActionClick(action, itemData),
22276
- "data-testid": `action-${action.event}`,
22277
- className: cn(
22278
- action.variant === "danger" && "text-error hover:bg-error/10"
22279
- ),
22280
- children: [
22281
- action.icon && /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: action.icon, size: "xs", className: "mr-1" }),
22282
- action.label
22283
- ]
22284
- },
22285
- idx
22286
- ))
22287
- }
22288
- )
22269
+ children: [
22270
+ action.icon && /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: action.icon, size: "xs", className: "mr-1" }),
22271
+ action.label
22272
+ ]
22273
+ },
22274
+ idx
22275
+ )) })
22289
22276
  ]
22290
22277
  }
22291
22278
  ),
@@ -33717,75 +33704,66 @@ var init_List = __esm({
33717
33704
  hasProgress && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "ml-auto", children: /* @__PURE__ */ jsxRuntime.jsx(ProgressIndicator, { value: progressValue }) })
33718
33705
  ] })
33719
33706
  ] }),
33720
- /* @__PURE__ */ jsxRuntime.jsxs(
33721
- HStack,
33722
- {
33723
- className: cn(
33724
- "flex items-center gap-1 flex-shrink-0 transition-opacity duration-200",
33725
- "opacity-0 group-hover:opacity-100"
33726
- ),
33727
- children: [
33728
- editAction && /* @__PURE__ */ jsxRuntime.jsx(
33729
- Button,
33730
- {
33731
- variant: "ghost",
33732
- action: editAction.event,
33733
- className: cn(
33734
- "p-2 rounded-lg transition-all duration-200",
33735
- "hover:bg-primary/10 hover:text-primary",
33736
- "text-muted-foreground",
33737
- "active:scale-95"
33738
- ),
33739
- title: editAction.label,
33740
- "data-testid": editAction.event ? `action-${editAction.event}` : void 0,
33741
- children: /* @__PURE__ */ jsxRuntime.jsx(LucideIcons.Pencil, { className: "w-4 h-4" })
33742
- }
33707
+ /* @__PURE__ */ jsxRuntime.jsxs(HStack, { className: "flex items-center gap-1 flex-shrink-0", children: [
33708
+ editAction && /* @__PURE__ */ jsxRuntime.jsx(
33709
+ Button,
33710
+ {
33711
+ variant: "ghost",
33712
+ action: editAction.event,
33713
+ className: cn(
33714
+ "p-2 rounded-lg transition-all duration-200",
33715
+ "hover:bg-primary/10 hover:text-primary",
33716
+ "text-muted-foreground",
33717
+ "active:scale-95"
33743
33718
  ),
33744
- viewAction && /* @__PURE__ */ jsxRuntime.jsx(
33745
- Button,
33746
- {
33747
- variant: "ghost",
33748
- action: viewAction.event,
33749
- className: cn(
33750
- "p-2 rounded-lg transition-all duration-200",
33751
- "hover:bg-muted hover:text-foreground",
33752
- "text-muted-foreground",
33753
- "active:scale-95"
33754
- ),
33755
- title: viewAction.label,
33756
- "data-testid": viewAction.event ? `action-${viewAction.event}` : void 0,
33757
- children: /* @__PURE__ */ jsxRuntime.jsx(LucideIcons.Eye, { className: "w-4 h-4" })
33758
- }
33719
+ title: editAction.label,
33720
+ "data-testid": editAction.event ? `action-${editAction.event}` : void 0,
33721
+ children: /* @__PURE__ */ jsxRuntime.jsx(LucideIcons.Pencil, { className: "w-4 h-4" })
33722
+ }
33723
+ ),
33724
+ viewAction && /* @__PURE__ */ jsxRuntime.jsx(
33725
+ Button,
33726
+ {
33727
+ variant: "ghost",
33728
+ action: viewAction.event,
33729
+ className: cn(
33730
+ "p-2 rounded-lg transition-all duration-200",
33731
+ "hover:bg-muted hover:text-foreground",
33732
+ "text-muted-foreground",
33733
+ "active:scale-95"
33759
33734
  ),
33760
- (() => {
33761
- const filteredActions = actions.filter(
33762
- (a) => !a.label.toLowerCase().includes("edit") && !a.label.toLowerCase().includes("view") && !a.label.toLowerCase().includes("open")
33763
- );
33764
- return filteredActions.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(
33765
- Menu,
33735
+ title: viewAction.label,
33736
+ "data-testid": viewAction.event ? `action-${viewAction.event}` : void 0,
33737
+ children: /* @__PURE__ */ jsxRuntime.jsx(LucideIcons.Eye, { className: "w-4 h-4" })
33738
+ }
33739
+ ),
33740
+ (() => {
33741
+ const filteredActions = actions.filter(
33742
+ (a) => !a.label.toLowerCase().includes("edit") && !a.label.toLowerCase().includes("view") && !a.label.toLowerCase().includes("open")
33743
+ );
33744
+ return filteredActions.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(
33745
+ Menu,
33746
+ {
33747
+ trigger: /* @__PURE__ */ jsxRuntime.jsx(
33748
+ Button,
33766
33749
  {
33767
- trigger: /* @__PURE__ */ jsxRuntime.jsx(
33768
- Button,
33769
- {
33770
- variant: "ghost",
33771
- className: cn(
33772
- "p-2 rounded-lg transition-all duration-200",
33773
- "hover:bg-muted hover:shadow-sm",
33774
- "text-muted-foreground hover:text-foreground",
33775
- "active:scale-95"
33776
- ),
33777
- children: /* @__PURE__ */ jsxRuntime.jsx(LucideIcons.MoreHorizontal, { className: "w-4 h-4" })
33778
- }
33750
+ variant: "ghost",
33751
+ className: cn(
33752
+ "p-2 rounded-lg transition-all duration-200",
33753
+ "hover:bg-muted hover:shadow-sm",
33754
+ "text-muted-foreground hover:text-foreground",
33755
+ "active:scale-95"
33779
33756
  ),
33780
- items: filteredActions,
33781
- position: "bottom-right"
33757
+ children: /* @__PURE__ */ jsxRuntime.jsx(LucideIcons.MoreHorizontal, { className: "w-4 h-4" })
33782
33758
  }
33783
- ) : null;
33784
- })(),
33785
- hasExplicitClick && /* @__PURE__ */ jsxRuntime.jsx(LucideIcons.ChevronRight, { className: "w-4 h-4 text-muted-foreground/50 group-hover:text-muted-foreground group-hover:translate-x-0.5 transition-all" })
33786
- ]
33787
- }
33788
- )
33759
+ ),
33760
+ items: filteredActions,
33761
+ position: "bottom-right"
33762
+ }
33763
+ ) : null;
33764
+ })(),
33765
+ hasExplicitClick && /* @__PURE__ */ jsxRuntime.jsx(LucideIcons.ChevronRight, { className: "w-4 h-4 text-muted-foreground/50 group-hover:text-muted-foreground group-hover:translate-x-0.5 transition-all" })
33766
+ ] })
33789
33767
  ]
33790
33768
  }
33791
33769
  ),
@@ -51389,7 +51367,7 @@ function useTraitStateMachine(traitBindings, slotsActions, options) {
51389
51367
  effects: result.effects,
51390
51368
  traitDefinition: binding.trait
51391
51369
  };
51392
- const handlers = createClientEffectHandlers({
51370
+ const clientHandlers = createClientEffectHandlers({
51393
51371
  eventBus,
51394
51372
  slotSetter: {
51395
51373
  addPattern: (slot, pattern, props) => {
@@ -51404,6 +51382,43 @@ function useTraitStateMachine(traitBindings, slotsActions, options) {
51404
51382
  navigate: optionsRef.current?.navigate,
51405
51383
  notify: optionsRef.current?.notify
51406
51384
  });
51385
+ const persistence = optionsRef.current?.persistence;
51386
+ let handlers = clientHandlers;
51387
+ if (persistence) {
51388
+ const sharedBindings = {
51389
+ entity: payload ?? {},
51390
+ payload: payload || {},
51391
+ state: result.previousState
51392
+ };
51393
+ if (binding.config) {
51394
+ sharedBindings.config = binding.config;
51395
+ }
51396
+ const serverHandlers = runtime.createServerEffectHandlers({
51397
+ persistence,
51398
+ eventBus,
51399
+ entityType: linkedEntity,
51400
+ entityId,
51401
+ bindings: sharedBindings,
51402
+ context: {
51403
+ traitName: binding.trait.name,
51404
+ state: result.previousState,
51405
+ transition: `${result.previousState}->${result.newState}`,
51406
+ linkedEntity,
51407
+ entityId
51408
+ },
51409
+ source: { trait: binding.trait.name },
51410
+ callService: optionsRef.current?.callService
51411
+ });
51412
+ handlers = {
51413
+ ...serverHandlers,
51414
+ // Client handlers own UI + emit: keep the slot setter
51415
+ // and pre-prefixed UI:* emit path intact.
51416
+ emit: clientHandlers.emit,
51417
+ renderUI: clientHandlers.renderUI,
51418
+ navigate: clientHandlers.navigate,
51419
+ notify: clientHandlers.notify
51420
+ };
51421
+ }
51407
51422
  const entityFromPayload = payload ?? {};
51408
51423
  const bindingCtx = {
51409
51424
  entity: entityFromPayload,
@@ -51903,7 +51918,7 @@ function applyServerEffects(effects, uiSlots, onNavigate) {
51903
51918
  }
51904
51919
  }
51905
51920
  }
51906
- function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFallback }) {
51921
+ function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFallback, persistence }) {
51907
51922
  const slotsActions = useSlotsActions();
51908
51923
  const bridge = useServerBridge();
51909
51924
  const uiSlots = useUISlots();
@@ -51915,7 +51930,7 @@ function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFa
51915
51930
  applyServerEffects(effects, uiSlots, onNavigate);
51916
51931
  }
51917
51932
  }, [bridge.connected, bridge.sendEvent, orbitalNames, uiSlots, onNavigate]);
51918
- const opts = orbitalNames ? { onEventProcessed, navigate: onNavigate } : { navigate: onNavigate };
51933
+ const opts = orbitalNames ? { onEventProcessed, navigate: onNavigate } : { navigate: onNavigate, persistence };
51919
51934
  const { sendEvent } = useTraitStateMachine(traits2, slotsActions, opts);
51920
51935
  const initSentRef = React126.useRef(false);
51921
51936
  React126.useEffect(() => {
@@ -51960,7 +51975,7 @@ function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFa
51960
51975
  }, [bridge.connected, orbitalNames, bridge.sendEvent, uiSlots, onNavigate]);
51961
51976
  return null;
51962
51977
  }
51963
- function SchemaRunner({ schema, serverUrl, mockData, pageName, onNavigate, onLocalFallback }) {
51978
+ function SchemaRunner({ schema, serverUrl, mockData, pageName, onNavigate, onLocalFallback, persistence }) {
51964
51979
  const { traits: traits2, allEntities, ir } = useResolvedSchema(schema, pageName);
51965
51980
  const allPageTraits = React126.useMemo(() => {
51966
51981
  if (pageName && traits2.length > 0) return traits2;
@@ -51993,7 +52008,8 @@ function SchemaRunner({ schema, serverUrl, mockData, pageName, onNavigate, onLoc
51993
52008
  traits: allPageTraits,
51994
52009
  orbitalNames: serverUrl ? orbitalNames : void 0,
51995
52010
  onNavigate,
51996
- onLocalFallback
52011
+ onLocalFallback,
52012
+ persistence
51997
52013
  }
51998
52014
  ),
51999
52015
  /* @__PURE__ */ jsxRuntime.jsx(SlotBridge, {}),
@@ -52041,6 +52057,13 @@ function OrbPreview({
52041
52057
  }, [schema, autoMock, serverUrl, mockData]);
52042
52058
  const parsedSchema = parseResult.ok ? parseResult.schema : null;
52043
52059
  const effectiveMockData = parseResult.ok ? parseResult.mockData : {};
52060
+ const persistence = React126.useMemo(() => {
52061
+ if (!parsedSchema || serverUrl) return void 0;
52062
+ if (!autoMock) return void 0;
52063
+ const adapter = new runtime.InMemoryPersistence();
52064
+ adapter.seed(effectiveMockData);
52065
+ return adapter;
52066
+ }, [parsedSchema, serverUrl, autoMock, effectiveMockData]);
52044
52067
  const pages = React126.useMemo(() => {
52045
52068
  if (!parsedSchema) return [];
52046
52069
  try {
@@ -52095,7 +52118,8 @@ function OrbPreview({
52095
52118
  mockData: effectiveMockData,
52096
52119
  pageName: currentPage,
52097
52120
  onNavigate: handleNavigate,
52098
- onLocalFallback: handleLocalFallback
52121
+ onLocalFallback: handleLocalFallback,
52122
+ persistence
52099
52123
  }
52100
52124
  ) }) })
52101
52125
  ]
package/dist/avl/index.js CHANGED
@@ -43,7 +43,7 @@ import { EffectComposer, Bloom, DepthOfField, Vignette } from '@react-three/post
43
43
  import ELK from 'elkjs/lib/elk.bundled.js';
44
44
  import { MarkerType, Handle, Position, getBezierPath, EdgeLabelRenderer, BaseEdge, ReactFlowProvider, useNodesState, useEdgesState, useReactFlow, ReactFlow, Controls, Background, BackgroundVariant } from '@xyflow/react';
45
45
  import '@tanstack/react-query';
46
- import { StateMachineManager, createContextFromBindings, interpolateValue, EffectExecutor } from '@almadar/runtime';
46
+ import { InMemoryPersistence, StateMachineManager, createContextFromBindings, interpolateValue, createServerEffectHandlers, EffectExecutor } from '@almadar/runtime';
47
47
 
48
48
  var __defProp = Object.defineProperty;
49
49
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@@ -22120,10 +22120,7 @@ var init_DataList = __esm({
22120
22120
  HStack,
22121
22121
  {
22122
22122
  gap: "xs",
22123
- className: cn(
22124
- "flex-shrink-0 transition-opacity duration-200",
22125
- "opacity-0 group-hover:opacity-100"
22126
- ),
22123
+ className: "flex-shrink-0",
22127
22124
  children: itemActions.map((action, idx) => /* @__PURE__ */ jsxs(
22128
22125
  Button,
22129
22126
  {
@@ -22213,33 +22210,23 @@ var init_DataList = __esm({
22213
22210
  ] }, field.name);
22214
22211
  })
22215
22212
  ] }),
22216
- itemActions && itemActions.length > 0 && /* @__PURE__ */ jsx(
22217
- HStack,
22213
+ itemActions && itemActions.length > 0 && /* @__PURE__ */ jsx(HStack, { gap: "xs", className: "flex-shrink-0", children: itemActions.map((action, idx) => /* @__PURE__ */ jsxs(
22214
+ Button,
22218
22215
  {
22219
- gap: "xs",
22216
+ variant: action.variant ?? "ghost",
22217
+ size: "sm",
22218
+ onClick: handleActionClick(action, itemData),
22219
+ "data-testid": `action-${action.event}`,
22220
22220
  className: cn(
22221
- "flex-shrink-0 transition-opacity duration-200",
22222
- "opacity-0 group-hover:opacity-100"
22221
+ action.variant === "danger" && "text-error hover:bg-error/10"
22223
22222
  ),
22224
- children: itemActions.map((action, idx) => /* @__PURE__ */ jsxs(
22225
- Button,
22226
- {
22227
- variant: action.variant ?? "ghost",
22228
- size: "sm",
22229
- onClick: handleActionClick(action, itemData),
22230
- "data-testid": `action-${action.event}`,
22231
- className: cn(
22232
- action.variant === "danger" && "text-error hover:bg-error/10"
22233
- ),
22234
- children: [
22235
- action.icon && /* @__PURE__ */ jsx(Icon, { name: action.icon, size: "xs", className: "mr-1" }),
22236
- action.label
22237
- ]
22238
- },
22239
- idx
22240
- ))
22241
- }
22242
- )
22223
+ children: [
22224
+ action.icon && /* @__PURE__ */ jsx(Icon, { name: action.icon, size: "xs", className: "mr-1" }),
22225
+ action.label
22226
+ ]
22227
+ },
22228
+ idx
22229
+ )) })
22243
22230
  ]
22244
22231
  }
22245
22232
  ),
@@ -33671,75 +33658,66 @@ var init_List = __esm({
33671
33658
  hasProgress && /* @__PURE__ */ jsx(Box, { className: "ml-auto", children: /* @__PURE__ */ jsx(ProgressIndicator, { value: progressValue }) })
33672
33659
  ] })
33673
33660
  ] }),
33674
- /* @__PURE__ */ jsxs(
33675
- HStack,
33676
- {
33677
- className: cn(
33678
- "flex items-center gap-1 flex-shrink-0 transition-opacity duration-200",
33679
- "opacity-0 group-hover:opacity-100"
33680
- ),
33681
- children: [
33682
- editAction && /* @__PURE__ */ jsx(
33683
- Button,
33684
- {
33685
- variant: "ghost",
33686
- action: editAction.event,
33687
- className: cn(
33688
- "p-2 rounded-lg transition-all duration-200",
33689
- "hover:bg-primary/10 hover:text-primary",
33690
- "text-muted-foreground",
33691
- "active:scale-95"
33692
- ),
33693
- title: editAction.label,
33694
- "data-testid": editAction.event ? `action-${editAction.event}` : void 0,
33695
- children: /* @__PURE__ */ jsx(Pencil, { className: "w-4 h-4" })
33696
- }
33661
+ /* @__PURE__ */ jsxs(HStack, { className: "flex items-center gap-1 flex-shrink-0", children: [
33662
+ editAction && /* @__PURE__ */ jsx(
33663
+ Button,
33664
+ {
33665
+ variant: "ghost",
33666
+ action: editAction.event,
33667
+ className: cn(
33668
+ "p-2 rounded-lg transition-all duration-200",
33669
+ "hover:bg-primary/10 hover:text-primary",
33670
+ "text-muted-foreground",
33671
+ "active:scale-95"
33697
33672
  ),
33698
- viewAction && /* @__PURE__ */ jsx(
33699
- Button,
33700
- {
33701
- variant: "ghost",
33702
- action: viewAction.event,
33703
- className: cn(
33704
- "p-2 rounded-lg transition-all duration-200",
33705
- "hover:bg-muted hover:text-foreground",
33706
- "text-muted-foreground",
33707
- "active:scale-95"
33708
- ),
33709
- title: viewAction.label,
33710
- "data-testid": viewAction.event ? `action-${viewAction.event}` : void 0,
33711
- children: /* @__PURE__ */ jsx(Eye, { className: "w-4 h-4" })
33712
- }
33673
+ title: editAction.label,
33674
+ "data-testid": editAction.event ? `action-${editAction.event}` : void 0,
33675
+ children: /* @__PURE__ */ jsx(Pencil, { className: "w-4 h-4" })
33676
+ }
33677
+ ),
33678
+ viewAction && /* @__PURE__ */ jsx(
33679
+ Button,
33680
+ {
33681
+ variant: "ghost",
33682
+ action: viewAction.event,
33683
+ className: cn(
33684
+ "p-2 rounded-lg transition-all duration-200",
33685
+ "hover:bg-muted hover:text-foreground",
33686
+ "text-muted-foreground",
33687
+ "active:scale-95"
33713
33688
  ),
33714
- (() => {
33715
- const filteredActions = actions.filter(
33716
- (a) => !a.label.toLowerCase().includes("edit") && !a.label.toLowerCase().includes("view") && !a.label.toLowerCase().includes("open")
33717
- );
33718
- return filteredActions.length > 0 ? /* @__PURE__ */ jsx(
33719
- Menu,
33689
+ title: viewAction.label,
33690
+ "data-testid": viewAction.event ? `action-${viewAction.event}` : void 0,
33691
+ children: /* @__PURE__ */ jsx(Eye, { className: "w-4 h-4" })
33692
+ }
33693
+ ),
33694
+ (() => {
33695
+ const filteredActions = actions.filter(
33696
+ (a) => !a.label.toLowerCase().includes("edit") && !a.label.toLowerCase().includes("view") && !a.label.toLowerCase().includes("open")
33697
+ );
33698
+ return filteredActions.length > 0 ? /* @__PURE__ */ jsx(
33699
+ Menu,
33700
+ {
33701
+ trigger: /* @__PURE__ */ jsx(
33702
+ Button,
33720
33703
  {
33721
- trigger: /* @__PURE__ */ jsx(
33722
- Button,
33723
- {
33724
- variant: "ghost",
33725
- className: cn(
33726
- "p-2 rounded-lg transition-all duration-200",
33727
- "hover:bg-muted hover:shadow-sm",
33728
- "text-muted-foreground hover:text-foreground",
33729
- "active:scale-95"
33730
- ),
33731
- children: /* @__PURE__ */ jsx(MoreHorizontal, { className: "w-4 h-4" })
33732
- }
33704
+ variant: "ghost",
33705
+ className: cn(
33706
+ "p-2 rounded-lg transition-all duration-200",
33707
+ "hover:bg-muted hover:shadow-sm",
33708
+ "text-muted-foreground hover:text-foreground",
33709
+ "active:scale-95"
33733
33710
  ),
33734
- items: filteredActions,
33735
- position: "bottom-right"
33711
+ children: /* @__PURE__ */ jsx(MoreHorizontal, { className: "w-4 h-4" })
33736
33712
  }
33737
- ) : null;
33738
- })(),
33739
- hasExplicitClick && /* @__PURE__ */ jsx(ChevronRight, { className: "w-4 h-4 text-muted-foreground/50 group-hover:text-muted-foreground group-hover:translate-x-0.5 transition-all" })
33740
- ]
33741
- }
33742
- )
33713
+ ),
33714
+ items: filteredActions,
33715
+ position: "bottom-right"
33716
+ }
33717
+ ) : null;
33718
+ })(),
33719
+ hasExplicitClick && /* @__PURE__ */ jsx(ChevronRight, { className: "w-4 h-4 text-muted-foreground/50 group-hover:text-muted-foreground group-hover:translate-x-0.5 transition-all" })
33720
+ ] })
33743
33721
  ]
33744
33722
  }
33745
33723
  ),
@@ -51343,7 +51321,7 @@ function useTraitStateMachine(traitBindings, slotsActions, options) {
51343
51321
  effects: result.effects,
51344
51322
  traitDefinition: binding.trait
51345
51323
  };
51346
- const handlers = createClientEffectHandlers({
51324
+ const clientHandlers = createClientEffectHandlers({
51347
51325
  eventBus,
51348
51326
  slotSetter: {
51349
51327
  addPattern: (slot, pattern, props) => {
@@ -51358,6 +51336,43 @@ function useTraitStateMachine(traitBindings, slotsActions, options) {
51358
51336
  navigate: optionsRef.current?.navigate,
51359
51337
  notify: optionsRef.current?.notify
51360
51338
  });
51339
+ const persistence = optionsRef.current?.persistence;
51340
+ let handlers = clientHandlers;
51341
+ if (persistence) {
51342
+ const sharedBindings = {
51343
+ entity: payload ?? {},
51344
+ payload: payload || {},
51345
+ state: result.previousState
51346
+ };
51347
+ if (binding.config) {
51348
+ sharedBindings.config = binding.config;
51349
+ }
51350
+ const serverHandlers = createServerEffectHandlers({
51351
+ persistence,
51352
+ eventBus,
51353
+ entityType: linkedEntity,
51354
+ entityId,
51355
+ bindings: sharedBindings,
51356
+ context: {
51357
+ traitName: binding.trait.name,
51358
+ state: result.previousState,
51359
+ transition: `${result.previousState}->${result.newState}`,
51360
+ linkedEntity,
51361
+ entityId
51362
+ },
51363
+ source: { trait: binding.trait.name },
51364
+ callService: optionsRef.current?.callService
51365
+ });
51366
+ handlers = {
51367
+ ...serverHandlers,
51368
+ // Client handlers own UI + emit: keep the slot setter
51369
+ // and pre-prefixed UI:* emit path intact.
51370
+ emit: clientHandlers.emit,
51371
+ renderUI: clientHandlers.renderUI,
51372
+ navigate: clientHandlers.navigate,
51373
+ notify: clientHandlers.notify
51374
+ };
51375
+ }
51361
51376
  const entityFromPayload = payload ?? {};
51362
51377
  const bindingCtx = {
51363
51378
  entity: entityFromPayload,
@@ -51857,7 +51872,7 @@ function applyServerEffects(effects, uiSlots, onNavigate) {
51857
51872
  }
51858
51873
  }
51859
51874
  }
51860
- function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFallback }) {
51875
+ function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFallback, persistence }) {
51861
51876
  const slotsActions = useSlotsActions();
51862
51877
  const bridge = useServerBridge();
51863
51878
  const uiSlots = useUISlots();
@@ -51869,7 +51884,7 @@ function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFa
51869
51884
  applyServerEffects(effects, uiSlots, onNavigate);
51870
51885
  }
51871
51886
  }, [bridge.connected, bridge.sendEvent, orbitalNames, uiSlots, onNavigate]);
51872
- const opts = orbitalNames ? { onEventProcessed, navigate: onNavigate } : { navigate: onNavigate };
51887
+ const opts = orbitalNames ? { onEventProcessed, navigate: onNavigate } : { navigate: onNavigate, persistence };
51873
51888
  const { sendEvent } = useTraitStateMachine(traits2, slotsActions, opts);
51874
51889
  const initSentRef = useRef(false);
51875
51890
  useEffect(() => {
@@ -51914,7 +51929,7 @@ function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFa
51914
51929
  }, [bridge.connected, orbitalNames, bridge.sendEvent, uiSlots, onNavigate]);
51915
51930
  return null;
51916
51931
  }
51917
- function SchemaRunner({ schema, serverUrl, mockData, pageName, onNavigate, onLocalFallback }) {
51932
+ function SchemaRunner({ schema, serverUrl, mockData, pageName, onNavigate, onLocalFallback, persistence }) {
51918
51933
  const { traits: traits2, allEntities, ir } = useResolvedSchema(schema, pageName);
51919
51934
  const allPageTraits = useMemo(() => {
51920
51935
  if (pageName && traits2.length > 0) return traits2;
@@ -51947,7 +51962,8 @@ function SchemaRunner({ schema, serverUrl, mockData, pageName, onNavigate, onLoc
51947
51962
  traits: allPageTraits,
51948
51963
  orbitalNames: serverUrl ? orbitalNames : void 0,
51949
51964
  onNavigate,
51950
- onLocalFallback
51965
+ onLocalFallback,
51966
+ persistence
51951
51967
  }
51952
51968
  ),
51953
51969
  /* @__PURE__ */ jsx(SlotBridge, {}),
@@ -51995,6 +52011,13 @@ function OrbPreview({
51995
52011
  }, [schema, autoMock, serverUrl, mockData]);
51996
52012
  const parsedSchema = parseResult.ok ? parseResult.schema : null;
51997
52013
  const effectiveMockData = parseResult.ok ? parseResult.mockData : {};
52014
+ const persistence = useMemo(() => {
52015
+ if (!parsedSchema || serverUrl) return void 0;
52016
+ if (!autoMock) return void 0;
52017
+ const adapter = new InMemoryPersistence();
52018
+ adapter.seed(effectiveMockData);
52019
+ return adapter;
52020
+ }, [parsedSchema, serverUrl, autoMock, effectiveMockData]);
51998
52021
  const pages = useMemo(() => {
51999
52022
  if (!parsedSchema) return [];
52000
52023
  try {
@@ -52049,7 +52072,8 @@ function OrbPreview({
52049
52072
  mockData: effectiveMockData,
52050
52073
  pageName: currentPage,
52051
52074
  onNavigate: handleNavigate,
52052
- onLocalFallback: handleLocalFallback
52075
+ onLocalFallback: handleLocalFallback,
52076
+ persistence
52053
52077
  }
52054
52078
  ) }) })
52055
52079
  ]