@object-ui/core 3.3.0 → 3.3.2

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 (101) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +20 -1
  3. package/dist/actions/ActionRunner.d.ts +9 -0
  4. package/dist/actions/ActionRunner.js +41 -4
  5. package/dist/adapters/ValueDataSource.js +3 -1
  6. package/dist/registry/Registry.d.ts +47 -0
  7. package/dist/registry/Registry.js +92 -0
  8. package/dist/utils/filter-converter.js +25 -5
  9. package/package.json +32 -8
  10. package/.turbo/turbo-build.log +0 -4
  11. package/src/__benchmarks__/core.bench.ts +0 -64
  12. package/src/__tests__/protocols/DndProtocol.test.ts +0 -186
  13. package/src/__tests__/protocols/KeyboardProtocol.test.ts +0 -177
  14. package/src/__tests__/protocols/NotificationProtocol.test.ts +0 -142
  15. package/src/__tests__/protocols/ResponsiveProtocol.test.ts +0 -176
  16. package/src/__tests__/protocols/SharingProtocol.test.ts +0 -188
  17. package/src/actions/ActionEngine.ts +0 -268
  18. package/src/actions/ActionRunner.ts +0 -717
  19. package/src/actions/TransactionManager.ts +0 -521
  20. package/src/actions/UndoManager.ts +0 -215
  21. package/src/actions/__tests__/ActionEngine.test.ts +0 -206
  22. package/src/actions/__tests__/ActionRunner.params.test.ts +0 -134
  23. package/src/actions/__tests__/ActionRunner.test.ts +0 -711
  24. package/src/actions/__tests__/TransactionManager.test.ts +0 -447
  25. package/src/actions/__tests__/UndoManager.test.ts +0 -320
  26. package/src/actions/index.ts +0 -12
  27. package/src/adapters/ApiDataSource.ts +0 -376
  28. package/src/adapters/README.md +0 -180
  29. package/src/adapters/ValueDataSource.ts +0 -459
  30. package/src/adapters/__tests__/ApiDataSource.test.ts +0 -418
  31. package/src/adapters/__tests__/ValueDataSource.test.ts +0 -571
  32. package/src/adapters/__tests__/resolveDataSource.test.ts +0 -144
  33. package/src/adapters/index.ts +0 -15
  34. package/src/adapters/resolveDataSource.ts +0 -79
  35. package/src/builder/__tests__/schema-builder.test.ts +0 -235
  36. package/src/builder/schema-builder.ts +0 -584
  37. package/src/data-scope/DataScopeManager.ts +0 -269
  38. package/src/data-scope/ViewDataProvider.ts +0 -282
  39. package/src/data-scope/__tests__/DataScopeManager.test.ts +0 -211
  40. package/src/data-scope/__tests__/ViewDataProvider.test.ts +0 -270
  41. package/src/data-scope/index.ts +0 -24
  42. package/src/errors/__tests__/errors.test.ts +0 -292
  43. package/src/errors/index.ts +0 -269
  44. package/src/evaluator/ExpressionCache.ts +0 -206
  45. package/src/evaluator/ExpressionContext.ts +0 -118
  46. package/src/evaluator/ExpressionEvaluator.ts +0 -315
  47. package/src/evaluator/FormulaFunctions.ts +0 -398
  48. package/src/evaluator/SafeExpressionParser.ts +0 -893
  49. package/src/evaluator/__tests__/ExpressionCache.test.ts +0 -135
  50. package/src/evaluator/__tests__/ExpressionContext.test.ts +0 -110
  51. package/src/evaluator/__tests__/ExpressionEvaluator.test.ts +0 -558
  52. package/src/evaluator/__tests__/FormulaFunctions.test.ts +0 -447
  53. package/src/evaluator/index.ts +0 -13
  54. package/src/index.ts +0 -38
  55. package/src/protocols/DndProtocol.ts +0 -168
  56. package/src/protocols/KeyboardProtocol.ts +0 -181
  57. package/src/protocols/NotificationProtocol.ts +0 -150
  58. package/src/protocols/ResponsiveProtocol.ts +0 -210
  59. package/src/protocols/SharingProtocol.ts +0 -185
  60. package/src/protocols/index.ts +0 -13
  61. package/src/query/__tests__/query-ast.test.ts +0 -211
  62. package/src/query/__tests__/window-functions.test.ts +0 -275
  63. package/src/query/index.ts +0 -7
  64. package/src/query/query-ast.ts +0 -341
  65. package/src/registry/PluginScopeImpl.ts +0 -259
  66. package/src/registry/PluginSystem.ts +0 -206
  67. package/src/registry/Registry.ts +0 -219
  68. package/src/registry/WidgetRegistry.ts +0 -316
  69. package/src/registry/__tests__/PluginSystem.test.ts +0 -309
  70. package/src/registry/__tests__/Registry.test.ts +0 -293
  71. package/src/registry/__tests__/WidgetRegistry.test.ts +0 -321
  72. package/src/registry/__tests__/plugin-scope-integration.test.ts +0 -283
  73. package/src/theme/ThemeEngine.ts +0 -530
  74. package/src/theme/__tests__/ThemeEngine.test.ts +0 -668
  75. package/src/theme/index.ts +0 -24
  76. package/src/types/index.ts +0 -21
  77. package/src/utils/__tests__/debug-collector.test.ts +0 -102
  78. package/src/utils/__tests__/debug.test.ts +0 -134
  79. package/src/utils/__tests__/expand-fields.test.ts +0 -120
  80. package/src/utils/__tests__/extract-records.test.ts +0 -50
  81. package/src/utils/__tests__/filter-converter.test.ts +0 -118
  82. package/src/utils/__tests__/merge-views-into-objects.test.ts +0 -110
  83. package/src/utils/__tests__/normalize-quick-filter.test.ts +0 -123
  84. package/src/utils/debug-collector.ts +0 -100
  85. package/src/utils/debug.ts +0 -148
  86. package/src/utils/expand-fields.ts +0 -76
  87. package/src/utils/extract-records.ts +0 -33
  88. package/src/utils/filter-converter.ts +0 -133
  89. package/src/utils/merge-views-into-objects.ts +0 -36
  90. package/src/utils/normalize-quick-filter.ts +0 -78
  91. package/src/validation/__tests__/object-validation-engine.test.ts +0 -567
  92. package/src/validation/__tests__/schema-validator.test.ts +0 -118
  93. package/src/validation/__tests__/validation-engine.test.ts +0 -102
  94. package/src/validation/index.ts +0 -10
  95. package/src/validation/schema-validator.ts +0 -344
  96. package/src/validation/validation-engine.ts +0 -528
  97. package/src/validation/validators/index.ts +0 -25
  98. package/src/validation/validators/object-validation-engine.ts +0 -722
  99. package/tsconfig.json +0 -15
  100. package/tsconfig.tsbuildinfo +0 -1
  101. package/vitest.config.ts +0 -2
@@ -1,283 +0,0 @@
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
- /**
10
- * Plugin Scope Integration Tests
11
- * Section 3.3: Test scoped plugin system to ensure isolation
12
- */
13
-
14
- import { describe, it, expect, beforeEach } from 'vitest';
15
- import { Registry } from '../Registry';
16
- import { PluginSystem } from '../PluginSystem';
17
- import type { PluginScope } from '@object-ui/types';
18
-
19
- describe('Plugin Scope Integration', () => {
20
- let registry: Registry;
21
- let pluginSystem: PluginSystem;
22
-
23
- beforeEach(() => {
24
- registry = new Registry();
25
- pluginSystem = new PluginSystem();
26
- });
27
-
28
- describe('Component Registration Isolation', () => {
29
- it('should isolate component registrations between plugins', async () => {
30
- const MockTableA = () => 'Table A';
31
- const MockTableB = () => 'Table B';
32
-
33
- const pluginA = {
34
- name: 'plugin-a',
35
- version: '1.0.0',
36
- register: (scope: PluginScope) => {
37
- scope.registerComponent('table', MockTableA);
38
- },
39
- };
40
-
41
- const pluginB = {
42
- name: 'plugin-b',
43
- version: '1.0.0',
44
- register: (scope: PluginScope) => {
45
- scope.registerComponent('table', MockTableB);
46
- },
47
- };
48
-
49
- await pluginSystem.loadPlugin(pluginA, registry, true);
50
- await pluginSystem.loadPlugin(pluginB, registry, true);
51
-
52
- // Both plugins should have their own namespaced component
53
- const tableA = registry.getConfig('plugin-a:table');
54
- const tableB = registry.getConfig('plugin-b:table');
55
-
56
- expect(tableA).toBeDefined();
57
- expect(tableB).toBeDefined();
58
- expect(tableA?.component).toBe(MockTableA);
59
- expect(tableB?.component).toBe(MockTableB);
60
- });
61
-
62
- it('should allow scoped component to access global components', async () => {
63
- const GlobalButton = () => 'Global Button';
64
- const MockGrid = () => 'Grid';
65
-
66
- // Register a global component
67
- registry.register('button', GlobalButton);
68
-
69
- const plugin = {
70
- name: 'plugin-grid',
71
- version: '1.0.0',
72
- register: (scope: PluginScope) => {
73
- scope.registerComponent('grid', MockGrid);
74
-
75
- // Plugin should be able to access global components
76
- const button = scope.getComponent('button');
77
- expect(button).toBe(GlobalButton);
78
- },
79
- };
80
-
81
- await pluginSystem.loadPlugin(plugin, registry, true);
82
- });
83
- });
84
-
85
- describe('State Management Isolation', () => {
86
- it('should isolate state between plugins', async () => {
87
- let stateA: any;
88
- let stateB: any;
89
-
90
- const pluginA = {
91
- name: 'plugin-a',
92
- version: '1.0.0',
93
- register: (scope: PluginScope) => {
94
- const [config, setConfig] = scope.useState('config', { theme: 'dark' });
95
- stateA = config;
96
- setConfig({ theme: 'light' });
97
- },
98
- };
99
-
100
- const pluginB = {
101
- name: 'plugin-b',
102
- version: '1.0.0',
103
- register: (scope: PluginScope) => {
104
- const [config, setConfig] = scope.useState('config', { theme: 'auto' });
105
- stateB = config;
106
- },
107
- };
108
-
109
- await pluginSystem.loadPlugin(pluginA, registry, true);
110
- await pluginSystem.loadPlugin(pluginB, registry, true);
111
-
112
- // State should be isolated
113
- const scopeA = pluginSystem.getScope('plugin-a');
114
- const scopeB = pluginSystem.getScope('plugin-b');
115
-
116
- expect(scopeA?.getState('config')).toEqual({ theme: 'light' });
117
- expect(scopeB?.getState('config')).toEqual({ theme: 'auto' });
118
- });
119
-
120
- it('should enforce state size limits', async () => {
121
- const plugin = {
122
- name: 'plugin-heavy',
123
- version: '1.0.0',
124
- scopeConfig: {
125
- maxStateSize: 100, // Very small limit for testing
126
- },
127
- register: (scope: PluginScope) => {
128
- // This should throw due to size limit
129
- expect(() => {
130
- scope.setState('largeData', {
131
- data: 'x'.repeat(1000), // Much larger than 100 bytes
132
- });
133
- }).toThrow(/exceeded maximum state size/);
134
- },
135
- };
136
-
137
- await pluginSystem.loadPlugin(plugin, registry, true);
138
- });
139
- });
140
-
141
- describe('Event Bus Isolation', () => {
142
- it('should isolate events between plugins', async () => {
143
- const eventsA: any[] = [];
144
- const eventsB: any[] = [];
145
-
146
- const pluginA = {
147
- name: 'plugin-a',
148
- version: '1.0.0',
149
- register: (scope: PluginScope) => {
150
- scope.on('data-updated', (data) => {
151
- eventsA.push(data);
152
- });
153
-
154
- scope.emit('data-updated', { source: 'A' });
155
- },
156
- };
157
-
158
- const pluginB = {
159
- name: 'plugin-b',
160
- version: '1.0.0',
161
- register: (scope: PluginScope) => {
162
- scope.on('data-updated', (data) => {
163
- eventsB.push(data);
164
- });
165
-
166
- scope.emit('data-updated', { source: 'B' });
167
- },
168
- };
169
-
170
- await pluginSystem.loadPlugin(pluginA, registry, true);
171
- await pluginSystem.loadPlugin(pluginB, registry, true);
172
-
173
- // Events should be isolated - plugin A should only see its own events
174
- expect(eventsA).toHaveLength(1);
175
- expect(eventsA[0]).toEqual({ source: 'A' });
176
-
177
- expect(eventsB).toHaveLength(1);
178
- expect(eventsB[0]).toEqual({ source: 'B' });
179
- });
180
-
181
- it('should support global events for cross-plugin communication', async () => {
182
- const globalEvents: any[] = [];
183
-
184
- const pluginA = {
185
- name: 'plugin-a',
186
- version: '1.0.0',
187
- register: (scope: PluginScope) => {
188
- scope.onGlobal('app-ready', (data) => {
189
- globalEvents.push({ plugin: 'A', data });
190
- });
191
- },
192
- };
193
-
194
- const pluginB = {
195
- name: 'plugin-b',
196
- version: '1.0.0',
197
- register: (scope: PluginScope) => {
198
- scope.onGlobal('app-ready', (data) => {
199
- globalEvents.push({ plugin: 'B', data });
200
- });
201
-
202
- // Emit global event
203
- scope.emitGlobal('app-ready', { status: 'ready' });
204
- },
205
- };
206
-
207
- await pluginSystem.loadPlugin(pluginA, registry, true);
208
- await pluginSystem.loadPlugin(pluginB, registry, true);
209
-
210
- // Both plugins should receive the global event
211
- expect(globalEvents).toHaveLength(2);
212
- expect(globalEvents[0]).toEqual({ plugin: 'A', data: { status: 'ready' } });
213
- expect(globalEvents[1]).toEqual({ plugin: 'B', data: { status: 'ready' } });
214
- });
215
- });
216
-
217
- describe('Plugin Lifecycle', () => {
218
- it('should cleanup plugin resources on unload', async () => {
219
- const plugin = {
220
- name: 'plugin-temp',
221
- version: '1.0.0',
222
- register: (scope: PluginScope) => {
223
- scope.setState('data', { value: 123 });
224
- scope.registerComponent('temp', () => 'Temp');
225
- },
226
- };
227
-
228
- await pluginSystem.loadPlugin(plugin, registry, true);
229
-
230
- const scope = pluginSystem.getScope('plugin-temp');
231
- expect(scope?.getState('data')).toEqual({ value: 123 });
232
-
233
- await pluginSystem.unloadPlugin('plugin-temp');
234
-
235
- // Scope should be cleaned up
236
- expect(pluginSystem.getScope('plugin-temp')).toBeUndefined();
237
- });
238
-
239
- it('should call lifecycle hooks', async () => {
240
- let loadCalled = false;
241
- let unloadCalled = false;
242
-
243
- const plugin = {
244
- name: 'plugin-lifecycle',
245
- version: '1.0.0',
246
- register: () => {},
247
- onLoad: async () => {
248
- loadCalled = true;
249
- },
250
- onUnload: async () => {
251
- unloadCalled = true;
252
- },
253
- };
254
-
255
- await pluginSystem.loadPlugin(plugin, registry, true);
256
- expect(loadCalled).toBe(true);
257
-
258
- await pluginSystem.unloadPlugin('plugin-lifecycle');
259
- expect(unloadCalled).toBe(true);
260
- });
261
- });
262
-
263
- describe('Legacy Compatibility', () => {
264
- it('should support legacy plugins without scopes', async () => {
265
- const MockComponent = () => 'Legacy';
266
-
267
- const legacyPlugin = {
268
- name: 'legacy-plugin',
269
- version: '1.0.0',
270
- register: (reg: Registry) => {
271
- reg.register('legacy', MockComponent);
272
- },
273
- };
274
-
275
- // Load without scope
276
- await pluginSystem.loadPlugin(legacyPlugin, registry, false);
277
-
278
- // Component should be registered directly
279
- const component = registry.getConfig('legacy');
280
- expect(component?.component).toBe(MockComponent);
281
- });
282
- });
283
- });