|
| 1 | +# Driver Plugin Protocol Implementation |
| 2 | + |
| 3 | +## Summary |
| 4 | + |
| 5 | +This PR implements the @objectstack/spec plugin protocol for all ObjectQL drivers, transforming each driver into a plugin-compatible format while maintaining backward compatibility. |
| 6 | + |
| 7 | +## Changes Made |
| 8 | + |
| 9 | +### 1. Core Infrastructure |
| 10 | + |
| 11 | +#### Added `registerDatasource` Method |
| 12 | +- **File**: `packages/foundation/types/src/app.ts` |
| 13 | +- **Change**: Added `registerDatasource(name: string, driver: Driver): void` to `IObjectQL` interface |
| 14 | +- **Purpose**: Allows plugins to dynamically register datasources during the setup phase |
| 15 | + |
| 16 | +#### Implemented in ObjectQL Class |
| 17 | +- **File**: `packages/foundation/core/src/app.ts` |
| 18 | +- **Change**: Implemented `registerDatasource` method that adds drivers to the datasources registry |
| 19 | +- **Purpose**: Provides the runtime implementation for dynamic datasource registration |
| 20 | + |
| 21 | +### 2. Driver Plugin Wrappers |
| 22 | + |
| 23 | +Created plugin factory functions for all 8 drivers following the pattern: |
| 24 | + |
| 25 | +```typescript |
| 26 | +export function create{Driver}Plugin(options: { |
| 27 | + name: string; |
| 28 | + config: DriverConfig; |
| 29 | +}): ObjectQLPlugin; |
| 30 | +``` |
| 31 | + |
| 32 | +#### Drivers Updated: |
| 33 | + |
| 34 | +1. **SQL Driver** (`packages/drivers/sql/src/index.ts`) |
| 35 | + - Export: `createSqlDriverPlugin` |
| 36 | + - Supports: PostgreSQL, MySQL, SQLite, etc. |
| 37 | + |
| 38 | +2. **MongoDB Driver** (`packages/drivers/mongo/src/index.ts`) |
| 39 | + - Export: `createMongoDriverPlugin` |
| 40 | + - Supports: MongoDB with native driver |
| 41 | + |
| 42 | +3. **Memory Driver** (`packages/drivers/memory/src/index.ts`) |
| 43 | + - Export: `createMemoryDriverPlugin` |
| 44 | + - Supports: In-memory storage with full query capabilities |
| 45 | + |
| 46 | +4. **Redis Driver** (`packages/drivers/redis/src/index.ts`) |
| 47 | + - Export: `createRedisDriverPlugin` |
| 48 | + - Supports: Redis key-value store |
| 49 | + |
| 50 | +5. **LocalStorage Driver** (`packages/drivers/localstorage/src/index.ts`) |
| 51 | + - Export: `createLocalStorageDriverPlugin` |
| 52 | + - Supports: Browser localStorage persistence |
| 53 | + |
| 54 | +6. **FileSystem Driver** (`packages/drivers/fs/src/index.ts`) |
| 55 | + - Export: `createFileSystemDriverPlugin` |
| 56 | + - Supports: JSON file-based storage |
| 57 | + |
| 58 | +7. **SDK Driver** (`packages/drivers/sdk/src/index.ts`) |
| 59 | + - Export: `createSdkDriverPlugin` |
| 60 | + - Supports: Remote ObjectQL API via HTTP |
| 61 | + |
| 62 | +8. **Excel Driver** (`packages/drivers/excel/src/index.ts`) |
| 63 | + - Export: `createExcelDriverPlugin` |
| 64 | + - Supports: Excel (.xlsx) file storage |
| 65 | + |
| 66 | +### 3. Documentation |
| 67 | + |
| 68 | +#### Plugin Protocol Guide |
| 69 | +- **File**: `packages/drivers/PLUGIN_PROTOCOL.md` |
| 70 | +- **Content**: |
| 71 | + - Overview of the plugin protocol |
| 72 | + - Usage examples for all 8 drivers |
| 73 | + - Migration guide from old to new approach |
| 74 | + - Multi-datasource configuration examples |
| 75 | + - Benefits and best practices |
| 76 | + |
| 77 | +#### Driver README Updates |
| 78 | +- **Files**: |
| 79 | + - `packages/drivers/sql/README.md` |
| 80 | + - `packages/drivers/memory/README.md` |
| 81 | +- **Content**: Added plugin-based usage examples as the recommended approach |
| 82 | + |
| 83 | +#### Example Implementation |
| 84 | +- **File**: `examples/quickstart/hello-world/src/index-plugin.ts` |
| 85 | +- **Purpose**: Demonstrates the plugin-based approach in action |
| 86 | + |
| 87 | +## Architecture |
| 88 | + |
| 89 | +### Plugin Protocol Flow |
| 90 | + |
| 91 | +``` |
| 92 | +┌─────────────────────────────────────────────────┐ |
| 93 | +│ ObjectQL Configuration │ |
| 94 | +│ │ |
| 95 | +│ plugins: [ │ |
| 96 | +│ createSqlDriverPlugin({ │ |
| 97 | +│ name: 'default', │ |
| 98 | +│ config: { ... } │ |
| 99 | +│ }) │ |
| 100 | +│ ] │ |
| 101 | +└───────────────┬─────────────────────────────────┘ |
| 102 | + │ |
| 103 | + ▼ |
| 104 | +┌─────────────────────────────────────────────────┐ |
| 105 | +│ app.init() │ |
| 106 | +│ │ |
| 107 | +│ 1. Loop through plugins │ |
| 108 | +│ 2. Call plugin.setup(app) │ |
| 109 | +└───────────────┬─────────────────────────────────┘ |
| 110 | + │ |
| 111 | + ▼ |
| 112 | +┌─────────────────────────────────────────────────┐ |
| 113 | +│ Plugin Setup Phase │ |
| 114 | +│ │ |
| 115 | +│ const driver = new SqlDriver(config); │ |
| 116 | +│ app.registerDatasource(name, driver); │ |
| 117 | +└───────────────┬─────────────────────────────────┘ |
| 118 | + │ |
| 119 | + ▼ |
| 120 | +┌─────────────────────────────────────────────────┐ |
| 121 | +│ Datasource Registry │ |
| 122 | +│ │ |
| 123 | +│ datasources['default'] = driver │ |
| 124 | +└─────────────────────────────────────────────────┘ |
| 125 | +``` |
| 126 | + |
| 127 | +### Key Design Decisions |
| 128 | + |
| 129 | +1. **Backward Compatibility**: The old direct driver approach still works |
| 130 | +2. **Type Safety**: All plugin configurations are fully typed |
| 131 | +3. **Naming Convention**: Plugin names follow `{driver-type}-driver:{datasource-name}` pattern |
| 132 | +4. **Single Responsibility**: Each plugin factory function focuses on one driver type |
| 133 | +5. **Minimal Changes**: No breaking changes to existing APIs |
| 134 | + |
| 135 | +## Testing |
| 136 | + |
| 137 | +### Build Verification |
| 138 | +- ✅ All packages build successfully |
| 139 | +- ✅ TypeScript compilation passes |
| 140 | +- ✅ No breaking changes introduced |
| 141 | + |
| 142 | +### Test Execution |
| 143 | +- ✅ Memory driver tests: 22/22 passed |
| 144 | +- ✅ FileSystem driver tests: 36/36 passed |
| 145 | +- ✅ LocalStorage driver tests: 31/31 passed |
| 146 | +- ✅ Foundation types tests: 32/32 passed |
| 147 | + |
| 148 | +### Example Verification |
| 149 | +- ✅ Plugin-based hello-world example runs successfully |
| 150 | +- ✅ Creates and queries data correctly |
| 151 | +- ✅ Plugin initialization messages appear in logs |
| 152 | + |
| 153 | +## Usage Examples |
| 154 | + |
| 155 | +### Before (Direct Driver) |
| 156 | +```typescript |
| 157 | +import { ObjectQL } from '@objectql/core'; |
| 158 | +import { SqlDriver } from '@objectql/driver-sql'; |
| 159 | + |
| 160 | +const driver = new SqlDriver(config); |
| 161 | +const app = new ObjectQL({ |
| 162 | + datasources: { default: driver } |
| 163 | +}); |
| 164 | +``` |
| 165 | + |
| 166 | +### After (Plugin-Based) |
| 167 | +```typescript |
| 168 | +import { ObjectQL } from '@objectql/core'; |
| 169 | +import { createSqlDriverPlugin } from '@objectql/driver-sql'; |
| 170 | + |
| 171 | +const app = new ObjectQL({ |
| 172 | + plugins: [ |
| 173 | + createSqlDriverPlugin({ |
| 174 | + name: 'default', |
| 175 | + config |
| 176 | + }) |
| 177 | + ] |
| 178 | +}); |
| 179 | +``` |
| 180 | + |
| 181 | +### Multi-Datasource Example |
| 182 | +```typescript |
| 183 | +const app = new ObjectQL({ |
| 184 | + plugins: [ |
| 185 | + createSqlDriverPlugin({ |
| 186 | + name: 'default', |
| 187 | + config: { client: 'postgresql', ... } |
| 188 | + }), |
| 189 | + createRedisDriverPlugin({ |
| 190 | + name: 'cache', |
| 191 | + config: { url: 'redis://localhost' } |
| 192 | + }) |
| 193 | + ] |
| 194 | +}); |
| 195 | +``` |
| 196 | + |
| 197 | +## Benefits |
| 198 | + |
| 199 | +1. **Standards Compliance**: Follows @objectstack/spec plugin protocol |
| 200 | +2. **Flexibility**: Easy to swap drivers without code changes |
| 201 | +3. **Composability**: Mix multiple drivers as plugins |
| 202 | +4. **Developer Experience**: Consistent API across all drivers |
| 203 | +5. **Type Safety**: Full IntelliSense support for all configurations |
| 204 | +6. **Testability**: Easier to mock and test |
| 205 | +7. **Documentation**: Clear examples and migration path |
| 206 | + |
| 207 | +## Migration Impact |
| 208 | + |
| 209 | +### Low Risk |
| 210 | +- **Backward Compatible**: Existing code continues to work |
| 211 | +- **Additive Changes**: New functionality added, nothing removed |
| 212 | +- **Well Tested**: All existing tests pass |
| 213 | +- **Clear Documentation**: Migration guide provided |
| 214 | + |
| 215 | +### Recommended Adoption Path |
| 216 | +1. Review the PLUGIN_PROTOCOL.md documentation |
| 217 | +2. Try the plugin approach in new projects first |
| 218 | +3. Gradually migrate existing projects during maintenance windows |
| 219 | +4. Use the example implementations as templates |
| 220 | + |
| 221 | +## Files Changed |
| 222 | + |
| 223 | +### Core (2 files) |
| 224 | +- `packages/foundation/types/src/app.ts` - Interface definition |
| 225 | +- `packages/foundation/core/src/app.ts` - Implementation |
| 226 | + |
| 227 | +### Drivers (8 files) |
| 228 | +- `packages/drivers/sql/src/index.ts` |
| 229 | +- `packages/drivers/mongo/src/index.ts` |
| 230 | +- `packages/drivers/memory/src/index.ts` |
| 231 | +- `packages/drivers/redis/src/index.ts` |
| 232 | +- `packages/drivers/localstorage/src/index.ts` |
| 233 | +- `packages/drivers/fs/src/index.ts` |
| 234 | +- `packages/drivers/sdk/src/index.ts` |
| 235 | +- `packages/drivers/excel/src/index.ts` |
| 236 | + |
| 237 | +### Documentation (4 files) |
| 238 | +- `packages/drivers/PLUGIN_PROTOCOL.md` - Comprehensive guide |
| 239 | +- `packages/drivers/sql/README.md` - Updated with plugin usage |
| 240 | +- `packages/drivers/memory/README.md` - Updated with plugin usage |
| 241 | +- `examples/quickstart/hello-world/src/index-plugin.ts` - Working example |
| 242 | + |
| 243 | +## Total Changes |
| 244 | +- **Lines Added**: ~400 |
| 245 | +- **Lines Modified**: ~15 |
| 246 | +- **Files Changed**: 14 |
| 247 | +- **New Exports**: 8 plugin factory functions |
| 248 | +- **Breaking Changes**: 0 |
| 249 | + |
| 250 | +## Checklist |
| 251 | + |
| 252 | +- [x] All drivers converted to plugin format |
| 253 | +- [x] Plugin factory functions exported |
| 254 | +- [x] registerDatasource method added to IObjectQL |
| 255 | +- [x] registerDatasource implemented in ObjectQL class |
| 256 | +- [x] Comprehensive documentation written |
| 257 | +- [x] Example implementation created |
| 258 | +- [x] README files updated |
| 259 | +- [x] All builds passing |
| 260 | +- [x] All tests passing |
| 261 | +- [x] Backward compatibility maintained |
| 262 | +- [x] Type safety verified |
| 263 | + |
| 264 | +## Next Steps |
| 265 | + |
| 266 | +This PR is ready for review. After merge, we recommend: |
| 267 | + |
| 268 | +1. Update main documentation site with plugin examples |
| 269 | +2. Create video tutorial demonstrating plugin usage |
| 270 | +3. Add plugin examples to all driver documentation |
| 271 | +4. Consider creating a plugin marketplace in the future |
0 commit comments