@constela/core 0.22.0 → 0.23.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/dist/index.d.ts CHANGED
@@ -641,12 +641,23 @@ interface TextNode {
641
641
  kind: 'text';
642
642
  value: Expression;
643
643
  }
644
+ /**
645
+ * Transition directive for enter/exit animations on if/each nodes
646
+ */
647
+ interface TransitionDirective {
648
+ enter: string;
649
+ enterActive: string;
650
+ exit: string;
651
+ exitActive: string;
652
+ duration?: number;
653
+ }
644
654
  /**
645
655
  * If node - conditional rendering
646
656
  */
647
657
  interface IfNode {
648
658
  kind: 'if';
649
659
  condition: Expression;
660
+ transition?: TransitionDirective;
650
661
  then: ViewNode;
651
662
  else?: ViewNode;
652
663
  }
@@ -659,6 +670,7 @@ interface EachNode {
659
670
  as: string;
660
671
  index?: string;
661
672
  key?: Expression;
673
+ transition?: TransitionDirective;
662
674
  body: ViewNode;
663
675
  }
664
676
  /**
@@ -1172,7 +1184,7 @@ declare function isLifecycleHooks(value: unknown): value is LifecycleHooks;
1172
1184
  * This module defines error types, the ConstelaError class,
1173
1185
  * and factory functions for creating specific errors.
1174
1186
  */
1175
- 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' | 'DUPLICATE_ISLAND_ID';
1187
+ 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' | 'DUPLICATE_ISLAND_ID' | 'A11Y_IMG_NO_ALT' | 'A11Y_BUTTON_NO_LABEL' | 'A11Y_ANCHOR_NO_LABEL' | 'A11Y_INPUT_NO_LABEL' | 'A11Y_HEADING_SKIP' | 'A11Y_POSITIVE_TABINDEX' | 'A11Y_DUPLICATE_ID';
1176
1188
  /**
1177
1189
  * Options for creating enhanced ConstelaError instances
1178
1190
  */
@@ -1383,6 +1395,34 @@ declare function createLocalActionInvalidStepError(stepType: string, path?: stri
1383
1395
  * Creates a duplicate island ID error
1384
1396
  */
1385
1397
  declare function createDuplicateIslandIdError(id: string, path?: string, suggestions?: string[]): ConstelaError;
1398
+ /**
1399
+ * Creates an a11y error for img missing alt attribute
1400
+ */
1401
+ declare function createA11yImgNoAltError(path?: string): ConstelaError;
1402
+ /**
1403
+ * Creates an a11y error for button missing accessible label
1404
+ */
1405
+ declare function createA11yButtonNoLabelError(path?: string): ConstelaError;
1406
+ /**
1407
+ * Creates an a11y error for anchor missing accessible label
1408
+ */
1409
+ declare function createA11yAnchorNoLabelError(path?: string): ConstelaError;
1410
+ /**
1411
+ * Creates an a11y error for form input missing label
1412
+ */
1413
+ declare function createA11yInputNoLabelError(tag: string, path?: string): ConstelaError;
1414
+ /**
1415
+ * Creates an a11y error for heading level skip
1416
+ */
1417
+ declare function createA11yHeadingSkipError(current: number, expected: number, path?: string): ConstelaError;
1418
+ /**
1419
+ * Creates an a11y error for positive tabindex
1420
+ */
1421
+ declare function createA11yPositiveTabindexError(value: number, path?: string): ConstelaError;
1422
+ /**
1423
+ * Creates an a11y error for duplicate id
1424
+ */
1425
+ declare function createA11yDuplicateIdError(id: string, path?: string): ConstelaError;
1386
1426
  /**
1387
1427
  * Finds similar names from a set of candidates using Levenshtein distance
1388
1428
  * and prefix matching.
@@ -2460,6 +2500,12 @@ interface CalendarDay {
2460
2500
  * Whitelist of global helper functions that can be called with target: null
2461
2501
  */
2462
2502
  declare const GLOBAL_FUNCTIONS: Record<string, (...args: unknown[]) => unknown>;
2503
+ declare function registerGlobalFunction(name: string, fn: (...args: unknown[]) => unknown): void;
2504
+ /**
2505
+ * Unregisters a custom global function.
2506
+ * Built-in functions cannot be unregistered.
2507
+ */
2508
+ declare function unregisterGlobalFunction(name: string): void;
2463
2509
  /**
2464
2510
  * Calls a global helper function by name
2465
2511
  *
@@ -2469,6 +2515,20 @@ declare const GLOBAL_FUNCTIONS: Record<string, (...args: unknown[]) => unknown>;
2469
2515
  */
2470
2516
  declare function callGlobalFunction(method: string, args: unknown[]): unknown;
2471
2517
 
2518
+ /**
2519
+ * Plugin System for Constela
2520
+ *
2521
+ * Allows external packages to register global helper functions
2522
+ * callable via { "expr": "call", "target": null, "method": "myFunc" }.
2523
+ */
2524
+ interface ConstelaPlugin {
2525
+ readonly name: string;
2526
+ readonly globalFunctions?: Record<string, (...args: unknown[]) => unknown>;
2527
+ }
2528
+ declare function registerPlugin(plugin: ConstelaPlugin): void;
2529
+ declare function getRegisteredPlugins(): readonly ConstelaPlugin[];
2530
+ declare function clearPlugins(): void;
2531
+
2472
2532
  /**
2473
2533
  * Types for the unified evaluate module.
2474
2534
  *
@@ -2525,4 +2585,4 @@ declare const SAFE_DATE_STATIC_METHODS: Set<string>;
2525
2585
  declare const SAFE_DATE_INSTANCE_METHODS: Set<string>;
2526
2586
  declare const FORBIDDEN_KEYS: Set<string>;
2527
2587
 
2528
- export { AI_OUTPUT_TYPES, AI_PROVIDER_TYPES, type ActionDefinition, type ActionStep, type AiDataSource, type AiOutputType, type AiProviderType, type ArrayExpr, BINARY_OPERATORS, type BinExpr, type BinaryOperator, type BindStep, type BooleanField, CLIPBOARD_OPERATIONS, COLOR_SCHEMES, type CalendarDay, type CallExpr, type CallStep, type ClearTimerStep, type ClipboardOperation, type ClipboardStep, type CloseStep, type CodeNode, type ColorScheme, type ComponentDef, type ComponentNode, type ComponentsRef, type CompoundVariant, type ConcatExpr, type CondExpr, type ConfirmStep, type ConstelaAst, ConstelaError, type ConstelaProgram, type CookieInitialExpr, type CoreEvaluationContext, DATA_SOURCE_TYPES, DATA_TRANSFORMS, type DataExpr, type DataSource, type DataSourceType, type DataTransform, type DelayStep, type DisposeStep, type DomStep, type EachNode, type ElementNode, type EnvironmentAdapter, type ErrorBoundaryNode, type ErrorCode, type ErrorOptions, type EventHandler, type EventHandlerOptions, type Expression, FOCUS_OPERATIONS, FORBIDDEN_KEYS, type FetchStep, type FlushStrategy, type FocusOperation, type FocusStep, GLOBAL_FUNCTIONS, type GenerateStep, type GetExpr, HTTP_METHODS, type HttpMethod, ISLAND_STRATEGIES, type IfNode, type IfStep, type ImportExpr, type ImportStep, type IndexExpr, type IntervalStep, type IslandNode, type IslandStrategy, type IslandStrategyOptions, type LambdaExpr, type LayoutProgram, type LifecycleHooks, type ListField, type LitExpr, type LocalActionDefinition, type LocalActionStep, type LocalExpr, type MarkdownNode, NAVIGATE_TARGETS, type NavigateStep, type NavigateTarget, type NotExpr, type NumberField, type ObjExpr, type ObjectField, type OptimisticStep, PARAM_TYPES, type ParamDef, type ParamExpr, type ParamType, type PortalNode, type Program, type ReconnectConfig, type RefExpr, type RejectStep, type RouteDefinition, type RouteExpr, SAFE_ARRAY_METHODS, SAFE_DATE_INSTANCE_METHODS, SAFE_DATE_STATIC_METHODS, SAFE_MATH_METHODS, SAFE_STRING_METHODS, type SSECloseStep, type SSEConnectStep, STORAGE_OPERATIONS, STORAGE_TYPES, type SendStep, type SetPathStep, type SetStep, type SlotNode, type StateExpr, type StateField, type StateReader, type StaticPathsDefinition, type StorageOperation, type StorageStep, type StorageType, type StreamChunk, type StreamChunkType, type StreamingRenderOptions, type StringField, type StyleExpr, type StylePreset, type SubscribeStep, type SuspenseBoundary, type SuspenseNode, type TextNode, type ThemeColors, type ThemeConfig, type ThemeFonts, UPDATE_OPERATIONS, type UnbindStep, type UpdateOperation, type UpdateStep, VALIDITY_PROPERTIES, type ValidationFailure, type ValidationResult, type ValidationSuccess, type ValidityExpr, type ValidityProperty, type VarExpr, type ViewNode, astSchema, callGlobalFunction, createClipboardWriteMissingValueError, createComponentCycleError, createComponentNotFoundError, createComponentPropMissingError, createComponentPropTypeError, createCondElseRequiredError, createDataNotDefinedError, createDuplicateActionError, createDuplicateDefaultSlotError, createDuplicateIslandIdError, 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, evaluate, evaluateStyle, findSimilarNames, isActionStep, isAiDataSource, isArrayExpr, isBinExpr, isBooleanField, isCallStep, isClipboardStep, isCodeNode, isColorScheme, isComponentNode, isConcatExpr, isCondExpr, isConstelaError, isCookieInitialExpr, isDataExpr, isDataSource, isDisposeStep, isEachNode, isElementNode, isErrorBoundaryNode, isEventHandler, isExpression, isFetchStep, isFocusStep, isGenerateStep, isGetExpr, isIfNode, isImportExpr, isImportStep, isIslandNode, isIslandStrategy, isIslandStrategyOptions, isLayoutProgram, isLifecycleHooks, isListField, isLitExpr, isLocalActionDefinition, isLocalActionStep, isMarkdownNode, isNamedSlotNode, isNavigateStep, isNotExpr, isNumberField, isObjectField, isParamExpr, isPortalNode, isRefExpr, isRouteDefinition, isRouteExpr, isSetPathStep, isSetStep, isSlotNode, isStateExpr, isStateField, isStaticPathsDefinition, isStorageStep, isStreamChunk, isStreamingRenderOptions, isStringField, isStyleExpr, isSubscribeStep, isSuspenseBoundary, isSuspenseNode, isTextNode, isThemeColors, isThemeConfig, isThemeFonts, isUpdateStep, isValidityExpr, isVarExpr, isViewNode, validateAst };
2588
+ export { AI_OUTPUT_TYPES, AI_PROVIDER_TYPES, type ActionDefinition, type ActionStep, type AiDataSource, type AiOutputType, type AiProviderType, type ArrayExpr, BINARY_OPERATORS, type BinExpr, type BinaryOperator, type BindStep, type BooleanField, CLIPBOARD_OPERATIONS, COLOR_SCHEMES, type CalendarDay, type CallExpr, type CallStep, type ClearTimerStep, type ClipboardOperation, type ClipboardStep, type CloseStep, type CodeNode, type ColorScheme, type ComponentDef, type ComponentNode, type ComponentsRef, type CompoundVariant, type ConcatExpr, type CondExpr, type ConfirmStep, type ConstelaAst, ConstelaError, type ConstelaPlugin, type ConstelaProgram, type CookieInitialExpr, type CoreEvaluationContext, DATA_SOURCE_TYPES, DATA_TRANSFORMS, type DataExpr, type DataSource, type DataSourceType, type DataTransform, type DelayStep, type DisposeStep, type DomStep, type EachNode, type ElementNode, type EnvironmentAdapter, type ErrorBoundaryNode, type ErrorCode, type ErrorOptions, type EventHandler, type EventHandlerOptions, type Expression, FOCUS_OPERATIONS, FORBIDDEN_KEYS, type FetchStep, type FlushStrategy, type FocusOperation, type FocusStep, GLOBAL_FUNCTIONS, type GenerateStep, type GetExpr, HTTP_METHODS, type HttpMethod, ISLAND_STRATEGIES, type IfNode, type IfStep, type ImportExpr, type ImportStep, type IndexExpr, type IntervalStep, type IslandNode, type IslandStrategy, type IslandStrategyOptions, type LambdaExpr, type LayoutProgram, type LifecycleHooks, type ListField, type LitExpr, type LocalActionDefinition, type LocalActionStep, type LocalExpr, type MarkdownNode, NAVIGATE_TARGETS, type NavigateStep, type NavigateTarget, type NotExpr, type NumberField, type ObjExpr, type ObjectField, type OptimisticStep, PARAM_TYPES, type ParamDef, type ParamExpr, type ParamType, type PortalNode, type Program, type ReconnectConfig, type RefExpr, type RejectStep, type RouteDefinition, type RouteExpr, SAFE_ARRAY_METHODS, SAFE_DATE_INSTANCE_METHODS, SAFE_DATE_STATIC_METHODS, SAFE_MATH_METHODS, SAFE_STRING_METHODS, type SSECloseStep, type SSEConnectStep, STORAGE_OPERATIONS, STORAGE_TYPES, type SendStep, type SetPathStep, type SetStep, type SlotNode, type StateExpr, type StateField, type StateReader, type StaticPathsDefinition, type StorageOperation, type StorageStep, type StorageType, type StreamChunk, type StreamChunkType, type StreamingRenderOptions, type StringField, type StyleExpr, type StylePreset, type SubscribeStep, type SuspenseBoundary, type SuspenseNode, type TextNode, type ThemeColors, type ThemeConfig, type ThemeFonts, type TransitionDirective, UPDATE_OPERATIONS, type UnbindStep, type UpdateOperation, type UpdateStep, VALIDITY_PROPERTIES, type ValidationFailure, type ValidationResult, type ValidationSuccess, type ValidityExpr, type ValidityProperty, type VarExpr, type ViewNode, astSchema, callGlobalFunction, clearPlugins, createA11yAnchorNoLabelError, createA11yButtonNoLabelError, createA11yDuplicateIdError, createA11yHeadingSkipError, createA11yImgNoAltError, createA11yInputNoLabelError, createA11yPositiveTabindexError, createClipboardWriteMissingValueError, createComponentCycleError, createComponentNotFoundError, createComponentPropMissingError, createComponentPropTypeError, createCondElseRequiredError, createDataNotDefinedError, createDuplicateActionError, createDuplicateDefaultSlotError, createDuplicateIslandIdError, 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, evaluate, evaluateStyle, findSimilarNames, getRegisteredPlugins, isActionStep, isAiDataSource, isArrayExpr, isBinExpr, isBooleanField, isCallStep, isClipboardStep, isCodeNode, isColorScheme, isComponentNode, isConcatExpr, isCondExpr, isConstelaError, isCookieInitialExpr, isDataExpr, isDataSource, isDisposeStep, isEachNode, isElementNode, isErrorBoundaryNode, isEventHandler, isExpression, isFetchStep, isFocusStep, isGenerateStep, isGetExpr, isIfNode, isImportExpr, isImportStep, isIslandNode, isIslandStrategy, isIslandStrategyOptions, isLayoutProgram, isLifecycleHooks, isListField, isLitExpr, isLocalActionDefinition, isLocalActionStep, isMarkdownNode, isNamedSlotNode, isNavigateStep, isNotExpr, isNumberField, isObjectField, isParamExpr, isPortalNode, isRefExpr, isRouteDefinition, isRouteExpr, isSetPathStep, isSetStep, isSlotNode, isStateExpr, isStateField, isStaticPathsDefinition, isStorageStep, isStreamChunk, isStreamingRenderOptions, isStringField, isStyleExpr, isSubscribeStep, isSuspenseBoundary, isSuspenseNode, isTextNode, isThemeColors, isThemeConfig, isThemeFonts, isUpdateStep, isValidityExpr, isVarExpr, isViewNode, registerGlobalFunction, registerPlugin, unregisterGlobalFunction, validateAst };
package/dist/index.js CHANGED
@@ -944,6 +944,62 @@ function createDuplicateIslandIdError(id, path, suggestions) {
944
944
  }
945
945
  );
946
946
  }
947
+ function createA11yImgNoAltError(path) {
948
+ return new ConstelaError(
949
+ "A11Y_IMG_NO_ALT",
950
+ `Accessibility: <img> element is missing an 'alt' attribute`,
951
+ path,
952
+ { severity: "warning", suggestion: `Add an 'alt' attribute to describe the image, or alt="" for decorative images` }
953
+ );
954
+ }
955
+ function createA11yButtonNoLabelError(path) {
956
+ return new ConstelaError(
957
+ "A11Y_BUTTON_NO_LABEL",
958
+ `Accessibility: <button> element has no text content or 'aria-label'`,
959
+ path,
960
+ { severity: "warning", suggestion: `Add text content or an 'aria-label' attribute` }
961
+ );
962
+ }
963
+ function createA11yAnchorNoLabelError(path) {
964
+ return new ConstelaError(
965
+ "A11Y_ANCHOR_NO_LABEL",
966
+ `Accessibility: <a> element has no text content or 'aria-label'`,
967
+ path,
968
+ { severity: "warning", suggestion: `Add text content or an 'aria-label' attribute` }
969
+ );
970
+ }
971
+ function createA11yInputNoLabelError(tag, path) {
972
+ return new ConstelaError(
973
+ "A11Y_INPUT_NO_LABEL",
974
+ `Accessibility: <${tag}> element has no 'aria-label' or 'aria-labelledby'`,
975
+ path,
976
+ { severity: "warning", suggestion: `Add an 'aria-label' or 'aria-labelledby' attribute` }
977
+ );
978
+ }
979
+ function createA11yHeadingSkipError(current, expected, path) {
980
+ return new ConstelaError(
981
+ "A11Y_HEADING_SKIP",
982
+ `Accessibility: Heading level skipped from h${expected - 1} to h${current}`,
983
+ path,
984
+ { severity: "warning", suggestion: `Use h${expected} instead of h${current} to maintain heading hierarchy` }
985
+ );
986
+ }
987
+ function createA11yPositiveTabindexError(value, path) {
988
+ return new ConstelaError(
989
+ "A11Y_POSITIVE_TABINDEX",
990
+ `Accessibility: Avoid positive tabindex value '${value}'`,
991
+ path,
992
+ { severity: "warning", suggestion: `Use tabindex="0" or tabindex="-1" instead` }
993
+ );
994
+ }
995
+ function createA11yDuplicateIdError(id, path) {
996
+ return new ConstelaError(
997
+ "A11Y_DUPLICATE_ID",
998
+ `Accessibility: Duplicate id '${id}' found`,
999
+ path,
1000
+ { severity: "warning", suggestion: `Use unique id values for each element` }
1001
+ );
1002
+ }
947
1003
  function levenshteinDistance(a, b) {
948
1004
  const aLen = a.length;
949
1005
  const bLen = b.length;
@@ -996,6 +1052,23 @@ var VALID_STATE_TYPES = ["number", "string", "list", "boolean", "object"];
996
1052
  var VALID_BIN_OPS = BINARY_OPERATORS;
997
1053
  var VALID_UPDATE_OPS = UPDATE_OPERATIONS;
998
1054
  var VALID_HTTP_METHODS = HTTP_METHODS;
1055
+ function validateTransitionDirective(transition, path) {
1056
+ if (typeof transition !== "object" || transition === null) {
1057
+ return { path, message: "transition must be an object" };
1058
+ }
1059
+ const t = transition;
1060
+ for (const field of ["enter", "enterActive", "exit", "exitActive"]) {
1061
+ if (typeof t[field] !== "string") {
1062
+ return { path: path + "/" + field, message: `${field} must be a string` };
1063
+ }
1064
+ }
1065
+ if ("duration" in t && t["duration"] !== void 0) {
1066
+ if (typeof t["duration"] !== "number" || t["duration"] < 0) {
1067
+ return { path: path + "/duration", message: "duration must be a non-negative number" };
1068
+ }
1069
+ }
1070
+ return null;
1071
+ }
999
1072
  function validateViewNode(node, path) {
1000
1073
  if (!isObject3(node)) {
1001
1074
  return { path, message: "must be an object" };
@@ -1043,6 +1116,10 @@ function validateViewNode(node, path) {
1043
1116
  {
1044
1117
  const condError = validateExpression(node["condition"], path + "/condition");
1045
1118
  if (condError) return condError;
1119
+ if ("transition" in node) {
1120
+ const transError = validateTransitionDirective(node["transition"], path + "/transition");
1121
+ if (transError) return transError;
1122
+ }
1046
1123
  const thenError = validateViewNode(node["then"], path + "/then");
1047
1124
  if (thenError) return thenError;
1048
1125
  if ("else" in node) {
@@ -1064,6 +1141,10 @@ function validateViewNode(node, path) {
1064
1141
  {
1065
1142
  const itemsError = validateExpression(node["items"], path + "/items");
1066
1143
  if (itemsError) return itemsError;
1144
+ if ("transition" in node) {
1145
+ const transError = validateTransitionDirective(node["transition"], path + "/transition");
1146
+ if (transError) return transError;
1147
+ }
1067
1148
  const bodyError = validateViewNode(node["body"], path + "/body");
1068
1149
  if (bodyError) return bodyError;
1069
1150
  }
@@ -3673,6 +3754,26 @@ var GLOBAL_FUNCTIONS = {
3673
3754
  return nums.length > 0 ? Math.max(...nums) : void 0;
3674
3755
  }
3675
3756
  };
3757
+ var BUILTIN_FUNCTION_NAMES = new Set(Object.keys(GLOBAL_FUNCTIONS));
3758
+ var FORBIDDEN_FUNCTION_NAMES = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
3759
+ function registerGlobalFunction(name, fn) {
3760
+ if (FORBIDDEN_FUNCTION_NAMES.has(name)) {
3761
+ throw new Error(`Cannot register global function '${name}': forbidden name`);
3762
+ }
3763
+ if (BUILTIN_FUNCTION_NAMES.has(name)) {
3764
+ throw new Error(`Cannot register global function '${name}': conflicts with built-in function`);
3765
+ }
3766
+ if (name in GLOBAL_FUNCTIONS) {
3767
+ throw new Error(`Cannot register global function '${name}': already registered`);
3768
+ }
3769
+ GLOBAL_FUNCTIONS[name] = fn;
3770
+ }
3771
+ function unregisterGlobalFunction(name) {
3772
+ if (BUILTIN_FUNCTION_NAMES.has(name)) {
3773
+ throw new Error(`Cannot unregister built-in function '${name}'`);
3774
+ }
3775
+ delete GLOBAL_FUNCTIONS[name];
3776
+ }
3676
3777
  function callGlobalFunction(method, args) {
3677
3778
  const fn = GLOBAL_FUNCTIONS[method];
3678
3779
  if (!fn) {
@@ -3681,6 +3782,42 @@ function callGlobalFunction(method, args) {
3681
3782
  return fn(...args);
3682
3783
  }
3683
3784
 
3785
+ // src/plugin/index.ts
3786
+ var registeredPlugins = [];
3787
+ function registerPlugin(plugin) {
3788
+ if (registeredPlugins.some((p) => p.name === plugin.name)) {
3789
+ throw new Error(`Plugin '${plugin.name}' is already registered`);
3790
+ }
3791
+ if (plugin.globalFunctions) {
3792
+ const registeredNames = [];
3793
+ try {
3794
+ for (const [name, fn] of Object.entries(plugin.globalFunctions)) {
3795
+ registerGlobalFunction(name, fn);
3796
+ registeredNames.push(name);
3797
+ }
3798
+ } catch (error) {
3799
+ for (const name of registeredNames) {
3800
+ unregisterGlobalFunction(name);
3801
+ }
3802
+ throw error;
3803
+ }
3804
+ }
3805
+ registeredPlugins.push(plugin);
3806
+ }
3807
+ function getRegisteredPlugins() {
3808
+ return [...registeredPlugins];
3809
+ }
3810
+ function clearPlugins() {
3811
+ for (const plugin of registeredPlugins) {
3812
+ if (plugin.globalFunctions) {
3813
+ for (const name of Object.keys(plugin.globalFunctions)) {
3814
+ unregisterGlobalFunction(name);
3815
+ }
3816
+ }
3817
+ }
3818
+ registeredPlugins.length = 0;
3819
+ }
3820
+
3684
3821
  // src/evaluate/constants.ts
3685
3822
  var SAFE_ARRAY_METHODS = /* @__PURE__ */ new Set([
3686
3823
  "length",
@@ -4275,6 +4412,14 @@ export {
4275
4412
  VALIDITY_PROPERTIES,
4276
4413
  astSchema,
4277
4414
  callGlobalFunction,
4415
+ clearPlugins,
4416
+ createA11yAnchorNoLabelError,
4417
+ createA11yButtonNoLabelError,
4418
+ createA11yDuplicateIdError,
4419
+ createA11yHeadingSkipError,
4420
+ createA11yImgNoAltError,
4421
+ createA11yInputNoLabelError,
4422
+ createA11yPositiveTabindexError,
4278
4423
  createClipboardWriteMissingValueError,
4279
4424
  createComponentCycleError,
4280
4425
  createComponentNotFoundError,
@@ -4319,6 +4464,7 @@ export {
4319
4464
  evaluate,
4320
4465
  evaluateStyle,
4321
4466
  findSimilarNames,
4467
+ getRegisteredPlugins,
4322
4468
  isActionStep,
4323
4469
  isAiDataSource,
4324
4470
  isArrayExpr,
@@ -4390,5 +4536,8 @@ export {
4390
4536
  isValidityExpr,
4391
4537
  isVarExpr,
4392
4538
  isViewNode,
4539
+ registerGlobalFunction,
4540
+ registerPlugin,
4541
+ unregisterGlobalFunction,
4393
4542
  validateAst
4394
4543
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@constela/core",
3
- "version": "0.22.0",
3
+ "version": "0.23.0",
4
4
  "description": "Core types, schema, and validator for Constela UI framework",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",