@almadar/ui 5.70.0 → 5.71.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.
Files changed (55) hide show
  1. package/dist/avl/index.cjs +1953 -1802
  2. package/dist/avl/index.d.cts +93 -56
  3. package/dist/avl/index.js +677 -526
  4. package/dist/components/avl/molecules/AvlEventWireEdge.d.ts +2 -1
  5. package/dist/components/avl/molecules/AvlTransitionEdge.d.ts +2 -1
  6. package/dist/components/avl/molecules/avl-behavior-compose-converter.d.ts +7 -5
  7. package/dist/components/avl/molecules/avl-behavior-compose-types.d.ts +41 -21
  8. package/dist/components/avl/molecules/avl-canvas-types.d.ts +10 -7
  9. package/dist/components/avl/molecules/avl-preview-converter.d.ts +5 -5
  10. package/dist/components/avl/molecules/avl-preview-types.d.ts +15 -4
  11. package/dist/components/avl/organisms/FlowCanvas.d.ts +2 -2
  12. package/dist/components/avl/organisms/avl-schema-parser.d.ts +18 -16
  13. package/dist/components/core/atoms/Button.d.ts +2 -0
  14. package/dist/components/core/atoms/ConditionalWrapper.d.ts +5 -4
  15. package/dist/components/core/molecules/Carousel.d.ts +2 -2
  16. package/dist/components/core/molecules/OrbitalVisualization.d.ts +4 -3
  17. package/dist/components/core/molecules/PageHeader.d.ts +3 -3
  18. package/dist/components/core/molecules/RepeatableFormSection.d.ts +4 -3
  19. package/dist/components/core/molecules/ViolationAlert.d.ts +2 -0
  20. package/dist/components/core/molecules/WizardContainer.d.ts +23 -22
  21. package/dist/components/core/organisms/CardGrid.d.ts +2 -2
  22. package/dist/components/core/organisms/CustomPattern.d.ts +3 -4
  23. package/dist/components/core/organisms/DataTable.d.ts +2 -2
  24. package/dist/components/core/organisms/DetailPanel.d.ts +1 -1
  25. package/dist/components/core/organisms/Form.d.ts +11 -11
  26. package/dist/components/core/organisms/List.d.ts +3 -5
  27. package/dist/components/core/organisms/StatCard.d.ts +2 -2
  28. package/dist/components/core/organisms/book/types.d.ts +1 -1
  29. package/dist/components/core/organisms/debug/RuntimeDebugger.d.ts +2 -1
  30. package/dist/components/core/organisms/debug/tabs/EventDispatcherTab.d.ts +2 -1
  31. package/dist/components/core/organisms/layout/DashboardGrid.d.ts +0 -2
  32. package/dist/components/core/organisms/types.d.ts +3 -2
  33. package/dist/components/game/atoms/ScoreDisplay.d.ts +3 -1
  34. package/dist/components/game/molecules/three/hooks/useSceneGraph.d.ts +2 -1
  35. package/dist/components/game/molecules/three/index.cjs +37 -24
  36. package/dist/components/game/molecules/three/index.js +37 -24
  37. package/dist/components/game/organisms/PinballBoard.d.ts +4 -4
  38. package/dist/components/game/organisms/boardEntity.d.ts +6 -6
  39. package/dist/components/game/organisms/puzzles/debugger/DebuggerBoard.d.ts +16 -2
  40. package/dist/components/game/organisms/puzzles/event-handler/puzzleObject.d.ts +21 -10
  41. package/dist/components/game/organisms/puzzles/state-architect/StateJsonView.d.ts +2 -1
  42. package/dist/components/index.cjs +1690 -1562
  43. package/dist/components/index.js +569 -441
  44. package/dist/docs/index.cjs +107 -104
  45. package/dist/docs/index.d.cts +2 -0
  46. package/dist/docs/index.js +38 -35
  47. package/dist/lib/getNestedValue.d.ts +2 -13
  48. package/dist/marketing/index.cjs +97 -98
  49. package/dist/marketing/index.d.cts +2 -0
  50. package/dist/marketing/index.js +54 -55
  51. package/dist/providers/index.cjs +1663 -1535
  52. package/dist/providers/index.js +554 -426
  53. package/dist/runtime/index.cjs +1721 -1593
  54. package/dist/runtime/index.js +560 -432
  55. package/package.json +1 -1
@@ -8,7 +8,7 @@
8
8
  * @packageDocumentation
9
9
  */
10
10
  import React from "react";
11
- import type { AssetUrl, EventKey, EventPayload } from "@almadar/core";
11
+ import type { AssetUrl, EventKey, EventPayload, JsonValue } from "@almadar/core";
12
12
  import type { UiError } from "../atoms/types";
13
13
  /**
14
14
  * Allowed element types for custom patterns.
@@ -49,7 +49,7 @@ export interface CustomPatternProps {
49
49
  /** Disabled state */
50
50
  disabled?: boolean;
51
51
  /** Additional HTML attributes */
52
- htmlProps?: Record<string, unknown>;
52
+ htmlProps?: React.HTMLAttributes<HTMLElement>;
53
53
  /** Loading state */
54
54
  isLoading?: boolean;
55
55
  /** Error state */
@@ -91,12 +91,11 @@ export interface CustomPatternConfig {
91
91
  href?: string;
92
92
  external?: boolean;
93
93
  disabled?: boolean;
94
- [key: string]: unknown;
95
94
  }
96
95
  /**
97
96
  * Check if a pattern config is a custom pattern.
98
97
  */
99
- export declare function isCustomPatternConfig(config: unknown): config is CustomPatternConfig;
98
+ export declare function isCustomPatternConfig(config: JsonValue | CustomPatternConfig): config is CustomPatternConfig;
100
99
  /**
101
100
  * Recursively render custom pattern configurations.
102
101
  *
@@ -2,7 +2,7 @@ import React from "react";
2
2
  import type { EventKey } from "@almadar/core";
3
3
  import type { IconInput } from "../atoms/Icon";
4
4
  import { DisplayStateProps } from "./types";
5
- import type { EntityRow } from "@almadar/core";
5
+ import type { EntityRow, FieldValue } from "@almadar/core";
6
6
  export type EntityTableLook = "dense" | "spacious" | "striped" | "borderless" | "card-rows";
7
7
  export interface Column<T> {
8
8
  key: keyof T | string;
@@ -13,7 +13,7 @@ export interface Column<T> {
13
13
  label?: string;
14
14
  width?: string;
15
15
  sortable?: boolean;
16
- render?: (value: unknown, row: T, index: number) => React.ReactNode;
16
+ render?: (value: FieldValue | undefined, row: T, index: number) => React.ReactNode;
17
17
  }
18
18
  export interface RowAction<T> {
19
19
  label: string;
@@ -65,7 +65,7 @@ export interface DetailPanelProps extends DisplayStateProps {
65
65
  /** Alias for fields - backwards compatibility */
66
66
  fieldNames?: readonly string[];
67
67
  /** Initial data for edit mode (passed by compiler) */
68
- initialData?: Record<string, unknown> | unknown;
68
+ initialData?: EntityRow;
69
69
  /** Display mode (passed by compiler) */
70
70
  mode?: string;
71
71
  /** Panel position (for drawer/sidebar placement) */
@@ -12,7 +12,7 @@
12
12
  * - Nested sections with collapsible support
13
13
  */
14
14
  import React from "react";
15
- import type { EventKey, FieldValue } from "@almadar/core";
15
+ import type { EntityRow, EventKey, FieldValue, JsonObject } from "@almadar/core";
16
16
  import { type SelectOption } from "../atoms/Select";
17
17
  import { type RelationOption } from "../molecules/RelationSelect";
18
18
  import type { OrbitalEntity } from "@almadar/core";
@@ -27,10 +27,10 @@ export type SExpression = SExpr;
27
27
  * Form-specific evaluation context
28
28
  */
29
29
  export interface FormEvaluationContext {
30
- formValues: Record<string, unknown>;
31
- globalVariables: Record<string, unknown>;
32
- localVariables?: Record<string, unknown>;
33
- entity?: Record<string, unknown>;
30
+ formValues: EntityRow;
31
+ globalVariables: Record<string, FieldValue>;
32
+ localVariables?: Record<string, FieldValue>;
33
+ entity?: EntityRow;
34
34
  }
35
35
  /**
36
36
  * Hidden calculation definition
@@ -117,7 +117,7 @@ export interface SchemaField {
117
117
  /** Whether field is required */
118
118
  required?: boolean;
119
119
  /** Default value */
120
- defaultValue?: unknown;
120
+ defaultValue?: FieldValue;
121
121
  /** Options for select/enum fields - accepts readonly for generated const arrays */
122
122
  options?: readonly SelectOption[];
123
123
  /** Enum values (alternative to options, just strings) - accepts readonly for generated const arrays */
@@ -131,7 +131,7 @@ export interface SchemaField {
131
131
  /** Pattern for validation */
132
132
  pattern?: string;
133
133
  /** Validation rules */
134
- validation?: Record<string, unknown>;
134
+ validation?: JsonObject;
135
135
  /** Whether field is readonly (displays value but cannot edit) */
136
136
  readonly?: boolean;
137
137
  /** Whether field is disabled (alternative to readonly for compatibility) */
@@ -156,7 +156,7 @@ export interface FormProps extends Omit<React.FormHTMLAttributes<HTMLFormElement
156
156
  /** Additional CSS classes */
157
157
  className?: string;
158
158
  /** Entity type name or schema object. When OrbitalEntity, fields are auto-derived if not provided. */
159
- entity?: string | OrbitalEntity | readonly Record<string, unknown>[];
159
+ entity?: string | OrbitalEntity | EntityRow | readonly EntityRow[];
160
160
  /**
161
161
  * Form mode — 'create' for new records, 'edit' for updating existing.
162
162
  * Accepts `string` so schema-driven callers (whose `config.mode` is typed
@@ -167,7 +167,7 @@ export interface FormProps extends Omit<React.FormHTMLAttributes<HTMLFormElement
167
167
  /** Fields definition (schema format) - accepts readonly for generated const arrays */
168
168
  fields: readonly Readonly<SchemaField>[];
169
169
  /** Initial form data */
170
- initialData?: Record<string, unknown> | unknown;
170
+ initialData?: EntityRow;
171
171
  /** Loading state */
172
172
  isLoading?: boolean;
173
173
  /** Error state */
@@ -196,8 +196,8 @@ export interface FormProps extends Omit<React.FormHTMLAttributes<HTMLFormElement
196
196
  hiddenCalculations?: HiddenCalculation[] | boolean;
197
197
  /** Violation conditions that emit VIOLATION_DETECTED when met (boolean true means enabled but config loaded separately) */
198
198
  violationTriggers?: ViolationTrigger[] | boolean;
199
- /** Context for S-expression evaluation - accepts flexible types from generated code */
200
- evaluationContext?: FormEvaluationContext | Record<string, unknown>;
199
+ /** Context for S-expression evaluation */
200
+ evaluationContext?: FormEvaluationContext;
201
201
  /** Nested form sections with optional conditions */
202
202
  sections?: FormSection[];
203
203
  /** Callback when any field value changes */
@@ -17,11 +17,10 @@
17
17
  * - No internal search/filter state — trait provides filtered data
18
18
  */
19
19
  import React from "react";
20
- import type { AssetUrl, EventKey } from "@almadar/core";
20
+ import type { AssetUrl, EventKey, FieldValue, EntityRow } from "@almadar/core";
21
21
  import type { IconInput } from "../atoms/Icon";
22
22
  import { type MenuItem } from "../molecules/Menu";
23
23
  import type { DisplayStateProps } from "./types";
24
- import type { EntityRow } from "@almadar/core";
25
24
  export type ListItem = {
26
25
  id: string;
27
26
  title?: string;
@@ -37,8 +36,7 @@ export type ListItem = {
37
36
  onClick?: () => void;
38
37
  disabled?: boolean;
39
38
  completed?: boolean;
40
- [key: string]: unknown;
41
- _fields?: Record<string, unknown>;
39
+ _fields?: Record<string, FieldValue | undefined>;
42
40
  };
43
41
  export interface SchemaItemAction {
44
42
  label: string;
@@ -51,7 +49,7 @@ export interface SchemaItemAction {
51
49
  action?: EventKey;
52
50
  variant?: "primary" | "secondary" | "ghost" | "danger" | "default";
53
51
  /** Click handler from generated code */
54
- onClick?: (row: unknown) => void;
52
+ onClick?: (row: EntityRow) => void;
55
53
  }
56
54
  /**
57
55
  * Field definition - can be a simple string or object with key/header or name/label
@@ -25,8 +25,8 @@ export interface StatCardProps extends DisplayStateProps {
25
25
  label?: string;
26
26
  /** Title (alias for label) */
27
27
  title?: string;
28
- /** Primary value - accepts array/unknown from generated code (will use first element or length) */
29
- value?: string | number | (string | number | undefined)[] | unknown;
28
+ /** Primary value - accepts array from generated code (will use first element or length) */
29
+ value?: string | number | (string | number | undefined)[];
30
30
  /** Previous value for comparison */
31
31
  previousValue?: number;
32
32
  /** Current value as number for trend calculation */
@@ -59,4 +59,4 @@ export declare function resolveFieldMap(fieldMap: BookFieldMap | string | undefi
59
59
  * chapter data come back as `EntityRow`s; the per-chapter `OrbitalSchema` is
60
60
  * lifted off into `schemaByChapterId`.
61
61
  */
62
- export declare function mapBookData(raw: Record<string, unknown>, fields?: BookFieldMap): NormalizedBook;
62
+ export declare function mapBookData(raw: EntityRow, fields?: BookFieldMap): NormalizedBook;
@@ -1,3 +1,4 @@
1
+ import type { OrbitalSchema } from '@almadar/core';
1
2
  import './RuntimeDebugger.css';
2
3
  export interface RuntimeDebuggerProps {
3
4
  /** Initial position */
@@ -11,7 +12,7 @@ export interface RuntimeDebuggerProps {
11
12
  /** Default active tab id */
12
13
  defaultTab?: string;
13
14
  /** Raw schema for EventDispatcherTab payload extraction */
14
- schema?: Record<string, unknown>;
15
+ schema?: OrbitalSchema;
15
16
  }
16
17
  export declare function RuntimeDebugger({ position, defaultCollapsed, className, mode, defaultTab, schema, }: RuntimeDebuggerProps): import("react/jsx-runtime").JSX.Element | null;
17
18
  export declare namespace RuntimeDebugger {
@@ -4,10 +4,11 @@
4
4
  * Shows available transitions per trait based on current state,
5
5
  * lets users click to fire events, and displays a compact transition log.
6
6
  */
7
+ import type { OrbitalSchema } from '@almadar/core';
7
8
  import type { TraitDebugInfo } from '../../../../../lib/traitRegistry';
8
9
  interface EventDispatcherTabProps {
9
10
  traits: TraitDebugInfo[];
10
- schema?: Record<string, unknown>;
11
+ schema?: OrbitalSchema;
11
12
  }
12
13
  export declare function EventDispatcherTab({ traits, schema }: EventDispatcherTabProps): import("react/jsx-runtime").JSX.Element;
13
14
  export declare namespace EventDispatcherTab {
@@ -17,8 +17,6 @@ export interface DashboardGridCell {
17
17
  colSpan?: 1 | 2 | 3 | 4;
18
18
  /** Number of rows this cell spans (1-2) */
19
19
  rowSpan?: 1 | 2;
20
- /** Allow additional schema-driven properties */
21
- [key: string]: unknown;
22
20
  }
23
21
  export interface DashboardGridProps extends DisplayStateProps {
24
22
  /** Number of columns */
@@ -7,6 +7,7 @@
7
7
  * Exception: Form manages local `formData` state for field input tracking.
8
8
  * This is the ONE allowed exception — documented here.
9
9
  */
10
+ import type { FieldValue } from '@almadar/core';
10
11
  import type { UiError } from '../atoms/types';
11
12
  export type { UiError };
12
13
  export declare const EntityDisplayEvents: {
@@ -32,7 +33,7 @@ export interface SearchPayload {
32
33
  export interface FilterPayload {
33
34
  field: string;
34
35
  operator: string;
35
- value: unknown;
36
+ value: FieldValue;
36
37
  }
37
38
  export interface SelectPayload {
38
39
  ids: (string | number)[];
@@ -65,7 +66,7 @@ export interface DisplayStateProps {
65
66
  /** Total number of items (for pagination display) */
66
67
  totalCount?: number;
67
68
  /** Active filters */
68
- activeFilters?: Record<string, unknown>;
69
+ activeFilters?: Record<string, FieldValue>;
69
70
  /** Currently selected item IDs */
70
71
  selectedIds?: readonly (string | number)[];
71
72
  }
@@ -5,6 +5,8 @@ export interface ScoreDisplayProps {
5
5
  assetUrl?: AssetUrl;
6
6
  /** Current score value */
7
7
  value: number;
8
+ /** Alias for value — common schema binding name */
9
+ score?: number;
8
10
  /** Label to display before score */
9
11
  label?: string;
10
12
  /** Icon component or emoji */
@@ -18,7 +20,7 @@ export interface ScoreDisplayProps {
18
20
  /** Number formatting locale */
19
21
  locale?: string;
20
22
  }
21
- export declare function ScoreDisplay({ assetUrl, value, label, icon, size, className, animated, locale, ...rest }: ScoreDisplayProps & Record<string, unknown>): import("react/jsx-runtime").JSX.Element;
23
+ export declare function ScoreDisplay({ assetUrl, value, score, label, icon, size, className, animated, locale, }: ScoreDisplayProps): import("react/jsx-runtime").JSX.Element;
22
24
  export declare namespace ScoreDisplay {
23
25
  var displayName: string;
24
26
  }
@@ -1,4 +1,5 @@
1
1
  import * as THREE from 'three';
2
+ import type { JsonObject } from '@almadar/core';
2
3
  export type NodeType = 'tile' | 'unit' | 'feature' | 'highlight' | 'effect';
3
4
  export interface SceneGraphNode {
4
5
  /** Unique node identifier */
@@ -19,7 +20,7 @@ export interface SceneGraphNode {
19
20
  z: number;
20
21
  };
21
22
  /** Optional metadata */
22
- metadata?: Record<string, unknown>;
23
+ metadata?: JsonObject;
23
24
  }
24
25
  export interface UseSceneGraphReturn {
25
26
  /** Reference to the nodes map */
@@ -3989,6 +3989,9 @@ var iconSizeStyles = {
3989
3989
  md: "h-icon-default w-icon-default",
3990
3990
  lg: "h-icon-default w-icon-default"
3991
3991
  };
3992
+ function isIconLike(v) {
3993
+ return typeof v.render === "function";
3994
+ }
3992
3995
  function resolveIconProp(value, sizeClass) {
3993
3996
  if (!value) return null;
3994
3997
  if (typeof value === "string") {
@@ -4001,7 +4004,7 @@ function resolveIconProp(value, sizeClass) {
4001
4004
  if (React11__default.default.isValidElement(value)) {
4002
4005
  return value;
4003
4006
  }
4004
- if (typeof value === "object" && value !== null && "render" in value) {
4007
+ if (typeof value === "object" && value !== null && isIconLike(value)) {
4005
4008
  const IconComp = value;
4006
4009
  return /* @__PURE__ */ jsxRuntime.jsx(IconComp, { className: sizeClass });
4007
4010
  }
@@ -4023,6 +4026,7 @@ var Button = React11__default.default.forwardRef(
4023
4026
  label,
4024
4027
  children,
4025
4028
  onClick,
4029
+ "data-testid": dataTestId,
4026
4030
  ...props
4027
4031
  }, ref) => {
4028
4032
  const eventBus = useEventBus();
@@ -4055,7 +4059,7 @@ var Button = React11__default.default.forwardRef(
4055
4059
  ),
4056
4060
  onClick: handleClick,
4057
4061
  ...props,
4058
- "data-testid": props["data-testid"] ?? (action ? `action-${action}` : void 0),
4062
+ "data-testid": dataTestId ?? (action ? `action-${action}` : void 0),
4059
4063
  children: [
4060
4064
  isLoading ? /* @__PURE__ */ jsxRuntime.jsx(LucideIcons.Loader2, { className: "h-icon-default w-icon-default animate-spin" }) : resolvedLeftIcon && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-shrink-0", children: resolvedLeftIcon }),
4061
4065
  children || label,
@@ -4152,9 +4156,8 @@ var Typography = ({
4152
4156
  }) => {
4153
4157
  const variant = variantProp ?? (level ? `h${level}` : "body1");
4154
4158
  const Component2 = as || defaultElements[variant];
4155
- const Comp = Component2;
4156
- return /* @__PURE__ */ jsxRuntime.jsx(
4157
- Comp,
4159
+ return React11__default.default.createElement(
4160
+ Component2,
4158
4161
  {
4159
4162
  id,
4160
4163
  className: cn(
@@ -4167,9 +4170,9 @@ var Typography = ({
4167
4170
  overflow && overflowStyles[overflow],
4168
4171
  className
4169
4172
  ),
4170
- style,
4171
- children: children ?? content
4172
- }
4173
+ style
4174
+ },
4175
+ children ?? content
4173
4176
  );
4174
4177
  };
4175
4178
  Typography.displayName = "Typography";
@@ -4226,9 +4229,8 @@ var Stack = ({
4226
4229
  };
4227
4230
  const isHorizontal = direction === "horizontal";
4228
4231
  const directionClass = responsive && isHorizontal ? reverse ? "flex-col-reverse md:flex-row-reverse" : "flex-col md:flex-row" : isHorizontal ? reverse ? "flex-row-reverse" : "flex-row" : reverse ? "flex-col-reverse" : "flex-col";
4229
- const Comp = Component2;
4230
- return /* @__PURE__ */ jsxRuntime.jsx(
4231
- Comp,
4232
+ return React11__default.default.createElement(
4233
+ Component2,
4232
4234
  {
4233
4235
  className: cn(
4234
4236
  "flex",
@@ -4244,9 +4246,9 @@ var Stack = ({
4244
4246
  onClick: action || onClick ? handleClick : void 0,
4245
4247
  onKeyDown,
4246
4248
  role,
4247
- tabIndex,
4248
- children
4249
- }
4249
+ tabIndex
4250
+ },
4251
+ children
4250
4252
  );
4251
4253
  };
4252
4254
  var VStack = (props) => /* @__PURE__ */ jsxRuntime.jsx(Stack, { direction: "vertical", ...props });
@@ -5163,9 +5165,17 @@ function getEntity(orbital) {
5163
5165
  if (typeof entity === "string") {
5164
5166
  return { name: entity, fields: [], persistence: "runtime" };
5165
5167
  }
5168
+ if ("extends" in entity) {
5169
+ const ec = entity;
5170
+ return {
5171
+ name: ec.name ?? orbital.name,
5172
+ fields: ec.fields ?? [],
5173
+ persistence: ec.persistence ?? "runtime"
5174
+ };
5175
+ }
5166
5176
  const e = entity;
5167
5177
  return {
5168
- name: e.name ?? orbital.name,
5178
+ name: e.name,
5169
5179
  fields: e.fields ?? [],
5170
5180
  persistence: e.persistence ?? "runtime"
5171
5181
  };
@@ -5174,6 +5184,7 @@ function getTraits(orbital) {
5174
5184
  if (!orbital.traits) return [];
5175
5185
  return orbital.traits.map((t) => {
5176
5186
  if (typeof t === "string") return { name: t };
5187
+ if ("ref" in t && !("stateMachine" in t)) return { name: t.name ?? t.ref };
5177
5188
  return t;
5178
5189
  });
5179
5190
  }
@@ -5181,6 +5192,7 @@ function getPages(orbital) {
5181
5192
  if (!orbital.pages) return [];
5182
5193
  return orbital.pages.map((p) => {
5183
5194
  if (typeof p === "string") return { name: p, path: `/${p.toLowerCase()}` };
5195
+ if ("ref" in p && !("path" in p)) return { name: p.ref, path: `/${p.ref.toLowerCase()}` };
5184
5196
  return p;
5185
5197
  });
5186
5198
  }
@@ -5199,12 +5211,12 @@ function getEvents(sm) {
5199
5211
  function getEmits(trait) {
5200
5212
  const emits = trait.emits;
5201
5213
  if (!emits) return [];
5202
- return emits.map((e) => typeof e === "string" ? e : e.event ?? e.name ?? "");
5214
+ return emits.map((e) => e.event ?? "");
5203
5215
  }
5204
5216
  function getListens(trait) {
5205
5217
  const listens = trait.listens;
5206
5218
  if (!listens) return [];
5207
- return listens.map((l) => typeof l === "string" ? l : l.event ?? "");
5219
+ return listens.map((l) => l.event ?? "");
5208
5220
  }
5209
5221
  function parseEffectType(effect) {
5210
5222
  if (Array.isArray(effect)) {
@@ -5375,14 +5387,14 @@ function parseTraitLevel(schema, orbitalName, traitName) {
5375
5387
  if (!sm) return null;
5376
5388
  const states = getStates(sm).map((s) => ({
5377
5389
  name: s.name ?? "",
5378
- isInitial: s.isInitial ?? false,
5379
- isTerminal: s.isTerminal ?? false
5390
+ isInitial: s.isInitial ?? null,
5391
+ isTerminal: s.isTerminal ?? null
5380
5392
  }));
5381
5393
  const transitions = getTransitions(sm).map((t, i) => ({
5382
5394
  from: t.from ?? "",
5383
5395
  to: t.to ?? "",
5384
5396
  event: t.event ?? "",
5385
- guard: t.guard,
5397
+ guard: t.guard ?? null,
5386
5398
  effects: (t.effects ?? []).map(parseEffectType),
5387
5399
  index: i
5388
5400
  }));
@@ -5401,13 +5413,14 @@ function parseTransitionLevel(schema, orbitalName, traitName, transitionIndex) {
5401
5413
  if (!traitData) return null;
5402
5414
  const transition = traitData.transitions[transitionIndex];
5403
5415
  if (!transition) return null;
5404
- const guard = transition.guard ? exprToTree(transition.guard) : null;
5416
+ const guardVal = transition.guard;
5417
+ const guard = guardVal != null ? exprToTree(guardVal) : null;
5405
5418
  const effects = transition.effects.map(
5406
5419
  (e) => exprToTree([e.type, ...e.args])
5407
5420
  );
5408
5421
  const slotTargets = transition.effects.filter((e) => e.type === "render-ui").map((e) => ({
5409
5422
  name: String(e.args[0] ?? "main"),
5410
- pattern: typeof e.args[1] === "object" && e.args[1] !== null ? e.args[1].type ?? "unknown" : String(e.args[1] ?? "unknown")
5423
+ pattern: typeof e.args[1] === "object" && e.args[1] !== null && !Array.isArray(e.args[1]) ? e.args[1].type ?? "unknown" : String(e.args[1] ?? "unknown")
5411
5424
  }));
5412
5425
  return {
5413
5426
  from: transition.from,
@@ -6870,8 +6883,8 @@ var Avl3DTraitScene = ({
6870
6883
  Avl3DStateNode,
6871
6884
  {
6872
6885
  name: state.name,
6873
- isInitial: state.isInitial,
6874
- isTerminal: state.isTerminal,
6886
+ isInitial: state.isInitial ?? void 0,
6887
+ isTerminal: state.isTerminal ?? void 0,
6875
6888
  position: pos,
6876
6889
  incomingCount: transitionCounts.incoming.get(state.name) ?? 0,
6877
6890
  outgoingCount: transitionCounts.outgoing.get(state.name) ?? 0
@@ -3965,6 +3965,9 @@ var iconSizeStyles = {
3965
3965
  md: "h-icon-default w-icon-default",
3966
3966
  lg: "h-icon-default w-icon-default"
3967
3967
  };
3968
+ function isIconLike(v) {
3969
+ return typeof v.render === "function";
3970
+ }
3968
3971
  function resolveIconProp(value, sizeClass) {
3969
3972
  if (!value) return null;
3970
3973
  if (typeof value === "string") {
@@ -3977,7 +3980,7 @@ function resolveIconProp(value, sizeClass) {
3977
3980
  if (React11.isValidElement(value)) {
3978
3981
  return value;
3979
3982
  }
3980
- if (typeof value === "object" && value !== null && "render" in value) {
3983
+ if (typeof value === "object" && value !== null && isIconLike(value)) {
3981
3984
  const IconComp = value;
3982
3985
  return /* @__PURE__ */ jsx(IconComp, { className: sizeClass });
3983
3986
  }
@@ -3999,6 +4002,7 @@ var Button = React11.forwardRef(
3999
4002
  label,
4000
4003
  children,
4001
4004
  onClick,
4005
+ "data-testid": dataTestId,
4002
4006
  ...props
4003
4007
  }, ref) => {
4004
4008
  const eventBus = useEventBus();
@@ -4031,7 +4035,7 @@ var Button = React11.forwardRef(
4031
4035
  ),
4032
4036
  onClick: handleClick,
4033
4037
  ...props,
4034
- "data-testid": props["data-testid"] ?? (action ? `action-${action}` : void 0),
4038
+ "data-testid": dataTestId ?? (action ? `action-${action}` : void 0),
4035
4039
  children: [
4036
4040
  isLoading ? /* @__PURE__ */ jsx(Loader2, { className: "h-icon-default w-icon-default animate-spin" }) : resolvedLeftIcon && /* @__PURE__ */ jsx("span", { className: "flex-shrink-0", children: resolvedLeftIcon }),
4037
4041
  children || label,
@@ -4128,9 +4132,8 @@ var Typography = ({
4128
4132
  }) => {
4129
4133
  const variant = variantProp ?? (level ? `h${level}` : "body1");
4130
4134
  const Component2 = as || defaultElements[variant];
4131
- const Comp = Component2;
4132
- return /* @__PURE__ */ jsx(
4133
- Comp,
4135
+ return React11.createElement(
4136
+ Component2,
4134
4137
  {
4135
4138
  id,
4136
4139
  className: cn(
@@ -4143,9 +4146,9 @@ var Typography = ({
4143
4146
  overflow && overflowStyles[overflow],
4144
4147
  className
4145
4148
  ),
4146
- style,
4147
- children: children ?? content
4148
- }
4149
+ style
4150
+ },
4151
+ children ?? content
4149
4152
  );
4150
4153
  };
4151
4154
  Typography.displayName = "Typography";
@@ -4202,9 +4205,8 @@ var Stack = ({
4202
4205
  };
4203
4206
  const isHorizontal = direction === "horizontal";
4204
4207
  const directionClass = responsive && isHorizontal ? reverse ? "flex-col-reverse md:flex-row-reverse" : "flex-col md:flex-row" : isHorizontal ? reverse ? "flex-row-reverse" : "flex-row" : reverse ? "flex-col-reverse" : "flex-col";
4205
- const Comp = Component2;
4206
- return /* @__PURE__ */ jsx(
4207
- Comp,
4208
+ return React11.createElement(
4209
+ Component2,
4208
4210
  {
4209
4211
  className: cn(
4210
4212
  "flex",
@@ -4220,9 +4222,9 @@ var Stack = ({
4220
4222
  onClick: action || onClick ? handleClick : void 0,
4221
4223
  onKeyDown,
4222
4224
  role,
4223
- tabIndex,
4224
- children
4225
- }
4225
+ tabIndex
4226
+ },
4227
+ children
4226
4228
  );
4227
4229
  };
4228
4230
  var VStack = (props) => /* @__PURE__ */ jsx(Stack, { direction: "vertical", ...props });
@@ -5139,9 +5141,17 @@ function getEntity(orbital) {
5139
5141
  if (typeof entity === "string") {
5140
5142
  return { name: entity, fields: [], persistence: "runtime" };
5141
5143
  }
5144
+ if ("extends" in entity) {
5145
+ const ec = entity;
5146
+ return {
5147
+ name: ec.name ?? orbital.name,
5148
+ fields: ec.fields ?? [],
5149
+ persistence: ec.persistence ?? "runtime"
5150
+ };
5151
+ }
5142
5152
  const e = entity;
5143
5153
  return {
5144
- name: e.name ?? orbital.name,
5154
+ name: e.name,
5145
5155
  fields: e.fields ?? [],
5146
5156
  persistence: e.persistence ?? "runtime"
5147
5157
  };
@@ -5150,6 +5160,7 @@ function getTraits(orbital) {
5150
5160
  if (!orbital.traits) return [];
5151
5161
  return orbital.traits.map((t) => {
5152
5162
  if (typeof t === "string") return { name: t };
5163
+ if ("ref" in t && !("stateMachine" in t)) return { name: t.name ?? t.ref };
5153
5164
  return t;
5154
5165
  });
5155
5166
  }
@@ -5157,6 +5168,7 @@ function getPages(orbital) {
5157
5168
  if (!orbital.pages) return [];
5158
5169
  return orbital.pages.map((p) => {
5159
5170
  if (typeof p === "string") return { name: p, path: `/${p.toLowerCase()}` };
5171
+ if ("ref" in p && !("path" in p)) return { name: p.ref, path: `/${p.ref.toLowerCase()}` };
5160
5172
  return p;
5161
5173
  });
5162
5174
  }
@@ -5175,12 +5187,12 @@ function getEvents(sm) {
5175
5187
  function getEmits(trait) {
5176
5188
  const emits = trait.emits;
5177
5189
  if (!emits) return [];
5178
- return emits.map((e) => typeof e === "string" ? e : e.event ?? e.name ?? "");
5190
+ return emits.map((e) => e.event ?? "");
5179
5191
  }
5180
5192
  function getListens(trait) {
5181
5193
  const listens = trait.listens;
5182
5194
  if (!listens) return [];
5183
- return listens.map((l) => typeof l === "string" ? l : l.event ?? "");
5195
+ return listens.map((l) => l.event ?? "");
5184
5196
  }
5185
5197
  function parseEffectType(effect) {
5186
5198
  if (Array.isArray(effect)) {
@@ -5351,14 +5363,14 @@ function parseTraitLevel(schema, orbitalName, traitName) {
5351
5363
  if (!sm) return null;
5352
5364
  const states = getStates(sm).map((s) => ({
5353
5365
  name: s.name ?? "",
5354
- isInitial: s.isInitial ?? false,
5355
- isTerminal: s.isTerminal ?? false
5366
+ isInitial: s.isInitial ?? null,
5367
+ isTerminal: s.isTerminal ?? null
5356
5368
  }));
5357
5369
  const transitions = getTransitions(sm).map((t, i) => ({
5358
5370
  from: t.from ?? "",
5359
5371
  to: t.to ?? "",
5360
5372
  event: t.event ?? "",
5361
- guard: t.guard,
5373
+ guard: t.guard ?? null,
5362
5374
  effects: (t.effects ?? []).map(parseEffectType),
5363
5375
  index: i
5364
5376
  }));
@@ -5377,13 +5389,14 @@ function parseTransitionLevel(schema, orbitalName, traitName, transitionIndex) {
5377
5389
  if (!traitData) return null;
5378
5390
  const transition = traitData.transitions[transitionIndex];
5379
5391
  if (!transition) return null;
5380
- const guard = transition.guard ? exprToTree(transition.guard) : null;
5392
+ const guardVal = transition.guard;
5393
+ const guard = guardVal != null ? exprToTree(guardVal) : null;
5381
5394
  const effects = transition.effects.map(
5382
5395
  (e) => exprToTree([e.type, ...e.args])
5383
5396
  );
5384
5397
  const slotTargets = transition.effects.filter((e) => e.type === "render-ui").map((e) => ({
5385
5398
  name: String(e.args[0] ?? "main"),
5386
- pattern: typeof e.args[1] === "object" && e.args[1] !== null ? e.args[1].type ?? "unknown" : String(e.args[1] ?? "unknown")
5399
+ pattern: typeof e.args[1] === "object" && e.args[1] !== null && !Array.isArray(e.args[1]) ? e.args[1].type ?? "unknown" : String(e.args[1] ?? "unknown")
5387
5400
  }));
5388
5401
  return {
5389
5402
  from: transition.from,
@@ -6846,8 +6859,8 @@ var Avl3DTraitScene = ({
6846
6859
  Avl3DStateNode,
6847
6860
  {
6848
6861
  name: state.name,
6849
- isInitial: state.isInitial,
6850
- isTerminal: state.isTerminal,
6862
+ isInitial: state.isInitial ?? void 0,
6863
+ isTerminal: state.isTerminal ?? void 0,
6851
6864
  position: pos,
6852
6865
  incomingCount: transitionCounts.incoming.get(state.name) ?? 0,
6853
6866
  outgoingCount: transitionCounts.outgoing.get(state.name) ?? 0
@@ -1,13 +1,13 @@
1
1
  import React from 'react';
2
- import type { AssetUrl, EventEmit } from '@almadar/core';
2
+ import type { AssetUrl, EventEmit, EntityRow } from '@almadar/core';
3
3
  import type { DisplayStateProps } from '../../core/organisms/types';
4
4
  export interface PinballBoardProps extends DisplayStateProps {
5
5
  /** Playfield tiles */
6
- tiles?: unknown[];
6
+ tiles?: readonly EntityRow[];
7
7
  /** Ball units on the board */
8
- units?: unknown[];
8
+ units?: readonly EntityRow[];
9
9
  /** Features (bumpers, paddles, etc.) on the board */
10
- features?: unknown[];
10
+ features?: readonly EntityRow[];
11
11
  /** Asset sprite manifest */
12
12
  assetManifest?: string;
13
13
  /** Base URL prepended to manifest sprite paths */