@object-ui/core 0.3.1 → 2.0.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 (118) hide show
  1. package/.turbo/turbo-build.log +4 -0
  2. package/CHANGELOG.md +11 -0
  3. package/dist/actions/ActionRunner.d.ts +228 -4
  4. package/dist/actions/ActionRunner.js +397 -45
  5. package/dist/actions/TransactionManager.d.ts +193 -0
  6. package/dist/actions/TransactionManager.js +410 -0
  7. package/dist/actions/index.d.ts +2 -1
  8. package/dist/actions/index.js +2 -1
  9. package/dist/adapters/ApiDataSource.d.ts +69 -0
  10. package/dist/adapters/ApiDataSource.js +293 -0
  11. package/dist/adapters/ValueDataSource.d.ts +55 -0
  12. package/dist/adapters/ValueDataSource.js +287 -0
  13. package/dist/adapters/index.d.ts +3 -0
  14. package/dist/adapters/index.js +5 -2
  15. package/dist/adapters/resolveDataSource.d.ts +40 -0
  16. package/dist/adapters/resolveDataSource.js +59 -0
  17. package/dist/data-scope/DataScopeManager.d.ts +127 -0
  18. package/dist/data-scope/DataScopeManager.js +229 -0
  19. package/dist/data-scope/index.d.ts +10 -0
  20. package/dist/data-scope/index.js +10 -0
  21. package/dist/evaluator/ExpressionCache.d.ts +101 -0
  22. package/dist/evaluator/ExpressionCache.js +135 -0
  23. package/dist/evaluator/ExpressionEvaluator.d.ts +30 -2
  24. package/dist/evaluator/ExpressionEvaluator.js +60 -16
  25. package/dist/evaluator/FormulaFunctions.d.ts +58 -0
  26. package/dist/evaluator/FormulaFunctions.js +350 -0
  27. package/dist/evaluator/index.d.ts +4 -2
  28. package/dist/evaluator/index.js +4 -2
  29. package/dist/index.d.ts +14 -7
  30. package/dist/index.js +13 -9
  31. package/dist/query/index.d.ts +6 -0
  32. package/dist/query/index.js +6 -0
  33. package/dist/query/query-ast.d.ts +32 -0
  34. package/dist/query/query-ast.js +268 -0
  35. package/dist/registry/PluginScopeImpl.d.ts +80 -0
  36. package/dist/registry/PluginScopeImpl.js +243 -0
  37. package/dist/registry/PluginSystem.d.ts +66 -0
  38. package/dist/registry/PluginSystem.js +142 -0
  39. package/dist/registry/Registry.d.ts +83 -4
  40. package/dist/registry/Registry.js +113 -7
  41. package/dist/registry/WidgetRegistry.d.ts +120 -0
  42. package/dist/registry/WidgetRegistry.js +275 -0
  43. package/dist/theme/ThemeEngine.d.ts +82 -0
  44. package/dist/theme/ThemeEngine.js +400 -0
  45. package/dist/theme/index.d.ts +8 -0
  46. package/dist/theme/index.js +8 -0
  47. package/dist/validation/index.d.ts +9 -0
  48. package/dist/validation/index.js +9 -0
  49. package/dist/validation/validation-engine.d.ts +88 -0
  50. package/dist/validation/validation-engine.js +428 -0
  51. package/dist/validation/validators/index.d.ts +16 -0
  52. package/dist/validation/validators/index.js +16 -0
  53. package/dist/validation/validators/object-validation-engine.d.ts +118 -0
  54. package/dist/validation/validators/object-validation-engine.js +538 -0
  55. package/package.json +14 -5
  56. package/src/actions/ActionRunner.ts +577 -55
  57. package/src/actions/TransactionManager.ts +521 -0
  58. package/src/actions/__tests__/ActionRunner.params.test.ts +134 -0
  59. package/src/actions/__tests__/ActionRunner.test.ts +711 -0
  60. package/src/actions/__tests__/TransactionManager.test.ts +447 -0
  61. package/src/actions/index.ts +2 -1
  62. package/src/adapters/ApiDataSource.ts +349 -0
  63. package/src/adapters/ValueDataSource.ts +332 -0
  64. package/src/adapters/__tests__/ApiDataSource.test.ts +418 -0
  65. package/src/adapters/__tests__/ValueDataSource.test.ts +325 -0
  66. package/src/adapters/__tests__/resolveDataSource.test.ts +144 -0
  67. package/src/adapters/index.ts +6 -1
  68. package/src/adapters/resolveDataSource.ts +79 -0
  69. package/src/builder/__tests__/schema-builder.test.ts +235 -0
  70. package/src/data-scope/DataScopeManager.ts +269 -0
  71. package/src/data-scope/__tests__/DataScopeManager.test.ts +211 -0
  72. package/src/data-scope/index.ts +16 -0
  73. package/src/evaluator/ExpressionCache.ts +192 -0
  74. package/src/evaluator/ExpressionEvaluator.ts +61 -16
  75. package/src/evaluator/FormulaFunctions.ts +398 -0
  76. package/src/evaluator/__tests__/ExpressionCache.test.ts +135 -0
  77. package/src/evaluator/__tests__/ExpressionContext.test.ts +110 -0
  78. package/src/evaluator/__tests__/FormulaFunctions.test.ts +447 -0
  79. package/src/evaluator/index.ts +4 -2
  80. package/src/index.ts +14 -10
  81. package/src/query/__tests__/query-ast.test.ts +211 -0
  82. package/src/query/__tests__/window-functions.test.ts +275 -0
  83. package/src/query/index.ts +7 -0
  84. package/src/query/query-ast.ts +341 -0
  85. package/src/registry/PluginScopeImpl.ts +259 -0
  86. package/src/registry/PluginSystem.ts +161 -0
  87. package/src/registry/Registry.ts +136 -8
  88. package/src/registry/WidgetRegistry.ts +316 -0
  89. package/src/registry/__tests__/PluginSystem.test.ts +226 -0
  90. package/src/registry/__tests__/Registry.test.ts +293 -0
  91. package/src/registry/__tests__/WidgetRegistry.test.ts +321 -0
  92. package/src/registry/__tests__/plugin-scope-integration.test.ts +283 -0
  93. package/src/theme/ThemeEngine.ts +452 -0
  94. package/src/theme/__tests__/ThemeEngine.test.ts +606 -0
  95. package/src/theme/index.ts +22 -0
  96. package/src/validation/__tests__/object-validation-engine.test.ts +567 -0
  97. package/src/validation/__tests__/schema-validator.test.ts +118 -0
  98. package/src/validation/__tests__/validation-engine.test.ts +102 -0
  99. package/src/validation/index.ts +10 -0
  100. package/src/validation/validation-engine.ts +520 -0
  101. package/src/validation/validators/index.ts +25 -0
  102. package/src/validation/validators/object-validation-engine.ts +722 -0
  103. package/tsconfig.tsbuildinfo +1 -1
  104. package/vitest.config.ts +2 -0
  105. package/src/adapters/index.d.ts +0 -8
  106. package/src/adapters/index.js +0 -10
  107. package/src/builder/schema-builder.d.ts +0 -294
  108. package/src/builder/schema-builder.js +0 -503
  109. package/src/index.d.ts +0 -13
  110. package/src/index.js +0 -16
  111. package/src/registry/Registry.d.ts +0 -56
  112. package/src/registry/Registry.js +0 -43
  113. package/src/types/index.d.ts +0 -19
  114. package/src/types/index.js +0 -8
  115. package/src/utils/filter-converter.d.ts +0 -57
  116. package/src/utils/filter-converter.js +0 -100
  117. package/src/validation/schema-validator.d.ts +0 -94
  118. package/src/validation/schema-validator.js +0 -278
@@ -0,0 +1,142 @@
1
+ /**
2
+ * ObjectUI
3
+ * Copyright (c) 2024-present ObjectStack Inc.
4
+ *
5
+ * This source code is licensed under the MIT license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ */
8
+ import { PluginScopeImpl } from './PluginScopeImpl.js';
9
+ export class PluginSystem {
10
+ constructor() {
11
+ Object.defineProperty(this, "plugins", {
12
+ enumerable: true,
13
+ configurable: true,
14
+ writable: true,
15
+ value: new Map()
16
+ });
17
+ Object.defineProperty(this, "loaded", {
18
+ enumerable: true,
19
+ configurable: true,
20
+ writable: true,
21
+ value: new Set()
22
+ });
23
+ Object.defineProperty(this, "scopes", {
24
+ enumerable: true,
25
+ configurable: true,
26
+ writable: true,
27
+ value: new Map()
28
+ });
29
+ }
30
+ /**
31
+ * Load a plugin into the system with optional scope isolation
32
+ * @param plugin The plugin definition to load
33
+ * @param registry The component registry to use for registration
34
+ * @param useScope Whether to use scoped loading (default: true for better isolation)
35
+ * @throws Error if dependencies are missing
36
+ */
37
+ async loadPlugin(plugin, registry, useScope = true) {
38
+ // Check if already loaded
39
+ if (this.loaded.has(plugin.name)) {
40
+ console.warn(`Plugin "${plugin.name}" is already loaded. Skipping.`);
41
+ return;
42
+ }
43
+ // Check dependencies
44
+ for (const dep of plugin.dependencies || []) {
45
+ if (!this.loaded.has(dep)) {
46
+ throw new Error(`Missing dependency: ${dep} required by ${plugin.name}`);
47
+ }
48
+ }
49
+ try {
50
+ if (useScope) {
51
+ // Create scoped environment for plugin
52
+ const scope = new PluginScopeImpl(plugin.name, plugin.version, registry, plugin.scopeConfig);
53
+ // Store scope for cleanup
54
+ this.scopes.set(plugin.name, scope);
55
+ // Execute registration with scope
56
+ plugin.register(scope);
57
+ }
58
+ else {
59
+ // Legacy mode: direct registry access
60
+ plugin.register(registry);
61
+ }
62
+ // Store plugin definition
63
+ this.plugins.set(plugin.name, plugin);
64
+ // Execute lifecycle hook
65
+ await plugin.onLoad?.();
66
+ // Mark as loaded
67
+ this.loaded.add(plugin.name);
68
+ }
69
+ catch (error) {
70
+ // Clean up on failure
71
+ this.plugins.delete(plugin.name);
72
+ this.scopes.delete(plugin.name);
73
+ throw error;
74
+ }
75
+ }
76
+ /**
77
+ * Unload a plugin from the system
78
+ * @param name The name of the plugin to unload
79
+ * @throws Error if other plugins depend on this plugin
80
+ */
81
+ async unloadPlugin(name) {
82
+ const plugin = this.plugins.get(name);
83
+ if (!plugin) {
84
+ throw new Error(`Plugin "${name}" is not loaded`);
85
+ }
86
+ // Check if any loaded plugins depend on this one
87
+ for (const [pluginName, pluginDef] of this.plugins.entries()) {
88
+ if (this.loaded.has(pluginName) && pluginDef.dependencies?.includes(name)) {
89
+ throw new Error(`Cannot unload plugin "${name}" - plugin "${pluginName}" depends on it`);
90
+ }
91
+ }
92
+ // Execute lifecycle hook
93
+ await plugin.onUnload?.();
94
+ // Clean up scope if exists
95
+ const scope = this.scopes.get(name);
96
+ if (scope) {
97
+ scope.cleanup();
98
+ this.scopes.delete(name);
99
+ }
100
+ // Remove from loaded set
101
+ this.loaded.delete(name);
102
+ this.plugins.delete(name);
103
+ }
104
+ /**
105
+ * Get the scope for a loaded plugin
106
+ * @param name The name of the plugin
107
+ * @returns The plugin scope or undefined
108
+ */
109
+ getScope(name) {
110
+ return this.scopes.get(name);
111
+ }
112
+ /**
113
+ * Check if a plugin is loaded
114
+ * @param name The name of the plugin
115
+ * @returns true if the plugin is loaded
116
+ */
117
+ isLoaded(name) {
118
+ return this.loaded.has(name);
119
+ }
120
+ /**
121
+ * Get a loaded plugin definition
122
+ * @param name The name of the plugin
123
+ * @returns The plugin definition or undefined
124
+ */
125
+ getPlugin(name) {
126
+ return this.plugins.get(name);
127
+ }
128
+ /**
129
+ * Get all loaded plugin names
130
+ * @returns Array of loaded plugin names
131
+ */
132
+ getLoadedPlugins() {
133
+ return Array.from(this.loaded);
134
+ }
135
+ /**
136
+ * Get all plugin definitions
137
+ * @returns Array of all plugin definitions
138
+ */
139
+ getAllPlugins() {
140
+ return Array.from(this.plugins.values());
141
+ }
142
+ }
@@ -5,7 +5,7 @@
5
5
  * This source code is licensed under the MIT license found in the
6
6
  * LICENSE file in the root directory of this source tree.
7
7
  */
8
- import type { SchemaNode } from '../types';
8
+ import type { SchemaNode } from '../types/index.js';
9
9
  export type ComponentRenderer<T = any> = T;
10
10
  export type ComponentInput = {
11
11
  name: string;
@@ -25,6 +25,17 @@ export type ComponentMeta = {
25
25
  label?: string;
26
26
  icon?: string;
27
27
  category?: string;
28
+ namespace?: string;
29
+ /**
30
+ * When true, prevents the component from being registered with a non-namespaced fallback.
31
+ * Use this when a component should only be accessible via its full namespaced key.
32
+ * This avoids conflicts with other components that share the same base name.
33
+ *
34
+ * @example
35
+ * // Register as 'view:form' only, don't overwrite 'form'
36
+ * registry.register('form', FormView, { namespace: 'view', skipFallback: true });
37
+ */
38
+ skipFallback?: boolean;
28
39
  inputs?: ComponentInput[];
29
40
  defaultProps?: Record<string, any>;
30
41
  defaultChildren?: SchemaNode[];
@@ -46,11 +57,79 @@ export type ComponentConfig<T = any> = ComponentMeta & {
46
57
  };
47
58
  export declare class Registry<T = any> {
48
59
  private components;
60
+ /**
61
+ * Register a component with optional namespace support.
62
+ * If namespace is provided in meta, the component will be registered as "namespace:type".
63
+ *
64
+ * @param type - Component type identifier
65
+ * @param component - Component renderer
66
+ * @param meta - Component metadata (including optional namespace)
67
+ *
68
+ * @example
69
+ * // Register with namespace
70
+ * registry.register('button', ButtonComponent, { namespace: 'ui' });
71
+ * // Accessible as 'ui:button' or 'button' (fallback)
72
+ *
73
+ * @example
74
+ * // Register without namespace (backward compatible)
75
+ * registry.register('button', ButtonComponent);
76
+ * // Accessible as 'button'
77
+ */
49
78
  register(type: string, component: ComponentRenderer<T>, meta?: ComponentMeta): void;
50
- get(type: string): ComponentRenderer<T> | undefined;
51
- getConfig(type: string): ComponentConfig<T> | undefined;
52
- has(type: string): boolean;
79
+ /**
80
+ * Get a component by type. Supports both namespaced and non-namespaced lookups.
81
+ *
82
+ * @param type - Component type (e.g., 'button' or 'ui:button')
83
+ * @param namespace - Optional namespace for lookup priority
84
+ * @returns Component renderer or undefined
85
+ *
86
+ * @example
87
+ * // Direct lookup
88
+ * registry.get('ui:button') // Gets ui:button
89
+ *
90
+ * @example
91
+ * // Fallback lookup
92
+ * registry.get('button') // Gets first registered button
93
+ *
94
+ * @example
95
+ * // Namespaced lookup with priority
96
+ * registry.get('button', 'ui') // Tries 'ui:button' first, then 'button'
97
+ */
98
+ get(type: string, namespace?: string): ComponentRenderer<T> | undefined;
99
+ /**
100
+ * Get component configuration by type with namespace support.
101
+ *
102
+ * @param type - Component type (e.g., 'button' or 'ui:button')
103
+ * @param namespace - Optional namespace for lookup priority
104
+ * @returns Component configuration or undefined
105
+ */
106
+ getConfig(type: string, namespace?: string): ComponentConfig<T> | undefined;
107
+ /**
108
+ * Check if a component type is registered.
109
+ *
110
+ * @param type - Component type (e.g., 'button' or 'ui:button')
111
+ * @param namespace - Optional namespace for lookup
112
+ * @returns True if component is registered
113
+ */
114
+ has(type: string, namespace?: string): boolean;
115
+ /**
116
+ * Get all registered component types.
117
+ *
118
+ * @returns Array of all component type identifiers
119
+ */
53
120
  getAllTypes(): string[];
121
+ /**
122
+ * Get all registered component configurations.
123
+ *
124
+ * @returns Array of all component configurations
125
+ */
54
126
  getAllConfigs(): ComponentConfig<T>[];
127
+ /**
128
+ * Get all components in a specific namespace.
129
+ *
130
+ * @param namespace - Namespace to filter by
131
+ * @returns Array of component configurations in the namespace
132
+ */
133
+ getNamespaceComponents(namespace: string): ComponentConfig<T>[];
55
134
  }
56
135
  export declare const ComponentRegistry: Registry<any>;
@@ -14,30 +14,136 @@ export class Registry {
14
14
  value: new Map()
15
15
  });
16
16
  }
17
+ /**
18
+ * Register a component with optional namespace support.
19
+ * If namespace is provided in meta, the component will be registered as "namespace:type".
20
+ *
21
+ * @param type - Component type identifier
22
+ * @param component - Component renderer
23
+ * @param meta - Component metadata (including optional namespace)
24
+ *
25
+ * @example
26
+ * // Register with namespace
27
+ * registry.register('button', ButtonComponent, { namespace: 'ui' });
28
+ * // Accessible as 'ui:button' or 'button' (fallback)
29
+ *
30
+ * @example
31
+ * // Register without namespace (backward compatible)
32
+ * registry.register('button', ButtonComponent);
33
+ * // Accessible as 'button'
34
+ */
17
35
  register(type, component, meta) {
18
- if (this.components.has(type)) {
19
- console.warn(`Component type "${type}" is already registered. Overwriting.`);
36
+ const fullType = meta?.namespace ? `${meta.namespace}:${type}` : type;
37
+ // Warn if registering without namespace (deprecated pattern)
38
+ if (!meta?.namespace) {
39
+ console.warn(`Registering component "${type}" without a namespace is deprecated. ` +
40
+ `Please provide a namespace in the meta parameter.`);
20
41
  }
21
- this.components.set(type, {
22
- type,
42
+ if (this.components.has(fullType)) {
43
+ // console.warn(`Component type "${fullType}" is already registered. Overwriting.`);
44
+ }
45
+ this.components.set(fullType, {
46
+ type: fullType,
23
47
  component,
24
48
  ...meta
25
49
  });
50
+ // Also register without namespace for backward compatibility
51
+ // This allows "button" to work even when registered as "ui:button"
52
+ // Note: If multiple namespaced components share the same short name,
53
+ // the last registration wins for non-namespaced lookups
54
+ // Skip this if skipFallback is true to avoid overwriting other components
55
+ if (meta?.namespace && !meta?.skipFallback) {
56
+ this.components.set(type, {
57
+ type: fullType, // Keep reference to namespaced type
58
+ component,
59
+ ...meta
60
+ });
61
+ }
26
62
  }
27
- get(type) {
63
+ /**
64
+ * Get a component by type. Supports both namespaced and non-namespaced lookups.
65
+ *
66
+ * @param type - Component type (e.g., 'button' or 'ui:button')
67
+ * @param namespace - Optional namespace for lookup priority
68
+ * @returns Component renderer or undefined
69
+ *
70
+ * @example
71
+ * // Direct lookup
72
+ * registry.get('ui:button') // Gets ui:button
73
+ *
74
+ * @example
75
+ * // Fallback lookup
76
+ * registry.get('button') // Gets first registered button
77
+ *
78
+ * @example
79
+ * // Namespaced lookup with priority
80
+ * registry.get('button', 'ui') // Tries 'ui:button' first, then 'button'
81
+ */
82
+ get(type, namespace) {
83
+ // If namespace is explicitly provided, ONLY look in that namespace (no fallback)
84
+ if (namespace) {
85
+ const namespacedType = `${namespace}:${type}`;
86
+ return this.components.get(namespacedType)?.component;
87
+ }
88
+ // When no namespace provided, use backward compatibility lookup
28
89
  return this.components.get(type)?.component;
29
90
  }
30
- getConfig(type) {
91
+ /**
92
+ * Get component configuration by type with namespace support.
93
+ *
94
+ * @param type - Component type (e.g., 'button' or 'ui:button')
95
+ * @param namespace - Optional namespace for lookup priority
96
+ * @returns Component configuration or undefined
97
+ */
98
+ getConfig(type, namespace) {
99
+ // If namespace is explicitly provided, ONLY look in that namespace (no fallback)
100
+ if (namespace) {
101
+ const namespacedType = `${namespace}:${type}`;
102
+ return this.components.get(namespacedType);
103
+ }
104
+ // When no namespace provided, use backward compatibility lookup
31
105
  return this.components.get(type);
32
106
  }
33
- has(type) {
107
+ /**
108
+ * Check if a component type is registered.
109
+ *
110
+ * @param type - Component type (e.g., 'button' or 'ui:button')
111
+ * @param namespace - Optional namespace for lookup
112
+ * @returns True if component is registered
113
+ */
114
+ has(type, namespace) {
115
+ // If namespace is explicitly provided, ONLY look in that namespace (no fallback)
116
+ if (namespace) {
117
+ const namespacedType = `${namespace}:${type}`;
118
+ return this.components.has(namespacedType);
119
+ }
120
+ // When no namespace provided, use backward compatibility lookup
34
121
  return this.components.has(type);
35
122
  }
123
+ /**
124
+ * Get all registered component types.
125
+ *
126
+ * @returns Array of all component type identifiers
127
+ */
36
128
  getAllTypes() {
37
129
  return Array.from(this.components.keys());
38
130
  }
131
+ /**
132
+ * Get all registered component configurations.
133
+ *
134
+ * @returns Array of all component configurations
135
+ */
39
136
  getAllConfigs() {
40
137
  return Array.from(this.components.values());
41
138
  }
139
+ /**
140
+ * Get all components in a specific namespace.
141
+ *
142
+ * @param namespace - Namespace to filter by
143
+ * @returns Array of component configurations in the namespace
144
+ */
145
+ getNamespaceComponents(namespace) {
146
+ return Array.from(this.components.values()).filter(config => config.namespace === namespace);
147
+ }
42
148
  }
43
149
  export const ComponentRegistry = new Registry();
@@ -0,0 +1,120 @@
1
+ /**
2
+ * ObjectUI
3
+ * Copyright (c) 2024-present ObjectStack Inc.
4
+ *
5
+ * This source code is licensed under the MIT license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ */
8
+ /**
9
+ * WidgetRegistry - Runtime widget management with auto-discovery.
10
+ *
11
+ * Provides registration, loading, and lookup of runtime widgets
12
+ * described by WidgetManifest objects. Widgets can be loaded from
13
+ * ES module URLs, provided inline, or resolved from the component registry.
14
+ *
15
+ * @module
16
+ */
17
+ import type { WidgetManifest, ResolvedWidget, WidgetRegistryListener } from '@object-ui/types';
18
+ import type { Registry } from './Registry.js';
19
+ /**
20
+ * Options for creating a WidgetRegistry instance.
21
+ */
22
+ export interface WidgetRegistryOptions {
23
+ /**
24
+ * Component registry to sync loaded widgets into.
25
+ * When a widget is loaded, its component is also registered here.
26
+ */
27
+ componentRegistry?: Registry;
28
+ }
29
+ /**
30
+ * WidgetRegistry manages runtime-loadable widgets described by manifests.
31
+ *
32
+ * @example
33
+ * ```ts
34
+ * const widgets = new WidgetRegistry({ componentRegistry: registry });
35
+ *
36
+ * widgets.register({
37
+ * name: 'custom-chart',
38
+ * version: '1.0.0',
39
+ * type: 'chart',
40
+ * label: 'Custom Chart',
41
+ * source: { type: 'module', url: '/widgets/chart.js' },
42
+ * });
43
+ *
44
+ * const resolved = await widgets.load('custom-chart');
45
+ * ```
46
+ */
47
+ export declare class WidgetRegistry {
48
+ private manifests;
49
+ private resolved;
50
+ private listeners;
51
+ private componentRegistry?;
52
+ constructor(options?: WidgetRegistryOptions);
53
+ /**
54
+ * Register a widget manifest.
55
+ * Does not load the widget; call `load()` to resolve it.
56
+ */
57
+ register(manifest: WidgetManifest): void;
58
+ /**
59
+ * Register multiple widget manifests at once.
60
+ */
61
+ registerAll(manifests: WidgetManifest[]): void;
62
+ /**
63
+ * Unregister a widget by name.
64
+ */
65
+ unregister(name: string): boolean;
66
+ /**
67
+ * Get a widget manifest by name.
68
+ */
69
+ getManifest(name: string): WidgetManifest | undefined;
70
+ /**
71
+ * Get all registered widget manifests.
72
+ */
73
+ getAllManifests(): WidgetManifest[];
74
+ /**
75
+ * Get manifests filtered by category.
76
+ */
77
+ getByCategory(category: string): WidgetManifest[];
78
+ /**
79
+ * Check if a widget is registered.
80
+ */
81
+ has(name: string): boolean;
82
+ /**
83
+ * Check if a widget has been loaded (resolved).
84
+ */
85
+ isLoaded(name: string): boolean;
86
+ /**
87
+ * Load (resolve) a widget by name.
88
+ * If already loaded, returns the cached resolved widget.
89
+ *
90
+ * @throws Error if the widget is not registered or fails to load.
91
+ */
92
+ load(name: string): Promise<ResolvedWidget>;
93
+ /**
94
+ * Load all registered widgets.
95
+ * Returns an array of results (settled promises).
96
+ */
97
+ loadAll(): Promise<Array<{
98
+ name: string;
99
+ result: ResolvedWidget | Error;
100
+ }>>;
101
+ /**
102
+ * Subscribe to widget registry events.
103
+ * @returns Unsubscribe function.
104
+ */
105
+ on(listener: WidgetRegistryListener): () => void;
106
+ /**
107
+ * Clear all registered and loaded widgets.
108
+ */
109
+ clear(): void;
110
+ /**
111
+ * Get registry statistics.
112
+ */
113
+ getStats(): {
114
+ registered: number;
115
+ loaded: number;
116
+ categories: string[];
117
+ };
118
+ private resolveComponent;
119
+ private emit;
120
+ }