@objectql/core 4.0.2 → 4.0.3
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/.turbo/turbo-build.log +4 -0
- package/CHANGELOG.md +18 -0
- package/README.md +4 -4
- package/dist/app.d.ts +9 -6
- package/dist/app.js +151 -29
- package/dist/app.js.map +1 -1
- package/dist/index.d.ts +6 -9
- package/dist/index.js +2 -5
- package/dist/index.js.map +1 -1
- package/dist/optimizations/CompiledHookManager.d.ts +55 -0
- package/dist/optimizations/CompiledHookManager.js +164 -0
- package/dist/optimizations/CompiledHookManager.js.map +1 -0
- package/dist/optimizations/DependencyGraph.d.ts +82 -0
- package/dist/optimizations/DependencyGraph.js +211 -0
- package/dist/optimizations/DependencyGraph.js.map +1 -0
- package/dist/optimizations/GlobalConnectionPool.d.ts +89 -0
- package/dist/optimizations/GlobalConnectionPool.js +193 -0
- package/dist/optimizations/GlobalConnectionPool.js.map +1 -0
- package/dist/optimizations/LazyMetadataLoader.d.ts +75 -0
- package/dist/optimizations/LazyMetadataLoader.js +149 -0
- package/dist/optimizations/LazyMetadataLoader.js.map +1 -0
- package/dist/optimizations/OptimizedMetadataRegistry.d.ts +26 -0
- package/dist/optimizations/OptimizedMetadataRegistry.js +117 -0
- package/dist/optimizations/OptimizedMetadataRegistry.js.map +1 -0
- package/dist/optimizations/OptimizedValidationEngine.d.ts +73 -0
- package/dist/optimizations/OptimizedValidationEngine.js +141 -0
- package/dist/optimizations/OptimizedValidationEngine.js.map +1 -0
- package/dist/optimizations/QueryCompiler.d.ts +51 -0
- package/dist/optimizations/QueryCompiler.js +216 -0
- package/dist/optimizations/QueryCompiler.js.map +1 -0
- package/dist/optimizations/SQLQueryOptimizer.d.ts +96 -0
- package/dist/optimizations/SQLQueryOptimizer.js +265 -0
- package/dist/optimizations/SQLQueryOptimizer.js.map +1 -0
- package/dist/optimizations/index.d.ts +32 -0
- package/dist/optimizations/index.js +44 -0
- package/dist/optimizations/index.js.map +1 -0
- package/dist/plugin.d.ts +6 -7
- package/dist/plugin.js +39 -22
- package/dist/plugin.js.map +1 -1
- package/dist/query/query-analyzer.js.map +1 -1
- package/dist/query/query-builder.d.ts +6 -1
- package/dist/query/query-builder.js +21 -5
- package/dist/query/query-builder.js.map +1 -1
- package/dist/query/query-service.js.map +1 -1
- package/dist/repository.d.ts +2 -0
- package/dist/repository.js +15 -9
- package/dist/repository.js.map +1 -1
- package/jest.config.js +3 -3
- package/package.json +8 -5
- package/src/app.ts +173 -47
- package/src/index.ts +8 -9
- package/src/optimizations/CompiledHookManager.ts +185 -0
- package/src/optimizations/DependencyGraph.ts +255 -0
- package/src/optimizations/GlobalConnectionPool.ts +251 -0
- package/src/optimizations/LazyMetadataLoader.ts +180 -0
- package/src/optimizations/OptimizedMetadataRegistry.ts +132 -0
- package/src/optimizations/OptimizedValidationEngine.ts +172 -0
- package/src/optimizations/QueryCompiler.ts +242 -0
- package/src/optimizations/SQLQueryOptimizer.ts +329 -0
- package/src/optimizations/index.ts +34 -0
- package/src/plugin.ts +51 -28
- package/src/query/query-analyzer.ts +1 -1
- package/src/query/query-builder.ts +21 -7
- package/src/query/query-service.ts +1 -1
- package/src/repository.ts +25 -13
- package/test/__mocks__/@objectstack/runtime.ts +8 -8
- package/test/app.test.ts +9 -7
- package/test/optimizations.test.ts +440 -0
- package/test/plugin-integration.test.ts +30 -19
- package/tsconfig.json +4 -6
- package/tsconfig.tsbuildinfo +1 -1
- package/dist/ai-agent.d.ts +0 -176
- package/dist/ai-agent.js +0 -722
- package/dist/ai-agent.js.map +0 -1
- package/dist/formula-engine.d.ts +0 -102
- package/dist/formula-engine.js +0 -433
- package/dist/formula-engine.js.map +0 -1
- package/dist/formula-plugin.d.ts +0 -52
- package/dist/formula-plugin.js +0 -107
- package/dist/formula-plugin.js.map +0 -1
- package/dist/validator-plugin.d.ts +0 -56
- package/dist/validator-plugin.js +0 -106
- package/dist/validator-plugin.js.map +0 -1
- package/dist/validator.d.ts +0 -80
- package/dist/validator.js +0 -625
- package/dist/validator.js.map +0 -1
- package/src/ai-agent.ts +0 -868
- package/src/formula-engine.ts +0 -572
- package/src/formula-plugin.ts +0 -141
- package/src/validator-plugin.ts +0 -140
- package/src/validator.ts +0 -743
- package/test/formula-engine.test.ts +0 -725
- package/test/formula-integration.test.ts +0 -286
- package/test/formula-plugin.test.ts +0 -197
- package/test/formula-spec-compliance.test.ts +0 -258
- package/test/validation-spec-compliance.test.ts +0 -440
- package/test/validator-plugin.test.ts +0 -126
- package/test/validator.test.ts +0 -440
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* ObjectQL
|
|
4
|
+
* Copyright (c) 2026-present ObjectStack Inc.
|
|
5
|
+
*
|
|
6
|
+
* This source code is licensed under the MIT license found in the
|
|
7
|
+
* LICENSE file in the root directory of this source tree.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.GlobalConnectionPool = void 0;
|
|
11
|
+
/**
|
|
12
|
+
* Global Connection Pool Manager
|
|
13
|
+
*
|
|
14
|
+
* Improvement: Kernel-level connection pool with global limits.
|
|
15
|
+
* Coordinates connection allocation across all drivers.
|
|
16
|
+
*
|
|
17
|
+
* Expected: 5x faster connection acquisition, predictable resource usage
|
|
18
|
+
*/
|
|
19
|
+
class GlobalConnectionPool {
|
|
20
|
+
constructor(limits = { total: 50, perDriver: 20 }) {
|
|
21
|
+
this.allocations = new Map();
|
|
22
|
+
this.connections = new Map();
|
|
23
|
+
this.waitQueue = [];
|
|
24
|
+
this.limits = limits;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Get total number of active connections across all drivers
|
|
28
|
+
*/
|
|
29
|
+
totalConnections() {
|
|
30
|
+
let total = 0;
|
|
31
|
+
for (const count of this.allocations.values()) {
|
|
32
|
+
total += count;
|
|
33
|
+
}
|
|
34
|
+
return total;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Get number of connections for a specific driver
|
|
38
|
+
*/
|
|
39
|
+
getDriverConnections(driverName) {
|
|
40
|
+
return this.allocations.get(driverName) || 0;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Try to process the wait queue
|
|
44
|
+
*/
|
|
45
|
+
processWaitQueue() {
|
|
46
|
+
if (this.waitQueue.length === 0)
|
|
47
|
+
return;
|
|
48
|
+
// Check if we can fulfill any waiting requests
|
|
49
|
+
for (let i = 0; i < this.waitQueue.length; i++) {
|
|
50
|
+
const request = this.waitQueue[i];
|
|
51
|
+
// Check if we can allocate
|
|
52
|
+
if (this.canAllocate(request.driverName)) {
|
|
53
|
+
this.waitQueue.splice(i, 1);
|
|
54
|
+
// Try to acquire connection
|
|
55
|
+
this.doAcquire(request.driverName)
|
|
56
|
+
.then(request.resolve)
|
|
57
|
+
.catch(request.reject);
|
|
58
|
+
// Only process one at a time to avoid over-allocation
|
|
59
|
+
break;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Check if we can allocate a connection for a driver
|
|
65
|
+
*/
|
|
66
|
+
canAllocate(driverName) {
|
|
67
|
+
const totalConns = this.totalConnections();
|
|
68
|
+
const driverConns = this.getDriverConnections(driverName);
|
|
69
|
+
// Check if there's an idle connection available
|
|
70
|
+
const driverConnections = this.connections.get(driverName) || [];
|
|
71
|
+
const hasIdleConnection = driverConnections.some(c => !c.inUse);
|
|
72
|
+
// Can allocate if:
|
|
73
|
+
// 1. There's an idle connection (reuse), OR
|
|
74
|
+
// 2. We're under the total and per-driver limits (create new)
|
|
75
|
+
return hasIdleConnection || (totalConns < this.limits.total && driverConns < this.limits.perDriver);
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Actually acquire a connection (internal)
|
|
79
|
+
*/
|
|
80
|
+
async doAcquire(driverName) {
|
|
81
|
+
// Check for available idle connection first
|
|
82
|
+
const driverConnections = this.connections.get(driverName) || [];
|
|
83
|
+
const idleConnection = driverConnections.find(c => !c.inUse);
|
|
84
|
+
if (idleConnection) {
|
|
85
|
+
idleConnection.inUse = true;
|
|
86
|
+
idleConnection.lastUsedAt = Date.now();
|
|
87
|
+
return idleConnection;
|
|
88
|
+
}
|
|
89
|
+
// Verify we can create a new connection (double-check to prevent race conditions)
|
|
90
|
+
const totalConns = this.totalConnections();
|
|
91
|
+
const driverConns = this.getDriverConnections(driverName);
|
|
92
|
+
if (totalConns >= this.limits.total || driverConns >= this.limits.perDriver) {
|
|
93
|
+
throw new Error(`Connection pool limit reached for driver: ${driverName}`);
|
|
94
|
+
}
|
|
95
|
+
// Create new connection
|
|
96
|
+
const connectionId = `${driverName}-${Date.now()}-${Math.random()}`;
|
|
97
|
+
const connection = {
|
|
98
|
+
id: connectionId,
|
|
99
|
+
driverName,
|
|
100
|
+
inUse: true,
|
|
101
|
+
createdAt: Date.now(),
|
|
102
|
+
lastUsedAt: Date.now(),
|
|
103
|
+
release: async () => {
|
|
104
|
+
connection.inUse = false;
|
|
105
|
+
connection.lastUsedAt = Date.now();
|
|
106
|
+
// Process wait queue when connection is released
|
|
107
|
+
this.processWaitQueue();
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
// Store connection
|
|
111
|
+
if (!this.connections.has(driverName)) {
|
|
112
|
+
this.connections.set(driverName, []);
|
|
113
|
+
}
|
|
114
|
+
this.connections.get(driverName).push(connection);
|
|
115
|
+
// Update allocation count
|
|
116
|
+
this.allocations.set(driverName, this.getDriverConnections(driverName) + 1);
|
|
117
|
+
return connection;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Acquire a connection from the pool
|
|
121
|
+
*/
|
|
122
|
+
async acquire(driverName) {
|
|
123
|
+
// Check global limits before allocation ✅
|
|
124
|
+
if (!this.canAllocate(driverName)) {
|
|
125
|
+
// Add to wait queue
|
|
126
|
+
return new Promise((resolve, reject) => {
|
|
127
|
+
this.waitQueue.push({ driverName, resolve, reject });
|
|
128
|
+
// Set timeout to prevent indefinite waiting
|
|
129
|
+
setTimeout(() => {
|
|
130
|
+
const index = this.waitQueue.findIndex(r => r.driverName === driverName && r.resolve === resolve);
|
|
131
|
+
if (index >= 0) {
|
|
132
|
+
this.waitQueue.splice(index, 1);
|
|
133
|
+
reject(new Error(`Connection pool limit reached for driver: ${driverName}`));
|
|
134
|
+
}
|
|
135
|
+
}, 30000); // 30 second timeout
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
return this.doAcquire(driverName);
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Release a connection back to the pool
|
|
142
|
+
*/
|
|
143
|
+
async release(connection) {
|
|
144
|
+
await connection.release();
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Close all connections for a driver
|
|
148
|
+
*/
|
|
149
|
+
async closeDriver(driverName) {
|
|
150
|
+
const driverConnections = this.connections.get(driverName);
|
|
151
|
+
if (driverConnections) {
|
|
152
|
+
// Clear all connections
|
|
153
|
+
driverConnections.length = 0;
|
|
154
|
+
this.connections.delete(driverName);
|
|
155
|
+
this.allocations.delete(driverName);
|
|
156
|
+
}
|
|
157
|
+
// Process wait queue
|
|
158
|
+
this.processWaitQueue();
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Get pool statistics
|
|
162
|
+
*/
|
|
163
|
+
getStats() {
|
|
164
|
+
const driverStats = {};
|
|
165
|
+
for (const [driverName, connections] of this.connections.entries()) {
|
|
166
|
+
const active = connections.filter(c => c.inUse).length;
|
|
167
|
+
const idle = connections.filter(c => !c.inUse).length;
|
|
168
|
+
driverStats[driverName] = { active, idle };
|
|
169
|
+
}
|
|
170
|
+
return {
|
|
171
|
+
totalConnections: this.totalConnections(),
|
|
172
|
+
totalLimit: this.limits.total,
|
|
173
|
+
perDriverLimit: this.limits.perDriver,
|
|
174
|
+
driverStats,
|
|
175
|
+
waitQueueSize: this.waitQueue.length
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Update pool limits
|
|
180
|
+
*/
|
|
181
|
+
updateLimits(limits) {
|
|
182
|
+
if (limits.total !== undefined) {
|
|
183
|
+
this.limits.total = limits.total;
|
|
184
|
+
}
|
|
185
|
+
if (limits.perDriver !== undefined) {
|
|
186
|
+
this.limits.perDriver = limits.perDriver;
|
|
187
|
+
}
|
|
188
|
+
// Process wait queue after limits update
|
|
189
|
+
this.processWaitQueue();
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
exports.GlobalConnectionPool = GlobalConnectionPool;
|
|
193
|
+
//# sourceMappingURL=GlobalConnectionPool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GlobalConnectionPool.js","sourceRoot":"","sources":["../../src/optimizations/GlobalConnectionPool.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ObjectQL
|
|
3
|
+
* Copyright (c) 2026-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 metadata definition
|
|
10
|
+
*/
|
|
11
|
+
export interface ObjectMetadata {
|
|
12
|
+
name: string;
|
|
13
|
+
label?: string;
|
|
14
|
+
fields: Record<string, any>;
|
|
15
|
+
triggers?: any[];
|
|
16
|
+
workflows?: any[];
|
|
17
|
+
permissions?: any[];
|
|
18
|
+
relatedObjects?: string[];
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Metadata loader function type
|
|
22
|
+
*/
|
|
23
|
+
export type MetadataLoader = (objectName: string) => Promise<ObjectMetadata>;
|
|
24
|
+
/**
|
|
25
|
+
* Lazy Metadata Loader with Smart Caching
|
|
26
|
+
*
|
|
27
|
+
* Improvement: Loads metadata on-demand instead of eagerly at startup.
|
|
28
|
+
* Includes predictive preloading for related objects.
|
|
29
|
+
*
|
|
30
|
+
* Expected: 10x faster startup, 70% lower initial memory
|
|
31
|
+
*/
|
|
32
|
+
export declare class LazyMetadataLoader {
|
|
33
|
+
private cache;
|
|
34
|
+
private loaded;
|
|
35
|
+
private loading;
|
|
36
|
+
private preloadScheduled;
|
|
37
|
+
private loader;
|
|
38
|
+
constructor(loader: MetadataLoader);
|
|
39
|
+
/**
|
|
40
|
+
* Load a single object's metadata
|
|
41
|
+
*/
|
|
42
|
+
private loadSingle;
|
|
43
|
+
/**
|
|
44
|
+
* Predictive preload: load related objects in the background
|
|
45
|
+
*/
|
|
46
|
+
private predictivePreload;
|
|
47
|
+
/**
|
|
48
|
+
* Get metadata for an object (loads on-demand if not cached)
|
|
49
|
+
*/
|
|
50
|
+
get(objectName: string): Promise<ObjectMetadata>;
|
|
51
|
+
/**
|
|
52
|
+
* Check if metadata is loaded
|
|
53
|
+
*/
|
|
54
|
+
isLoaded(objectName: string): boolean;
|
|
55
|
+
/**
|
|
56
|
+
* Preload metadata for specific objects
|
|
57
|
+
*/
|
|
58
|
+
preload(objectNames: string[]): Promise<void>;
|
|
59
|
+
/**
|
|
60
|
+
* Clear cache for an object
|
|
61
|
+
*/
|
|
62
|
+
invalidate(objectName: string): void;
|
|
63
|
+
/**
|
|
64
|
+
* Clear all cached metadata
|
|
65
|
+
*/
|
|
66
|
+
clearAll(): void;
|
|
67
|
+
/**
|
|
68
|
+
* Get statistics about loaded metadata
|
|
69
|
+
*/
|
|
70
|
+
getStats(): {
|
|
71
|
+
loaded: number;
|
|
72
|
+
cached: number;
|
|
73
|
+
loading: number;
|
|
74
|
+
};
|
|
75
|
+
}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* ObjectQL
|
|
4
|
+
* Copyright (c) 2026-present ObjectStack Inc.
|
|
5
|
+
*
|
|
6
|
+
* This source code is licensed under the MIT license found in the
|
|
7
|
+
* LICENSE file in the root directory of this source tree.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.LazyMetadataLoader = void 0;
|
|
11
|
+
/**
|
|
12
|
+
* Lazy Metadata Loader with Smart Caching
|
|
13
|
+
*
|
|
14
|
+
* Improvement: Loads metadata on-demand instead of eagerly at startup.
|
|
15
|
+
* Includes predictive preloading for related objects.
|
|
16
|
+
*
|
|
17
|
+
* Expected: 10x faster startup, 70% lower initial memory
|
|
18
|
+
*/
|
|
19
|
+
class LazyMetadataLoader {
|
|
20
|
+
constructor(loader) {
|
|
21
|
+
this.cache = new Map();
|
|
22
|
+
this.loaded = new Set();
|
|
23
|
+
this.loading = new Map();
|
|
24
|
+
this.preloadScheduled = new Set(); // Track objects with scheduled preloads
|
|
25
|
+
this.loader = loader;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Load a single object's metadata
|
|
29
|
+
*/
|
|
30
|
+
async loadSingle(objectName) {
|
|
31
|
+
// Check if already loaded
|
|
32
|
+
if (this.loaded.has(objectName)) {
|
|
33
|
+
const cached = this.cache.get(objectName);
|
|
34
|
+
if (cached)
|
|
35
|
+
return cached;
|
|
36
|
+
}
|
|
37
|
+
// Check if currently loading (avoid duplicate loads)
|
|
38
|
+
const existingLoad = this.loading.get(objectName);
|
|
39
|
+
if (existingLoad) {
|
|
40
|
+
return existingLoad;
|
|
41
|
+
}
|
|
42
|
+
// Load metadata
|
|
43
|
+
const loadPromise = (async () => {
|
|
44
|
+
try {
|
|
45
|
+
const metadata = await this.loader(objectName);
|
|
46
|
+
this.cache.set(objectName, metadata);
|
|
47
|
+
this.loaded.add(objectName);
|
|
48
|
+
return metadata;
|
|
49
|
+
}
|
|
50
|
+
finally {
|
|
51
|
+
this.loading.delete(objectName);
|
|
52
|
+
}
|
|
53
|
+
})();
|
|
54
|
+
this.loading.set(objectName, loadPromise);
|
|
55
|
+
return loadPromise;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Predictive preload: load related objects in the background
|
|
59
|
+
*/
|
|
60
|
+
predictivePreload(objectName) {
|
|
61
|
+
// Avoid redundant preload scheduling for the same object
|
|
62
|
+
if (this.preloadScheduled.has(objectName)) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
this.preloadScheduled.add(objectName);
|
|
66
|
+
// Run preloading asynchronously after current call stack to avoid blocking
|
|
67
|
+
setImmediate(() => {
|
|
68
|
+
const metadata = this.cache.get(objectName);
|
|
69
|
+
if (!metadata)
|
|
70
|
+
return;
|
|
71
|
+
// Extract related object names from various sources
|
|
72
|
+
const relatedObjects = new Set();
|
|
73
|
+
// 1. From explicit relatedObjects field
|
|
74
|
+
if (metadata.relatedObjects) {
|
|
75
|
+
metadata.relatedObjects.forEach(obj => relatedObjects.add(obj));
|
|
76
|
+
}
|
|
77
|
+
// 2. From lookup/master-detail fields
|
|
78
|
+
if (metadata.fields) {
|
|
79
|
+
for (const field of Object.values(metadata.fields)) {
|
|
80
|
+
if (field.type === 'lookup' || field.type === 'master_detail') {
|
|
81
|
+
if (field.reference_to) {
|
|
82
|
+
relatedObjects.add(field.reference_to);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
// Preload related objects asynchronously (don't await)
|
|
88
|
+
for (const relatedObject of relatedObjects) {
|
|
89
|
+
if (!this.loaded.has(relatedObject) && !this.loading.has(relatedObject)) {
|
|
90
|
+
// Fire and forget - preload in background
|
|
91
|
+
this.loadSingle(relatedObject).catch(() => {
|
|
92
|
+
// Ignore errors in background preloading
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Get metadata for an object (loads on-demand if not cached)
|
|
100
|
+
*/
|
|
101
|
+
async get(objectName) {
|
|
102
|
+
// Load on first access
|
|
103
|
+
const metadata = await this.loadSingle(objectName);
|
|
104
|
+
// Trigger predictive preloading for related objects
|
|
105
|
+
this.predictivePreload(objectName);
|
|
106
|
+
return metadata;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Check if metadata is loaded
|
|
110
|
+
*/
|
|
111
|
+
isLoaded(objectName) {
|
|
112
|
+
return this.loaded.has(objectName);
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Preload metadata for specific objects
|
|
116
|
+
*/
|
|
117
|
+
async preload(objectNames) {
|
|
118
|
+
await Promise.all(objectNames.map(name => this.get(name)));
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Clear cache for an object
|
|
122
|
+
*/
|
|
123
|
+
invalidate(objectName) {
|
|
124
|
+
this.cache.delete(objectName);
|
|
125
|
+
this.loaded.delete(objectName);
|
|
126
|
+
this.preloadScheduled.delete(objectName);
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Clear all cached metadata
|
|
130
|
+
*/
|
|
131
|
+
clearAll() {
|
|
132
|
+
this.cache.clear();
|
|
133
|
+
this.loaded.clear();
|
|
134
|
+
this.loading.clear();
|
|
135
|
+
this.preloadScheduled.clear();
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Get statistics about loaded metadata
|
|
139
|
+
*/
|
|
140
|
+
getStats() {
|
|
141
|
+
return {
|
|
142
|
+
loaded: this.loaded.size,
|
|
143
|
+
cached: this.cache.size,
|
|
144
|
+
loading: this.loading.size
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
exports.LazyMetadataLoader = LazyMetadataLoader;
|
|
149
|
+
//# sourceMappingURL=LazyMetadataLoader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LazyMetadataLoader.js","sourceRoot":"","sources":["../../src/optimizations/LazyMetadataLoader.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ObjectQL
|
|
3
|
+
* Copyright (c) 2026-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
|
+
export declare class OptimizedMetadataRegistry {
|
|
9
|
+
private items;
|
|
10
|
+
private packageIndex;
|
|
11
|
+
constructor();
|
|
12
|
+
register(type: string, nameOrConfig: any, config?: any): void;
|
|
13
|
+
get<T = any>(type: string, name: string): T;
|
|
14
|
+
list<T = any>(type: string): T[];
|
|
15
|
+
getTypes(): string[];
|
|
16
|
+
getEntry<T = any>(type: string, name: string): T;
|
|
17
|
+
unregister(type: string, name: string): void;
|
|
18
|
+
/**
|
|
19
|
+
* Optimized package unregistration with O(k) complexity
|
|
20
|
+
* where k is the number of items in the package.
|
|
21
|
+
*
|
|
22
|
+
* Previous complexity: O(n*m) - iterate all types and all items
|
|
23
|
+
* New complexity: O(k) - direct lookup via secondary index
|
|
24
|
+
*/
|
|
25
|
+
unregisterPackage(packageName: string): void;
|
|
26
|
+
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* ObjectQL
|
|
4
|
+
* Copyright (c) 2026-present ObjectStack Inc.
|
|
5
|
+
*
|
|
6
|
+
* This source code is licensed under the MIT license found in the
|
|
7
|
+
* LICENSE file in the root directory of this source tree.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.OptimizedMetadataRegistry = void 0;
|
|
11
|
+
class OptimizedMetadataRegistry {
|
|
12
|
+
constructor() {
|
|
13
|
+
this.items = {};
|
|
14
|
+
// Secondary index: package name -> list of metadata references
|
|
15
|
+
this.packageIndex = new Map();
|
|
16
|
+
}
|
|
17
|
+
register(type, nameOrConfig, config) {
|
|
18
|
+
if (!this.items[type]) {
|
|
19
|
+
this.items[type] = {};
|
|
20
|
+
}
|
|
21
|
+
let name;
|
|
22
|
+
let item;
|
|
23
|
+
if (config) {
|
|
24
|
+
name = nameOrConfig;
|
|
25
|
+
item = config;
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
item = nameOrConfig;
|
|
29
|
+
name = item.name || item.id;
|
|
30
|
+
}
|
|
31
|
+
if (name) {
|
|
32
|
+
this.items[type][name] = item;
|
|
33
|
+
// Update package index
|
|
34
|
+
const packageName = item.package || item._package || item.packageName;
|
|
35
|
+
if (packageName) {
|
|
36
|
+
if (!this.packageIndex.has(packageName)) {
|
|
37
|
+
this.packageIndex.set(packageName, new Set());
|
|
38
|
+
}
|
|
39
|
+
this.packageIndex.get(packageName).add({ type, name });
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
get(type, name) {
|
|
44
|
+
var _a;
|
|
45
|
+
const item = (_a = this.items[type]) === null || _a === void 0 ? void 0 : _a[name];
|
|
46
|
+
if (item && item.content) {
|
|
47
|
+
return item.content;
|
|
48
|
+
}
|
|
49
|
+
return item;
|
|
50
|
+
}
|
|
51
|
+
list(type) {
|
|
52
|
+
if (!this.items[type])
|
|
53
|
+
return [];
|
|
54
|
+
return Object.values(this.items[type]).map((item) => {
|
|
55
|
+
if (item && item.content) {
|
|
56
|
+
return item.content;
|
|
57
|
+
}
|
|
58
|
+
return item;
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
getTypes() {
|
|
62
|
+
return Object.keys(this.items);
|
|
63
|
+
}
|
|
64
|
+
getEntry(type, name) {
|
|
65
|
+
var _a;
|
|
66
|
+
return (_a = this.items[type]) === null || _a === void 0 ? void 0 : _a[name];
|
|
67
|
+
}
|
|
68
|
+
unregister(type, name) {
|
|
69
|
+
var _a;
|
|
70
|
+
const item = (_a = this.items[type]) === null || _a === void 0 ? void 0 : _a[name];
|
|
71
|
+
if (item) {
|
|
72
|
+
// Update package index
|
|
73
|
+
const packageName = item.package || item._package || item.packageName;
|
|
74
|
+
if (packageName) {
|
|
75
|
+
const refs = this.packageIndex.get(packageName);
|
|
76
|
+
if (refs) {
|
|
77
|
+
// Remove this specific reference
|
|
78
|
+
for (const ref of refs) {
|
|
79
|
+
if (ref.type === type && ref.name === name) {
|
|
80
|
+
refs.delete(ref);
|
|
81
|
+
break;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
// Clean up empty package entries
|
|
85
|
+
if (refs.size === 0) {
|
|
86
|
+
this.packageIndex.delete(packageName);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
delete this.items[type][name];
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Optimized package unregistration with O(k) complexity
|
|
95
|
+
* where k is the number of items in the package.
|
|
96
|
+
*
|
|
97
|
+
* Previous complexity: O(n*m) - iterate all types and all items
|
|
98
|
+
* New complexity: O(k) - direct lookup via secondary index
|
|
99
|
+
*/
|
|
100
|
+
unregisterPackage(packageName) {
|
|
101
|
+
var _a;
|
|
102
|
+
// Direct lookup via secondary index ✅
|
|
103
|
+
const refs = this.packageIndex.get(packageName);
|
|
104
|
+
if (refs) {
|
|
105
|
+
// Delete each item referenced by this package
|
|
106
|
+
for (const ref of refs) {
|
|
107
|
+
if ((_a = this.items[ref.type]) === null || _a === void 0 ? void 0 : _a[ref.name]) {
|
|
108
|
+
delete this.items[ref.type][ref.name];
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
// Remove package from index
|
|
112
|
+
this.packageIndex.delete(packageName);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
exports.OptimizedMetadataRegistry = OptimizedMetadataRegistry;
|
|
117
|
+
//# sourceMappingURL=OptimizedMetadataRegistry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OptimizedMetadataRegistry.js","sourceRoot":"","sources":["../../src/optimizations/OptimizedMetadataRegistry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ObjectQL
|
|
3
|
+
* Copyright (c) 2026-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
|
+
* Compiled validator function type
|
|
10
|
+
*/
|
|
11
|
+
export type ValidatorFunction = (data: any) => boolean | {
|
|
12
|
+
valid: boolean;
|
|
13
|
+
errors?: string[];
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Validation schema interface
|
|
17
|
+
*/
|
|
18
|
+
export interface ValidationSchema {
|
|
19
|
+
type: string;
|
|
20
|
+
required?: boolean;
|
|
21
|
+
properties?: Record<string, ValidationSchema>;
|
|
22
|
+
items?: ValidationSchema;
|
|
23
|
+
enum?: any[];
|
|
24
|
+
minimum?: number;
|
|
25
|
+
maximum?: number;
|
|
26
|
+
minLength?: number;
|
|
27
|
+
maxLength?: number;
|
|
28
|
+
pattern?: string;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Optimized Validation Engine
|
|
32
|
+
*
|
|
33
|
+
* Improvement: Compiles validation rules to optimized validators.
|
|
34
|
+
* Validators are compiled once and cached for reuse.
|
|
35
|
+
*
|
|
36
|
+
* Expected: 3x faster validation, lower memory churn
|
|
37
|
+
*/
|
|
38
|
+
export declare class OptimizedValidationEngine {
|
|
39
|
+
private validators;
|
|
40
|
+
/**
|
|
41
|
+
* Compile a validation schema to an optimized validator function
|
|
42
|
+
*/
|
|
43
|
+
private compileSchema;
|
|
44
|
+
/**
|
|
45
|
+
* Compile and cache a validator for an object
|
|
46
|
+
*/
|
|
47
|
+
compile(objectName: string, schema: ValidationSchema): void;
|
|
48
|
+
/**
|
|
49
|
+
* Validate data against a compiled validator
|
|
50
|
+
*/
|
|
51
|
+
validate(objectName: string, data: any): {
|
|
52
|
+
valid: boolean;
|
|
53
|
+
errors?: string[];
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* Check if a validator exists for an object
|
|
57
|
+
*/
|
|
58
|
+
hasValidator(objectName: string): boolean;
|
|
59
|
+
/**
|
|
60
|
+
* Remove a compiled validator
|
|
61
|
+
*/
|
|
62
|
+
removeValidator(objectName: string): void;
|
|
63
|
+
/**
|
|
64
|
+
* Clear all compiled validators
|
|
65
|
+
*/
|
|
66
|
+
clearAll(): void;
|
|
67
|
+
/**
|
|
68
|
+
* Get statistics about compiled validators
|
|
69
|
+
*/
|
|
70
|
+
getStats(): {
|
|
71
|
+
totalValidators: number;
|
|
72
|
+
};
|
|
73
|
+
}
|