@objectstack/core 0.9.0 → 0.9.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 +8 -0
- package/README.md +36 -0
- package/dist/logger.d.ts +1 -0
- package/dist/logger.d.ts.map +1 -1
- package/dist/logger.js +35 -11
- package/dist/security/plugin-signature-verifier.js +3 -3
- package/package.json +2 -2
- package/src/logger.ts +36 -11
- package/src/security/plugin-signature-verifier.ts +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# @objectstack/core
|
|
2
2
|
|
|
3
|
+
## 0.9.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Patch release for maintenance and stability improvements. All packages updated with unified versioning.
|
|
8
|
+
- Updated dependencies
|
|
9
|
+
- @objectstack/spec@0.9.1
|
|
10
|
+
|
|
3
11
|
## 0.8.2
|
|
4
12
|
|
|
5
13
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -82,6 +82,42 @@ const service = kernel.getService('my-service');
|
|
|
82
82
|
await kernel.shutdown();
|
|
83
83
|
```
|
|
84
84
|
|
|
85
|
+
## 🤖 AI Quick Reference
|
|
86
|
+
|
|
87
|
+
**For AI Agents:** This package implements a microkernel architecture. Key concepts:
|
|
88
|
+
|
|
89
|
+
1. **Plugin Lifecycle**: `init()` → `start()` → `destroy()`
|
|
90
|
+
2. **Service Registry**: Share functionality via `ctx.registerService(name, service)` and `ctx.getService(name)`
|
|
91
|
+
3. **Dependencies**: Declare plugin dependencies for automatic load ordering
|
|
92
|
+
4. **Hooks/Events**: Decouple plugins with `ctx.hook(event, handler)` and `ctx.trigger(event, ...args)`
|
|
93
|
+
5. **Logger**: Always use `ctx.logger` for consistent, structured logging
|
|
94
|
+
|
|
95
|
+
**Common Plugin Pattern:**
|
|
96
|
+
```typescript
|
|
97
|
+
const plugin: Plugin = {
|
|
98
|
+
name: 'my-plugin',
|
|
99
|
+
dependencies: ['other-plugin'], // Load after these plugins
|
|
100
|
+
|
|
101
|
+
async init(ctx: PluginContext) {
|
|
102
|
+
// Register services and hooks
|
|
103
|
+
const otherService = ctx.getService('other-service');
|
|
104
|
+
ctx.registerService('my-service', new MyService(otherService));
|
|
105
|
+
ctx.hook('data:created', async (data) => { /* ... */ });
|
|
106
|
+
},
|
|
107
|
+
|
|
108
|
+
async start(ctx: PluginContext) {
|
|
109
|
+
// Execute business logic
|
|
110
|
+
const service = ctx.getService('my-service');
|
|
111
|
+
await service.initialize();
|
|
112
|
+
},
|
|
113
|
+
|
|
114
|
+
async destroy() {
|
|
115
|
+
// Cleanup resources
|
|
116
|
+
await service.close();
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
```
|
|
120
|
+
|
|
85
121
|
## Configurable Logger
|
|
86
122
|
|
|
87
123
|
The logger uses **[Pino](https://github.com/pinojs/pino)** for Node.js environments (high-performance, low-overhead) and a simple console-based logger for browsers. It automatically detects the runtime environment.
|
package/dist/logger.d.ts
CHANGED
package/dist/logger.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAY,MAAM,0BAA0B,CAAC;AACvE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,6BAA6B,CAAC;AAE1D;;;;;;;;;;;;;;GAcG;AACH,qBAAa,YAAa,YAAW,MAAM;IACvC,OAAO,CAAC,MAAM,CAAkJ;IAChK,OAAO,CAAC,MAAM,CAAU;IACxB,OAAO,CAAC,UAAU,CAAC,CAAM;IACzB,OAAO,CAAC,YAAY,CAAC,CAAM;
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAY,MAAM,0BAA0B,CAAC;AACvE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,6BAA6B,CAAC;AAE1D;;;;;;;;;;;;;;GAcG;AACH,qBAAa,YAAa,YAAW,MAAM;IACvC,OAAO,CAAC,MAAM,CAAkJ;IAChK,OAAO,CAAC,MAAM,CAAU;IACxB,OAAO,CAAC,UAAU,CAAC,CAAM;IACzB,OAAO,CAAC,YAAY,CAAC,CAAM;IAC3B,OAAO,CAAC,OAAO,CAAC,CAAM;gBAEV,MAAM,GAAE,OAAO,CAAC,YAAY,CAAM;IAwB9C;;OAEG;IACH,OAAO,CAAC,cAAc;IAuGtB;;OAEG;IACH,OAAO,CAAC,eAAe;IAqBvB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAsCxB;;OAEG;IACH,OAAO,CAAC,UAAU;IAelB;;OAEG;IACH,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI;IAQxD,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI;IAQvD,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI;IAQvD,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI;IASvE,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI;IASvE;;;OAGG;IACH,KAAK,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,YAAY;IAYjD;;OAEG;IACH,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,YAAY;IAIzD;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ9B;;OAEG;IACH,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI;CAG7C;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,GAAG,YAAY,CAEzE"}
|
package/dist/logger.js
CHANGED
|
@@ -42,8 +42,12 @@ export class ObjectLogger {
|
|
|
42
42
|
if (!this.isNode)
|
|
43
43
|
return;
|
|
44
44
|
try {
|
|
45
|
-
//
|
|
46
|
-
|
|
45
|
+
// Create require function dynamically for Node.js (avoids bundling issues in browser)
|
|
46
|
+
// @ts-ignore - dynamic import of Node.js module
|
|
47
|
+
const { createRequire } = eval('require("module")');
|
|
48
|
+
this.require = createRequire(import.meta.url);
|
|
49
|
+
// Synchronous import for Pino using createRequire (works in ESM)
|
|
50
|
+
const pino = this.require('pino');
|
|
47
51
|
// Build Pino options
|
|
48
52
|
const pinoOptions = {
|
|
49
53
|
level: this.config.level,
|
|
@@ -60,15 +64,35 @@ export class ObjectLogger {
|
|
|
60
64
|
const targets = [];
|
|
61
65
|
// Console transport
|
|
62
66
|
if (this.config.format === 'pretty') {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
}
|
|
67
|
+
// Check if pino-pretty is available
|
|
68
|
+
let hasPretty = false;
|
|
69
|
+
try {
|
|
70
|
+
this.require.resolve('pino-pretty');
|
|
71
|
+
hasPretty = true;
|
|
72
|
+
}
|
|
73
|
+
catch (e) {
|
|
74
|
+
// ignore
|
|
75
|
+
}
|
|
76
|
+
if (hasPretty) {
|
|
77
|
+
targets.push({
|
|
78
|
+
target: 'pino-pretty',
|
|
79
|
+
options: {
|
|
80
|
+
colorize: true,
|
|
81
|
+
translateTime: 'SYS:standard',
|
|
82
|
+
ignore: 'pid,hostname'
|
|
83
|
+
},
|
|
84
|
+
level: this.config.level
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
console.warn('[Logger] pino-pretty not found. Install it for pretty logging: pnpm add -D pino-pretty');
|
|
89
|
+
// Fallback to text/simple
|
|
90
|
+
targets.push({
|
|
91
|
+
target: 'pino/file',
|
|
92
|
+
options: { destination: 1 },
|
|
93
|
+
level: this.config.level
|
|
94
|
+
});
|
|
95
|
+
}
|
|
72
96
|
}
|
|
73
97
|
else if (this.config.format === 'json') {
|
|
74
98
|
// JSON to stdout
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
let cryptoModule = null;
|
|
3
3
|
if (typeof globalThis.window === 'undefined') {
|
|
4
4
|
try {
|
|
5
|
-
// Dynamic import for Node.js crypto module
|
|
6
|
-
//
|
|
7
|
-
cryptoModule = require(
|
|
5
|
+
// Dynamic import for Node.js crypto module (using eval to avoid bundling issues)
|
|
6
|
+
// @ts-ignore - dynamic require for Node.js
|
|
7
|
+
cryptoModule = eval('require("crypto")');
|
|
8
8
|
}
|
|
9
9
|
catch {
|
|
10
10
|
// Crypto module not available (e.g., browser environment)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@objectstack/core",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.1",
|
|
4
4
|
"description": "Microkernel Core for ObjectStack",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"pino": "^8.17.0",
|
|
15
15
|
"pino-pretty": "^10.3.0",
|
|
16
16
|
"zod": "^4.3.6",
|
|
17
|
-
"@objectstack/spec": "0.9.
|
|
17
|
+
"@objectstack/spec": "0.9.1"
|
|
18
18
|
},
|
|
19
19
|
"peerDependencies": {
|
|
20
20
|
"pino": "^8.0.0"
|
package/src/logger.ts
CHANGED
|
@@ -21,6 +21,7 @@ export class ObjectLogger implements Logger {
|
|
|
21
21
|
private isNode: boolean;
|
|
22
22
|
private pinoLogger?: any; // Pino logger instance for Node.js
|
|
23
23
|
private pinoInstance?: any; // Base Pino instance for creating child loggers
|
|
24
|
+
private require?: any; // CommonJS require function for Node.js
|
|
24
25
|
|
|
25
26
|
constructor(config: Partial<LoggerConfig> = {}) {
|
|
26
27
|
// Detect runtime environment
|
|
@@ -53,8 +54,13 @@ export class ObjectLogger implements Logger {
|
|
|
53
54
|
if (!this.isNode) return;
|
|
54
55
|
|
|
55
56
|
try {
|
|
56
|
-
//
|
|
57
|
-
|
|
57
|
+
// Create require function dynamically for Node.js (avoids bundling issues in browser)
|
|
58
|
+
// @ts-ignore - dynamic import of Node.js module
|
|
59
|
+
const { createRequire } = eval('require("module")');
|
|
60
|
+
this.require = createRequire(import.meta.url);
|
|
61
|
+
|
|
62
|
+
// Synchronous import for Pino using createRequire (works in ESM)
|
|
63
|
+
const pino = this.require('pino');
|
|
58
64
|
|
|
59
65
|
// Build Pino options
|
|
60
66
|
const pinoOptions: any = {
|
|
@@ -75,15 +81,34 @@ export class ObjectLogger implements Logger {
|
|
|
75
81
|
|
|
76
82
|
// Console transport
|
|
77
83
|
if (this.config.format === 'pretty') {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
84
|
+
// Check if pino-pretty is available
|
|
85
|
+
let hasPretty = false;
|
|
86
|
+
try {
|
|
87
|
+
this.require.resolve('pino-pretty');
|
|
88
|
+
hasPretty = true;
|
|
89
|
+
} catch (e) {
|
|
90
|
+
// ignore
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (hasPretty) {
|
|
94
|
+
targets.push({
|
|
95
|
+
target: 'pino-pretty',
|
|
96
|
+
options: {
|
|
97
|
+
colorize: true,
|
|
98
|
+
translateTime: 'SYS:standard',
|
|
99
|
+
ignore: 'pid,hostname'
|
|
100
|
+
},
|
|
101
|
+
level: this.config.level
|
|
102
|
+
});
|
|
103
|
+
} else {
|
|
104
|
+
console.warn('[Logger] pino-pretty not found. Install it for pretty logging: pnpm add -D pino-pretty');
|
|
105
|
+
// Fallback to text/simple
|
|
106
|
+
targets.push({
|
|
107
|
+
target: 'pino/file',
|
|
108
|
+
options: { destination: 1 },
|
|
109
|
+
level: this.config.level
|
|
110
|
+
});
|
|
111
|
+
}
|
|
87
112
|
} else if (this.config.format === 'json') {
|
|
88
113
|
// JSON to stdout
|
|
89
114
|
targets.push({
|
|
@@ -5,9 +5,9 @@ import type { PluginMetadata } from '../plugin-loader.js';
|
|
|
5
5
|
let cryptoModule: typeof import('crypto') | null = null;
|
|
6
6
|
if (typeof (globalThis as any).window === 'undefined') {
|
|
7
7
|
try {
|
|
8
|
-
// Dynamic import for Node.js crypto module
|
|
9
|
-
//
|
|
10
|
-
cryptoModule = require(
|
|
8
|
+
// Dynamic import for Node.js crypto module (using eval to avoid bundling issues)
|
|
9
|
+
// @ts-ignore - dynamic require for Node.js
|
|
10
|
+
cryptoModule = eval('require("crypto")');
|
|
11
11
|
} catch {
|
|
12
12
|
// Crypto module not available (e.g., browser environment)
|
|
13
13
|
}
|