@object-ui/core 0.3.1 → 0.5.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 (68) hide show
  1. package/.turbo/turbo-build.log +4 -0
  2. package/dist/actions/index.d.ts +1 -1
  3. package/dist/actions/index.js +1 -1
  4. package/dist/evaluator/ExpressionCache.d.ts +101 -0
  5. package/dist/evaluator/ExpressionCache.js +135 -0
  6. package/dist/evaluator/ExpressionEvaluator.d.ts +20 -2
  7. package/dist/evaluator/ExpressionEvaluator.js +34 -14
  8. package/dist/evaluator/index.d.ts +3 -2
  9. package/dist/evaluator/index.js +3 -2
  10. package/dist/index.d.ts +10 -7
  11. package/dist/index.js +9 -7
  12. package/dist/query/index.d.ts +6 -0
  13. package/dist/query/index.js +6 -0
  14. package/dist/query/query-ast.d.ts +32 -0
  15. package/dist/query/query-ast.js +268 -0
  16. package/dist/registry/PluginScopeImpl.d.ts +80 -0
  17. package/dist/registry/PluginScopeImpl.js +243 -0
  18. package/dist/registry/PluginSystem.d.ts +66 -0
  19. package/dist/registry/PluginSystem.js +142 -0
  20. package/dist/registry/Registry.d.ts +73 -4
  21. package/dist/registry/Registry.js +112 -7
  22. package/dist/validation/index.d.ts +9 -0
  23. package/dist/validation/index.js +9 -0
  24. package/dist/validation/validation-engine.d.ts +70 -0
  25. package/dist/validation/validation-engine.js +363 -0
  26. package/dist/validation/validators/index.d.ts +16 -0
  27. package/dist/validation/validators/index.js +16 -0
  28. package/dist/validation/validators/object-validation-engine.d.ts +118 -0
  29. package/dist/validation/validators/object-validation-engine.js +538 -0
  30. package/package.json +13 -5
  31. package/src/actions/index.ts +1 -1
  32. package/src/evaluator/ExpressionCache.ts +192 -0
  33. package/src/evaluator/ExpressionEvaluator.ts +33 -14
  34. package/src/evaluator/__tests__/ExpressionCache.test.ts +135 -0
  35. package/src/evaluator/index.ts +3 -2
  36. package/src/index.ts +10 -7
  37. package/src/query/__tests__/query-ast.test.ts +211 -0
  38. package/src/query/__tests__/window-functions.test.ts +275 -0
  39. package/src/query/index.ts +7 -0
  40. package/src/query/query-ast.ts +341 -0
  41. package/src/registry/PluginScopeImpl.ts +259 -0
  42. package/src/registry/PluginSystem.ts +161 -0
  43. package/src/registry/Registry.ts +125 -8
  44. package/src/registry/__tests__/PluginSystem.test.ts +226 -0
  45. package/src/registry/__tests__/Registry.test.ts +293 -0
  46. package/src/registry/__tests__/plugin-scope-integration.test.ts +283 -0
  47. package/src/validation/__tests__/object-validation-engine.test.ts +567 -0
  48. package/src/validation/__tests__/validation-engine.test.ts +102 -0
  49. package/src/validation/index.ts +10 -0
  50. package/src/validation/validation-engine.ts +461 -0
  51. package/src/validation/validators/index.ts +25 -0
  52. package/src/validation/validators/object-validation-engine.ts +722 -0
  53. package/tsconfig.tsbuildinfo +1 -1
  54. package/vitest.config.ts +2 -0
  55. package/src/adapters/index.d.ts +0 -8
  56. package/src/adapters/index.js +0 -10
  57. package/src/builder/schema-builder.d.ts +0 -294
  58. package/src/builder/schema-builder.js +0 -503
  59. package/src/index.d.ts +0 -13
  60. package/src/index.js +0 -16
  61. package/src/registry/Registry.d.ts +0 -56
  62. package/src/registry/Registry.js +0 -43
  63. package/src/types/index.d.ts +0 -19
  64. package/src/types/index.js +0 -8
  65. package/src/utils/filter-converter.d.ts +0 -57
  66. package/src/utils/filter-converter.js +0 -100
  67. package/src/validation/schema-validator.d.ts +0 -94
  68. package/src/validation/schema-validator.js +0 -278
@@ -0,0 +1,268 @@
1
+ /**
2
+ * ObjectUI - Query AST Builder
3
+ * Phase 3.3: QuerySchema AST implementation
4
+ * ObjectStack Spec v0.7.1: Window functions support
5
+ */
6
+ /**
7
+ * Query AST Builder - Converts QuerySchema to AST
8
+ */
9
+ export class QueryASTBuilder {
10
+ build(query) {
11
+ const ast = {
12
+ select: this.buildSelect(query),
13
+ from: this.buildFrom(query),
14
+ };
15
+ if (query.filter) {
16
+ ast.where = this.buildWhere(query.filter);
17
+ }
18
+ if (query.joins && query.joins.length > 0) {
19
+ ast.joins = query.joins.map(join => this.buildJoin(join));
20
+ }
21
+ if (query.group_by && query.group_by.length > 0) {
22
+ ast.group_by = this.buildGroupBy(query.group_by);
23
+ }
24
+ if (query.sort && query.sort.length > 0) {
25
+ ast.order_by = this.buildOrderBy(query.sort);
26
+ }
27
+ if (query.limit !== undefined) {
28
+ ast.limit = this.buildLimit(query.limit);
29
+ }
30
+ if (query.offset !== undefined) {
31
+ ast.offset = this.buildOffset(query.offset);
32
+ }
33
+ return ast;
34
+ }
35
+ buildSelect(query) {
36
+ const fields = [];
37
+ if (query.fields && query.fields.length > 0) {
38
+ fields.push(...query.fields.map(field => this.buildField(field)));
39
+ }
40
+ else if (!query.aggregations || query.aggregations.length === 0) {
41
+ // Only add '*' if there are no aggregations
42
+ fields.push(this.buildField('*'));
43
+ }
44
+ if (query.aggregations && query.aggregations.length > 0) {
45
+ fields.push(...query.aggregations.map(agg => this.buildAggregation(agg)));
46
+ }
47
+ // Add window functions (ObjectStack Spec v0.7.1)
48
+ if (query.windows && query.windows.length > 0) {
49
+ fields.push(...query.windows.map(win => this.buildWindow(win)));
50
+ }
51
+ return {
52
+ type: 'select',
53
+ fields,
54
+ distinct: false,
55
+ };
56
+ }
57
+ buildFrom(query) {
58
+ return {
59
+ type: 'from',
60
+ table: query.object,
61
+ };
62
+ }
63
+ buildWhere(filter) {
64
+ return {
65
+ type: 'where',
66
+ condition: this.buildFilterCondition(filter),
67
+ };
68
+ }
69
+ buildFilterCondition(filter) {
70
+ const operator = filter.operator || 'and';
71
+ const operands = [];
72
+ if (filter.conditions && filter.conditions.length > 0) {
73
+ operands.push(...filter.conditions.map(cond => this.buildCondition(cond)));
74
+ }
75
+ if (filter.groups && filter.groups.length > 0) {
76
+ operands.push(...filter.groups.map(group => this.buildFilterCondition(group)));
77
+ }
78
+ return {
79
+ type: 'operator',
80
+ operator: operator,
81
+ operands,
82
+ };
83
+ }
84
+ buildCondition(condition) {
85
+ const field = this.buildField(condition.field);
86
+ // Map filter operators to comparison operators
87
+ const operatorMap = {
88
+ 'equals': '=',
89
+ 'not_equals': '!=',
90
+ 'greater_than': '>',
91
+ 'greater_than_or_equal': '>=',
92
+ 'less_than': '<',
93
+ 'less_than_or_equal': '<=',
94
+ 'contains': 'contains',
95
+ 'not_contains': 'contains',
96
+ 'starts_with': 'starts_with',
97
+ 'ends_with': 'ends_with',
98
+ 'like': 'like',
99
+ 'ilike': 'ilike',
100
+ 'in': 'in',
101
+ 'not_in': 'not_in',
102
+ 'is_null': 'is_null',
103
+ 'is_not_null': 'is_not_null',
104
+ 'between': 'between',
105
+ };
106
+ const operator = operatorMap[condition.operator] || '=';
107
+ // Handle special operators
108
+ if (operator === 'between' && condition.values && condition.values.length === 2) {
109
+ return {
110
+ type: 'operator',
111
+ operator: 'between',
112
+ operands: [
113
+ field,
114
+ this.buildLiteral(condition.values[0]),
115
+ this.buildLiteral(condition.values[1])
116
+ ],
117
+ };
118
+ }
119
+ if ((operator === 'in' || operator === 'not_in') && condition.values) {
120
+ return {
121
+ type: 'operator',
122
+ operator: operator,
123
+ operands: [field, ...condition.values.map(v => this.buildLiteral(v))],
124
+ };
125
+ }
126
+ if (operator === 'is_null' || operator === 'is_not_null') {
127
+ return {
128
+ type: 'operator',
129
+ operator: operator,
130
+ operands: [field],
131
+ };
132
+ }
133
+ // Standard binary operator
134
+ const value = this.buildLiteral(condition.value);
135
+ return {
136
+ type: 'operator',
137
+ operator: operator,
138
+ operands: [field, value],
139
+ };
140
+ }
141
+ buildJoin(join) {
142
+ const onCondition = {
143
+ type: 'operator',
144
+ operator: '=',
145
+ operands: [
146
+ this.buildField(join.on.local_field),
147
+ this.buildField(join.on.foreign_field, join.alias || join.object),
148
+ ],
149
+ };
150
+ return {
151
+ type: 'join',
152
+ join_type: join.type,
153
+ table: join.object,
154
+ alias: join.alias,
155
+ on: onCondition,
156
+ };
157
+ }
158
+ buildGroupBy(fields) {
159
+ return {
160
+ type: 'group_by',
161
+ fields: fields.map(field => this.buildField(field)),
162
+ };
163
+ }
164
+ buildOrderBy(sorts) {
165
+ return {
166
+ type: 'order_by',
167
+ fields: sorts.map(sort => ({
168
+ field: this.buildField(sort.field),
169
+ direction: sort.order,
170
+ })),
171
+ };
172
+ }
173
+ buildLimit(limit) {
174
+ return {
175
+ type: 'limit',
176
+ value: limit,
177
+ };
178
+ }
179
+ buildOffset(offset) {
180
+ return {
181
+ type: 'offset',
182
+ value: offset,
183
+ };
184
+ }
185
+ buildField(field, table) {
186
+ const parts = field.split('.');
187
+ if (parts.length === 2) {
188
+ return {
189
+ type: 'field',
190
+ table: parts[0],
191
+ name: parts[1],
192
+ };
193
+ }
194
+ return {
195
+ type: 'field',
196
+ table,
197
+ name: field,
198
+ };
199
+ }
200
+ buildLiteral(value) {
201
+ let dataType = 'string';
202
+ if (value === null || value === undefined) {
203
+ dataType = 'null';
204
+ }
205
+ else if (typeof value === 'number') {
206
+ dataType = 'number';
207
+ }
208
+ else if (typeof value === 'boolean') {
209
+ dataType = 'boolean';
210
+ }
211
+ else if (value instanceof Date) {
212
+ dataType = 'date';
213
+ }
214
+ return {
215
+ type: 'literal',
216
+ value,
217
+ data_type: dataType,
218
+ };
219
+ }
220
+ buildAggregation(agg) {
221
+ return {
222
+ type: 'aggregate',
223
+ function: agg.function,
224
+ field: agg.field ? this.buildField(agg.field) : undefined,
225
+ alias: agg.alias,
226
+ distinct: agg.distinct,
227
+ };
228
+ }
229
+ /**
230
+ * Build window function node (ObjectStack Spec v0.7.1)
231
+ */
232
+ buildWindow(config) {
233
+ const node = {
234
+ type: 'window',
235
+ function: config.function,
236
+ alias: config.alias,
237
+ };
238
+ if (config.field) {
239
+ node.field = this.buildField(config.field);
240
+ }
241
+ if (config.partitionBy && config.partitionBy.length > 0) {
242
+ node.partitionBy = config.partitionBy.map(field => this.buildField(field));
243
+ }
244
+ if (config.orderBy && config.orderBy.length > 0) {
245
+ node.orderBy = config.orderBy.map(sort => ({
246
+ field: this.buildField(sort.field),
247
+ direction: sort.direction,
248
+ }));
249
+ }
250
+ if (config.frame) {
251
+ node.frame = config.frame;
252
+ }
253
+ if (config.offset !== undefined) {
254
+ node.offset = config.offset;
255
+ }
256
+ if (config.defaultValue !== undefined) {
257
+ node.defaultValue = this.buildLiteral(config.defaultValue);
258
+ }
259
+ return node;
260
+ }
261
+ optimize(ast) {
262
+ return ast;
263
+ }
264
+ }
265
+ export const defaultQueryASTBuilder = new QueryASTBuilder();
266
+ export function buildQueryAST(query) {
267
+ return defaultQueryASTBuilder.build(query);
268
+ }
@@ -0,0 +1,80 @@
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
+ * @object-ui/core - Plugin Scope Implementation
10
+ *
11
+ * Section 3.3: Implementation of scoped plugin system to prevent conflicts.
12
+ * Provides isolated component registration, state management, and event bus.
13
+ *
14
+ * @module plugin-scope-impl
15
+ * @packageDocumentation
16
+ */
17
+ import type { PluginScope, PluginScopeConfig, PluginEventHandler } from '@object-ui/types';
18
+ import type { Registry } from './Registry.js';
19
+ /**
20
+ * Plugin Scope Implementation
21
+ *
22
+ * Provides isolated access to registry, state, and events for each plugin.
23
+ */
24
+ export declare class PluginScopeImpl implements PluginScope {
25
+ readonly name: string;
26
+ readonly version: string;
27
+ private registry;
28
+ private state;
29
+ private eventBus;
30
+ private config;
31
+ constructor(name: string, version: string, registry: Registry, config?: PluginScopeConfig);
32
+ /**
33
+ * Register a component in the scoped namespace
34
+ */
35
+ registerComponent(type: string, component: any, meta?: any): void;
36
+ /**
37
+ * Get a component from the scoped namespace
38
+ */
39
+ getComponent(type: string): any | undefined;
40
+ /**
41
+ * Scoped state management
42
+ */
43
+ useState<T>(key: string, initialValue: T): [T, (value: T | ((prev: T) => T)) => void];
44
+ /**
45
+ * Get scoped state value
46
+ */
47
+ getState<T>(key: string): T | undefined;
48
+ /**
49
+ * Set scoped state value
50
+ */
51
+ setState<T>(key: string, value: T): void;
52
+ /**
53
+ * Subscribe to scoped events
54
+ */
55
+ on(event: string, handler: PluginEventHandler): () => void;
56
+ /**
57
+ * Emit a scoped event
58
+ */
59
+ emit(event: string, data?: any): void;
60
+ /**
61
+ * Emit a global event
62
+ */
63
+ emitGlobal(event: string, data?: any): void;
64
+ /**
65
+ * Subscribe to global events
66
+ */
67
+ onGlobal(event: string, handler: PluginEventHandler): () => void;
68
+ /**
69
+ * Clean up all plugin resources
70
+ */
71
+ cleanup(): void;
72
+ /**
73
+ * Estimate total state size in bytes
74
+ */
75
+ private estimateStateSize;
76
+ /**
77
+ * Estimate size of a value in bytes
78
+ */
79
+ private estimateValueSize;
80
+ }
@@ -0,0 +1,243 @@
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
+ * Event Bus for scoped plugin events
10
+ */
11
+ class EventBus {
12
+ constructor() {
13
+ Object.defineProperty(this, "listeners", {
14
+ enumerable: true,
15
+ configurable: true,
16
+ writable: true,
17
+ value: new Map()
18
+ });
19
+ }
20
+ on(event, handler) {
21
+ if (!this.listeners.has(event)) {
22
+ this.listeners.set(event, new Set());
23
+ }
24
+ this.listeners.get(event).add(handler);
25
+ // Return unsubscribe function
26
+ return () => {
27
+ this.listeners.get(event)?.delete(handler);
28
+ if (this.listeners.get(event)?.size === 0) {
29
+ this.listeners.delete(event);
30
+ }
31
+ };
32
+ }
33
+ emit(event, data) {
34
+ const handlers = this.listeners.get(event);
35
+ if (handlers) {
36
+ handlers.forEach(handler => {
37
+ try {
38
+ handler(data);
39
+ }
40
+ catch (error) {
41
+ console.error(`Error in event handler for "${event}":`, error);
42
+ }
43
+ });
44
+ }
45
+ }
46
+ cleanup() {
47
+ this.listeners.clear();
48
+ }
49
+ }
50
+ /**
51
+ * Global event bus for cross-plugin communication
52
+ */
53
+ const globalEventBus = new EventBus();
54
+ /**
55
+ * Plugin Scope Implementation
56
+ *
57
+ * Provides isolated access to registry, state, and events for each plugin.
58
+ */
59
+ export class PluginScopeImpl {
60
+ constructor(name, version, registry, config) {
61
+ Object.defineProperty(this, "name", {
62
+ enumerable: true,
63
+ configurable: true,
64
+ writable: true,
65
+ value: void 0
66
+ });
67
+ Object.defineProperty(this, "version", {
68
+ enumerable: true,
69
+ configurable: true,
70
+ writable: true,
71
+ value: void 0
72
+ });
73
+ Object.defineProperty(this, "registry", {
74
+ enumerable: true,
75
+ configurable: true,
76
+ writable: true,
77
+ value: void 0
78
+ });
79
+ Object.defineProperty(this, "state", {
80
+ enumerable: true,
81
+ configurable: true,
82
+ writable: true,
83
+ value: new Map()
84
+ });
85
+ Object.defineProperty(this, "eventBus", {
86
+ enumerable: true,
87
+ configurable: true,
88
+ writable: true,
89
+ value: new EventBus()
90
+ });
91
+ Object.defineProperty(this, "config", {
92
+ enumerable: true,
93
+ configurable: true,
94
+ writable: true,
95
+ value: void 0
96
+ });
97
+ this.name = name;
98
+ this.version = version;
99
+ this.registry = registry;
100
+ this.config = {
101
+ enableStateIsolation: config?.enableStateIsolation ?? true,
102
+ enableEventIsolation: config?.enableEventIsolation ?? true,
103
+ allowGlobalEvents: config?.allowGlobalEvents ?? true,
104
+ maxStateSize: config?.maxStateSize ?? 5 * 1024 * 1024, // 5MB
105
+ };
106
+ }
107
+ /**
108
+ * Register a component in the scoped namespace
109
+ */
110
+ registerComponent(type, component, meta) {
111
+ // Components are registered as "pluginName:type"
112
+ const registryMeta = {
113
+ ...meta,
114
+ namespace: this.name,
115
+ };
116
+ this.registry.register(type, component, registryMeta);
117
+ }
118
+ /**
119
+ * Get a component from the scoped namespace
120
+ */
121
+ getComponent(type) {
122
+ // First try scoped lookup
123
+ const scoped = this.registry.get(`${this.name}:${type}`);
124
+ if (scoped) {
125
+ return scoped;
126
+ }
127
+ // Fall back to global lookup
128
+ return this.registry.get(type);
129
+ }
130
+ /**
131
+ * Scoped state management
132
+ */
133
+ useState(key, initialValue) {
134
+ if (!this.config.enableStateIsolation) {
135
+ throw new Error('State isolation is disabled for this plugin');
136
+ }
137
+ // Initialize state if not present
138
+ if (!this.state.has(key)) {
139
+ this.setState(key, initialValue);
140
+ }
141
+ const currentValue = this.getState(key) ?? initialValue;
142
+ const setValue = (value) => {
143
+ const newValue = typeof value === 'function'
144
+ ? value(this.getState(key) ?? initialValue)
145
+ : value;
146
+ this.setState(key, newValue);
147
+ };
148
+ return [currentValue, setValue];
149
+ }
150
+ /**
151
+ * Get scoped state value
152
+ */
153
+ getState(key) {
154
+ return this.state.get(key);
155
+ }
156
+ /**
157
+ * Set scoped state value
158
+ */
159
+ setState(key, value) {
160
+ if (!this.config.enableStateIsolation) {
161
+ throw new Error('State isolation is disabled for this plugin');
162
+ }
163
+ // Check state size limit
164
+ const stateSize = this.estimateStateSize();
165
+ const valueSize = this.estimateValueSize(value);
166
+ if (stateSize + valueSize > this.config.maxStateSize) {
167
+ throw new Error(`Plugin "${this.name}" exceeded maximum state size of ${this.config.maxStateSize} bytes`);
168
+ }
169
+ this.state.set(key, value);
170
+ }
171
+ /**
172
+ * Subscribe to scoped events
173
+ */
174
+ on(event, handler) {
175
+ if (!this.config.enableEventIsolation) {
176
+ // If isolation is disabled, use global event bus
177
+ return this.onGlobal(event, handler);
178
+ }
179
+ // Scoped event: prefix with plugin name
180
+ const scopedEvent = `${this.name}:${event}`;
181
+ return this.eventBus.on(scopedEvent, handler);
182
+ }
183
+ /**
184
+ * Emit a scoped event
185
+ */
186
+ emit(event, data) {
187
+ if (!this.config.enableEventIsolation) {
188
+ // If isolation is disabled, emit globally
189
+ this.emitGlobal(event, data);
190
+ return;
191
+ }
192
+ // Scoped event: prefix with plugin name
193
+ const scopedEvent = `${this.name}:${event}`;
194
+ this.eventBus.emit(scopedEvent, data);
195
+ }
196
+ /**
197
+ * Emit a global event
198
+ */
199
+ emitGlobal(event, data) {
200
+ if (!this.config.allowGlobalEvents) {
201
+ throw new Error('Global events are disabled for this plugin');
202
+ }
203
+ globalEventBus.emit(event, data);
204
+ }
205
+ /**
206
+ * Subscribe to global events
207
+ */
208
+ onGlobal(event, handler) {
209
+ if (!this.config.allowGlobalEvents) {
210
+ throw new Error('Global events are disabled for this plugin');
211
+ }
212
+ return globalEventBus.on(event, handler);
213
+ }
214
+ /**
215
+ * Clean up all plugin resources
216
+ */
217
+ cleanup() {
218
+ this.state.clear();
219
+ this.eventBus.cleanup();
220
+ }
221
+ /**
222
+ * Estimate total state size in bytes
223
+ */
224
+ estimateStateSize() {
225
+ let size = 0;
226
+ for (const value of this.state.values()) {
227
+ size += this.estimateValueSize(value);
228
+ }
229
+ return size;
230
+ }
231
+ /**
232
+ * Estimate size of a value in bytes
233
+ */
234
+ estimateValueSize(value) {
235
+ try {
236
+ return JSON.stringify(value).length * 2; // UTF-16 encoding
237
+ }
238
+ catch {
239
+ // If not serializable, use rough estimate
240
+ return 1024; // 1KB default
241
+ }
242
+ }
243
+ }
@@ -0,0 +1,66 @@
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 type { Registry } from './Registry.js';
9
+ import type { PluginScope, PluginScopeConfig } from '@object-ui/types';
10
+ export interface PluginDefinition {
11
+ name: string;
12
+ version: string;
13
+ dependencies?: string[];
14
+ peerDependencies?: string[];
15
+ register: (registry: Registry | PluginScope) => void;
16
+ onLoad?: () => void | Promise<void>;
17
+ onUnload?: () => void | Promise<void>;
18
+ scopeConfig?: PluginScopeConfig;
19
+ }
20
+ export declare class PluginSystem {
21
+ private plugins;
22
+ private loaded;
23
+ private scopes;
24
+ /**
25
+ * Load a plugin into the system with optional scope isolation
26
+ * @param plugin The plugin definition to load
27
+ * @param registry The component registry to use for registration
28
+ * @param useScope Whether to use scoped loading (default: true for better isolation)
29
+ * @throws Error if dependencies are missing
30
+ */
31
+ loadPlugin(plugin: PluginDefinition, registry: Registry, useScope?: boolean): Promise<void>;
32
+ /**
33
+ * Unload a plugin from the system
34
+ * @param name The name of the plugin to unload
35
+ * @throws Error if other plugins depend on this plugin
36
+ */
37
+ unloadPlugin(name: string): Promise<void>;
38
+ /**
39
+ * Get the scope for a loaded plugin
40
+ * @param name The name of the plugin
41
+ * @returns The plugin scope or undefined
42
+ */
43
+ getScope(name: string): PluginScope | undefined;
44
+ /**
45
+ * Check if a plugin is loaded
46
+ * @param name The name of the plugin
47
+ * @returns true if the plugin is loaded
48
+ */
49
+ isLoaded(name: string): boolean;
50
+ /**
51
+ * Get a loaded plugin definition
52
+ * @param name The name of the plugin
53
+ * @returns The plugin definition or undefined
54
+ */
55
+ getPlugin(name: string): PluginDefinition | undefined;
56
+ /**
57
+ * Get all loaded plugin names
58
+ * @returns Array of loaded plugin names
59
+ */
60
+ getLoadedPlugins(): string[];
61
+ /**
62
+ * Get all plugin definitions
63
+ * @returns Array of all plugin definitions
64
+ */
65
+ getAllPlugins(): PluginDefinition[];
66
+ }