@objectstack/objectql 0.0.1 → 0.1.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 ADDED
@@ -0,0 +1,9 @@
1
+ # @objectstack/objectql
2
+
3
+ ## 0.1.1
4
+
5
+ ### Patch Changes
6
+
7
+ - Remove debug logs from registry and protocol modules
8
+ - Updated dependencies
9
+ - @objectstack/spec@0.1.2
package/dist/index.d.ts CHANGED
@@ -1,3 +1,41 @@
1
- export { ObjectQL } from './engine';
1
+ import { DriverInterface, DriverOptions } from '@objectstack/spec';
2
2
  export { SchemaRegistry } from './registry';
3
- export type { DriverInterface, DriverOptions, QueryAST } from '@objectstack/spec';
3
+ /**
4
+ * Host Context provided to plugins
5
+ */
6
+ export interface PluginContext {
7
+ ql: ObjectQL;
8
+ logger: Console;
9
+ [key: string]: any;
10
+ }
11
+ /**
12
+ * ObjectQL Engine
13
+ */
14
+ export declare class ObjectQL {
15
+ private drivers;
16
+ private defaultDriver;
17
+ private hostContext;
18
+ constructor(hostContext?: Record<string, any>);
19
+ /**
20
+ * Load and Register a Plugin
21
+ */
22
+ use(manifestPart: any, runtimePart?: any): Promise<void>;
23
+ /**
24
+ * Register a new storage driver
25
+ */
26
+ registerDriver(driver: DriverInterface, isDefault?: boolean): void;
27
+ /**
28
+ * Helper to get the target driver
29
+ */
30
+ private getDriver;
31
+ /**
32
+ * Initialize the engine and all registered drivers
33
+ */
34
+ init(): Promise<void>;
35
+ destroy(): Promise<void>;
36
+ find(object: string, filters?: any, options?: DriverOptions): Promise<Record<string, any>[]>;
37
+ insert(object: string, data: Record<string, any>, options?: DriverOptions): Promise<Record<string, any>>;
38
+ update(object: string, id: string, data: Record<string, any>, options?: DriverOptions): Promise<Record<string, any>>;
39
+ delete(object: string, id: string, options?: DriverOptions): Promise<boolean>;
40
+ }
41
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,aAAa,EAAiC,MAAM,mBAAmB,CAAC;AAIlG,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE5C;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,QAAQ,CAAC;IACb,MAAM,EAAE,OAAO,CAAC;IAEhB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB;AAED;;GAEG;AACH,qBAAa,QAAQ;IACnB,OAAO,CAAC,OAAO,CAAsC;IACrD,OAAO,CAAC,aAAa,CAAuB;IAG5C,OAAO,CAAC,WAAW,CAA2B;gBAElC,WAAW,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM;IAKjD;;OAEG;IACG,GAAG,CAAC,YAAY,EAAE,GAAG,EAAE,WAAW,CAAC,EAAE,GAAG;IA4D9C;;OAEG;IACH,cAAc,CAAC,MAAM,EAAE,eAAe,EAAE,SAAS,GAAE,OAAe;IAclE;;OAEG;IACH,OAAO,CAAC,SAAS;IASjB;;OAEG;IACG,IAAI;IAYJ,OAAO;IAUP,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,GAAQ,EAAE,OAAO,CAAC,EAAE,aAAa;IAmB/D,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,OAAO,CAAC,EAAE,aAAa;IAYzE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,OAAO,CAAC,EAAE,aAAa;IAMrF,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa;CAKjE"}
package/dist/index.js CHANGED
@@ -1,8 +1,159 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.SchemaRegistry = exports.ObjectQL = void 0;
4
- // Export core engine
5
- var engine_1 = require("./engine");
6
- Object.defineProperty(exports, "ObjectQL", { enumerable: true, get: function () { return engine_1.ObjectQL; } });
7
- var registry_1 = require("./registry");
8
- Object.defineProperty(exports, "SchemaRegistry", { enumerable: true, get: function () { return registry_1.SchemaRegistry; } });
3
+ exports.ObjectQL = exports.SchemaRegistry = void 0;
4
+ const registry_1 = require("./registry");
5
+ // Export Registry for consumers
6
+ var registry_2 = require("./registry");
7
+ Object.defineProperty(exports, "SchemaRegistry", { enumerable: true, get: function () { return registry_2.SchemaRegistry; } });
8
+ /**
9
+ * ObjectQL Engine
10
+ */
11
+ class ObjectQL {
12
+ constructor(hostContext = {}) {
13
+ this.drivers = new Map();
14
+ this.defaultDriver = null;
15
+ // Host provided context additions (e.g. Server router)
16
+ this.hostContext = {};
17
+ this.hostContext = hostContext;
18
+ console.log(`[ObjectQL] Engine Instance Created`);
19
+ }
20
+ /**
21
+ * Load and Register a Plugin
22
+ */
23
+ async use(manifestPart, runtimePart) {
24
+ // 1. Validate / Register Manifest
25
+ if (manifestPart) {
26
+ // 1. Handle Module Imports (commonjs/esm interop)
27
+ // If the passed object is a module namespace with a default export, use that.
28
+ const manifest = manifestPart.default || manifestPart;
29
+ // In a real scenario, we might strictly parse this using Zod
30
+ // For now, simple ID check
31
+ const id = manifest.id || manifest.name;
32
+ if (!id) {
33
+ console.warn(`[ObjectQL] Plugin manifest missing ID (keys: ${Object.keys(manifest)})`, manifest);
34
+ // Don't return, try to proceed if it looks like an App (Apps might use 'name' instead of 'id')
35
+ // return;
36
+ }
37
+ console.log(`[ObjectQL] Loading Plugin: ${id}`);
38
+ registry_1.SchemaRegistry.registerPlugin(manifest);
39
+ // Register Objects from App/Plugin
40
+ if (manifest.objects) {
41
+ for (const obj of manifest.objects) {
42
+ // Ensure object name is registered globally
43
+ registry_1.SchemaRegistry.registerObject(obj);
44
+ console.log(`[ObjectQL] Registered Object: ${obj.name}`);
45
+ }
46
+ }
47
+ // Register contributions
48
+ if (manifest.contributes?.kinds) {
49
+ for (const kind of manifest.contributes.kinds) {
50
+ registry_1.SchemaRegistry.registerKind(kind);
51
+ }
52
+ }
53
+ // Register Data Seeding (Lazy execution or immediate?)
54
+ // We store it in a temporary registry or execute immediately if engine is ready.
55
+ // Since `use` is init time, we might need to store it and run later in `seed()`.
56
+ // For this MVP, let's attach it to the manifest object in registry so Kernel can find it.
57
+ }
58
+ // 2. Execute Runtime
59
+ if (runtimePart) {
60
+ const pluginDef = runtimePart.default || runtimePart;
61
+ if (pluginDef.onEnable) {
62
+ const context = {
63
+ ql: this,
64
+ logger: console,
65
+ // Expose the driver registry helper explicitly if needed
66
+ drivers: {
67
+ register: (driver) => this.registerDriver(driver)
68
+ },
69
+ ...this.hostContext
70
+ };
71
+ await pluginDef.onEnable(context);
72
+ }
73
+ }
74
+ }
75
+ /**
76
+ * Register a new storage driver
77
+ */
78
+ registerDriver(driver, isDefault = false) {
79
+ if (this.drivers.has(driver.name)) {
80
+ console.warn(`[ObjectQL] Driver ${driver.name} is already registered. Skipping.`);
81
+ return;
82
+ }
83
+ this.drivers.set(driver.name, driver);
84
+ console.log(`[ObjectQL] Registered driver: ${driver.name} v${driver.version}`);
85
+ if (isDefault || this.drivers.size === 1) {
86
+ this.defaultDriver = driver.name;
87
+ }
88
+ }
89
+ /**
90
+ * Helper to get the target driver
91
+ */
92
+ getDriver(_object) {
93
+ // TODO: Look up Object definition to see if it specifies a specific datasource/driver
94
+ // For now, always return default
95
+ if (!this.defaultDriver) {
96
+ throw new Error('[ObjectQL] No drivers registered!');
97
+ }
98
+ return this.drivers.get(this.defaultDriver);
99
+ }
100
+ /**
101
+ * Initialize the engine and all registered drivers
102
+ */
103
+ async init() {
104
+ console.log('[ObjectQL] Initializing drivers...');
105
+ for (const [name, driver] of this.drivers) {
106
+ try {
107
+ await driver.connect();
108
+ }
109
+ catch (e) {
110
+ console.error(`[ObjectQL] Failed to connect driver ${name}`, e);
111
+ }
112
+ }
113
+ // In a real app, we would sync schemas here
114
+ }
115
+ async destroy() {
116
+ for (const driver of this.drivers.values()) {
117
+ await driver.disconnect();
118
+ }
119
+ }
120
+ // ============================================
121
+ // Data Access Methods
122
+ // ============================================
123
+ async find(object, filters = {}, options) {
124
+ const driver = this.getDriver(object);
125
+ console.log(`[ObjectQL] Finding ${object} on ${driver.name}...`);
126
+ // Transform simplified filters to QueryAST
127
+ // This is a simplified "Mock" transform.
128
+ // Real implementation would parse complex JSON or FilterBuilders.
129
+ const ast = {
130
+ object, // Add missing required field
131
+ // Pass through if it looks like AST, otherwise empty
132
+ // In this demo, we assume the caller passes a simplified object or raw AST
133
+ filters: filters.filters || undefined,
134
+ top: filters.top || 100,
135
+ sort: filters.sort || []
136
+ };
137
+ return driver.find(object, ast, options);
138
+ }
139
+ async insert(object, data, options) {
140
+ const driver = this.getDriver(object);
141
+ console.log(`[ObjectQL] Creating ${object} on ${driver.name}...`);
142
+ // 1. Validate Schema
143
+ // 2. Run "Before Insert" Triggers
144
+ const result = await driver.create(object, data, options);
145
+ // 3. Run "After Insert" Triggers
146
+ return result;
147
+ }
148
+ async update(object, id, data, options) {
149
+ const driver = this.getDriver(object);
150
+ console.log(`[ObjectQL] Updating ${object} ${id}...`);
151
+ return driver.update(object, id, data, options);
152
+ }
153
+ async delete(object, id, options) {
154
+ const driver = this.getDriver(object);
155
+ console.log(`[ObjectQL] Deleting ${object} ${id}...`);
156
+ return driver.delete(object, id, options);
157
+ }
158
+ }
159
+ exports.ObjectQL = ObjectQL;
@@ -53,3 +53,4 @@ export declare class SchemaRegistry {
53
53
  globs: string[];
54
54
  }[];
55
55
  }
56
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,GAAG,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAE5E;;;GAGG;AACH,qBAAa,cAAc;IAEzB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAuC;IAE9D;;;;;OAKG;IACH,MAAM,CAAC,YAAY,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,QAAQ,GAAE,MAAM,CAAqB;IAcnF;;OAEG;IACH,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS;IAI5D;;OAEG;IACH,MAAM,CAAC,SAAS,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,CAAC,EAAE;IAItC;;OAEG;IACH,MAAM,CAAC,kBAAkB,IAAI,MAAM,EAAE;IAQrC;;OAEG;IACH,MAAM,CAAC,cAAc,CAAC,MAAM,EAAE,aAAa;IAI3C,MAAM,CAAC,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS;IAIzD,MAAM,CAAC,aAAa,IAAI,aAAa,EAAE;IAIvC;;OAEG;IACH,MAAM,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG;IAI3B,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,GAAG,GAAG,SAAS;IAI5C,MAAM,CAAC,UAAU,IAAI,GAAG,EAAE;IAI1B;;OAEG;IACH,MAAM,CAAC,cAAc,CAAC,QAAQ,EAAE,mBAAmB;IAInD,MAAM,CAAC,aAAa,IAAI,mBAAmB,EAAE;IAI7C;;OAEG;IACH,MAAM,CAAC,YAAY,CAAC,IAAI,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,EAAE,CAAA;KAAE;IAIzD,MAAM,CAAC,WAAW,IAAI;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,EAAE,CAAA;KAAE,EAAE;CAGxD"}
package/package.json CHANGED
@@ -1,17 +1,18 @@
1
1
  {
2
2
  "name": "@objectstack/objectql",
3
- "version": "0.0.1",
4
- "description": "ObjectQL Reference Implementation",
5
- "main": "dist/index.js",
6
- "types": "dist/index.d.ts",
3
+ "version": "0.1.1",
4
+ "description": "Isomorphic ObjectQL Engine for ObjectStack",
5
+ "main": "src/index.ts",
6
+ "types": "src/index.ts",
7
7
  "dependencies": {
8
- "@objectstack/spec": "0.1.1"
8
+ "@objectstack/spec": "0.1.2"
9
9
  },
10
10
  "devDependencies": {
11
- "typescript": "^5.0.0"
11
+ "typescript": "^5.0.0",
12
+ "vitest": "^1.0.0"
12
13
  },
13
14
  "scripts": {
14
15
  "build": "tsc",
15
- "dev": "tsc -w"
16
+ "test": "vitest"
16
17
  }
17
18
  }
package/src/index.ts CHANGED
@@ -1,6 +1,191 @@
1
- // Export core engine
2
- export { ObjectQL } from './engine';
1
+ import { DriverInterface, DriverOptions, QueryAST, ObjectStackManifest } from '@objectstack/spec';
2
+ import { SchemaRegistry } from './registry';
3
+
4
+ // Export Registry for consumers
3
5
  export { SchemaRegistry } from './registry';
4
6
 
5
- // Re-export common types from spec for convenience
6
- export type { DriverInterface, DriverOptions, QueryAST } from '@objectstack/spec';
7
+ /**
8
+ * Host Context provided to plugins
9
+ */
10
+ export interface PluginContext {
11
+ ql: ObjectQL;
12
+ logger: Console;
13
+ // Extensible map for host-specific globals (like HTTP Router, etc.)
14
+ [key: string]: any;
15
+ }
16
+
17
+ /**
18
+ * ObjectQL Engine
19
+ */
20
+ export class ObjectQL {
21
+ private drivers = new Map<string, DriverInterface>();
22
+ private defaultDriver: string | null = null;
23
+
24
+ // Host provided context additions (e.g. Server router)
25
+ private hostContext: Record<string, any> = {};
26
+
27
+ constructor(hostContext: Record<string, any> = {}) {
28
+ this.hostContext = hostContext;
29
+ console.log(`[ObjectQL] Engine Instance Created`);
30
+ }
31
+
32
+ /**
33
+ * Load and Register a Plugin
34
+ */
35
+ async use(manifestPart: any, runtimePart?: any) {
36
+ // 1. Validate / Register Manifest
37
+ if (manifestPart) {
38
+ // 1. Handle Module Imports (commonjs/esm interop)
39
+ // If the passed object is a module namespace with a default export, use that.
40
+ const manifest = manifestPart.default || manifestPart;
41
+
42
+ // In a real scenario, we might strictly parse this using Zod
43
+ // For now, simple ID check
44
+ const id = manifest.id || manifest.name;
45
+ if (!id) {
46
+ console.warn(`[ObjectQL] Plugin manifest missing ID (keys: ${Object.keys(manifest)})`, manifest);
47
+ // Don't return, try to proceed if it looks like an App (Apps might use 'name' instead of 'id')
48
+ // return;
49
+ }
50
+
51
+ console.log(`[ObjectQL] Loading Plugin: ${id}`);
52
+ SchemaRegistry.registerPlugin(manifest as ObjectStackManifest);
53
+
54
+ // Register Objects from App/Plugin
55
+ if (manifest.objects) {
56
+ for (const obj of manifest.objects) {
57
+ // Ensure object name is registered globally
58
+ SchemaRegistry.registerObject(obj);
59
+ console.log(`[ObjectQL] Registered Object: ${obj.name}`);
60
+ }
61
+ }
62
+
63
+ // Register contributions
64
+ if (manifest.contributes?.kinds) {
65
+ for (const kind of manifest.contributes.kinds) {
66
+ SchemaRegistry.registerKind(kind);
67
+ }
68
+ }
69
+
70
+ // Register Data Seeding (Lazy execution or immediate?)
71
+ // We store it in a temporary registry or execute immediately if engine is ready.
72
+ // Since `use` is init time, we might need to store it and run later in `seed()`.
73
+ // For this MVP, let's attach it to the manifest object in registry so Kernel can find it.
74
+ }
75
+
76
+ // 2. Execute Runtime
77
+ if (runtimePart) {
78
+ const pluginDef = (runtimePart as any).default || runtimePart;
79
+ if (pluginDef.onEnable) {
80
+ const context: PluginContext = {
81
+ ql: this,
82
+ logger: console,
83
+ // Expose the driver registry helper explicitly if needed
84
+ drivers: {
85
+ register: (driver: DriverInterface) => this.registerDriver(driver)
86
+ },
87
+ ...this.hostContext
88
+ };
89
+
90
+ await pluginDef.onEnable(context);
91
+ }
92
+ }
93
+ }
94
+
95
+ /**
96
+ * Register a new storage driver
97
+ */
98
+ registerDriver(driver: DriverInterface, isDefault: boolean = false) {
99
+ if (this.drivers.has(driver.name)) {
100
+ console.warn(`[ObjectQL] Driver ${driver.name} is already registered. Skipping.`);
101
+ return;
102
+ }
103
+
104
+ this.drivers.set(driver.name, driver);
105
+ console.log(`[ObjectQL] Registered driver: ${driver.name} v${driver.version}`);
106
+
107
+ if (isDefault || this.drivers.size === 1) {
108
+ this.defaultDriver = driver.name;
109
+ }
110
+ }
111
+
112
+ /**
113
+ * Helper to get the target driver
114
+ */
115
+ private getDriver(_object: string): DriverInterface {
116
+ // TODO: Look up Object definition to see if it specifies a specific datasource/driver
117
+ // For now, always return default
118
+ if (!this.defaultDriver) {
119
+ throw new Error('[ObjectQL] No drivers registered!');
120
+ }
121
+ return this.drivers.get(this.defaultDriver)!;
122
+ }
123
+
124
+ /**
125
+ * Initialize the engine and all registered drivers
126
+ */
127
+ async init() {
128
+ console.log('[ObjectQL] Initializing drivers...');
129
+ for (const [name, driver] of this.drivers) {
130
+ try {
131
+ await driver.connect();
132
+ } catch (e) {
133
+ console.error(`[ObjectQL] Failed to connect driver ${name}`, e);
134
+ }
135
+ }
136
+ // In a real app, we would sync schemas here
137
+ }
138
+
139
+ async destroy() {
140
+ for (const driver of this.drivers.values()) {
141
+ await driver.disconnect();
142
+ }
143
+ }
144
+
145
+ // ============================================
146
+ // Data Access Methods
147
+ // ============================================
148
+
149
+ async find(object: string, filters: any = {}, options?: DriverOptions) {
150
+ const driver = this.getDriver(object);
151
+ console.log(`[ObjectQL] Finding ${object} on ${driver.name}...`);
152
+
153
+ // Transform simplified filters to QueryAST
154
+ // This is a simplified "Mock" transform.
155
+ // Real implementation would parse complex JSON or FilterBuilders.
156
+ const ast: QueryAST = {
157
+ object, // Add missing required field
158
+ // Pass through if it looks like AST, otherwise empty
159
+ // In this demo, we assume the caller passes a simplified object or raw AST
160
+ filters: filters.filters || undefined,
161
+ top: filters.top || 100,
162
+ sort: filters.sort || []
163
+ };
164
+
165
+ return driver.find(object, ast, options);
166
+ }
167
+
168
+ async insert(object: string, data: Record<string, any>, options?: DriverOptions) {
169
+ const driver = this.getDriver(object);
170
+ console.log(`[ObjectQL] Creating ${object} on ${driver.name}...`);
171
+ // 1. Validate Schema
172
+ // 2. Run "Before Insert" Triggers
173
+
174
+ const result = await driver.create(object, data, options);
175
+
176
+ // 3. Run "After Insert" Triggers
177
+ return result;
178
+ }
179
+
180
+ async update(object: string, id: string, data: Record<string, any>, options?: DriverOptions) {
181
+ const driver = this.getDriver(object);
182
+ console.log(`[ObjectQL] Updating ${object} ${id}...`);
183
+ return driver.update(object, id, data, options);
184
+ }
185
+
186
+ async delete(object: string, id: string, options?: DriverOptions) {
187
+ const driver = this.getDriver(object);
188
+ console.log(`[ObjectQL] Deleting ${object} ${id}...`);
189
+ return driver.delete(object, id, options);
190
+ }
191
+ }
package/tsconfig.json CHANGED
@@ -1,13 +1,9 @@
1
1
  {
2
+ "extends": "../../tsconfig.json",
3
+ "include": ["src/**/*"],
4
+ "exclude": ["node_modules", "dist"],
2
5
  "compilerOptions": {
3
- "target": "ES2020",
4
- "module": "commonjs",
5
- "declaration": true,
6
- "outDir": "./dist",
7
- "strict": true,
8
- "esModuleInterop": true,
9
- "skipLibCheck": true,
10
- "forceConsistentCasingInFileNames": true
11
- },
12
- "include": ["src/**/*"]
6
+ "outDir": "dist",
7
+ "rootDir": "src"
8
+ }
13
9
  }
package/dist/engine.d.ts DELETED
@@ -1,40 +0,0 @@
1
- import { DriverInterface, DriverOptions } from '@objectstack/spec';
2
- /**
3
- * Host Context provided to plugins
4
- */
5
- export interface PluginContext {
6
- ql: ObjectQL;
7
- logger: Console;
8
- [key: string]: any;
9
- }
10
- /**
11
- * ObjectQL Engine
12
- */
13
- export declare class ObjectQL {
14
- private drivers;
15
- private defaultDriver;
16
- private plugins;
17
- private hostContext;
18
- constructor(hostContext?: Record<string, any>);
19
- /**
20
- * Load and Register a Plugin
21
- */
22
- use(manifestPart: any, runtimePart?: any): Promise<void>;
23
- /**
24
- * Register a new storage driver
25
- */
26
- registerDriver(driver: DriverInterface, isDefault?: boolean): void;
27
- /**
28
- * Helper to get the target driver
29
- */
30
- private getDriver;
31
- /**
32
- * Initialize the engine and all registered drivers
33
- */
34
- init(): Promise<void>;
35
- destroy(): Promise<void>;
36
- find(object: string, filters?: any, options?: DriverOptions): Promise<Record<string, any>[]>;
37
- insert(object: string, data: Record<string, any>, options?: DriverOptions): Promise<Record<string, any>>;
38
- update(object: string, id: string, data: Record<string, any>, options?: DriverOptions): Promise<Record<string, any>>;
39
- delete(object: string, id: string, options?: DriverOptions): Promise<boolean>;
40
- }
package/dist/engine.js DELETED
@@ -1,139 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ObjectQL = void 0;
4
- const registry_1 = require("./registry");
5
- /**
6
- * ObjectQL Engine
7
- */
8
- class ObjectQL {
9
- constructor(hostContext = {}) {
10
- this.drivers = new Map();
11
- this.defaultDriver = null;
12
- this.plugins = new Map();
13
- // Host provided context additions (e.g. Server router)
14
- this.hostContext = {};
15
- this.hostContext = hostContext;
16
- console.log(`[ObjectQL] Engine Instance Created`);
17
- }
18
- /**
19
- * Load and Register a Plugin
20
- */
21
- async use(manifestPart, runtimePart) {
22
- // 1. Validate / Register Manifest
23
- if (manifestPart) {
24
- // In a real scenario, we might strictly parse this using Zod
25
- // For now, simple ID check
26
- const id = manifestPart.id;
27
- if (!id) {
28
- console.warn('[ObjectQL] Plugin manifest missing ID', manifestPart);
29
- return;
30
- }
31
- console.log(`[ObjectQL] Loading Plugin: ${id}`);
32
- registry_1.SchemaRegistry.registerPlugin(manifestPart);
33
- // Register contributions
34
- if (manifestPart.contributes?.kinds) {
35
- for (const kind of manifestPart.contributes.kinds) {
36
- registry_1.SchemaRegistry.registerKind(kind);
37
- }
38
- }
39
- }
40
- // 2. Execute Runtime
41
- if (runtimePart) {
42
- const pluginDef = runtimePart.default || runtimePart;
43
- if (pluginDef.onEnable) {
44
- const context = {
45
- ql: this,
46
- logger: console,
47
- // Expose the driver registry helper explicitly if needed
48
- drivers: this, // Since `registerDriver` is on `this`, we can alias it or expose `this`
49
- ...this.hostContext
50
- };
51
- await pluginDef.onEnable(context);
52
- }
53
- }
54
- }
55
- /**
56
- * Register a new storage driver
57
- */
58
- registerDriver(driver, isDefault = false) {
59
- if (this.drivers.has(driver.name)) {
60
- console.warn(`[ObjectQL] Driver ${driver.name} is already registered. Skipping.`);
61
- return;
62
- }
63
- this.drivers.set(driver.name, driver);
64
- console.log(`[ObjectQL] Registered driver: ${driver.name} v${driver.version}`);
65
- if (isDefault || this.drivers.size === 1) {
66
- this.defaultDriver = driver.name;
67
- }
68
- }
69
- /**
70
- * Helper to get the target driver
71
- */
72
- getDriver(object) {
73
- // TODO: Look up Object definition to see if it specifies a specific datasource/driver
74
- // For now, always return default
75
- if (!this.defaultDriver) {
76
- throw new Error('[ObjectQL] No drivers registered!');
77
- }
78
- return this.drivers.get(this.defaultDriver);
79
- }
80
- /**
81
- * Initialize the engine and all registered drivers
82
- */
83
- async init() {
84
- console.log('[ObjectQL] Initializing drivers...');
85
- for (const [name, driver] of this.drivers) {
86
- try {
87
- await driver.connect();
88
- }
89
- catch (e) {
90
- console.error(`[ObjectQL] Failed to connect driver ${name}`, e);
91
- }
92
- }
93
- // In a real app, we would sync schemas here
94
- }
95
- async destroy() {
96
- for (const driver of this.drivers.values()) {
97
- await driver.disconnect();
98
- }
99
- }
100
- // ============================================
101
- // Data Access Methods
102
- // ============================================
103
- async find(object, filters = {}, options) {
104
- const driver = this.getDriver(object);
105
- console.log(`[ObjectQL] Finding ${object} on ${driver.name}...`);
106
- // Transform simplified filters to QueryAST
107
- // This is a simplified "Mock" transform.
108
- // Real implementation would parse complex JSON or FilterBuilders.
109
- const ast = {
110
- object, // Add missing required field
111
- // Pass through if it looks like AST, otherwise empty
112
- // In this demo, we assume the caller passes a simplified object or raw AST
113
- filters: filters.filters || undefined,
114
- top: filters.top || 100,
115
- sort: filters.sort || []
116
- };
117
- return driver.find(object, ast, options);
118
- }
119
- async insert(object, data, options) {
120
- const driver = this.getDriver(object);
121
- console.log(`[ObjectQL] Creating ${object} on ${driver.name}...`);
122
- // 1. Validate Schema
123
- // 2. Run "Before Insert" Triggers
124
- const result = await driver.create(object, data, options);
125
- // 3. Run "After Insert" Triggers
126
- return result;
127
- }
128
- async update(object, id, data, options) {
129
- const driver = this.getDriver(object);
130
- console.log(`[ObjectQL] Updating ${object} ${id}...`);
131
- return driver.update(object, id, data, options);
132
- }
133
- async delete(object, id, options) {
134
- const driver = this.getDriver(object);
135
- console.log(`[ObjectQL] Deleting ${object} ${id}...`);
136
- return driver.delete(object, id, options);
137
- }
138
- }
139
- exports.ObjectQL = ObjectQL;
package/src/engine.ts DELETED
@@ -1,168 +0,0 @@
1
- import { DriverInterface, DriverOptions, QueryAST, ObjectStackManifest, ManifestSchema } from '@objectstack/spec';
2
- import { SchemaRegistry } from './registry';
3
-
4
- /**
5
- * Host Context provided to plugins
6
- */
7
- export interface PluginContext {
8
- ql: ObjectQL;
9
- logger: Console;
10
- // Extensible map for host-specific globals (like HTTP Router, etc.)
11
- [key: string]: any;
12
- }
13
-
14
- /**
15
- * ObjectQL Engine
16
- */
17
- export class ObjectQL {
18
- private drivers = new Map<string, DriverInterface>();
19
- private defaultDriver: string | null = null;
20
- private plugins = new Map<string, any>();
21
-
22
- // Host provided context additions (e.g. Server router)
23
- private hostContext: Record<string, any> = {};
24
-
25
- constructor(hostContext: Record<string, any> = {}) {
26
- this.hostContext = hostContext;
27
- console.log(`[ObjectQL] Engine Instance Created`);
28
- }
29
-
30
- /**
31
- * Load and Register a Plugin
32
- */
33
- async use(manifestPart: any, runtimePart?: any) {
34
- // 1. Validate / Register Manifest
35
- if (manifestPart) {
36
- // In a real scenario, we might strictly parse this using Zod
37
- // For now, simple ID check
38
- const id = manifestPart.id;
39
- if (!id) {
40
- console.warn('[ObjectQL] Plugin manifest missing ID', manifestPart);
41
- return;
42
- }
43
-
44
- console.log(`[ObjectQL] Loading Plugin: ${id}`);
45
- SchemaRegistry.registerPlugin(manifestPart as ObjectStackManifest);
46
-
47
- // Register contributions
48
- if (manifestPart.contributes?.kinds) {
49
- for (const kind of manifestPart.contributes.kinds) {
50
- SchemaRegistry.registerKind(kind);
51
- }
52
- }
53
- }
54
-
55
- // 2. Execute Runtime
56
- if (runtimePart) {
57
- const pluginDef = (runtimePart as any).default || runtimePart;
58
- if (pluginDef.onEnable) {
59
- const context: PluginContext = {
60
- ql: this,
61
- logger: console,
62
- // Expose the driver registry helper explicitly if needed
63
- drivers: this, // Since `registerDriver` is on `this`, we can alias it or expose `this`
64
- ...this.hostContext
65
- };
66
-
67
- await pluginDef.onEnable(context);
68
- }
69
- }
70
- }
71
-
72
- /**
73
- * Register a new storage driver
74
- */
75
- registerDriver(driver: DriverInterface, isDefault: boolean = false) {
76
- if (this.drivers.has(driver.name)) {
77
- console.warn(`[ObjectQL] Driver ${driver.name} is already registered. Skipping.`);
78
- return;
79
- }
80
-
81
- this.drivers.set(driver.name, driver);
82
- console.log(`[ObjectQL] Registered driver: ${driver.name} v${driver.version}`);
83
-
84
- if (isDefault || this.drivers.size === 1) {
85
- this.defaultDriver = driver.name;
86
- }
87
- }
88
-
89
- /**
90
- * Helper to get the target driver
91
- */
92
- private getDriver(object: string): DriverInterface {
93
- // TODO: Look up Object definition to see if it specifies a specific datasource/driver
94
- // For now, always return default
95
- if (!this.defaultDriver) {
96
- throw new Error('[ObjectQL] No drivers registered!');
97
- }
98
- return this.drivers.get(this.defaultDriver)!;
99
- }
100
-
101
- /**
102
- * Initialize the engine and all registered drivers
103
- */
104
- async init() {
105
- console.log('[ObjectQL] Initializing drivers...');
106
- for (const [name, driver] of this.drivers) {
107
- try {
108
- await driver.connect();
109
- } catch (e) {
110
- console.error(`[ObjectQL] Failed to connect driver ${name}`, e);
111
- }
112
- }
113
- // In a real app, we would sync schemas here
114
- }
115
-
116
- async destroy() {
117
- for (const driver of this.drivers.values()) {
118
- await driver.disconnect();
119
- }
120
- }
121
-
122
- // ============================================
123
- // Data Access Methods
124
- // ============================================
125
-
126
- async find(object: string, filters: any = {}, options?: DriverOptions) {
127
- const driver = this.getDriver(object);
128
- console.log(`[ObjectQL] Finding ${object} on ${driver.name}...`);
129
-
130
- // Transform simplified filters to QueryAST
131
- // This is a simplified "Mock" transform.
132
- // Real implementation would parse complex JSON or FilterBuilders.
133
- const ast: QueryAST = {
134
- object, // Add missing required field
135
- // Pass through if it looks like AST, otherwise empty
136
- // In this demo, we assume the caller passes a simplified object or raw AST
137
- filters: filters.filters || undefined,
138
- top: filters.top || 100,
139
- sort: filters.sort || []
140
- };
141
-
142
- return driver.find(object, ast, options);
143
- }
144
-
145
- async insert(object: string, data: Record<string, any>, options?: DriverOptions) {
146
- const driver = this.getDriver(object);
147
- console.log(`[ObjectQL] Creating ${object} on ${driver.name}...`);
148
- // 1. Validate Schema
149
- // 2. Run "Before Insert" Triggers
150
-
151
- const result = await driver.create(object, data, options);
152
-
153
- // 3. Run "After Insert" Triggers
154
- return result;
155
- }
156
-
157
- async update(object: string, id: string, data: Record<string, any>, options?: DriverOptions) {
158
- const driver = this.getDriver(object);
159
- console.log(`[ObjectQL] Updating ${object} ${id}...`);
160
- return driver.update(object, id, data, options);
161
- }
162
-
163
- async delete(object: string, id: string, options?: DriverOptions) {
164
- const driver = this.getDriver(object);
165
- console.log(`[ObjectQL] Deleting ${object} ${id}...`);
166
- return driver.delete(object, id, options);
167
- }
168
- }