Skip to content

Commit 02368bb

Browse files
authored
Merge pull request #238 from objectstack-ai/copilot/fix-runtimeplugin-issues
2 parents 02c617e + ba06716 commit 02368bb

File tree

63 files changed

+2346
-856
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+2346
-856
lines changed
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
# RuntimePlugin Interface Implementation - Summary
2+
3+
## Issue
4+
The GraphQL, OData V4, and JSON-RPC protocol plugins were not formally implementing a standard `RuntimePlugin` interface, leading to architectural inconsistency issues.
5+
6+
## Solution
7+
We have successfully implemented the `RuntimePlugin` interface specification and updated all three protocol plugins to conform to it.
8+
9+
## Changes Made
10+
11+
### 1. RuntimePlugin Interface Definition (`@objectql/types`)
12+
13+
Created `/packages/foundation/types/src/plugin.ts` defining:
14+
15+
#### RuntimePlugin Interface
16+
```typescript
17+
export interface RuntimePlugin {
18+
name: string;
19+
version?: string;
20+
install?(ctx: RuntimeContext): void | Promise<void>;
21+
onStart?(ctx: RuntimeContext): void | Promise<void>;
22+
onStop?(ctx: RuntimeContext): void | Promise<void>;
23+
}
24+
```
25+
26+
#### RuntimeContext Interface
27+
```typescript
28+
export interface RuntimeContext {
29+
engine: any;
30+
getKernel?: () => any;
31+
}
32+
```
33+
34+
### 2. Protocol Plugin Updates
35+
36+
#### GraphQL Plugin (`@objectql/protocol-graphql`)
37+
- ✅ Implements `RuntimePlugin` interface
38+
- ✅ Removed dependency on `@objectstack/runtime`
39+
- ✅ Added helper methods for metadata and CRUD operations
40+
- ✅ Direct engine access via RuntimeContext
41+
42+
#### OData V4 Plugin (`@objectql/protocol-odata-v4`)
43+
- ✅ Implements `RuntimePlugin` interface
44+
- ✅ Removed dependency on `@objectstack/runtime`
45+
- ✅ Added helper methods for metadata and CRUD operations
46+
- ✅ Direct engine access via RuntimeContext
47+
48+
#### JSON-RPC Plugin (`@objectql/protocol-json-rpc`)
49+
- ✅ Implements `RuntimePlugin` interface
50+
- ✅ Removed dependency on `@objectstack/runtime`
51+
- ✅ Added helper methods for metadata and CRUD operations
52+
- ✅ Direct engine access via RuntimeContext
53+
54+
### 3. Package Dependencies
55+
56+
Updated all three plugin `package.json` files to:
57+
- Remove `@objectstack/runtime` dependency
58+
- Use only `@objectql/types` for interface definitions
59+
60+
### 4. Tests
61+
62+
Added comprehensive test suite in `/packages/foundation/types/test/plugin.test.ts`:
63+
- RuntimePlugin interface conformance tests
64+
- RuntimeContext functionality tests
65+
- Lifecycle hook execution order tests
66+
- Sync/async hook support tests
67+
68+
### 5. Documentation
69+
70+
Updated `/packages/protocols/README.md`:
71+
- Documented RuntimePlugin interface
72+
- Documented RuntimeContext
73+
- Updated plugin implementation pattern
74+
- Added Engine API documentation
75+
- Removed references to deprecated ObjectStackRuntimeProtocol
76+
77+
## Architecture Compliance
78+
79+
### ✅ Standard Lifecycle Hooks
80+
All plugins now implement:
81+
1. **install(ctx)** - Called during kernel initialization
82+
2. **onStart(ctx)** - Called when kernel starts
83+
3. **onStop(ctx)** - Called when kernel stops
84+
85+
### ✅ Consistent Interface
86+
All plugins implement the same `RuntimePlugin` interface from `@objectql/types`, ensuring:
87+
- Uniform plugin architecture
88+
- Predictable lifecycle management
89+
- Easy plugin discovery and validation
90+
- Type-safe plugin development
91+
92+
### ✅ Direct Engine Access
93+
Plugins no longer depend on a separate protocol bridge layer. Instead:
94+
- They access the kernel/engine directly via RuntimeContext
95+
- They implement their own helper methods for common operations
96+
- They maintain full control over their data access patterns
97+
98+
## Impact
99+
100+
### Architecture Consistency ✅
101+
- All protocol plugins follow the same interface
102+
- Clear lifecycle management
103+
- Consistent error handling
104+
105+
### Plugin Extensibility ✅
106+
- Easy to add new protocol plugins
107+
- Clear contract to implement
108+
- Type-safe development
109+
110+
### Maintenance Cost ✅
111+
- Reduced dependency on non-existent packages
112+
- Simpler architecture
113+
- Better testability
114+
115+
## Testing Results
116+
117+
- ✅ RuntimePlugin interface tests pass
118+
- ✅ Existing plugin lifecycle tests remain valid
119+
- ✅ No breaking changes to plugin APIs
120+
- ✅ TypeScript compilation successful (modulo external dependencies)
121+
122+
## Next Steps
123+
124+
The implementation is complete and ready for use. Protocol plugins can now be:
125+
1. Instantiated with their configuration
126+
2. Passed to the kernel/runtime
127+
3. Initialized via the install hook
128+
4. Started via the onStart hook
129+
5. Stopped via the onStop hook
130+
131+
All three plugins (GraphQL, OData V4, JSON-RPC) are now fully compliant with the ObjectStack RuntimePlugin specification.

examples/integrations/express-server/jest.config.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,18 @@ module.exports = {
1313
moduleNameMapper: {
1414
},
1515
transform: {
16-
'^.+\\.ts$': ['ts-jest', {
16+
'^.+\\.(t|j)sx?$': ['ts-jest', {
1717
isolatedModules: true,
18+
tsconfig: {
19+
esModuleInterop: true,
20+
allowSyntheticDefaultImports: true,
21+
allowJs: true,
22+
}
1823
}],
1924
},
25+
transformIgnorePatterns: [
26+
"/node_modules/(?!(@objectstack|.pnpm))"
27+
],
2028
collectCoverageFrom: [
2129
'src/**/*.ts',
2230
'!src/**/*.d.ts',

examples/protocols/multi-protocol-server/package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
"@objectql/protocol-graphql": "workspace:*",
1515
"@objectql/protocol-json-rpc": "workspace:*",
1616
"@objectql/protocol-odata-v4": "workspace:*",
17-
"@objectstack/runtime": "workspace:*",
1817
"@objectql/types": "workspace:*"
1918
},
2019
"devDependencies": {

examples/showcase/enterprise-erp/jest.config.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,18 @@ module.exports = {
1313
moduleNameMapper: {
1414
},
1515
transform: {
16-
'^.+\\.ts$': ['ts-jest', {
16+
'^.+\\.(t|j)sx?$': ['ts-jest', {
1717
isolatedModules: true,
18+
tsconfig: {
19+
esModuleInterop: true,
20+
allowSyntheticDefaultImports: true,
21+
allowJs: true,
22+
}
1823
}],
1924
},
25+
transformIgnorePatterns: [
26+
"/node_modules/(?!(@objectstack|.pnpm))"
27+
],
2028
collectCoverageFrom: [
2129
'src/**/*.ts',
2230
'!src/**/*.d.ts',

examples/showcase/enterprise-erp/package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@
4343
"@objectql/driver-sql": "workspace:*",
4444
"@objectql/platform-node": "workspace:*",
4545
"@objectql/types": "workspace:*",
46-
"@objectstack/spec": "workspace:*",
4746
"@types/jest": "^30.0.0",
4847
"@types/node": "^20.0.0",
4948
"jest": "^30.2.0",

examples/showcase/project-tracker/jest.config.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,18 @@ module.exports = {
1313
moduleNameMapper: {
1414
},
1515
transform: {
16-
'^.+\\.ts$': ['ts-jest', {
16+
'^.+\\.(t|j)sx?$': ['ts-jest', {
1717
isolatedModules: true,
18+
tsconfig: {
19+
esModuleInterop: true,
20+
allowSyntheticDefaultImports: true,
21+
allowJs: true,
22+
}
1823
}],
1924
},
25+
transformIgnorePatterns: [
26+
"/node_modules/(?!(@objectstack|.pnpm))"
27+
],
2028
collectCoverageFrom: [
2129
'src/**/*.ts',
2230
'!src/**/*.d.ts',

package.json

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,6 @@
2424
"@changesets/cli": "^2.29.8",
2525
"@objectql/example-enterprise-erp": "workspace:*",
2626
"@objectql/example-project-tracker": "workspace:*",
27-
"@objectstack/objectql": "workspace:*",
28-
"@objectstack/runtime": "workspace:*",
29-
"@objectstack/spec": "workspace:*",
3027
"@types/jest": "^30.0.0",
3128
"@types/js-yaml": "^4.0.9",
3229
"@types/node": "^20.10.0",

packages/drivers/excel/jest.config.js

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,14 @@ module.exports = {
1313
collectCoverageFrom: ['src/**/*.ts'],
1414
moduleNameMapper: {
1515
'^@objectql/types$': '<rootDir>/../../foundation/types/src',
16-
}
16+
},
17+
transform: {
18+
'^.+\\.ts$': ['ts-jest', {
19+
isolatedModules: true,
20+
tsconfig: {
21+
esModuleInterop: true,
22+
allowSyntheticDefaultImports: true,
23+
}
24+
}],
25+
},
1726
};

packages/drivers/excel/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
},
2222
"dependencies": {
2323
"@objectql/types": "workspace:*",
24-
"@objectstack/spec": "workspace:*",
24+
"@objectstack/spec": "^0.6.1",
2525
"exceljs": "^4.4.0"
2626
},
2727
"devDependencies": {

packages/drivers/fs/jest.config.js

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,14 @@ module.exports = {
1313
collectCoverageFrom: ['src/**/*.ts'],
1414
moduleNameMapper: {
1515
'^@objectql/types$': '<rootDir>/../../foundation/types/src',
16-
}
16+
},
17+
transform: {
18+
'^.+\\.ts$': ['ts-jest', {
19+
isolatedModules: true,
20+
tsconfig: {
21+
esModuleInterop: true,
22+
allowSyntheticDefaultImports: true,
23+
}
24+
}],
25+
},
1726
};

0 commit comments

Comments
 (0)