@almadar/ui 2.17.0 → 2.19.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.
@@ -1,4 +1,5 @@
1
- import React3, { createContext, useCallback, useState, useEffect, useMemo, useContext, useRef, useSyncExternalStore } from 'react';
1
+ import React2, { createContext, useCallback, useState, useEffect, useMemo, useContext, useRef, useSyncExternalStore } from 'react';
2
+ import { EventBusContext } from '@almadar/ui/providers';
2
3
  import 'react/jsx-runtime';
3
4
  import { useQueryClient, useMutation, useQuery } from '@tanstack/react-query';
4
5
 
@@ -865,9 +866,6 @@ function useDeepAgentGeneration() {
865
866
  submitInterruptDecisions
866
867
  };
867
868
  }
868
- var EventBusContext = createContext(null);
869
-
870
- // hooks/useEventBus.ts
871
869
  function getGlobalEventBus() {
872
870
  if (typeof window !== "undefined") {
873
871
  return window.__kflowEventBus ?? null;
@@ -1233,7 +1231,7 @@ function EntityDataProvider({
1233
1231
  adapter,
1234
1232
  children
1235
1233
  }) {
1236
- return React3.createElement(
1234
+ return React2.createElement(
1237
1235
  EntityDataContext.Provider,
1238
1236
  { value: adapter },
1239
1237
  children
@@ -3656,8 +3656,14 @@ var HeroSection = ({
3656
3656
  ),
3657
3657
  installCommand && /* @__PURE__ */ jsxRuntime.jsx(InstallBox, { command: installCommand }),
3658
3658
  (primaryAction || secondaryAction) && /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "md", align: "center", children: [
3659
- primaryAction && /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "primary", size: "lg", children: primaryAction.label }),
3660
- secondaryAction && /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "secondary", size: "lg", children: secondaryAction.label })
3659
+ primaryAction && /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "primary", size: "lg", onClick: () => {
3660
+ const external = primaryAction.href.startsWith("http");
3661
+ window.open(primaryAction.href, external ? "_blank" : "_self");
3662
+ }, children: primaryAction.label }),
3663
+ secondaryAction && /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "secondary", size: "lg", onClick: () => {
3664
+ const external = secondaryAction.href.startsWith("http");
3665
+ window.open(secondaryAction.href, external ? "_blank" : "_self");
3666
+ }, children: secondaryAction.label })
3661
3667
  ] }),
3662
3668
  children
3663
3669
  ]
@@ -3632,8 +3632,14 @@ var HeroSection = ({
3632
3632
  ),
3633
3633
  installCommand && /* @__PURE__ */ jsx(InstallBox, { command: installCommand }),
3634
3634
  (primaryAction || secondaryAction) && /* @__PURE__ */ jsxs(HStack, { gap: "md", align: "center", children: [
3635
- primaryAction && /* @__PURE__ */ jsx(Button, { variant: "primary", size: "lg", children: primaryAction.label }),
3636
- secondaryAction && /* @__PURE__ */ jsx(Button, { variant: "secondary", size: "lg", children: secondaryAction.label })
3635
+ primaryAction && /* @__PURE__ */ jsx(Button, { variant: "primary", size: "lg", onClick: () => {
3636
+ const external = primaryAction.href.startsWith("http");
3637
+ window.open(primaryAction.href, external ? "_blank" : "_self");
3638
+ }, children: primaryAction.label }),
3639
+ secondaryAction && /* @__PURE__ */ jsx(Button, { variant: "secondary", size: "lg", onClick: () => {
3640
+ const external = secondaryAction.href.startsWith("http");
3641
+ window.open(secondaryAction.href, external ? "_blank" : "_self");
3642
+ }, children: secondaryAction.label })
3637
3643
  ] }),
3638
3644
  children
3639
3645
  ]
@@ -18,15 +18,9 @@ import type { EventBusContextType } from '../hooks/event-bus-types';
18
18
  * Use SelectionProvider and useSelection hook instead.
19
19
  */
20
20
  export interface EventBusContextTypeExtended extends EventBusContextType {
21
- /**
22
- * @deprecated Use useSelection from SelectionProvider instead.
23
- * This method now returns null - selection state moved to SelectionProvider.
24
- */
21
+ /** @deprecated Use useSelection from SelectionProvider instead. */
25
22
  getSelectedEntity: () => unknown | null;
26
- /**
27
- * @deprecated Use useSelection from SelectionProvider instead.
28
- * This method is now a no-op - selection state moved to SelectionProvider.
29
- */
23
+ /** @deprecated Use useSelection from SelectionProvider instead. */
30
24
  clearSelectedEntity: () => void;
31
25
  }
32
26
  export declare const EventBusContext: React.Context<EventBusContextTypeExtended | null>;
@@ -2,6 +2,7 @@
2
2
 
3
3
  var React110 = require('react');
4
4
  var jsxRuntime = require('react/jsx-runtime');
5
+ var providers = require('@almadar/ui/providers');
5
6
  require('react-dom');
6
7
  require('@almadar/ui/context');
7
8
  var LucideIcons = require('lucide-react');
@@ -355,10 +356,10 @@ var fallbackEventBus = {
355
356
  }
356
357
  };
357
358
  function useEventBus() {
358
- const context = React110.useContext(EventBusContext);
359
+ const context = React110.useContext(providers.EventBusContext);
359
360
  return context ?? getGlobalEventBus() ?? fallbackEventBus;
360
361
  }
361
- var EventBusContext = React110.createContext(null);
362
+ var EventBusContext2 = React110.createContext(null);
362
363
  function EventBusProvider({ children, debug: debug2 = false }) {
363
364
  const listenersRef = React110.useRef(/* @__PURE__ */ new Map());
364
365
  const anyListenersRef = React110.useRef(/* @__PURE__ */ new Set());
@@ -474,7 +475,7 @@ function EventBusProvider({ children, debug: debug2 = false }) {
474
475
  setGlobalEventBus(null);
475
476
  };
476
477
  }, [contextValue]);
477
- return /* @__PURE__ */ jsxRuntime.jsx(EventBusContext.Provider, { value: contextValue, children });
478
+ return /* @__PURE__ */ jsxRuntime.jsx(EventBusContext2.Provider, { value: contextValue, children });
478
479
  }
479
480
  var SelectionContext = React110.createContext(null);
480
481
  var defaultCompareEntities = (a, b) => {
@@ -3424,7 +3425,7 @@ function useOptionalOfflineMode() {
3424
3425
  return React110.useContext(OfflineModeContext);
3425
3426
  }
3426
3427
 
3427
- exports.EventBusContext = EventBusContext;
3428
+ exports.EventBusContext = EventBusContext2;
3428
3429
  exports.EventBusProvider = EventBusProvider;
3429
3430
  exports.FetchedDataContext = FetchedDataContext;
3430
3431
  exports.FetchedDataProvider = FetchedDataProvider;
@@ -1,6 +1,7 @@
1
1
  import * as React110 from 'react';
2
2
  import React110__default, { createContext, useCallback, useState, useRef, useLayoutEffect, useEffect, lazy, useContext, useMemo } from 'react';
3
3
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
4
+ import { EventBusContext } from '@almadar/ui/providers';
4
5
  import 'react-dom';
5
6
  import '@almadar/ui/context';
6
7
  import * as LucideIcons from 'lucide-react';
@@ -328,7 +329,7 @@ function useEventBus() {
328
329
  const context = useContext(EventBusContext);
329
330
  return context ?? getGlobalEventBus() ?? fallbackEventBus;
330
331
  }
331
- var EventBusContext = createContext(null);
332
+ var EventBusContext2 = createContext(null);
332
333
  function EventBusProvider({ children, debug: debug2 = false }) {
333
334
  const listenersRef = useRef(/* @__PURE__ */ new Map());
334
335
  const anyListenersRef = useRef(/* @__PURE__ */ new Set());
@@ -444,7 +445,7 @@ function EventBusProvider({ children, debug: debug2 = false }) {
444
445
  setGlobalEventBus(null);
445
446
  };
446
447
  }, [contextValue]);
447
- return /* @__PURE__ */ jsx(EventBusContext.Provider, { value: contextValue, children });
448
+ return /* @__PURE__ */ jsx(EventBusContext2.Provider, { value: contextValue, children });
448
449
  }
449
450
  var SelectionContext = createContext(null);
450
451
  var defaultCompareEntities = (a, b) => {
@@ -3394,4 +3395,4 @@ function useOptionalOfflineMode() {
3394
3395
  return useContext(OfflineModeContext);
3395
3396
  }
3396
3397
 
3397
- export { EventBusContext, EventBusProvider, FetchedDataContext, FetchedDataProvider, OfflineModeProvider, OrbitalProvider, SelectionContext, SelectionProvider, VerificationProvider, useFetchedData, useFetchedDataContext, useFetchedEntity, useOfflineMode, useOptionalOfflineMode, useSelection, useSelectionOptional };
3398
+ export { EventBusContext2 as EventBusContext, EventBusProvider, FetchedDataContext, FetchedDataProvider, OfflineModeProvider, OrbitalProvider, SelectionContext, SelectionProvider, VerificationProvider, useFetchedData, useFetchedDataContext, useFetchedEntity, useOfflineMode, useOptionalOfflineMode, useSelection, useSelectionOptional };
@@ -0,0 +1,39 @@
1
+ /**
2
+ * OrbPreview Component
3
+ *
4
+ * Renders a live preview of an Orbital schema (.orb program).
5
+ * Lazily loads the full runtime stack (providers, context, state machines)
6
+ * and renders the schema's UI via UISlotRenderer.
7
+ *
8
+ * Usage:
9
+ * <OrbPreview schema={orbJsonStringOrObject} />
10
+ *
11
+ * @packageDocumentation
12
+ */
13
+ import React from 'react';
14
+ export interface OrbPreviewProps {
15
+ /** The orbital schema. Accepts a JSON string or a parsed object. */
16
+ schema: string | Record<string, unknown>;
17
+ /** Mock entity data keyed by entity name. */
18
+ mockData?: Record<string, unknown[]>;
19
+ /** Preview container height. Default: '400px'. */
20
+ height?: string;
21
+ /** CSS class for the outer container. */
22
+ className?: string;
23
+ }
24
+ /**
25
+ * Renders a live preview of an Orbital schema.
26
+ *
27
+ * Lazily loads the full Almadar runtime (providers, state machines, slot system)
28
+ * and renders the schema's UI. Suitable for documentation sites, playgrounds,
29
+ * and any context where you want to show a running .orb program.
30
+ *
31
+ * @example
32
+ * ```tsx
33
+ * <OrbPreview schema={orbJsonString} height="300px" />
34
+ * ```
35
+ */
36
+ export declare function OrbPreview({ schema, mockData, height, className, }: OrbPreviewProps): React.ReactElement;
37
+ export declare namespace OrbPreview {
38
+ var displayName: string;
39
+ }
@@ -1,6 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var React110 = require('react');
4
+ var providers = require('@almadar/ui/providers');
4
5
  var jsxRuntime = require('react/jsx-runtime');
5
6
  require('@tanstack/react-query');
6
7
  require('react-dom');
@@ -56,7 +57,6 @@ var dark__default = /*#__PURE__*/_interopDefault(dark);
56
57
  var __defProp = Object.defineProperty;
57
58
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
58
59
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
59
- var EventBusContext = React110.createContext(null);
60
60
  function getGlobalEventBus() {
61
61
  if (typeof window !== "undefined") {
62
62
  return window.__kflowEventBus ?? null;
@@ -124,7 +124,7 @@ var fallbackEventBus = {
124
124
  }
125
125
  };
126
126
  function useEventBus() {
127
- const context = React110.useContext(EventBusContext);
127
+ const context = React110.useContext(providers.EventBusContext);
128
128
  return context ?? getGlobalEventBus() ?? fallbackEventBus;
129
129
  }
130
130
  React110.createContext(null);
@@ -255,6 +255,7 @@ function useTranslate() {
255
255
  }
256
256
  typeof process !== "undefined" && process.env?.VITE_API_URL ? process.env.VITE_API_URL : "http://localhost:3000";
257
257
  React110.createContext(void 0);
258
+ React110.createContext(null);
258
259
  var FetchedDataContext = React110.createContext(null);
259
260
  function useFetchedDataContext() {
260
261
  return React110.useContext(FetchedDataContext);
@@ -3013,8 +3014,144 @@ function useSlotsActions() {
3013
3014
  }
3014
3015
  return actions;
3015
3016
  }
3017
+ var runtimeCache = null;
3018
+ async function loadRuntime() {
3019
+ if (runtimeCache) return runtimeCache;
3020
+ const [providers, context, runtime, components] = await Promise.all([
3021
+ import('@almadar/ui/providers'),
3022
+ import('@almadar/ui/context'),
3023
+ import('@almadar/ui/runtime'),
3024
+ import('@almadar/ui/components')
3025
+ ]);
3026
+ runtimeCache = {
3027
+ OrbitalProvider: providers.OrbitalProvider,
3028
+ UISlotProvider: context.UISlotProvider,
3029
+ SlotsProvider: runtime.SlotsProvider,
3030
+ EntitySchemaProvider: runtime.EntitySchemaProvider,
3031
+ VerificationProvider: providers.VerificationProvider,
3032
+ UISlotRenderer: components.UISlotRenderer,
3033
+ useResolvedSchema: runtime.useResolvedSchema,
3034
+ useTraitStateMachine: runtime.useTraitStateMachine,
3035
+ useSlotsActions: runtime.useSlotsActions,
3036
+ useSlots: runtime.useSlots,
3037
+ useUISlots: context.useUISlots
3038
+ };
3039
+ return runtimeCache;
3040
+ }
3041
+ function normalizeChild(child) {
3042
+ const { type, children, ...rest } = child;
3043
+ const normalizedChildren = Array.isArray(children) ? children.map((c) => normalizeChild(c)) : children;
3044
+ return {
3045
+ type,
3046
+ props: { ...rest, ...normalizedChildren !== void 0 ? { children: normalizedChildren } : {} }
3047
+ };
3048
+ }
3049
+ function SlotBridge({ rt }) {
3050
+ const slots = rt.useSlots();
3051
+ const { render, clear } = rt.useUISlots();
3052
+ React110.useEffect(() => {
3053
+ for (const [slotName, slotState] of Object.entries(slots)) {
3054
+ if (slotState.patterns.length === 0) {
3055
+ clear(slotName);
3056
+ continue;
3057
+ }
3058
+ const entry = slotState.patterns[slotState.patterns.length - 1];
3059
+ const { type: patternType, children, ...inlineProps } = entry.pattern;
3060
+ const normalizedChildren = Array.isArray(children) ? children.map((c) => normalizeChild(c)) : children;
3061
+ render({
3062
+ target: slotName,
3063
+ pattern: patternType,
3064
+ props: {
3065
+ ...inlineProps,
3066
+ ...entry.props,
3067
+ ...normalizedChildren !== void 0 ? { children: normalizedChildren } : {}
3068
+ },
3069
+ sourceTrait: slotState.source?.trait
3070
+ });
3071
+ }
3072
+ }, [slots]);
3073
+ return null;
3074
+ }
3075
+ function TraitInitializer({ rt, traits: traits2 }) {
3076
+ const slotsActions = rt.useSlotsActions();
3077
+ const { sendEvent } = rt.useTraitStateMachine(traits2, slotsActions, {});
3078
+ React110.useEffect(() => {
3079
+ const t = setTimeout(() => sendEvent("INIT"), 50);
3080
+ return () => clearTimeout(t);
3081
+ }, [traits2]);
3082
+ return null;
3083
+ }
3084
+ function SchemaRunner({ rt, schema, mockData }) {
3085
+ const { traits: traits2, allEntities, ir } = rt.useResolvedSchema(schema);
3086
+ const allPageTraits = React110.useMemo(() => {
3087
+ if (!ir?.pages || ir.pages.size <= 1) return traits2;
3088
+ const combined = [];
3089
+ const seen = /* @__PURE__ */ new Set();
3090
+ for (const page of ir.pages.values()) {
3091
+ for (const t of page.traits) {
3092
+ const binding = t;
3093
+ const traitObj = binding.trait;
3094
+ const name = traitObj?.name ?? binding.name ?? "";
3095
+ if (name && !seen.has(name)) {
3096
+ seen.add(name);
3097
+ combined.push(t);
3098
+ }
3099
+ }
3100
+ }
3101
+ return combined.length > 0 ? combined : traits2;
3102
+ }, [ir, traits2]);
3103
+ return /* @__PURE__ */ jsxRuntime.jsx(rt.VerificationProvider, { enabled: true, children: /* @__PURE__ */ jsxRuntime.jsx(rt.SlotsProvider, { children: /* @__PURE__ */ jsxRuntime.jsxs(rt.EntitySchemaProvider, { entities: Array.from(allEntities.values()), children: [
3104
+ /* @__PURE__ */ jsxRuntime.jsx(TraitInitializer, { rt, traits: allPageTraits }),
3105
+ /* @__PURE__ */ jsxRuntime.jsx(SlotBridge, { rt }),
3106
+ /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "min-h-full p-4", children: /* @__PURE__ */ jsxRuntime.jsx(rt.UISlotRenderer, { includeHud: true, hudMode: "inline", includeFloating: true }) })
3107
+ ] }) }) });
3108
+ }
3109
+ function OrbPreview({
3110
+ schema,
3111
+ mockData = {},
3112
+ height = "400px",
3113
+ className
3114
+ }) {
3115
+ const [rt, setRt] = React110.useState(null);
3116
+ const [error, setError] = React110.useState(null);
3117
+ const parsedSchema = React110.useMemo(() => {
3118
+ if (typeof schema === "string") {
3119
+ try {
3120
+ return JSON.parse(schema);
3121
+ } catch (e) {
3122
+ return { error: String(e) };
3123
+ }
3124
+ }
3125
+ return schema;
3126
+ }, [schema]);
3127
+ React110.useEffect(() => {
3128
+ loadRuntime().then(setRt).catch((e) => setError(String(e)));
3129
+ }, []);
3130
+ if (parsedSchema.error) {
3131
+ return /* @__PURE__ */ jsxRuntime.jsx(Box, { className, style: { height }, children: /* @__PURE__ */ jsxRuntime.jsxs(Typography, { as: "pre", color: "error", variant: "small", className: "font-mono whitespace-pre-wrap break-all m-0 p-4", children: [
3132
+ "Parse error: ",
3133
+ parsedSchema.error
3134
+ ] }) });
3135
+ }
3136
+ if (error) {
3137
+ return /* @__PURE__ */ jsxRuntime.jsx(Box, { className, style: { height }, children: /* @__PURE__ */ jsxRuntime.jsx(Typography, { as: "pre", color: "error", variant: "small", className: "font-mono whitespace-pre-wrap break-all m-0 p-4", children: error }) });
3138
+ }
3139
+ if (!rt) {
3140
+ return /* @__PURE__ */ jsxRuntime.jsx(Box, { className: `flex items-center justify-center ${className ?? ""}`, style: { height }, children: /* @__PURE__ */ jsxRuntime.jsx(Typography, { color: "muted", variant: "small", children: "Loading runtime..." }) });
3141
+ }
3142
+ return /* @__PURE__ */ jsxRuntime.jsx(
3143
+ Box,
3144
+ {
3145
+ className: `overflow-auto border border-[var(--color-border)] rounded-[var(--radius-md)] ${className ?? ""}`,
3146
+ style: { height },
3147
+ children: /* @__PURE__ */ jsxRuntime.jsx(rt.OrbitalProvider, { initialData: mockData, skipTheme: true, verification: true, children: /* @__PURE__ */ jsxRuntime.jsx(rt.UISlotProvider, { children: /* @__PURE__ */ jsxRuntime.jsx(SchemaRunner, { rt, schema: parsedSchema, mockData }) }) })
3148
+ }
3149
+ );
3150
+ }
3151
+ OrbPreview.displayName = "OrbPreview";
3016
3152
 
3017
3153
  exports.EntitySchemaProvider = EntitySchemaProvider;
3154
+ exports.OrbPreview = OrbPreview;
3018
3155
  exports.SlotsProvider = SlotsProvider;
3019
3156
  exports.TraitContext = TraitContext;
3020
3157
  exports.TraitProvider = TraitProvider;
@@ -12,4 +12,5 @@ export { EntitySchemaProvider, useEntitySchema, useEntityDefinition, type Entity
12
12
  export { TraitProvider, TraitContext, useTraitContext, useTrait, type TraitContextValue, type TraitInstance, type TraitProviderProps, } from './TraitProvider';
13
13
  export { SlotsProvider, useSlots, useSlotContent, useSlotsActions, type SlotsState, type SlotState, type SlotPatternEntry, type SlotSource, type SlotsActions, type SlotsProviderProps, } from './ui/SlotsContext';
14
14
  export { createClientEffectHandlers, type ClientEventBus, type SlotSetter, type CreateClientEffectHandlersOptions, } from './createClientEffectHandlers';
15
+ export { OrbPreview, type OrbPreviewProps } from './OrbPreview';
15
16
  export type { ResolvedTraitBinding, ResolvedTrait, ResolvedEntity, ResolvedPage, ResolvedIR, } from './types';
@@ -1,5 +1,6 @@
1
1
  import * as React110 from 'react';
2
2
  import React110__default, { createContext, useCallback, useState, useRef, useLayoutEffect, useEffect, lazy, useContext, useMemo } from 'react';
3
+ import { EventBusContext } from '@almadar/ui/providers';
3
4
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
4
5
  import '@tanstack/react-query';
5
6
  import 'react-dom';
@@ -26,7 +27,6 @@ import { StateMachineManager, createContextFromBindings, interpolateValue, Effec
26
27
  var __defProp = Object.defineProperty;
27
28
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
28
29
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
29
- var EventBusContext = createContext(null);
30
30
  function getGlobalEventBus() {
31
31
  if (typeof window !== "undefined") {
32
32
  return window.__kflowEventBus ?? null;
@@ -225,6 +225,7 @@ function useTranslate() {
225
225
  }
226
226
  typeof process !== "undefined" && process.env?.VITE_API_URL ? process.env.VITE_API_URL : "http://localhost:3000";
227
227
  createContext(void 0);
228
+ createContext(null);
228
229
  var FetchedDataContext = createContext(null);
229
230
  function useFetchedDataContext() {
230
231
  return useContext(FetchedDataContext);
@@ -2983,5 +2984,140 @@ function useSlotsActions() {
2983
2984
  }
2984
2985
  return actions;
2985
2986
  }
2987
+ var runtimeCache = null;
2988
+ async function loadRuntime() {
2989
+ if (runtimeCache) return runtimeCache;
2990
+ const [providers, context, runtime, components] = await Promise.all([
2991
+ import('@almadar/ui/providers'),
2992
+ import('@almadar/ui/context'),
2993
+ import('@almadar/ui/runtime'),
2994
+ import('@almadar/ui/components')
2995
+ ]);
2996
+ runtimeCache = {
2997
+ OrbitalProvider: providers.OrbitalProvider,
2998
+ UISlotProvider: context.UISlotProvider,
2999
+ SlotsProvider: runtime.SlotsProvider,
3000
+ EntitySchemaProvider: runtime.EntitySchemaProvider,
3001
+ VerificationProvider: providers.VerificationProvider,
3002
+ UISlotRenderer: components.UISlotRenderer,
3003
+ useResolvedSchema: runtime.useResolvedSchema,
3004
+ useTraitStateMachine: runtime.useTraitStateMachine,
3005
+ useSlotsActions: runtime.useSlotsActions,
3006
+ useSlots: runtime.useSlots,
3007
+ useUISlots: context.useUISlots
3008
+ };
3009
+ return runtimeCache;
3010
+ }
3011
+ function normalizeChild(child) {
3012
+ const { type, children, ...rest } = child;
3013
+ const normalizedChildren = Array.isArray(children) ? children.map((c) => normalizeChild(c)) : children;
3014
+ return {
3015
+ type,
3016
+ props: { ...rest, ...normalizedChildren !== void 0 ? { children: normalizedChildren } : {} }
3017
+ };
3018
+ }
3019
+ function SlotBridge({ rt }) {
3020
+ const slots = rt.useSlots();
3021
+ const { render, clear } = rt.useUISlots();
3022
+ useEffect(() => {
3023
+ for (const [slotName, slotState] of Object.entries(slots)) {
3024
+ if (slotState.patterns.length === 0) {
3025
+ clear(slotName);
3026
+ continue;
3027
+ }
3028
+ const entry = slotState.patterns[slotState.patterns.length - 1];
3029
+ const { type: patternType, children, ...inlineProps } = entry.pattern;
3030
+ const normalizedChildren = Array.isArray(children) ? children.map((c) => normalizeChild(c)) : children;
3031
+ render({
3032
+ target: slotName,
3033
+ pattern: patternType,
3034
+ props: {
3035
+ ...inlineProps,
3036
+ ...entry.props,
3037
+ ...normalizedChildren !== void 0 ? { children: normalizedChildren } : {}
3038
+ },
3039
+ sourceTrait: slotState.source?.trait
3040
+ });
3041
+ }
3042
+ }, [slots]);
3043
+ return null;
3044
+ }
3045
+ function TraitInitializer({ rt, traits: traits2 }) {
3046
+ const slotsActions = rt.useSlotsActions();
3047
+ const { sendEvent } = rt.useTraitStateMachine(traits2, slotsActions, {});
3048
+ useEffect(() => {
3049
+ const t = setTimeout(() => sendEvent("INIT"), 50);
3050
+ return () => clearTimeout(t);
3051
+ }, [traits2]);
3052
+ return null;
3053
+ }
3054
+ function SchemaRunner({ rt, schema, mockData }) {
3055
+ const { traits: traits2, allEntities, ir } = rt.useResolvedSchema(schema);
3056
+ const allPageTraits = useMemo(() => {
3057
+ if (!ir?.pages || ir.pages.size <= 1) return traits2;
3058
+ const combined = [];
3059
+ const seen = /* @__PURE__ */ new Set();
3060
+ for (const page of ir.pages.values()) {
3061
+ for (const t of page.traits) {
3062
+ const binding = t;
3063
+ const traitObj = binding.trait;
3064
+ const name = traitObj?.name ?? binding.name ?? "";
3065
+ if (name && !seen.has(name)) {
3066
+ seen.add(name);
3067
+ combined.push(t);
3068
+ }
3069
+ }
3070
+ }
3071
+ return combined.length > 0 ? combined : traits2;
3072
+ }, [ir, traits2]);
3073
+ return /* @__PURE__ */ jsx(rt.VerificationProvider, { enabled: true, children: /* @__PURE__ */ jsx(rt.SlotsProvider, { children: /* @__PURE__ */ jsxs(rt.EntitySchemaProvider, { entities: Array.from(allEntities.values()), children: [
3074
+ /* @__PURE__ */ jsx(TraitInitializer, { rt, traits: allPageTraits }),
3075
+ /* @__PURE__ */ jsx(SlotBridge, { rt }),
3076
+ /* @__PURE__ */ jsx(Box, { className: "min-h-full p-4", children: /* @__PURE__ */ jsx(rt.UISlotRenderer, { includeHud: true, hudMode: "inline", includeFloating: true }) })
3077
+ ] }) }) });
3078
+ }
3079
+ function OrbPreview({
3080
+ schema,
3081
+ mockData = {},
3082
+ height = "400px",
3083
+ className
3084
+ }) {
3085
+ const [rt, setRt] = useState(null);
3086
+ const [error, setError] = useState(null);
3087
+ const parsedSchema = useMemo(() => {
3088
+ if (typeof schema === "string") {
3089
+ try {
3090
+ return JSON.parse(schema);
3091
+ } catch (e) {
3092
+ return { error: String(e) };
3093
+ }
3094
+ }
3095
+ return schema;
3096
+ }, [schema]);
3097
+ useEffect(() => {
3098
+ loadRuntime().then(setRt).catch((e) => setError(String(e)));
3099
+ }, []);
3100
+ if (parsedSchema.error) {
3101
+ return /* @__PURE__ */ jsx(Box, { className, style: { height }, children: /* @__PURE__ */ jsxs(Typography, { as: "pre", color: "error", variant: "small", className: "font-mono whitespace-pre-wrap break-all m-0 p-4", children: [
3102
+ "Parse error: ",
3103
+ parsedSchema.error
3104
+ ] }) });
3105
+ }
3106
+ if (error) {
3107
+ return /* @__PURE__ */ jsx(Box, { className, style: { height }, children: /* @__PURE__ */ jsx(Typography, { as: "pre", color: "error", variant: "small", className: "font-mono whitespace-pre-wrap break-all m-0 p-4", children: error }) });
3108
+ }
3109
+ if (!rt) {
3110
+ return /* @__PURE__ */ jsx(Box, { className: `flex items-center justify-center ${className ?? ""}`, style: { height }, children: /* @__PURE__ */ jsx(Typography, { color: "muted", variant: "small", children: "Loading runtime..." }) });
3111
+ }
3112
+ return /* @__PURE__ */ jsx(
3113
+ Box,
3114
+ {
3115
+ className: `overflow-auto border border-[var(--color-border)] rounded-[var(--radius-md)] ${className ?? ""}`,
3116
+ style: { height },
3117
+ children: /* @__PURE__ */ jsx(rt.OrbitalProvider, { initialData: mockData, skipTheme: true, verification: true, children: /* @__PURE__ */ jsx(rt.UISlotProvider, { children: /* @__PURE__ */ jsx(SchemaRunner, { rt, schema: parsedSchema, mockData }) }) })
3118
+ }
3119
+ );
3120
+ }
3121
+ OrbPreview.displayName = "OrbPreview";
2986
3122
 
2987
- export { EntitySchemaProvider, SlotsProvider, TraitContext, TraitProvider, clearSchemaCache, createClientEffectHandlers, useEntityDefinition, useEntitySchema, useResolvedSchema, useSlotContent, useSlots, useSlotsActions, useTrait, useTraitContext, useTraitStateMachine };
3123
+ export { EntitySchemaProvider, OrbPreview, SlotsProvider, TraitContext, TraitProvider, clearSchemaCache, createClientEffectHandlers, useEntityDefinition, useEntitySchema, useResolvedSchema, useSlotContent, useSlots, useSlotsActions, useTrait, useTraitContext, useTraitStateMachine };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@almadar/ui",
3
- "version": "2.17.0",
3
+ "version": "2.19.0",
4
4
  "description": "React UI components, hooks, and providers for Almadar",
5
5
  "type": "module",
6
6
  "main": "./dist/components/index.js",