@constela/core 0.9.1 → 0.11.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.
package/README.md CHANGED
@@ -42,7 +42,7 @@ All fields except `version`, `state`, `actions`, and `view` are optional.
42
42
 
43
43
  ## Expression Types
44
44
 
45
- 13 expression types for constrained computation:
45
+ 14 expression types for constrained computation:
46
46
 
47
47
  | Type | JSON Example | Description |
48
48
  |------|-------------|-------------|
@@ -59,9 +59,29 @@ All fields except `version`, `state`, `actions`, and `view` are optional.
59
59
  | `data` | `{ "expr": "data", "name": "posts" }` | Build-time data |
60
60
  | `ref` | `{ "expr": "ref", "name": "inputEl" }` | DOM element ref |
61
61
  | `style` | `{ "expr": "style", "name": "button", "variants": {...} }` | Style reference |
62
+ | `concat` | `{ "expr": "concat", "items": [...] }` | String concatenation |
62
63
 
63
64
  **Binary Operators:** `+`, `-`, `*`, `/`, `==`, `!=`, `<`, `<=`, `>`, `>=`, `&&`, `||`
64
65
 
66
+ **Concat Expression:**
67
+
68
+ Concatenate multiple expressions into a single string:
69
+
70
+ ```json
71
+ {
72
+ "expr": "concat",
73
+ "items": [
74
+ { "expr": "lit", "value": "Hello, " },
75
+ { "expr": "var", "name": "username" },
76
+ { "expr": "lit", "value": "!" }
77
+ ]
78
+ }
79
+ ```
80
+
81
+ - Evaluates each item and joins them as strings
82
+ - `null`/`undefined` values become empty strings
83
+ - Numbers and booleans are converted to strings
84
+
65
85
  ## View Node Types
66
86
 
67
87
  8 node types for building UI:
@@ -305,11 +325,11 @@ if (result.ok) {
305
325
 
306
326
  ### Type Guards
307
327
 
308
- 47 type guard functions for runtime type checking:
328
+ 48 type guard functions for runtime type checking:
309
329
 
310
330
  ```typescript
311
331
  import {
312
- isLitExpr, isStateExpr, isVarExpr, isBinExpr,
332
+ isLitExpr, isStateExpr, isVarExpr, isBinExpr, isConcatExpr,
313
333
  isElementNode, isTextNode, isIfNode, isEachNode,
314
334
  isSetStep, isUpdateStep, isFetchStep,
315
335
  isNumberField, isStringField, isListField,
package/dist/index.d.ts CHANGED
@@ -16,6 +16,10 @@ declare const STORAGE_TYPES: readonly ["local", "session"];
16
16
  type StorageType = (typeof STORAGE_TYPES)[number];
17
17
  declare const CLIPBOARD_OPERATIONS: readonly ["write", "read"];
18
18
  type ClipboardOperation = (typeof CLIPBOARD_OPERATIONS)[number];
19
+ declare const FOCUS_OPERATIONS: readonly ["focus", "blur", "select"];
20
+ type FocusOperation = (typeof FOCUS_OPERATIONS)[number];
21
+ declare const VALIDITY_PROPERTIES: readonly ["valid", "valueMissing", "typeMismatch", "patternMismatch", "tooLong", "tooShort", "rangeUnderflow", "rangeOverflow", "customError", "message"];
22
+ type ValidityProperty = (typeof VALIDITY_PROPERTIES)[number];
19
23
  declare const NAVIGATE_TARGETS: readonly ["_self", "_blank"];
20
24
  type NavigateTarget = (typeof NAVIGATE_TARGETS)[number];
21
25
  declare const PARAM_TYPES: readonly ["string", "number", "boolean", "json"];
@@ -142,7 +146,15 @@ interface ConcatExpr {
142
146
  expr: 'concat';
143
147
  items: Expression[];
144
148
  }
145
- type Expression = LitExpr | StateExpr | VarExpr | BinExpr | NotExpr | ParamExpr | CondExpr | GetExpr | RouteExpr | ImportExpr | DataExpr | RefExpr | IndexExpr | StyleExpr | ConcatExpr;
149
+ /**
150
+ * Validity expression - gets form element validation state
151
+ */
152
+ interface ValidityExpr {
153
+ expr: 'validity';
154
+ ref: string;
155
+ property?: ValidityProperty;
156
+ }
157
+ type Expression = LitExpr | StateExpr | VarExpr | BinExpr | NotExpr | ParamExpr | CondExpr | GetExpr | RouteExpr | ImportExpr | DataExpr | RefExpr | IndexExpr | StyleExpr | ConcatExpr | ValidityExpr;
146
158
  /**
147
159
  * Number state field
148
160
  */
@@ -340,7 +352,51 @@ interface CloseStep {
340
352
  do: 'close';
341
353
  connection: string;
342
354
  }
343
- type ActionStep = SetStep | UpdateStep | SetPathStep | FetchStep | StorageStep | ClipboardStep | NavigateStep | ImportStep | CallStep | SubscribeStep | DisposeStep | DomStep | SendStep | CloseStep;
355
+ /**
356
+ * Delay step - executes steps after a delay (setTimeout equivalent)
357
+ */
358
+ interface DelayStep {
359
+ do: 'delay';
360
+ ms: Expression;
361
+ then: ActionStep[];
362
+ result?: string;
363
+ }
364
+ /**
365
+ * Interval step - executes an action repeatedly (setInterval equivalent)
366
+ */
367
+ interface IntervalStep {
368
+ do: 'interval';
369
+ ms: Expression;
370
+ action: string;
371
+ result?: string;
372
+ }
373
+ /**
374
+ * ClearTimer step - clears a timer (clearTimeout/clearInterval equivalent)
375
+ */
376
+ interface ClearTimerStep {
377
+ do: 'clearTimer';
378
+ target: Expression;
379
+ }
380
+ /**
381
+ * Focus step - manages form element focus
382
+ */
383
+ interface FocusStep {
384
+ do: 'focus';
385
+ target: Expression;
386
+ operation: FocusOperation;
387
+ onSuccess?: ActionStep[];
388
+ onError?: ActionStep[];
389
+ }
390
+ type ActionStep = SetStep | UpdateStep | SetPathStep | FetchStep | StorageStep | ClipboardStep | NavigateStep | ImportStep | CallStep | SubscribeStep | DisposeStep | DomStep | SendStep | CloseStep | DelayStep | IntervalStep | ClearTimerStep | FocusStep;
391
+ type LocalActionStep = SetStep | UpdateStep | SetPathStep;
392
+ /**
393
+ * Event handler options for special events like intersect
394
+ */
395
+ interface EventHandlerOptions {
396
+ threshold?: number;
397
+ rootMargin?: string;
398
+ once?: boolean;
399
+ }
344
400
  /**
345
401
  * Event handler - binds an event to an action
346
402
  */
@@ -348,6 +404,9 @@ interface EventHandler {
348
404
  event: string;
349
405
  action: string;
350
406
  payload?: Expression;
407
+ debounce?: number;
408
+ throttle?: number;
409
+ options?: EventHandlerOptions;
351
410
  }
352
411
  /**
353
412
  * Action definition - a named sequence of steps
@@ -356,6 +415,14 @@ interface ActionDefinition {
356
415
  name: string;
357
416
  steps: ActionStep[];
358
417
  }
418
+ /**
419
+ * Local action definition - a named sequence of local steps
420
+ * Only set, update, and setPath steps are allowed
421
+ */
422
+ interface LocalActionDefinition {
423
+ name: string;
424
+ steps: LocalActionStep[];
425
+ }
359
426
  /**
360
427
  * Element node - represents an HTML element
361
428
  */
@@ -425,9 +492,19 @@ interface CodeNode {
425
492
  language: Expression;
426
493
  content: Expression;
427
494
  }
428
- type ViewNode = ElementNode | TextNode | IfNode | EachNode | ComponentNode | SlotNode | MarkdownNode | CodeNode;
495
+ /**
496
+ * Portal node - renders children to a different DOM location
497
+ */
498
+ interface PortalNode {
499
+ kind: 'portal';
500
+ target: 'body' | 'head' | string;
501
+ children: ViewNode[];
502
+ }
503
+ type ViewNode = ElementNode | TextNode | IfNode | EachNode | ComponentNode | SlotNode | MarkdownNode | CodeNode | PortalNode;
429
504
  interface ComponentDef {
430
505
  params?: Record<string, ParamDef>;
506
+ localState?: Record<string, StateField>;
507
+ localActions?: LocalActionDefinition[];
431
508
  view: ViewNode;
432
509
  }
433
510
  /**
@@ -622,6 +699,10 @@ declare function isStyleExpr(value: unknown): value is StyleExpr;
622
699
  * Checks if value is a concat expression
623
700
  */
624
701
  declare function isConcatExpr(value: unknown): value is ConcatExpr;
702
+ /**
703
+ * Checks if value is a validity expression
704
+ */
705
+ declare function isValidityExpr(value: unknown): value is ValidityExpr;
625
706
  /**
626
707
  * Checks if value is a data source
627
708
  */
@@ -670,6 +751,10 @@ declare function isMarkdownNode(value: unknown): value is MarkdownNode;
670
751
  * Checks if value is a code node
671
752
  */
672
753
  declare function isCodeNode(value: unknown): value is CodeNode;
754
+ /**
755
+ * Checks if value is a portal node
756
+ */
757
+ declare function isPortalNode(value: unknown): value is PortalNode;
673
758
  /**
674
759
  * Checks if value is any valid view node
675
760
  */
@@ -682,6 +767,10 @@ declare function isSetStep(value: unknown): value is SetStep;
682
767
  * Checks if value is an update step
683
768
  */
684
769
  declare function isUpdateStep(value: unknown): value is UpdateStep;
770
+ /**
771
+ * Checks if value is a setPath step
772
+ */
773
+ declare function isSetPathStep(value: unknown): value is SetPathStep;
685
774
  /**
686
775
  * Checks if value is a fetch step
687
776
  */
@@ -714,10 +803,23 @@ declare function isSubscribeStep(value: unknown): value is SubscribeStep;
714
803
  * Checks if value is a dispose step
715
804
  */
716
805
  declare function isDisposeStep(value: unknown): value is DisposeStep;
806
+ /**
807
+ * Checks if value is a focus step
808
+ */
809
+ declare function isFocusStep(value: unknown): value is FocusStep;
717
810
  /**
718
811
  * Checks if value is any valid action step
719
812
  */
720
813
  declare function isActionStep(value: unknown): value is ActionStep;
814
+ /**
815
+ * Checks if value is a valid local action step
816
+ * Local actions only allow set, update, and setPath steps
817
+ */
818
+ declare function isLocalActionStep(value: unknown): value is LocalActionStep;
819
+ /**
820
+ * Checks if value is a local action definition
821
+ */
822
+ declare function isLocalActionDefinition(value: unknown): value is LocalActionDefinition;
721
823
  /**
722
824
  * Checks if value is a number field
723
825
  */
@@ -770,7 +872,7 @@ declare function isLifecycleHooks(value: unknown): value is LifecycleHooks;
770
872
  * This module defines error types, the ConstelaError class,
771
873
  * and factory functions for creating specific errors.
772
874
  */
773
- type ErrorCode = 'SCHEMA_INVALID' | 'UNDEFINED_STATE' | 'UNDEFINED_ACTION' | 'VAR_UNDEFINED' | 'DUPLICATE_ACTION' | 'UNSUPPORTED_VERSION' | 'COMPONENT_NOT_FOUND' | 'COMPONENT_PROP_MISSING' | 'COMPONENT_CYCLE' | 'COMPONENT_PROP_TYPE' | 'PARAM_UNDEFINED' | 'OPERATION_INVALID_FOR_TYPE' | 'OPERATION_MISSING_FIELD' | 'OPERATION_UNKNOWN' | 'EXPR_INVALID_BASE' | 'EXPR_INVALID_CONDITION' | 'EXPR_COND_ELSE_REQUIRED' | 'UNDEFINED_ROUTE_PARAM' | 'ROUTE_NOT_DEFINED' | 'UNDEFINED_IMPORT' | 'IMPORTS_NOT_DEFINED' | 'LAYOUT_MISSING_SLOT' | 'LAYOUT_NOT_FOUND' | 'INVALID_SLOT_NAME' | 'DUPLICATE_SLOT_NAME' | 'DUPLICATE_DEFAULT_SLOT' | 'SLOT_IN_LOOP' | 'INVALID_DATA_SOURCE' | 'UNDEFINED_DATA_SOURCE' | 'DATA_NOT_DEFINED' | 'UNDEFINED_DATA' | 'UNDEFINED_REF' | 'INVALID_STORAGE_OPERATION' | 'INVALID_STORAGE_TYPE' | 'STORAGE_SET_MISSING_VALUE' | 'INVALID_CLIPBOARD_OPERATION' | 'CLIPBOARD_WRITE_MISSING_VALUE' | 'INVALID_NAVIGATE_TARGET' | 'UNDEFINED_STYLE' | 'UNDEFINED_VARIANT';
875
+ type ErrorCode = 'SCHEMA_INVALID' | 'UNDEFINED_STATE' | 'UNDEFINED_ACTION' | 'VAR_UNDEFINED' | 'DUPLICATE_ACTION' | 'UNSUPPORTED_VERSION' | 'COMPONENT_NOT_FOUND' | 'COMPONENT_PROP_MISSING' | 'COMPONENT_CYCLE' | 'COMPONENT_PROP_TYPE' | 'PARAM_UNDEFINED' | 'OPERATION_INVALID_FOR_TYPE' | 'OPERATION_MISSING_FIELD' | 'OPERATION_UNKNOWN' | 'EXPR_INVALID_BASE' | 'EXPR_INVALID_CONDITION' | 'EXPR_COND_ELSE_REQUIRED' | 'UNDEFINED_ROUTE_PARAM' | 'ROUTE_NOT_DEFINED' | 'UNDEFINED_IMPORT' | 'IMPORTS_NOT_DEFINED' | 'LAYOUT_MISSING_SLOT' | 'LAYOUT_NOT_FOUND' | 'INVALID_SLOT_NAME' | 'DUPLICATE_SLOT_NAME' | 'DUPLICATE_DEFAULT_SLOT' | 'SLOT_IN_LOOP' | 'INVALID_DATA_SOURCE' | 'UNDEFINED_DATA_SOURCE' | 'DATA_NOT_DEFINED' | 'UNDEFINED_DATA' | 'UNDEFINED_REF' | 'INVALID_STORAGE_OPERATION' | 'INVALID_STORAGE_TYPE' | 'STORAGE_SET_MISSING_VALUE' | 'INVALID_CLIPBOARD_OPERATION' | 'CLIPBOARD_WRITE_MISSING_VALUE' | 'INVALID_NAVIGATE_TARGET' | 'UNDEFINED_STYLE' | 'UNDEFINED_VARIANT' | 'UNDEFINED_LOCAL_STATE' | 'LOCAL_ACTION_INVALID_STEP';
774
876
  /**
775
877
  * Options for creating enhanced ConstelaError instances
776
878
  */
@@ -969,6 +1071,14 @@ declare function createUndefinedStyleError(styleName: string, path?: string, opt
969
1071
  * Creates an undefined variant key error
970
1072
  */
971
1073
  declare function createUndefinedVariantError(variantKey: string, styleName: string, path?: string, options?: ErrorOptions): ConstelaError;
1074
+ /**
1075
+ * Creates an undefined local state reference error
1076
+ */
1077
+ declare function createUndefinedLocalStateError(stateName: string, path?: string, options?: ErrorOptions): ConstelaError;
1078
+ /**
1079
+ * Creates a local action invalid step error
1080
+ */
1081
+ declare function createLocalActionInvalidStepError(stepType: string, path?: string): ConstelaError;
972
1082
  /**
973
1083
  * Finds similar names from a set of candidates using Levenshtein distance
974
1084
  * and prefix matching.
@@ -1077,6 +1187,8 @@ declare const astSchema: {
1077
1187
  readonly $ref: "#/$defs/IndexExpr";
1078
1188
  }, {
1079
1189
  readonly $ref: "#/$defs/StyleExpr";
1190
+ }, {
1191
+ readonly $ref: "#/$defs/ValidityExpr";
1080
1192
  }];
1081
1193
  };
1082
1194
  readonly LitExpr: {
@@ -1263,6 +1375,24 @@ declare const astSchema: {
1263
1375
  };
1264
1376
  };
1265
1377
  };
1378
+ readonly ValidityExpr: {
1379
+ readonly type: "object";
1380
+ readonly required: readonly ["expr", "ref"];
1381
+ readonly additionalProperties: false;
1382
+ readonly properties: {
1383
+ readonly expr: {
1384
+ readonly type: "string";
1385
+ readonly const: "validity";
1386
+ };
1387
+ readonly ref: {
1388
+ readonly type: "string";
1389
+ };
1390
+ readonly property: {
1391
+ readonly type: "string";
1392
+ readonly enum: readonly ["valid", "valueMissing", "typeMismatch", "patternMismatch", "tooLong", "tooShort", "rangeUnderflow", "rangeOverflow", "customError", "message"];
1393
+ };
1394
+ };
1395
+ };
1266
1396
  readonly StylePreset: {
1267
1397
  readonly type: "object";
1268
1398
  readonly required: readonly ["base"];
@@ -1396,6 +1526,14 @@ declare const astSchema: {
1396
1526
  readonly $ref: "#/$defs/UpdateStep";
1397
1527
  }, {
1398
1528
  readonly $ref: "#/$defs/FetchStep";
1529
+ }, {
1530
+ readonly $ref: "#/$defs/DelayStep";
1531
+ }, {
1532
+ readonly $ref: "#/$defs/IntervalStep";
1533
+ }, {
1534
+ readonly $ref: "#/$defs/ClearTimerStep";
1535
+ }, {
1536
+ readonly $ref: "#/$defs/FocusStep";
1399
1537
  }];
1400
1538
  };
1401
1539
  readonly SetStep: {
@@ -1478,6 +1616,93 @@ declare const astSchema: {
1478
1616
  };
1479
1617
  };
1480
1618
  };
1619
+ readonly DelayStep: {
1620
+ readonly type: "object";
1621
+ readonly required: readonly ["do", "ms", "then"];
1622
+ readonly additionalProperties: false;
1623
+ readonly properties: {
1624
+ readonly do: {
1625
+ readonly type: "string";
1626
+ readonly const: "delay";
1627
+ };
1628
+ readonly ms: {
1629
+ readonly $ref: "#/$defs/Expression";
1630
+ };
1631
+ readonly then: {
1632
+ readonly type: "array";
1633
+ readonly items: {
1634
+ readonly $ref: "#/$defs/ActionStep";
1635
+ };
1636
+ };
1637
+ readonly result: {
1638
+ readonly type: "string";
1639
+ };
1640
+ };
1641
+ };
1642
+ readonly IntervalStep: {
1643
+ readonly type: "object";
1644
+ readonly required: readonly ["do", "ms", "action"];
1645
+ readonly additionalProperties: false;
1646
+ readonly properties: {
1647
+ readonly do: {
1648
+ readonly type: "string";
1649
+ readonly const: "interval";
1650
+ };
1651
+ readonly ms: {
1652
+ readonly $ref: "#/$defs/Expression";
1653
+ };
1654
+ readonly action: {
1655
+ readonly type: "string";
1656
+ };
1657
+ readonly result: {
1658
+ readonly type: "string";
1659
+ };
1660
+ };
1661
+ };
1662
+ readonly ClearTimerStep: {
1663
+ readonly type: "object";
1664
+ readonly required: readonly ["do", "target"];
1665
+ readonly additionalProperties: false;
1666
+ readonly properties: {
1667
+ readonly do: {
1668
+ readonly type: "string";
1669
+ readonly const: "clearTimer";
1670
+ };
1671
+ readonly target: {
1672
+ readonly $ref: "#/$defs/Expression";
1673
+ };
1674
+ };
1675
+ };
1676
+ readonly FocusStep: {
1677
+ readonly type: "object";
1678
+ readonly required: readonly ["do", "target", "operation"];
1679
+ readonly additionalProperties: false;
1680
+ readonly properties: {
1681
+ readonly do: {
1682
+ readonly type: "string";
1683
+ readonly const: "focus";
1684
+ };
1685
+ readonly target: {
1686
+ readonly $ref: "#/$defs/Expression";
1687
+ };
1688
+ readonly operation: {
1689
+ readonly type: "string";
1690
+ readonly enum: readonly ["focus", "blur", "select"];
1691
+ };
1692
+ readonly onSuccess: {
1693
+ readonly type: "array";
1694
+ readonly items: {
1695
+ readonly $ref: "#/$defs/ActionStep";
1696
+ };
1697
+ };
1698
+ readonly onError: {
1699
+ readonly type: "array";
1700
+ readonly items: {
1701
+ readonly $ref: "#/$defs/ActionStep";
1702
+ };
1703
+ };
1704
+ };
1705
+ };
1481
1706
  readonly EventHandler: {
1482
1707
  readonly type: "object";
1483
1708
  readonly required: readonly ["event", "action"];
@@ -1492,6 +1717,30 @@ declare const astSchema: {
1492
1717
  readonly payload: {
1493
1718
  readonly $ref: "#/$defs/Expression";
1494
1719
  };
1720
+ readonly debounce: {
1721
+ readonly type: "number";
1722
+ };
1723
+ readonly throttle: {
1724
+ readonly type: "number";
1725
+ };
1726
+ readonly options: {
1727
+ readonly $ref: "#/$defs/EventHandlerOptions";
1728
+ };
1729
+ };
1730
+ };
1731
+ readonly EventHandlerOptions: {
1732
+ readonly type: "object";
1733
+ readonly additionalProperties: false;
1734
+ readonly properties: {
1735
+ readonly threshold: {
1736
+ readonly type: "number";
1737
+ };
1738
+ readonly rootMargin: {
1739
+ readonly type: "string";
1740
+ };
1741
+ readonly once: {
1742
+ readonly type: "boolean";
1743
+ };
1495
1744
  };
1496
1745
  };
1497
1746
  readonly ActionDefinition: {
@@ -1527,6 +1776,8 @@ declare const astSchema: {
1527
1776
  readonly $ref: "#/$defs/MarkdownNode";
1528
1777
  }, {
1529
1778
  readonly $ref: "#/$defs/CodeNode";
1779
+ }, {
1780
+ readonly $ref: "#/$defs/PortalNode";
1530
1781
  }];
1531
1782
  };
1532
1783
  readonly ElementNode: {
@@ -1687,6 +1938,26 @@ declare const astSchema: {
1687
1938
  };
1688
1939
  };
1689
1940
  };
1941
+ readonly PortalNode: {
1942
+ readonly type: "object";
1943
+ readonly required: readonly ["kind", "target", "children"];
1944
+ readonly additionalProperties: false;
1945
+ readonly properties: {
1946
+ readonly kind: {
1947
+ readonly type: "string";
1948
+ readonly const: "portal";
1949
+ };
1950
+ readonly target: {
1951
+ readonly type: "string";
1952
+ };
1953
+ readonly children: {
1954
+ readonly type: "array";
1955
+ readonly items: {
1956
+ readonly $ref: "#/$defs/ViewNode";
1957
+ };
1958
+ };
1959
+ };
1960
+ };
1690
1961
  readonly ParamDef: {
1691
1962
  readonly type: "object";
1692
1963
  readonly required: readonly ["type"];
@@ -1720,4 +1991,4 @@ declare const astSchema: {
1720
1991
  };
1721
1992
  };
1722
1993
 
1723
- export { type ActionDefinition, type ActionStep, BINARY_OPERATORS, type BinExpr, type BinaryOperator, type BooleanField, CLIPBOARD_OPERATIONS, type CallStep, type ClipboardOperation, type ClipboardStep, type CloseStep, type CodeNode, type ComponentDef, type ComponentNode, type ComponentsRef, type CompoundVariant, type ConcatExpr, type CondExpr, type ConstelaAst, ConstelaError, type ConstelaProgram, DATA_SOURCE_TYPES, DATA_TRANSFORMS, type DataExpr, type DataSource, type DataSourceType, type DataTransform, type DisposeStep, type DomStep, type EachNode, type ElementNode, type ErrorCode, type ErrorOptions, type EventHandler, type Expression, type FetchStep, type GetExpr, HTTP_METHODS, type HttpMethod, type IfNode, type ImportExpr, type ImportStep, type LayoutProgram, type LifecycleHooks, type ListField, type LitExpr, type MarkdownNode, NAVIGATE_TARGETS, type NavigateStep, type NavigateTarget, type NotExpr, type NumberField, type ObjectField, PARAM_TYPES, type ParamDef, type ParamExpr, type ParamType, type Program, type RefExpr, type RouteDefinition, type RouteExpr, STORAGE_OPERATIONS, STORAGE_TYPES, type SendStep, type SetPathStep, type SetStep, type SlotNode, type StateExpr, type StateField, type StaticPathsDefinition, type StorageOperation, type StorageStep, type StorageType, type StringField, type StyleExpr, type StylePreset, type SubscribeStep, type TextNode, UPDATE_OPERATIONS, type UpdateOperation, type UpdateStep, type ValidationFailure, type ValidationResult, type ValidationSuccess, type VarExpr, type ViewNode, astSchema, createClipboardWriteMissingValueError, createComponentCycleError, createComponentNotFoundError, createComponentPropMissingError, createComponentPropTypeError, createCondElseRequiredError, createDataNotDefinedError, createDuplicateActionError, createDuplicateDefaultSlotError, createDuplicateSlotNameError, createImportsNotDefinedError, createInvalidClipboardOperationError, createInvalidDataSourceError, createInvalidNavigateTargetError, createInvalidSlotNameError, createInvalidStorageOperationError, createInvalidStorageTypeError, createLayoutMissingSlotError, createLayoutNotFoundError, createOperationInvalidForTypeError, createOperationMissingFieldError, createOperationUnknownError, createRouteNotDefinedError, createSchemaError, createSlotInLoopError, createStorageSetMissingValueError, createUndefinedActionError, createUndefinedDataError, createUndefinedDataSourceError, createUndefinedImportError, createUndefinedParamError, createUndefinedRefError, createUndefinedRouteParamError, createUndefinedStateError, createUndefinedStyleError, createUndefinedVarError, createUndefinedVariantError, createUnsupportedVersionError, findSimilarNames, isActionStep, isBinExpr, isBooleanField, isCallStep, isClipboardStep, isCodeNode, isComponentNode, isConcatExpr, isCondExpr, isConstelaError, isDataExpr, isDataSource, isDisposeStep, isEachNode, isElementNode, isEventHandler, isExpression, isFetchStep, isGetExpr, isIfNode, isImportExpr, isImportStep, isLayoutProgram, isLifecycleHooks, isListField, isLitExpr, isMarkdownNode, isNamedSlotNode, isNavigateStep, isNotExpr, isNumberField, isObjectField, isParamExpr, isRefExpr, isRouteDefinition, isRouteExpr, isSetStep, isSlotNode, isStateExpr, isStateField, isStaticPathsDefinition, isStorageStep, isStringField, isStyleExpr, isSubscribeStep, isTextNode, isUpdateStep, isVarExpr, isViewNode, validateAst };
1994
+ export { type ActionDefinition, type ActionStep, BINARY_OPERATORS, type BinExpr, type BinaryOperator, type BooleanField, CLIPBOARD_OPERATIONS, type CallStep, type ClearTimerStep, type ClipboardOperation, type ClipboardStep, type CloseStep, type CodeNode, type ComponentDef, type ComponentNode, type ComponentsRef, type CompoundVariant, type ConcatExpr, type CondExpr, type ConstelaAst, ConstelaError, type ConstelaProgram, DATA_SOURCE_TYPES, DATA_TRANSFORMS, type DataExpr, type DataSource, type DataSourceType, type DataTransform, type DelayStep, type DisposeStep, type DomStep, type EachNode, type ElementNode, type ErrorCode, type ErrorOptions, type EventHandler, type EventHandlerOptions, type Expression, FOCUS_OPERATIONS, type FetchStep, type FocusOperation, type FocusStep, type GetExpr, HTTP_METHODS, type HttpMethod, type IfNode, type ImportExpr, type ImportStep, type IntervalStep, type LayoutProgram, type LifecycleHooks, type ListField, type LitExpr, type LocalActionDefinition, type LocalActionStep, type MarkdownNode, NAVIGATE_TARGETS, type NavigateStep, type NavigateTarget, type NotExpr, type NumberField, type ObjectField, PARAM_TYPES, type ParamDef, type ParamExpr, type ParamType, type PortalNode, type Program, type RefExpr, type RouteDefinition, type RouteExpr, STORAGE_OPERATIONS, STORAGE_TYPES, type SendStep, type SetPathStep, type SetStep, type SlotNode, type StateExpr, type StateField, type StaticPathsDefinition, type StorageOperation, type StorageStep, type StorageType, type StringField, type StyleExpr, type StylePreset, type SubscribeStep, type TextNode, UPDATE_OPERATIONS, type UpdateOperation, type UpdateStep, VALIDITY_PROPERTIES, type ValidationFailure, type ValidationResult, type ValidationSuccess, type ValidityExpr, type ValidityProperty, type VarExpr, type ViewNode, astSchema, createClipboardWriteMissingValueError, createComponentCycleError, createComponentNotFoundError, createComponentPropMissingError, createComponentPropTypeError, createCondElseRequiredError, createDataNotDefinedError, createDuplicateActionError, createDuplicateDefaultSlotError, createDuplicateSlotNameError, createImportsNotDefinedError, createInvalidClipboardOperationError, createInvalidDataSourceError, createInvalidNavigateTargetError, createInvalidSlotNameError, createInvalidStorageOperationError, createInvalidStorageTypeError, createLayoutMissingSlotError, createLayoutNotFoundError, createLocalActionInvalidStepError, createOperationInvalidForTypeError, createOperationMissingFieldError, createOperationUnknownError, createRouteNotDefinedError, createSchemaError, createSlotInLoopError, createStorageSetMissingValueError, createUndefinedActionError, createUndefinedDataError, createUndefinedDataSourceError, createUndefinedImportError, createUndefinedLocalStateError, createUndefinedParamError, createUndefinedRefError, createUndefinedRouteParamError, createUndefinedStateError, createUndefinedStyleError, createUndefinedVarError, createUndefinedVariantError, createUnsupportedVersionError, findSimilarNames, isActionStep, isBinExpr, isBooleanField, isCallStep, isClipboardStep, isCodeNode, isComponentNode, isConcatExpr, isCondExpr, isConstelaError, isDataExpr, isDataSource, isDisposeStep, isEachNode, isElementNode, isEventHandler, isExpression, isFetchStep, isFocusStep, isGetExpr, isIfNode, isImportExpr, isImportStep, isLayoutProgram, isLifecycleHooks, isListField, isLitExpr, isLocalActionDefinition, isLocalActionStep, isMarkdownNode, isNamedSlotNode, isNavigateStep, isNotExpr, isNumberField, isObjectField, isParamExpr, isPortalNode, isRefExpr, isRouteDefinition, isRouteExpr, isSetPathStep, isSetStep, isSlotNode, isStateExpr, isStateField, isStaticPathsDefinition, isStorageStep, isStringField, isStyleExpr, isSubscribeStep, isTextNode, isUpdateStep, isValidityExpr, isVarExpr, isViewNode, validateAst };
package/dist/index.js CHANGED
@@ -29,6 +29,19 @@ var HTTP_METHODS = ["GET", "POST", "PUT", "DELETE"];
29
29
  var STORAGE_OPERATIONS = ["get", "set", "remove"];
30
30
  var STORAGE_TYPES = ["local", "session"];
31
31
  var CLIPBOARD_OPERATIONS = ["write", "read"];
32
+ var FOCUS_OPERATIONS = ["focus", "blur", "select"];
33
+ var VALIDITY_PROPERTIES = [
34
+ "valid",
35
+ "valueMissing",
36
+ "typeMismatch",
37
+ "patternMismatch",
38
+ "tooLong",
39
+ "tooShort",
40
+ "rangeUnderflow",
41
+ "rangeOverflow",
42
+ "customError",
43
+ "message"
44
+ ];
32
45
  var NAVIGATE_TARGETS = ["_self", "_blank"];
33
46
  var PARAM_TYPES = ["string", "number", "boolean", "json"];
34
47
  var DATA_TRANSFORMS = ["mdx", "yaml", "csv"];
@@ -142,6 +155,17 @@ function isStyleExpr(value) {
142
155
  function isConcatExpr(value) {
143
156
  return typeof value === "object" && value !== null && value.expr === "concat" && Array.isArray(value.items);
144
157
  }
158
+ function isValidityExpr(value) {
159
+ if (!isObject(value)) return false;
160
+ if (value["expr"] !== "validity") return false;
161
+ if (typeof value["ref"] !== "string") return false;
162
+ if ("property" in value && value["property"] !== void 0) {
163
+ if (!VALIDITY_PROPERTIES.includes(value["property"])) {
164
+ return false;
165
+ }
166
+ }
167
+ return true;
168
+ }
145
169
  function isDataSource(value) {
146
170
  if (!isObject(value)) return false;
147
171
  const type = value["type"];
@@ -178,7 +202,7 @@ function isRouteDefinition(value) {
178
202
  return true;
179
203
  }
180
204
  function isExpression(value) {
181
- return isLitExpr(value) || isStateExpr(value) || isVarExpr(value) || isBinExpr(value) || isNotExpr(value) || isParamExpr(value) || isCondExpr(value) || isGetExpr(value) || isRouteExpr(value) || isImportExpr(value) || isDataExpr(value) || isRefExpr(value) || isIndexExpr(value) || isStyleExpr(value) || isConcatExpr(value);
205
+ return isLitExpr(value) || isStateExpr(value) || isVarExpr(value) || isBinExpr(value) || isNotExpr(value) || isParamExpr(value) || isCondExpr(value) || isGetExpr(value) || isRouteExpr(value) || isImportExpr(value) || isDataExpr(value) || isRefExpr(value) || isIndexExpr(value) || isStyleExpr(value) || isConcatExpr(value) || isValidityExpr(value);
182
206
  }
183
207
  function isElementNode(value) {
184
208
  if (!isObject(value)) return false;
@@ -233,8 +257,15 @@ function isCodeNode(value) {
233
257
  if (!("content" in value) || !isObject(value["content"])) return false;
234
258
  return true;
235
259
  }
260
+ function isPortalNode(value) {
261
+ if (!isObject(value)) return false;
262
+ if (value["kind"] !== "portal") return false;
263
+ if (typeof value["target"] !== "string") return false;
264
+ if (!Array.isArray(value["children"])) return false;
265
+ return true;
266
+ }
236
267
  function isViewNode(value) {
237
- return isElementNode(value) || isTextNode(value) || isIfNode(value) || isEachNode(value) || isComponentNode(value) || isSlotNode(value) || isMarkdownNode(value) || isCodeNode(value);
268
+ return isElementNode(value) || isTextNode(value) || isIfNode(value) || isEachNode(value) || isComponentNode(value) || isSlotNode(value) || isMarkdownNode(value) || isCodeNode(value) || isPortalNode(value);
238
269
  }
239
270
  function isSetStep(value) {
240
271
  if (!isObject(value)) return false;
@@ -252,6 +283,14 @@ function isUpdateStep(value) {
252
283
  }
253
284
  return true;
254
285
  }
286
+ function isSetPathStep(value) {
287
+ if (!isObject(value)) return false;
288
+ if (value["do"] !== "setPath") return false;
289
+ if (typeof value["target"] !== "string") return false;
290
+ if (!isObject(value["path"])) return false;
291
+ if (!isObject(value["value"])) return false;
292
+ return true;
293
+ }
255
294
  function isFetchStep(value) {
256
295
  if (!isObject(value)) return false;
257
296
  if (value["do"] !== "fetch") return false;
@@ -321,8 +360,49 @@ function isDisposeStep(value) {
321
360
  if (!isObject(value["target"])) return false;
322
361
  return true;
323
362
  }
363
+ function isDelayStep(value) {
364
+ if (!isObject(value)) return false;
365
+ if (value["do"] !== "delay") return false;
366
+ if (!isObject(value["ms"])) return false;
367
+ if (!Array.isArray(value["then"])) return false;
368
+ return true;
369
+ }
370
+ function isIntervalStep(value) {
371
+ if (!isObject(value)) return false;
372
+ if (value["do"] !== "interval") return false;
373
+ if (!isObject(value["ms"])) return false;
374
+ if (typeof value["action"] !== "string") return false;
375
+ return true;
376
+ }
377
+ function isClearTimerStep(value) {
378
+ if (!isObject(value)) return false;
379
+ if (value["do"] !== "clearTimer") return false;
380
+ if (!isObject(value["target"])) return false;
381
+ return true;
382
+ }
383
+ function isFocusStep(value) {
384
+ if (!isObject(value)) return false;
385
+ if (value["do"] !== "focus") return false;
386
+ if (!isObject(value["target"])) return false;
387
+ if (!FOCUS_OPERATIONS.includes(value["operation"])) {
388
+ return false;
389
+ }
390
+ return true;
391
+ }
324
392
  function isActionStep(value) {
325
- return isSetStep(value) || isUpdateStep(value) || isFetchStep(value) || isStorageStep(value) || isClipboardStep(value) || isNavigateStep(value) || isImportStep(value) || isCallStep(value) || isSubscribeStep(value) || isDisposeStep(value);
393
+ return isSetStep(value) || isUpdateStep(value) || isSetPathStep(value) || isFetchStep(value) || isStorageStep(value) || isClipboardStep(value) || isNavigateStep(value) || isImportStep(value) || isCallStep(value) || isSubscribeStep(value) || isDisposeStep(value) || isDelayStep(value) || isIntervalStep(value) || isClearTimerStep(value) || isFocusStep(value);
394
+ }
395
+ function isLocalActionStep(value) {
396
+ return isSetStep(value) || isUpdateStep(value) || isSetPathStep(value);
397
+ }
398
+ function isLocalActionDefinition(value) {
399
+ if (!isObject(value)) return false;
400
+ if (typeof value["name"] !== "string") return false;
401
+ if (!Array.isArray(value["steps"])) return false;
402
+ for (const step of value["steps"]) {
403
+ if (!isLocalActionStep(step)) return false;
404
+ }
405
+ return true;
326
406
  }
327
407
  function isNumberField(value) {
328
408
  if (!isObject(value)) return false;
@@ -697,6 +777,21 @@ function createUndefinedVariantError(variantKey, styleName, path, options) {
697
777
  options
698
778
  );
699
779
  }
780
+ function createUndefinedLocalStateError(stateName, path, options) {
781
+ return new ConstelaError(
782
+ "UNDEFINED_LOCAL_STATE",
783
+ `Undefined local state reference: '${stateName}' is not defined in localState`,
784
+ path,
785
+ options
786
+ );
787
+ }
788
+ function createLocalActionInvalidStepError(stepType, path) {
789
+ return new ConstelaError(
790
+ "LOCAL_ACTION_INVALID_STEP",
791
+ `Invalid step type '${stepType}' in local action. Only 'set', 'update', and 'setPath' are allowed`,
792
+ path
793
+ );
794
+ }
700
795
  function levenshteinDistance(a, b) {
701
796
  const aLen = a.length;
702
797
  const bLen = b.length;
@@ -1424,7 +1519,8 @@ var astSchema = {
1424
1519
  { $ref: "#/$defs/CondExpr" },
1425
1520
  { $ref: "#/$defs/GetExpr" },
1426
1521
  { $ref: "#/$defs/IndexExpr" },
1427
- { $ref: "#/$defs/StyleExpr" }
1522
+ { $ref: "#/$defs/StyleExpr" },
1523
+ { $ref: "#/$defs/ValidityExpr" }
1428
1524
  ]
1429
1525
  },
1430
1526
  LitExpr: {
@@ -1541,6 +1637,19 @@ var astSchema = {
1541
1637
  }
1542
1638
  }
1543
1639
  },
1640
+ ValidityExpr: {
1641
+ type: "object",
1642
+ required: ["expr", "ref"],
1643
+ additionalProperties: false,
1644
+ properties: {
1645
+ expr: { type: "string", const: "validity" },
1646
+ ref: { type: "string" },
1647
+ property: {
1648
+ type: "string",
1649
+ enum: ["valid", "valueMissing", "typeMismatch", "patternMismatch", "tooLong", "tooShort", "rangeUnderflow", "rangeOverflow", "customError", "message"]
1650
+ }
1651
+ }
1652
+ },
1544
1653
  // ==================== Style Presets ====================
1545
1654
  StylePreset: {
1546
1655
  type: "object",
@@ -1633,7 +1742,11 @@ var astSchema = {
1633
1742
  oneOf: [
1634
1743
  { $ref: "#/$defs/SetStep" },
1635
1744
  { $ref: "#/$defs/UpdateStep" },
1636
- { $ref: "#/$defs/FetchStep" }
1745
+ { $ref: "#/$defs/FetchStep" },
1746
+ { $ref: "#/$defs/DelayStep" },
1747
+ { $ref: "#/$defs/IntervalStep" },
1748
+ { $ref: "#/$defs/ClearTimerStep" },
1749
+ { $ref: "#/$defs/FocusStep" }
1637
1750
  ]
1638
1751
  },
1639
1752
  SetStep: {
@@ -1685,6 +1798,61 @@ var astSchema = {
1685
1798
  }
1686
1799
  }
1687
1800
  },
1801
+ DelayStep: {
1802
+ type: "object",
1803
+ required: ["do", "ms", "then"],
1804
+ additionalProperties: false,
1805
+ properties: {
1806
+ do: { type: "string", const: "delay" },
1807
+ ms: { $ref: "#/$defs/Expression" },
1808
+ then: {
1809
+ type: "array",
1810
+ items: { $ref: "#/$defs/ActionStep" }
1811
+ },
1812
+ result: { type: "string" }
1813
+ }
1814
+ },
1815
+ IntervalStep: {
1816
+ type: "object",
1817
+ required: ["do", "ms", "action"],
1818
+ additionalProperties: false,
1819
+ properties: {
1820
+ do: { type: "string", const: "interval" },
1821
+ ms: { $ref: "#/$defs/Expression" },
1822
+ action: { type: "string" },
1823
+ result: { type: "string" }
1824
+ }
1825
+ },
1826
+ ClearTimerStep: {
1827
+ type: "object",
1828
+ required: ["do", "target"],
1829
+ additionalProperties: false,
1830
+ properties: {
1831
+ do: { type: "string", const: "clearTimer" },
1832
+ target: { $ref: "#/$defs/Expression" }
1833
+ }
1834
+ },
1835
+ FocusStep: {
1836
+ type: "object",
1837
+ required: ["do", "target", "operation"],
1838
+ additionalProperties: false,
1839
+ properties: {
1840
+ do: { type: "string", const: "focus" },
1841
+ target: { $ref: "#/$defs/Expression" },
1842
+ operation: {
1843
+ type: "string",
1844
+ enum: ["focus", "blur", "select"]
1845
+ },
1846
+ onSuccess: {
1847
+ type: "array",
1848
+ items: { $ref: "#/$defs/ActionStep" }
1849
+ },
1850
+ onError: {
1851
+ type: "array",
1852
+ items: { $ref: "#/$defs/ActionStep" }
1853
+ }
1854
+ }
1855
+ },
1688
1856
  // ==================== Event Handler ====================
1689
1857
  EventHandler: {
1690
1858
  type: "object",
@@ -1693,7 +1861,19 @@ var astSchema = {
1693
1861
  properties: {
1694
1862
  event: { type: "string" },
1695
1863
  action: { type: "string" },
1696
- payload: { $ref: "#/$defs/Expression" }
1864
+ payload: { $ref: "#/$defs/Expression" },
1865
+ debounce: { type: "number" },
1866
+ throttle: { type: "number" },
1867
+ options: { $ref: "#/$defs/EventHandlerOptions" }
1868
+ }
1869
+ },
1870
+ EventHandlerOptions: {
1871
+ type: "object",
1872
+ additionalProperties: false,
1873
+ properties: {
1874
+ threshold: { type: "number" },
1875
+ rootMargin: { type: "string" },
1876
+ once: { type: "boolean" }
1697
1877
  }
1698
1878
  },
1699
1879
  // ==================== Action Definition ====================
@@ -1719,7 +1899,8 @@ var astSchema = {
1719
1899
  { $ref: "#/$defs/ComponentNode" },
1720
1900
  { $ref: "#/$defs/SlotNode" },
1721
1901
  { $ref: "#/$defs/MarkdownNode" },
1722
- { $ref: "#/$defs/CodeNode" }
1902
+ { $ref: "#/$defs/CodeNode" },
1903
+ { $ref: "#/$defs/PortalNode" }
1723
1904
  ]
1724
1905
  },
1725
1906
  ElementNode: {
@@ -1821,6 +2002,19 @@ var astSchema = {
1821
2002
  content: { $ref: "#/$defs/Expression" }
1822
2003
  }
1823
2004
  },
2005
+ PortalNode: {
2006
+ type: "object",
2007
+ required: ["kind", "target", "children"],
2008
+ additionalProperties: false,
2009
+ properties: {
2010
+ kind: { type: "string", const: "portal" },
2011
+ target: { type: "string" },
2012
+ children: {
2013
+ type: "array",
2014
+ items: { $ref: "#/$defs/ViewNode" }
2015
+ }
2016
+ }
2017
+ },
1824
2018
  // ==================== Component Definition ====================
1825
2019
  ParamDef: {
1826
2020
  type: "object",
@@ -1854,12 +2048,14 @@ export {
1854
2048
  ConstelaError,
1855
2049
  DATA_SOURCE_TYPES,
1856
2050
  DATA_TRANSFORMS,
2051
+ FOCUS_OPERATIONS,
1857
2052
  HTTP_METHODS,
1858
2053
  NAVIGATE_TARGETS,
1859
2054
  PARAM_TYPES,
1860
2055
  STORAGE_OPERATIONS,
1861
2056
  STORAGE_TYPES,
1862
2057
  UPDATE_OPERATIONS,
2058
+ VALIDITY_PROPERTIES,
1863
2059
  astSchema,
1864
2060
  createClipboardWriteMissingValueError,
1865
2061
  createComponentCycleError,
@@ -1880,6 +2076,7 @@ export {
1880
2076
  createInvalidStorageTypeError,
1881
2077
  createLayoutMissingSlotError,
1882
2078
  createLayoutNotFoundError,
2079
+ createLocalActionInvalidStepError,
1883
2080
  createOperationInvalidForTypeError,
1884
2081
  createOperationMissingFieldError,
1885
2082
  createOperationUnknownError,
@@ -1891,6 +2088,7 @@ export {
1891
2088
  createUndefinedDataError,
1892
2089
  createUndefinedDataSourceError,
1893
2090
  createUndefinedImportError,
2091
+ createUndefinedLocalStateError,
1894
2092
  createUndefinedParamError,
1895
2093
  createUndefinedRefError,
1896
2094
  createUndefinedRouteParamError,
@@ -1918,6 +2116,7 @@ export {
1918
2116
  isEventHandler,
1919
2117
  isExpression,
1920
2118
  isFetchStep,
2119
+ isFocusStep,
1921
2120
  isGetExpr,
1922
2121
  isIfNode,
1923
2122
  isImportExpr,
@@ -1926,6 +2125,8 @@ export {
1926
2125
  isLifecycleHooks,
1927
2126
  isListField,
1928
2127
  isLitExpr,
2128
+ isLocalActionDefinition,
2129
+ isLocalActionStep,
1929
2130
  isMarkdownNode,
1930
2131
  isNamedSlotNode,
1931
2132
  isNavigateStep,
@@ -1933,9 +2134,11 @@ export {
1933
2134
  isNumberField,
1934
2135
  isObjectField,
1935
2136
  isParamExpr,
2137
+ isPortalNode,
1936
2138
  isRefExpr,
1937
2139
  isRouteDefinition,
1938
2140
  isRouteExpr,
2141
+ isSetPathStep,
1939
2142
  isSetStep,
1940
2143
  isSlotNode,
1941
2144
  isStateExpr,
@@ -1947,6 +2150,7 @@ export {
1947
2150
  isSubscribeStep,
1948
2151
  isTextNode,
1949
2152
  isUpdateStep,
2153
+ isValidityExpr,
1950
2154
  isVarExpr,
1951
2155
  isViewNode,
1952
2156
  validateAst
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@constela/core",
3
- "version": "0.9.1",
3
+ "version": "0.11.0",
4
4
  "description": "Core types, schema, and validator for Constela UI framework",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",