@objectstack/core 0.6.1 → 0.7.1
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/CHANGELOG.md +7 -0
- package/ENHANCED_FEATURES.md +380 -0
- package/README.md +299 -12
- package/dist/contracts/data-engine.d.ts +39 -22
- package/dist/contracts/data-engine.d.ts.map +1 -1
- package/dist/contracts/logger.d.ts +63 -0
- package/dist/contracts/logger.d.ts.map +1 -0
- package/dist/contracts/logger.js +1 -0
- package/dist/enhanced-kernel.d.ts +103 -0
- package/dist/enhanced-kernel.d.ts.map +1 -0
- package/dist/enhanced-kernel.js +403 -0
- package/dist/enhanced-kernel.test.d.ts +2 -0
- package/dist/enhanced-kernel.test.d.ts.map +1 -0
- package/dist/enhanced-kernel.test.js +412 -0
- package/dist/index.d.ts +11 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -2
- package/dist/kernel-base.d.ts +84 -0
- package/dist/kernel-base.d.ts.map +1 -0
- package/dist/kernel-base.js +219 -0
- package/dist/kernel.d.ts +11 -18
- package/dist/kernel.d.ts.map +1 -1
- package/dist/kernel.js +43 -114
- package/dist/kernel.test.d.ts +2 -0
- package/dist/kernel.test.d.ts.map +1 -0
- package/dist/kernel.test.js +161 -0
- package/dist/logger.d.ts +70 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +268 -0
- package/dist/logger.test.d.ts +2 -0
- package/dist/logger.test.d.ts.map +1 -0
- package/dist/logger.test.js +92 -0
- package/dist/plugin-loader.d.ts +148 -0
- package/dist/plugin-loader.d.ts.map +1 -0
- package/dist/plugin-loader.js +287 -0
- package/dist/plugin-loader.test.d.ts +2 -0
- package/dist/plugin-loader.test.d.ts.map +1 -0
- package/dist/plugin-loader.test.js +339 -0
- package/dist/types.d.ts +2 -1
- package/dist/types.d.ts.map +1 -1
- package/examples/enhanced-kernel-example.ts +309 -0
- package/package.json +19 -4
- package/src/contracts/data-engine.ts +46 -24
- package/src/contracts/logger.ts +70 -0
- package/src/enhanced-kernel.test.ts +535 -0
- package/src/enhanced-kernel.ts +496 -0
- package/src/index.ts +23 -2
- package/src/kernel-base.ts +256 -0
- package/src/kernel.test.ts +200 -0
- package/src/kernel.ts +55 -129
- package/src/logger.test.ts +116 -0
- package/src/logger.ts +306 -0
- package/src/plugin-loader.test.ts +412 -0
- package/src/plugin-loader.ts +435 -0
- package/src/types.ts +2 -1
- package/vitest.config.ts +8 -0
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Enhanced ObjectKernel Example
|
|
3
|
+
*
|
|
4
|
+
* Demonstrates advanced plugin features:
|
|
5
|
+
* - Version compatibility
|
|
6
|
+
* - Service factories with lifecycle management
|
|
7
|
+
* - Plugin timeout control
|
|
8
|
+
* - Startup failure rollback
|
|
9
|
+
* - Health checks
|
|
10
|
+
* - Performance metrics
|
|
11
|
+
* - Graceful shutdown
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import {
|
|
15
|
+
EnhancedObjectKernel,
|
|
16
|
+
PluginMetadata,
|
|
17
|
+
ServiceLifecycle,
|
|
18
|
+
PluginContext
|
|
19
|
+
} from '../index.js';
|
|
20
|
+
|
|
21
|
+
// ============================================================================
|
|
22
|
+
// Example 1: Database Plugin with Health Checks
|
|
23
|
+
// ============================================================================
|
|
24
|
+
|
|
25
|
+
const databasePlugin: PluginMetadata = {
|
|
26
|
+
name: 'database',
|
|
27
|
+
version: '1.0.0',
|
|
28
|
+
startupTimeout: 10000, // 10 second timeout
|
|
29
|
+
|
|
30
|
+
async init(ctx: PluginContext) {
|
|
31
|
+
ctx.logger.info('Initializing database plugin');
|
|
32
|
+
|
|
33
|
+
// Register database service using factory
|
|
34
|
+
// This creates a singleton that's initialized once
|
|
35
|
+
const db = {
|
|
36
|
+
connected: false,
|
|
37
|
+
async connect() {
|
|
38
|
+
ctx.logger.info('Connecting to database...');
|
|
39
|
+
await new Promise(resolve => setTimeout(resolve, 100)); // Simulate connection
|
|
40
|
+
this.connected = true;
|
|
41
|
+
ctx.logger.info('Database connected');
|
|
42
|
+
},
|
|
43
|
+
async disconnect() {
|
|
44
|
+
ctx.logger.info('Disconnecting from database...');
|
|
45
|
+
this.connected = false;
|
|
46
|
+
},
|
|
47
|
+
async query(sql: string) {
|
|
48
|
+
if (!this.connected) {
|
|
49
|
+
throw new Error('Database not connected');
|
|
50
|
+
}
|
|
51
|
+
return { rows: [] };
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
ctx.registerService('db', db);
|
|
56
|
+
},
|
|
57
|
+
|
|
58
|
+
async start(ctx: PluginContext) {
|
|
59
|
+
const db = ctx.getService<any>('db');
|
|
60
|
+
await db.connect();
|
|
61
|
+
},
|
|
62
|
+
|
|
63
|
+
async destroy() {
|
|
64
|
+
// Cleanup on shutdown
|
|
65
|
+
console.log('Cleaning up database connection');
|
|
66
|
+
},
|
|
67
|
+
|
|
68
|
+
async healthCheck() {
|
|
69
|
+
// Health check returns status
|
|
70
|
+
return {
|
|
71
|
+
healthy: true,
|
|
72
|
+
message: 'Database is operational',
|
|
73
|
+
details: {
|
|
74
|
+
connections: 5,
|
|
75
|
+
responseTime: 45
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
// ============================================================================
|
|
82
|
+
// Example 2: API Plugin with Dependencies
|
|
83
|
+
// ============================================================================
|
|
84
|
+
|
|
85
|
+
const apiPlugin: PluginMetadata = {
|
|
86
|
+
name: 'api',
|
|
87
|
+
version: '2.1.0',
|
|
88
|
+
dependencies: ['database'], // Requires database plugin to be loaded first
|
|
89
|
+
|
|
90
|
+
async init(ctx: PluginContext) {
|
|
91
|
+
ctx.logger.info('Initializing API plugin');
|
|
92
|
+
|
|
93
|
+
// Access database service (guaranteed to exist due to dependencies)
|
|
94
|
+
const db = ctx.getService<any>('db');
|
|
95
|
+
|
|
96
|
+
const api = {
|
|
97
|
+
async getUsers() {
|
|
98
|
+
return await db.query('SELECT * FROM users');
|
|
99
|
+
},
|
|
100
|
+
async createUser(data: any) {
|
|
101
|
+
return await db.query('INSERT INTO users VALUES ...', data);
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
ctx.registerService('api', api);
|
|
106
|
+
},
|
|
107
|
+
|
|
108
|
+
async healthCheck() {
|
|
109
|
+
return {
|
|
110
|
+
healthy: true,
|
|
111
|
+
message: 'API is ready',
|
|
112
|
+
details: {
|
|
113
|
+
routes: 15,
|
|
114
|
+
activeRequests: 3
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
// ============================================================================
|
|
121
|
+
// Example 3: Cache Plugin with Scoped Services
|
|
122
|
+
// ============================================================================
|
|
123
|
+
|
|
124
|
+
const cachePlugin: PluginMetadata = {
|
|
125
|
+
name: 'cache',
|
|
126
|
+
version: '1.2.3',
|
|
127
|
+
|
|
128
|
+
async init(ctx: PluginContext) {
|
|
129
|
+
ctx.logger.info('Initializing cache plugin');
|
|
130
|
+
|
|
131
|
+
// Simple in-memory cache
|
|
132
|
+
const cache = new Map<string, any>();
|
|
133
|
+
|
|
134
|
+
ctx.registerService('cache', {
|
|
135
|
+
get(key: string) {
|
|
136
|
+
return cache.get(key);
|
|
137
|
+
},
|
|
138
|
+
set(key: string, value: any) {
|
|
139
|
+
cache.set(key, value);
|
|
140
|
+
},
|
|
141
|
+
clear() {
|
|
142
|
+
cache.clear();
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
},
|
|
146
|
+
|
|
147
|
+
async healthCheck() {
|
|
148
|
+
return {
|
|
149
|
+
healthy: true,
|
|
150
|
+
message: 'Cache is operational'
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
// ============================================================================
|
|
156
|
+
// Example 4: Using Service Factories
|
|
157
|
+
// ============================================================================
|
|
158
|
+
|
|
159
|
+
async function setupServiceFactories(kernel: EnhancedObjectKernel) {
|
|
160
|
+
// Singleton: Created once, shared across all requests
|
|
161
|
+
kernel.registerServiceFactory(
|
|
162
|
+
'logger-service',
|
|
163
|
+
(ctx) => {
|
|
164
|
+
return {
|
|
165
|
+
log: (message: string) => {
|
|
166
|
+
ctx.logger.info(message);
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
},
|
|
170
|
+
ServiceLifecycle.SINGLETON
|
|
171
|
+
);
|
|
172
|
+
|
|
173
|
+
// Transient: New instance on every request
|
|
174
|
+
kernel.registerServiceFactory(
|
|
175
|
+
'request-id',
|
|
176
|
+
() => {
|
|
177
|
+
return `req-${Date.now()}-${Math.random().toString(36).slice(2, 11)}`;
|
|
178
|
+
},
|
|
179
|
+
ServiceLifecycle.TRANSIENT
|
|
180
|
+
);
|
|
181
|
+
|
|
182
|
+
// Scoped: One instance per scope (e.g., per HTTP request)
|
|
183
|
+
kernel.registerServiceFactory(
|
|
184
|
+
'user-session',
|
|
185
|
+
() => {
|
|
186
|
+
return {
|
|
187
|
+
id: Math.random().toString(36),
|
|
188
|
+
data: new Map<string, any>()
|
|
189
|
+
};
|
|
190
|
+
},
|
|
191
|
+
ServiceLifecycle.SCOPED
|
|
192
|
+
);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// ============================================================================
|
|
196
|
+
// Main Application
|
|
197
|
+
// ============================================================================
|
|
198
|
+
|
|
199
|
+
async function main() {
|
|
200
|
+
console.log('🚀 Starting Enhanced ObjectKernel Example\n');
|
|
201
|
+
|
|
202
|
+
// Create enhanced kernel with configuration
|
|
203
|
+
const kernel = new EnhancedObjectKernel({
|
|
204
|
+
logger: {
|
|
205
|
+
level: 'info',
|
|
206
|
+
format: 'pretty'
|
|
207
|
+
},
|
|
208
|
+
defaultStartupTimeout: 30000, // 30 seconds
|
|
209
|
+
gracefulShutdown: true,
|
|
210
|
+
shutdownTimeout: 60000, // 60 seconds
|
|
211
|
+
rollbackOnFailure: true, // Rollback on failure
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
// Setup service factories
|
|
215
|
+
await setupServiceFactories(kernel);
|
|
216
|
+
|
|
217
|
+
// Register plugins
|
|
218
|
+
await kernel.use(databasePlugin);
|
|
219
|
+
await kernel.use(cachePlugin);
|
|
220
|
+
await kernel.use(apiPlugin);
|
|
221
|
+
|
|
222
|
+
console.log('📦 Plugins registered\n');
|
|
223
|
+
|
|
224
|
+
// Bootstrap kernel
|
|
225
|
+
console.log('⚡ Bootstrapping kernel...\n');
|
|
226
|
+
await kernel.bootstrap();
|
|
227
|
+
|
|
228
|
+
console.log('\n✅ Kernel started successfully!\n');
|
|
229
|
+
|
|
230
|
+
// Show plugin metrics
|
|
231
|
+
console.log('📊 Plugin Startup Metrics:');
|
|
232
|
+
const metrics = kernel.getPluginMetrics();
|
|
233
|
+
for (const [name, time] of metrics) {
|
|
234
|
+
console.log(` ${name}: ${time}ms`);
|
|
235
|
+
}
|
|
236
|
+
console.log('');
|
|
237
|
+
|
|
238
|
+
// Check plugin health
|
|
239
|
+
console.log('🏥 Plugin Health Status:');
|
|
240
|
+
const healthStatuses = await kernel.checkAllPluginsHealth();
|
|
241
|
+
for (const [name, health] of healthStatuses) {
|
|
242
|
+
const status = health.healthy ? '✅' : '❌';
|
|
243
|
+
console.log(` ${status} ${name}: ${health.message}`);
|
|
244
|
+
if (health.details) {
|
|
245
|
+
console.log(` Details:`, health.details);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
console.log('');
|
|
249
|
+
|
|
250
|
+
// Use services
|
|
251
|
+
console.log('🔧 Using services:');
|
|
252
|
+
const db = kernel.getService<any>('db');
|
|
253
|
+
console.log(' Database connected:', db.connected);
|
|
254
|
+
|
|
255
|
+
const cache = kernel.getService<any>('cache');
|
|
256
|
+
cache.set('user:1', { name: 'John Doe' });
|
|
257
|
+
console.log(' Cached user:', cache.get('user:1'));
|
|
258
|
+
|
|
259
|
+
const api = kernel.getService<any>('api');
|
|
260
|
+
console.log(' API ready:', !!api);
|
|
261
|
+
console.log('');
|
|
262
|
+
|
|
263
|
+
// Test service factories
|
|
264
|
+
console.log('🏭 Testing Service Factories:');
|
|
265
|
+
|
|
266
|
+
// Singleton - same instance
|
|
267
|
+
const logger1 = await kernel.getServiceAsync('logger-service');
|
|
268
|
+
const logger2 = await kernel.getServiceAsync('logger-service');
|
|
269
|
+
console.log(' Singleton test:', logger1 === logger2 ? 'PASS ✅' : 'FAIL ❌');
|
|
270
|
+
|
|
271
|
+
// Transient - different instances
|
|
272
|
+
const id1 = await kernel.getServiceAsync('request-id');
|
|
273
|
+
const id2 = await kernel.getServiceAsync('request-id');
|
|
274
|
+
console.log(' Transient test:', id1 !== id2 ? 'PASS ✅' : 'FAIL ❌');
|
|
275
|
+
console.log(' Generated IDs:', id1, 'and', id2);
|
|
276
|
+
|
|
277
|
+
// Scoped - same within scope, different across scopes
|
|
278
|
+
const session1a = await kernel.getServiceAsync('user-session', 'request-1');
|
|
279
|
+
const session1b = await kernel.getServiceAsync('user-session', 'request-1');
|
|
280
|
+
const session2 = await kernel.getServiceAsync('user-session', 'request-2');
|
|
281
|
+
console.log(' Scoped (same scope):', session1a === session1b ? 'PASS ✅' : 'FAIL ❌');
|
|
282
|
+
console.log(' Scoped (diff scope):', session1a !== session2 ? 'PASS ✅' : 'FAIL ❌');
|
|
283
|
+
console.log('');
|
|
284
|
+
|
|
285
|
+
// Register custom shutdown handler
|
|
286
|
+
kernel.onShutdown(async () => {
|
|
287
|
+
console.log('🧹 Running custom cleanup...');
|
|
288
|
+
});
|
|
289
|
+
|
|
290
|
+
// Simulate running for a bit
|
|
291
|
+
console.log('⏳ Running for 2 seconds...\n');
|
|
292
|
+
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
293
|
+
|
|
294
|
+
// Graceful shutdown
|
|
295
|
+
console.log('🛑 Initiating graceful shutdown...\n');
|
|
296
|
+
await kernel.shutdown();
|
|
297
|
+
|
|
298
|
+
console.log('\n✅ Shutdown complete!\n');
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
// Run the example
|
|
302
|
+
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
303
|
+
main().catch(error => {
|
|
304
|
+
console.error('❌ Error:', error);
|
|
305
|
+
process.exit(1);
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
export { main };
|
package/package.json
CHANGED
|
@@ -1,17 +1,32 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@objectstack/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.1",
|
|
4
4
|
"description": "Microkernel Core for ObjectStack",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
8
8
|
"devDependencies": {
|
|
9
|
-
"typescript": "^5.0.0"
|
|
9
|
+
"typescript": "^5.0.0",
|
|
10
|
+
"vitest": "^1.0.0",
|
|
11
|
+
"@types/node": "^20.0.0"
|
|
10
12
|
},
|
|
11
13
|
"dependencies": {
|
|
12
|
-
"
|
|
14
|
+
"pino": "^8.17.0",
|
|
15
|
+
"pino-pretty": "^10.3.0",
|
|
16
|
+
"zod": "^3.22.0",
|
|
17
|
+
"@objectstack/spec": "0.7.1"
|
|
18
|
+
},
|
|
19
|
+
"peerDependencies": {
|
|
20
|
+
"pino": "^8.0.0"
|
|
21
|
+
},
|
|
22
|
+
"peerDependenciesMeta": {
|
|
23
|
+
"pino": {
|
|
24
|
+
"optional": true
|
|
25
|
+
}
|
|
13
26
|
},
|
|
14
27
|
"scripts": {
|
|
15
|
-
"build": "tsc"
|
|
28
|
+
"build": "tsc",
|
|
29
|
+
"test": "vitest run",
|
|
30
|
+
"test:watch": "vitest"
|
|
16
31
|
}
|
|
17
32
|
}
|
|
@@ -1,5 +1,14 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import {
|
|
2
|
+
DataEngineQueryOptions,
|
|
3
|
+
DataEngineInsertOptions,
|
|
4
|
+
DataEngineUpdateOptions,
|
|
5
|
+
DataEngineDeleteOptions,
|
|
6
|
+
DataEngineAggregateOptions,
|
|
7
|
+
DataEngineCountOptions,
|
|
8
|
+
DataEngineRequest, // Added Request type for batch
|
|
9
|
+
QueryAST,
|
|
10
|
+
DriverOptions
|
|
11
|
+
} from '@objectstack/spec/data';
|
|
3
12
|
|
|
4
13
|
/**
|
|
5
14
|
* IDataEngine - Standard Data Engine Interface
|
|
@@ -7,32 +16,33 @@ import { DriverOptions } from '@objectstack/spec/system';
|
|
|
7
16
|
* Abstract interface for data persistence capabilities.
|
|
8
17
|
* Following the Dependency Inversion Principle - plugins depend on this interface,
|
|
9
18
|
* not on concrete database implementations.
|
|
19
|
+
*
|
|
20
|
+
* Aligned with 'src/data/data-engine.zod.ts' in @objectstack/spec.
|
|
10
21
|
*/
|
|
11
22
|
|
|
12
|
-
export interface DataEngineFilter {
|
|
13
|
-
[key: string]: any;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export interface DataEngineQueryOptions {
|
|
17
|
-
/** Filter conditions */
|
|
18
|
-
filter?: DataEngineFilter;
|
|
19
|
-
/** Fields to select */
|
|
20
|
-
select?: string[];
|
|
21
|
-
/** Sort order */
|
|
22
|
-
sort?: Record<string, 1 | -1 | 'asc' | 'desc'>;
|
|
23
|
-
/** Limit number of results */
|
|
24
|
-
limit?: number;
|
|
25
|
-
/** Skip number of results */
|
|
26
|
-
skip?: number;
|
|
27
|
-
/** Maximum number of results */
|
|
28
|
-
top?: number;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
23
|
export interface IDataEngine {
|
|
32
|
-
insert(objectName: string, data: any): Promise<any>;
|
|
33
24
|
find(objectName: string, query?: DataEngineQueryOptions): Promise<any[]>;
|
|
34
|
-
|
|
35
|
-
|
|
25
|
+
findOne(objectName: string, query?: DataEngineQueryOptions): Promise<any>;
|
|
26
|
+
insert(objectName: string, data: any | any[], options?: DataEngineInsertOptions): Promise<any>;
|
|
27
|
+
update(objectName: string, data: any, options?: DataEngineUpdateOptions): Promise<any>;
|
|
28
|
+
delete(objectName: string, options?: DataEngineDeleteOptions): Promise<any>;
|
|
29
|
+
count(objectName: string, query?: DataEngineCountOptions): Promise<number>;
|
|
30
|
+
aggregate(objectName: string, query: DataEngineAggregateOptions): Promise<any[]>;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Vector Search (AI/RAG)
|
|
34
|
+
*/
|
|
35
|
+
vectorFind?(objectName: string, vector: number[], options?: { filter?: any, limit?: number, select?: string[], threshold?: number }): Promise<any[]>;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Batch Operations (Transactional)
|
|
39
|
+
*/
|
|
40
|
+
batch?(requests: DataEngineRequest[], options?: { transaction?: boolean }): Promise<any[]>;
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Execute raw command (Escape hatch)
|
|
44
|
+
*/
|
|
45
|
+
execute?(command: any, options?: Record<string, any>): Promise<any>;
|
|
36
46
|
}
|
|
37
47
|
|
|
38
48
|
export interface DriverInterface {
|
|
@@ -47,6 +57,18 @@ export interface DriverInterface {
|
|
|
47
57
|
update(object: string, id: any, data: any, options?: DriverOptions): Promise<any>;
|
|
48
58
|
delete(object: string, id: any, options?: DriverOptions): Promise<any>;
|
|
49
59
|
|
|
60
|
+
/**
|
|
61
|
+
* Bulk & Batch Operations
|
|
62
|
+
*/
|
|
63
|
+
bulkCreate?(object: string, data: any[], options?: DriverOptions): Promise<any>;
|
|
64
|
+
updateMany?(object: string, query: QueryAST, data: any, options?: DriverOptions): Promise<any>;
|
|
65
|
+
deleteMany?(object: string, query: QueryAST, options?: DriverOptions): Promise<any>;
|
|
66
|
+
|
|
50
67
|
count?(object: string, query: QueryAST, options?: DriverOptions): Promise<number>;
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Raw Execution
|
|
71
|
+
*/
|
|
72
|
+
execute?(command: any, params?: any, options?: DriverOptions): Promise<any>;
|
|
51
73
|
}
|
|
52
74
|
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Logger Contract
|
|
3
|
+
*
|
|
4
|
+
* Defines the interface for logging in ObjectStack.
|
|
5
|
+
* Compatible with both browser console and structured logging systems.
|
|
6
|
+
*/
|
|
7
|
+
export interface Logger {
|
|
8
|
+
/**
|
|
9
|
+
* Log a debug message
|
|
10
|
+
* @param message - The message to log
|
|
11
|
+
* @param meta - Optional metadata to include
|
|
12
|
+
*/
|
|
13
|
+
debug(message: string, meta?: Record<string, any>): void;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Log an informational message
|
|
17
|
+
* @param message - The message to log
|
|
18
|
+
* @param meta - Optional metadata to include
|
|
19
|
+
*/
|
|
20
|
+
info(message: string, meta?: Record<string, any>): void;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Log a warning message
|
|
24
|
+
* @param message - The message to log
|
|
25
|
+
* @param meta - Optional metadata to include
|
|
26
|
+
*/
|
|
27
|
+
warn(message: string, meta?: Record<string, any>): void;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Log an error message
|
|
31
|
+
* @param message - The message to log
|
|
32
|
+
* @param error - Optional error object
|
|
33
|
+
* @param meta - Optional metadata to include
|
|
34
|
+
*/
|
|
35
|
+
error(message: string, error?: Error, meta?: Record<string, any>): void;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Log a fatal error message
|
|
39
|
+
* @param message - The message to log
|
|
40
|
+
* @param error - Optional error object
|
|
41
|
+
* @param meta - Optional metadata to include
|
|
42
|
+
*/
|
|
43
|
+
fatal?(message: string, error?: Error, meta?: Record<string, any>): void;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Create a child logger with additional context
|
|
47
|
+
* @param context - Context to add to all logs from this child
|
|
48
|
+
*/
|
|
49
|
+
child?(context: Record<string, any>): Logger;
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Set trace context for distributed tracing
|
|
53
|
+
* @param traceId - Trace identifier
|
|
54
|
+
* @param spanId - Span identifier
|
|
55
|
+
*/
|
|
56
|
+
withTrace?(traceId: string, spanId?: string): Logger;
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Compatibility method for console.log usage
|
|
60
|
+
* @param message - The message to log
|
|
61
|
+
* @param args - Additional arguments
|
|
62
|
+
*/
|
|
63
|
+
log?(message: string, ...args: any[]): void;
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Cleanup resources (close file streams, etc.)
|
|
67
|
+
* Should be called when the logger is no longer needed
|
|
68
|
+
*/
|
|
69
|
+
destroy?(): Promise<void>;
|
|
70
|
+
}
|