@objectstack/runtime 0.1.0 → 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,11 @@
1
+ # @objectstack/runtime
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
10
+ - @objectstack/objectql@0.1.1
11
+ - @objectstack/types@0.1.1
package/dist/index.d.ts CHANGED
@@ -1,5 +1,4 @@
1
- export { ObjectQL } from './engine';
2
- export { SchemaRegistry } from './registry';
3
- export { DataEngine } from './data-engine';
1
+ export { ObjectQL, SchemaRegistry } from '@objectstack/objectql';
2
+ export { ObjectStackKernel } from './kernel';
4
3
  export { ObjectStackRuntimeProtocol } from './protocol';
5
- export type { DriverInterface, DriverOptions, QueryAST } from '@objectstack/spec';
4
+ export * from './types';
package/dist/index.js CHANGED
@@ -1,12 +1,26 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
2
16
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ObjectStackRuntimeProtocol = exports.DataEngine = exports.SchemaRegistry = exports.ObjectQL = void 0;
17
+ exports.ObjectStackRuntimeProtocol = exports.ObjectStackKernel = exports.SchemaRegistry = exports.ObjectQL = void 0;
4
18
  // 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; } });
9
- var data_engine_1 = require("./data-engine");
10
- Object.defineProperty(exports, "DataEngine", { enumerable: true, get: function () { return data_engine_1.DataEngine; } });
19
+ var objectql_1 = require("@objectstack/objectql");
20
+ Object.defineProperty(exports, "ObjectQL", { enumerable: true, get: function () { return objectql_1.ObjectQL; } });
21
+ Object.defineProperty(exports, "SchemaRegistry", { enumerable: true, get: function () { return objectql_1.SchemaRegistry; } });
22
+ var kernel_1 = require("./kernel");
23
+ Object.defineProperty(exports, "ObjectStackKernel", { enumerable: true, get: function () { return kernel_1.ObjectStackKernel; } });
11
24
  var protocol_1 = require("./protocol");
12
25
  Object.defineProperty(exports, "ObjectStackRuntimeProtocol", { enumerable: true, get: function () { return protocol_1.ObjectStackRuntimeProtocol; } });
26
+ __exportStar(require("./types"), exports);
@@ -1,13 +1,11 @@
1
- import { ObjectQL } from './engine';
1
+ import { ObjectQL } from '@objectstack/objectql';
2
2
  /**
3
- * Server Data Engine Wrapper
3
+ * ObjectStack Kernel (Microkernel)
4
4
  *
5
- * This class is now a thin wrapper that initializes the ObjectQL Engine
6
- * with the appropriate Server-Side configuration (Registry, Drivers).
7
- *
8
- * The core logic has been moved to @objectstack/objectql.
5
+ * The central container orchestrating the application lifecycle,
6
+ * plugins, and the core ObjectQL engine.
9
7
  */
10
- export declare class DataEngine {
8
+ export declare class ObjectStackKernel {
11
9
  ql: ObjectQL;
12
10
  private plugins;
13
11
  constructor(plugins?: any[]);
@@ -33,39 +33,44 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.DataEngine = void 0;
37
- const registry_1 = require("./registry");
38
- const engine_1 = require("./engine");
36
+ exports.ObjectStackKernel = void 0;
37
+ const objectql_1 = require("@objectstack/objectql");
39
38
  /**
40
- * Server Data Engine Wrapper
39
+ * ObjectStack Kernel (Microkernel)
41
40
  *
42
- * This class is now a thin wrapper that initializes the ObjectQL Engine
43
- * with the appropriate Server-Side configuration (Registry, Drivers).
44
- *
45
- * The core logic has been moved to @objectstack/objectql.
41
+ * The central container orchestrating the application lifecycle,
42
+ * plugins, and the core ObjectQL engine.
46
43
  */
47
- class DataEngine {
44
+ class ObjectStackKernel {
48
45
  constructor(plugins = []) {
49
46
  // 1. Initialize Engine with Host Context (Simulated OS services)
50
- this.ql = new engine_1.ObjectQL({
47
+ this.ql = new objectql_1.ObjectQL({
51
48
  env: process.env.NODE_ENV || 'development'
52
49
  });
53
50
  this.plugins = plugins;
54
51
  }
55
52
  async start() {
56
- console.log('[DataEngine] Starting...');
53
+ console.log('[Kernel] Starting...');
57
54
  // 0. Register Provided Plugins
58
- this.plugins.forEach(p => {
59
- console.log(`[DataEngine] Loading Plugin: ${p.id || p.name}`);
60
- registry_1.SchemaRegistry.registerPlugin(p);
55
+ for (const p of this.plugins) {
56
+ // Check if it is a Runtime Plugin (System Capability)
57
+ if ('onStart' in p || 'install' in p) {
58
+ console.log(`[Kernel] Loading Runtime Plugin: ${p.name}`);
59
+ if (p.install)
60
+ await p.install({ engine: this });
61
+ continue;
62
+ }
63
+ // Otherwise treat as App Manifest
64
+ console.log(`[Kernel] Loading App Manifest: ${p.id || p.name}`);
65
+ objectql_1.SchemaRegistry.registerPlugin(p);
61
66
  // Register Objects from App/Plugin
62
67
  if (p.objects) {
63
68
  for (const obj of p.objects) {
64
- registry_1.SchemaRegistry.registerObject(obj);
65
- console.log(`[DataEngine] Registered Object: ${obj.name}`);
69
+ objectql_1.SchemaRegistry.registerObject(obj);
70
+ console.log(`[Kernel] Registered Object: ${obj.name}`);
66
71
  }
67
72
  }
68
- });
73
+ }
69
74
  // 1. Load Drivers (Default to Memory if none provided in plugins)
70
75
  // TODO: Detect driver from plugins. For now, we still hard load memory driver if needed?
71
76
  // In strict mode, user should pass driver in plugins array (DriverManifest).
@@ -84,6 +89,13 @@ class DataEngine {
84
89
  await this.ql.init();
85
90
  // 3. Seed Data
86
91
  await this.seed();
92
+ // 4. Start Runtime Plugins
93
+ for (const p of this.plugins) {
94
+ if (('onStart' in p) && typeof p.onStart === 'function') {
95
+ console.log(`[Kernel] Starting Plugin: ${p.name}`);
96
+ await p.onStart({ engine: this });
97
+ }
98
+ }
87
99
  }
88
100
  async seed() {
89
101
  // If no driver registered yet, this might fail or wait.
@@ -96,28 +108,28 @@ class DataEngine {
96
108
  }
97
109
  catch { }
98
110
  // Iterate over all registered plugins/apps and check for 'data' property in manifest
99
- const plugins = registry_1.SchemaRegistry.getRegisteredTypes(); // This returns types like 'plugin', 'app'
111
+ const plugins = objectql_1.SchemaRegistry.getRegisteredTypes(); // This returns types like 'plugin', 'app'
100
112
  // This is a bit hacky because we don't have a direct "getAllManifests" API exposed easily
101
113
  // We will iterate known apps for now, or improve Registry API later.
102
114
  // Actually, SchemaRegistry.listItems('app') returns the manifests!
103
- const apps = [...registry_1.SchemaRegistry.listItems('app'), ...registry_1.SchemaRegistry.listItems('plugin')];
115
+ const apps = [...objectql_1.SchemaRegistry.listItems('app'), ...objectql_1.SchemaRegistry.listItems('plugin')];
104
116
  for (const appItem of apps) {
105
117
  const app = appItem; // Cast to access data prop safely
106
118
  if (app.data && Array.isArray(app.data)) {
107
- console.log(`[DataEngine] Seeding data for ${app.name || app.id}...`);
119
+ console.log(`[Kernel] Seeding data for ${app.name || app.id}...`);
108
120
  for (const seed of app.data) {
109
121
  try {
110
122
  // Check if data exists
111
123
  const existing = await this.ql.find(seed.object, { top: 1 });
112
124
  if (existing.length === 0) {
113
- console.log(`[DataEngine] Inserting ${seed.records.length} records into ${seed.object}`);
125
+ console.log(`[Kernel] Inserting ${seed.records.length} records into ${seed.object}`);
114
126
  for (const record of seed.records) {
115
127
  await this.ql.insert(seed.object, record);
116
128
  }
117
129
  }
118
130
  }
119
131
  catch (e) {
120
- console.warn(`[DataEngine] Failed to seed ${seed.object}`, e);
132
+ console.warn(`[Kernel] Failed to seed ${seed.object}`, e);
121
133
  }
122
134
  }
123
135
  }
@@ -173,10 +185,10 @@ class DataEngine {
173
185
  return null;
174
186
  }
175
187
  ensureSchema(name) {
176
- const schema = registry_1.SchemaRegistry.getObject(name);
188
+ const schema = objectql_1.SchemaRegistry.getObject(name);
177
189
  if (!schema)
178
190
  throw new Error(`Unknown object: ${name}`);
179
191
  return schema;
180
192
  }
181
193
  }
182
- exports.DataEngine = DataEngine;
194
+ exports.ObjectStackKernel = ObjectStackKernel;
@@ -1,4 +1,4 @@
1
- import { DataEngine } from './data-engine';
1
+ import { ObjectStackKernel } from './kernel';
2
2
  export interface ApiRequest {
3
3
  params: Record<string, string>;
4
4
  query: Record<string, string | string[]>;
@@ -6,7 +6,7 @@ export interface ApiRequest {
6
6
  }
7
7
  export declare class ObjectStackRuntimeProtocol {
8
8
  private engine;
9
- constructor(engine: DataEngine);
9
+ constructor(engine: ObjectStackKernel);
10
10
  getDiscovery(): {
11
11
  name: string;
12
12
  version: string;
package/dist/protocol.js CHANGED
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ObjectStackRuntimeProtocol = void 0;
4
- const registry_1 = require("./registry");
4
+ const objectql_1 = require("@objectstack/objectql");
5
5
  class ObjectStackRuntimeProtocol {
6
6
  constructor(engine) {
7
7
  this.engine = engine;
@@ -27,12 +27,12 @@ class ObjectStackRuntimeProtocol {
27
27
  }
28
28
  // 2. Metadata: List Types
29
29
  getMetaTypes() {
30
- const types = registry_1.SchemaRegistry.getRegisteredTypes();
30
+ const types = objectql_1.SchemaRegistry.getRegisteredTypes();
31
31
  return {
32
32
  data: types.map(type => ({
33
33
  type,
34
34
  href: `/api/v1/meta/${type}s`,
35
- count: registry_1.SchemaRegistry.listItems(type).length
35
+ count: objectql_1.SchemaRegistry.listItems(type).length
36
36
  }))
37
37
  };
38
38
  }
@@ -48,7 +48,7 @@ class ObjectStackRuntimeProtocol {
48
48
  'kinds': 'kind'
49
49
  };
50
50
  const type = typeMap[typePlural] || typePlural;
51
- const items = registry_1.SchemaRegistry.listItems(type);
51
+ const items = objectql_1.SchemaRegistry.listItems(type);
52
52
  const summaries = items.map((item) => ({
53
53
  id: item.id,
54
54
  name: item.name,
@@ -72,7 +72,7 @@ class ObjectStackRuntimeProtocol {
72
72
  'kinds': 'kind'
73
73
  };
74
74
  const type = typeMap[typePlural] || typePlural;
75
- const item = registry_1.SchemaRegistry.getItem(type, name);
75
+ const item = objectql_1.SchemaRegistry.getItem(type, name);
76
76
  if (!item)
77
77
  throw new Error(`Metadata not found: ${type}/${name}`);
78
78
  return item;
@@ -0,0 +1,9 @@
1
+ import { ObjectStackKernel } from './kernel';
2
+ export interface RuntimeContext {
3
+ engine: ObjectStackKernel;
4
+ }
5
+ export interface RuntimePlugin {
6
+ name: string;
7
+ install?: (ctx: RuntimeContext) => void | Promise<void>;
8
+ onStart?: (ctx: RuntimeContext) => void | Promise<void>;
9
+ }
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
package/package.json CHANGED
@@ -1,11 +1,13 @@
1
1
  {
2
2
  "name": "@objectstack/runtime",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "ObjectStack Core Runtime & Query Engine",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "dependencies": {
8
- "@objectstack/spec": "0.1.1"
8
+ "@objectstack/objectql": "0.1.1",
9
+ "@objectstack/types": "0.1.1",
10
+ "@objectstack/spec": "0.1.2"
9
11
  },
10
12
  "devDependencies": {
11
13
  "typescript": "^5.0.0"
package/src/index.ts CHANGED
@@ -1,10 +1,7 @@
1
1
  // Export core engine
2
- export { ObjectQL } from './engine';
3
- export { SchemaRegistry } from './registry';
4
- export { DataEngine } from './data-engine';
2
+ export { ObjectQL, SchemaRegistry } from '@objectstack/objectql';
3
+ export { ObjectStackKernel } from './kernel';
5
4
  export { ObjectStackRuntimeProtocol } from './protocol';
6
5
 
6
+ export * from './types';
7
7
 
8
-
9
- // Re-export common types from spec for convenience
10
- export type { DriverInterface, DriverOptions, QueryAST } from '@objectstack/spec';
@@ -1,16 +1,13 @@
1
1
  import { ServiceObject } from '@objectstack/spec';
2
- import { SchemaRegistry } from './registry';
3
- import { ObjectQL } from './engine';
2
+ import { SchemaRegistry, ObjectQL } from '@objectstack/objectql';
4
3
 
5
4
  /**
6
- * Server Data Engine Wrapper
5
+ * ObjectStack Kernel (Microkernel)
7
6
  *
8
- * This class is now a thin wrapper that initializes the ObjectQL Engine
9
- * with the appropriate Server-Side configuration (Registry, Drivers).
10
- *
11
- * The core logic has been moved to @objectstack/objectql.
7
+ * The central container orchestrating the application lifecycle,
8
+ * plugins, and the core ObjectQL engine.
12
9
  */
13
- export class DataEngine {
10
+ export class ObjectStackKernel {
14
11
  public ql: ObjectQL;
15
12
  private plugins: any[];
16
13
 
@@ -23,21 +20,29 @@ export class DataEngine {
23
20
  }
24
21
 
25
22
  async start() {
26
- console.log('[DataEngine] Starting...');
23
+ console.log('[Kernel] Starting...');
27
24
 
28
25
  // 0. Register Provided Plugins
29
- this.plugins.forEach(p => {
30
- console.log(`[DataEngine] Loading Plugin: ${p.id || p.name}`);
26
+ for (const p of this.plugins) {
27
+ // Check if it is a Runtime Plugin (System Capability)
28
+ if ('onStart' in p || 'install' in p) {
29
+ console.log(`[Kernel] Loading Runtime Plugin: ${p.name}`);
30
+ if (p.install) await p.install({ engine: this });
31
+ continue;
32
+ }
33
+
34
+ // Otherwise treat as App Manifest
35
+ console.log(`[Kernel] Loading App Manifest: ${p.id || p.name}`);
31
36
  SchemaRegistry.registerPlugin(p);
32
37
 
33
38
  // Register Objects from App/Plugin
34
39
  if (p.objects) {
35
40
  for (const obj of p.objects) {
36
41
  SchemaRegistry.registerObject(obj);
37
- console.log(`[DataEngine] Registered Object: ${obj.name}`);
42
+ console.log(`[Kernel] Registered Object: ${obj.name}`);
38
43
  }
39
44
  }
40
- });
45
+ }
41
46
 
42
47
  // 1. Load Drivers (Default to Memory if none provided in plugins)
43
48
  // TODO: Detect driver from plugins. For now, we still hard load memory driver if needed?
@@ -60,6 +65,14 @@ export class DataEngine {
60
65
 
61
66
  // 3. Seed Data
62
67
  await this.seed();
68
+
69
+ // 4. Start Runtime Plugins
70
+ for (const p of this.plugins) {
71
+ if (('onStart' in p) && typeof p.onStart === 'function') {
72
+ console.log(`[Kernel] Starting Plugin: ${p.name}`);
73
+ await p.onStart({ engine: this });
74
+ }
75
+ }
63
76
  }
64
77
 
65
78
  async seed() {
@@ -85,19 +98,19 @@ export class DataEngine {
85
98
  for (const appItem of apps) {
86
99
  const app = appItem as any; // Cast to access data prop safely
87
100
  if (app.data && Array.isArray(app.data)) {
88
- console.log(`[DataEngine] Seeding data for ${app.name || app.id}...`);
101
+ console.log(`[Kernel] Seeding data for ${app.name || app.id}...`);
89
102
  for (const seed of app.data) {
90
103
  try {
91
104
  // Check if data exists
92
105
  const existing = await this.ql.find(seed.object, { top: 1 });
93
106
  if (existing.length === 0) {
94
- console.log(`[DataEngine] Inserting ${seed.records.length} records into ${seed.object}`);
107
+ console.log(`[Kernel] Inserting ${seed.records.length} records into ${seed.object}`);
95
108
  for (const record of seed.records) {
96
109
  await this.ql.insert(seed.object, record);
97
110
  }
98
111
  }
99
112
  } catch (e) {
100
- console.warn(`[DataEngine] Failed to seed ${seed.object}`, e);
113
+ console.warn(`[Kernel] Failed to seed ${seed.object}`, e);
101
114
  }
102
115
  }
103
116
  }
package/src/protocol.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { SchemaRegistry } from './registry';
2
- import { DataEngine } from './data-engine';
1
+ import { SchemaRegistry } from '@objectstack/objectql';
2
+ import { ObjectStackKernel } from './kernel';
3
3
 
4
4
  export interface ApiRequest {
5
5
  params: Record<string, string>;
@@ -8,9 +8,9 @@ export interface ApiRequest {
8
8
  }
9
9
 
10
10
  export class ObjectStackRuntimeProtocol {
11
- private engine: DataEngine;
11
+ private engine: ObjectStackKernel;
12
12
 
13
- constructor(engine: DataEngine) {
13
+ constructor(engine: ObjectStackKernel) {
14
14
  this.engine = engine;
15
15
  }
16
16
 
package/src/types.ts ADDED
@@ -0,0 +1,11 @@
1
+ import { ObjectStackKernel } from './kernel';
2
+
3
+ export interface RuntimeContext {
4
+ engine: ObjectStackKernel;
5
+ }
6
+
7
+ export interface RuntimePlugin {
8
+ name: string;
9
+ install?: (ctx: RuntimeContext) => void | Promise<void>;
10
+ onStart?: (ctx: RuntimeContext) => void | Promise<void>;
11
+ }
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,157 +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
- // 1. Handle Module Imports (commonjs/esm interop)
25
- // If the passed object is a module namespace with a default export, use that.
26
- const manifest = manifestPart.default || manifestPart;
27
- // In a real scenario, we might strictly parse this using Zod
28
- // For now, simple ID check
29
- const id = manifest.id || manifest.name;
30
- if (!id) {
31
- console.warn(`[ObjectQL] Plugin manifest missing ID (keys: ${Object.keys(manifest)})`, manifest);
32
- // Don't return, try to proceed if it looks like an App (Apps might use 'name' instead of 'id')
33
- // return;
34
- }
35
- console.log(`[ObjectQL] Loading Plugin: ${id}`);
36
- registry_1.SchemaRegistry.registerPlugin(manifest);
37
- // Register Objects from App/Plugin
38
- if (manifest.objects) {
39
- for (const obj of manifest.objects) {
40
- // Ensure object name is registered globally
41
- registry_1.SchemaRegistry.registerObject(obj);
42
- console.log(`[ObjectQL] Registered Object: ${obj.name}`);
43
- }
44
- }
45
- // Register contributions
46
- if (manifest.contributes?.kinds) {
47
- for (const kind of manifest.contributes.kinds) {
48
- registry_1.SchemaRegistry.registerKind(kind);
49
- }
50
- }
51
- // Register Data Seeding (Lazy execution or immediate?)
52
- // We store it in a temporary registry or execute immediately if engine is ready.
53
- // Since `use` is init time, we might need to store it and run later in `seed()`.
54
- // For this MVP, let's attach it to the manifest object in registry so DataEngine can find it.
55
- }
56
- // 2. Execute Runtime
57
- if (runtimePart) {
58
- const pluginDef = runtimePart.default || runtimePart;
59
- if (pluginDef.onEnable) {
60
- const context = {
61
- ql: this,
62
- logger: console,
63
- // Expose the driver registry helper explicitly if needed
64
- drivers: {
65
- register: (driver) => this.registerDriver(driver)
66
- },
67
- ...this.hostContext
68
- };
69
- await pluginDef.onEnable(context);
70
- }
71
- }
72
- }
73
- /**
74
- * Register a new storage driver
75
- */
76
- registerDriver(driver, isDefault = false) {
77
- if (this.drivers.has(driver.name)) {
78
- console.warn(`[ObjectQL] Driver ${driver.name} is already registered. Skipping.`);
79
- return;
80
- }
81
- this.drivers.set(driver.name, driver);
82
- console.log(`[ObjectQL] Registered driver: ${driver.name} v${driver.version}`);
83
- if (isDefault || this.drivers.size === 1) {
84
- this.defaultDriver = driver.name;
85
- }
86
- }
87
- /**
88
- * Helper to get the target driver
89
- */
90
- getDriver(object) {
91
- // TODO: Look up Object definition to see if it specifies a specific datasource/driver
92
- // For now, always return default
93
- if (!this.defaultDriver) {
94
- throw new Error('[ObjectQL] No drivers registered!');
95
- }
96
- return this.drivers.get(this.defaultDriver);
97
- }
98
- /**
99
- * Initialize the engine and all registered drivers
100
- */
101
- async init() {
102
- console.log('[ObjectQL] Initializing drivers...');
103
- for (const [name, driver] of this.drivers) {
104
- try {
105
- await driver.connect();
106
- }
107
- catch (e) {
108
- console.error(`[ObjectQL] Failed to connect driver ${name}`, e);
109
- }
110
- }
111
- // In a real app, we would sync schemas here
112
- }
113
- async destroy() {
114
- for (const driver of this.drivers.values()) {
115
- await driver.disconnect();
116
- }
117
- }
118
- // ============================================
119
- // Data Access Methods
120
- // ============================================
121
- async find(object, filters = {}, options) {
122
- const driver = this.getDriver(object);
123
- console.log(`[ObjectQL] Finding ${object} on ${driver.name}...`);
124
- // Transform simplified filters to QueryAST
125
- // This is a simplified "Mock" transform.
126
- // Real implementation would parse complex JSON or FilterBuilders.
127
- const ast = {
128
- object, // Add missing required field
129
- // Pass through if it looks like AST, otherwise empty
130
- // In this demo, we assume the caller passes a simplified object or raw AST
131
- filters: filters.filters || undefined,
132
- top: filters.top || 100,
133
- sort: filters.sort || []
134
- };
135
- return driver.find(object, ast, options);
136
- }
137
- async insert(object, data, options) {
138
- const driver = this.getDriver(object);
139
- console.log(`[ObjectQL] Creating ${object} on ${driver.name}...`);
140
- // 1. Validate Schema
141
- // 2. Run "Before Insert" Triggers
142
- const result = await driver.create(object, data, options);
143
- // 3. Run "After Insert" Triggers
144
- return result;
145
- }
146
- async update(object, id, data, options) {
147
- const driver = this.getDriver(object);
148
- console.log(`[ObjectQL] Updating ${object} ${id}...`);
149
- return driver.update(object, id, data, options);
150
- }
151
- async delete(object, id, options) {
152
- const driver = this.getDriver(object);
153
- console.log(`[ObjectQL] Deleting ${object} ${id}...`);
154
- return driver.delete(object, id, options);
155
- }
156
- }
157
- exports.ObjectQL = ObjectQL;
@@ -1,55 +0,0 @@
1
- import { ServiceObject, App, ObjectStackManifest } from '@objectstack/spec';
2
- /**
3
- * Global Schema Registry
4
- * Unified storage for all metadata types (Objects, Apps, Flows, Layouts, etc.)
5
- */
6
- export declare class SchemaRegistry {
7
- private static metadata;
8
- /**
9
- * Universal Register Method
10
- * @param type The category of metadata (e.g., 'object', 'app', 'plugin')
11
- * @param item The metadata item itself
12
- * @param keyField The property to use as the unique key (default: 'name')
13
- */
14
- static registerItem<T>(type: string, item: T, keyField?: keyof T): void;
15
- /**
16
- * Universal Get Method
17
- */
18
- static getItem<T>(type: string, name: string): T | undefined;
19
- /**
20
- * Universal List Method
21
- */
22
- static listItems<T>(type: string): T[];
23
- /**
24
- * Get all registered metadata types (Kinds)
25
- */
26
- static getRegisteredTypes(): string[];
27
- /**
28
- * Object Helpers
29
- */
30
- static registerObject(schema: ServiceObject): void;
31
- static getObject(name: string): ServiceObject | undefined;
32
- static getAllObjects(): ServiceObject[];
33
- /**
34
- * App Helpers
35
- */
36
- static registerApp(app: App): void;
37
- static getApp(name: string): App | undefined;
38
- static getAllApps(): App[];
39
- /**
40
- * Plugin Helpers
41
- */
42
- static registerPlugin(manifest: ObjectStackManifest): void;
43
- static getAllPlugins(): ObjectStackManifest[];
44
- /**
45
- * Kind (Metadata Type) Helpers
46
- */
47
- static registerKind(kind: {
48
- id: string;
49
- globs: string[];
50
- }): void;
51
- static getAllKinds(): {
52
- id: string;
53
- globs: string[];
54
- }[];
55
- }
package/dist/registry.js DELETED
@@ -1,93 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.SchemaRegistry = void 0;
4
- /**
5
- * Global Schema Registry
6
- * Unified storage for all metadata types (Objects, Apps, Flows, Layouts, etc.)
7
- */
8
- class SchemaRegistry {
9
- /**
10
- * Universal Register Method
11
- * @param type The category of metadata (e.g., 'object', 'app', 'plugin')
12
- * @param item The metadata item itself
13
- * @param keyField The property to use as the unique key (default: 'name')
14
- */
15
- static registerItem(type, item, keyField = 'name') {
16
- if (!this.metadata.has(type)) {
17
- this.metadata.set(type, new Map());
18
- }
19
- const collection = this.metadata.get(type);
20
- const key = String(item[keyField]);
21
- if (collection.has(key)) {
22
- console.warn(`[Registry] Overwriting ${type}: ${key}`);
23
- }
24
- collection.set(key, item);
25
- console.log(`[Registry] Registered ${type}: ${key}`);
26
- }
27
- /**
28
- * Universal Get Method
29
- */
30
- static getItem(type, name) {
31
- return this.metadata.get(type)?.get(name);
32
- }
33
- /**
34
- * Universal List Method
35
- */
36
- static listItems(type) {
37
- return Array.from(this.metadata.get(type)?.values() || []);
38
- }
39
- /**
40
- * Get all registered metadata types (Kinds)
41
- */
42
- static getRegisteredTypes() {
43
- return Array.from(this.metadata.keys());
44
- }
45
- // ==========================================
46
- // Typed Helper Methods (Shortcuts)
47
- // ==========================================
48
- /**
49
- * Object Helpers
50
- */
51
- static registerObject(schema) {
52
- this.registerItem('object', schema, 'name');
53
- }
54
- static getObject(name) {
55
- return this.getItem('object', name);
56
- }
57
- static getAllObjects() {
58
- return this.listItems('object');
59
- }
60
- /**
61
- * App Helpers
62
- */
63
- static registerApp(app) {
64
- this.registerItem('app', app, 'name');
65
- }
66
- static getApp(name) {
67
- return this.getItem('app', name);
68
- }
69
- static getAllApps() {
70
- return this.listItems('app');
71
- }
72
- /**
73
- * Plugin Helpers
74
- */
75
- static registerPlugin(manifest) {
76
- this.registerItem('plugin', manifest, 'id');
77
- }
78
- static getAllPlugins() {
79
- return this.listItems('plugin');
80
- }
81
- /**
82
- * Kind (Metadata Type) Helpers
83
- */
84
- static registerKind(kind) {
85
- this.registerItem('kind', kind, 'id');
86
- }
87
- static getAllKinds() {
88
- return this.listItems('kind');
89
- }
90
- }
91
- exports.SchemaRegistry = SchemaRegistry;
92
- // Nested Map: Type -> Name/ID -> MetadataItem
93
- SchemaRegistry.metadata = new Map();
package/src/engine.ts DELETED
@@ -1,189 +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
- // 1. Handle Module Imports (commonjs/esm interop)
37
- // If the passed object is a module namespace with a default export, use that.
38
- const manifest = manifestPart.default || manifestPart;
39
-
40
- // In a real scenario, we might strictly parse this using Zod
41
- // For now, simple ID check
42
- const id = manifest.id || manifest.name;
43
- if (!id) {
44
- console.warn(`[ObjectQL] Plugin manifest missing ID (keys: ${Object.keys(manifest)})`, manifest);
45
- // Don't return, try to proceed if it looks like an App (Apps might use 'name' instead of 'id')
46
- // return;
47
- }
48
-
49
- console.log(`[ObjectQL] Loading Plugin: ${id}`);
50
- SchemaRegistry.registerPlugin(manifest as ObjectStackManifest);
51
-
52
- // Register Objects from App/Plugin
53
- if (manifest.objects) {
54
- for (const obj of manifest.objects) {
55
- // Ensure object name is registered globally
56
- SchemaRegistry.registerObject(obj);
57
- console.log(`[ObjectQL] Registered Object: ${obj.name}`);
58
- }
59
- }
60
-
61
- // Register contributions
62
- if (manifest.contributes?.kinds) {
63
- for (const kind of manifest.contributes.kinds) {
64
- SchemaRegistry.registerKind(kind);
65
- }
66
- }
67
-
68
- // Register Data Seeding (Lazy execution or immediate?)
69
- // We store it in a temporary registry or execute immediately if engine is ready.
70
- // Since `use` is init time, we might need to store it and run later in `seed()`.
71
- // For this MVP, let's attach it to the manifest object in registry so DataEngine can find it.
72
- }
73
-
74
- // 2. Execute Runtime
75
- if (runtimePart) {
76
- const pluginDef = (runtimePart as any).default || runtimePart;
77
- if (pluginDef.onEnable) {
78
- const context: PluginContext = {
79
- ql: this,
80
- logger: console,
81
- // Expose the driver registry helper explicitly if needed
82
- drivers: {
83
- register: (driver: DriverInterface) => this.registerDriver(driver)
84
- },
85
- ...this.hostContext
86
- };
87
-
88
- await pluginDef.onEnable(context);
89
- }
90
- }
91
- }
92
-
93
- /**
94
- * Register a new storage driver
95
- */
96
- registerDriver(driver: DriverInterface, isDefault: boolean = false) {
97
- if (this.drivers.has(driver.name)) {
98
- console.warn(`[ObjectQL] Driver ${driver.name} is already registered. Skipping.`);
99
- return;
100
- }
101
-
102
- this.drivers.set(driver.name, driver);
103
- console.log(`[ObjectQL] Registered driver: ${driver.name} v${driver.version}`);
104
-
105
- if (isDefault || this.drivers.size === 1) {
106
- this.defaultDriver = driver.name;
107
- }
108
- }
109
-
110
- /**
111
- * Helper to get the target driver
112
- */
113
- private getDriver(object: string): DriverInterface {
114
- // TODO: Look up Object definition to see if it specifies a specific datasource/driver
115
- // For now, always return default
116
- if (!this.defaultDriver) {
117
- throw new Error('[ObjectQL] No drivers registered!');
118
- }
119
- return this.drivers.get(this.defaultDriver)!;
120
- }
121
-
122
- /**
123
- * Initialize the engine and all registered drivers
124
- */
125
- async init() {
126
- console.log('[ObjectQL] Initializing drivers...');
127
- for (const [name, driver] of this.drivers) {
128
- try {
129
- await driver.connect();
130
- } catch (e) {
131
- console.error(`[ObjectQL] Failed to connect driver ${name}`, e);
132
- }
133
- }
134
- // In a real app, we would sync schemas here
135
- }
136
-
137
- async destroy() {
138
- for (const driver of this.drivers.values()) {
139
- await driver.disconnect();
140
- }
141
- }
142
-
143
- // ============================================
144
- // Data Access Methods
145
- // ============================================
146
-
147
- async find(object: string, filters: any = {}, options?: DriverOptions) {
148
- const driver = this.getDriver(object);
149
- console.log(`[ObjectQL] Finding ${object} on ${driver.name}...`);
150
-
151
- // Transform simplified filters to QueryAST
152
- // This is a simplified "Mock" transform.
153
- // Real implementation would parse complex JSON or FilterBuilders.
154
- const ast: QueryAST = {
155
- object, // Add missing required field
156
- // Pass through if it looks like AST, otherwise empty
157
- // In this demo, we assume the caller passes a simplified object or raw AST
158
- filters: filters.filters || undefined,
159
- top: filters.top || 100,
160
- sort: filters.sort || []
161
- };
162
-
163
- return driver.find(object, ast, options);
164
- }
165
-
166
- async insert(object: string, data: Record<string, any>, options?: DriverOptions) {
167
- const driver = this.getDriver(object);
168
- console.log(`[ObjectQL] Creating ${object} on ${driver.name}...`);
169
- // 1. Validate Schema
170
- // 2. Run "Before Insert" Triggers
171
-
172
- const result = await driver.create(object, data, options);
173
-
174
- // 3. Run "After Insert" Triggers
175
- return result;
176
- }
177
-
178
- async update(object: string, id: string, data: Record<string, any>, options?: DriverOptions) {
179
- const driver = this.getDriver(object);
180
- console.log(`[ObjectQL] Updating ${object} ${id}...`);
181
- return driver.update(object, id, data, options);
182
- }
183
-
184
- async delete(object: string, id: string, options?: DriverOptions) {
185
- const driver = this.getDriver(object);
186
- console.log(`[ObjectQL] Deleting ${object} ${id}...`);
187
- return driver.delete(object, id, options);
188
- }
189
- }
package/src/registry.ts DELETED
@@ -1,107 +0,0 @@
1
- import { ServiceObject, App, ObjectStackManifest } from '@objectstack/spec';
2
-
3
- /**
4
- * Global Schema Registry
5
- * Unified storage for all metadata types (Objects, Apps, Flows, Layouts, etc.)
6
- */
7
- export class SchemaRegistry {
8
- // Nested Map: Type -> Name/ID -> MetadataItem
9
- private static metadata = new Map<string, Map<string, any>>();
10
-
11
- /**
12
- * Universal Register Method
13
- * @param type The category of metadata (e.g., 'object', 'app', 'plugin')
14
- * @param item The metadata item itself
15
- * @param keyField The property to use as the unique key (default: 'name')
16
- */
17
- static registerItem<T>(type: string, item: T, keyField: keyof T = 'name' as keyof T) {
18
- if (!this.metadata.has(type)) {
19
- this.metadata.set(type, new Map());
20
- }
21
- const collection = this.metadata.get(type)!;
22
- const key = String(item[keyField]);
23
-
24
- if (collection.has(key)) {
25
- console.warn(`[Registry] Overwriting ${type}: ${key}`);
26
- }
27
- collection.set(key, item);
28
- console.log(`[Registry] Registered ${type}: ${key}`);
29
- }
30
-
31
- /**
32
- * Universal Get Method
33
- */
34
- static getItem<T>(type: string, name: string): T | undefined {
35
- return this.metadata.get(type)?.get(name) as T;
36
- }
37
-
38
- /**
39
- * Universal List Method
40
- */
41
- static listItems<T>(type: string): T[] {
42
- return Array.from(this.metadata.get(type)?.values() || []) as T[];
43
- }
44
-
45
- /**
46
- * Get all registered metadata types (Kinds)
47
- */
48
- static getRegisteredTypes(): string[] {
49
- return Array.from(this.metadata.keys());
50
- }
51
-
52
- // ==========================================
53
- // Typed Helper Methods (Shortcuts)
54
- // ==========================================
55
-
56
- /**
57
- * Object Helpers
58
- */
59
- static registerObject(schema: ServiceObject) {
60
- this.registerItem('object', schema, 'name');
61
- }
62
-
63
- static getObject(name: string): ServiceObject | undefined {
64
- return this.getItem<ServiceObject>('object', name);
65
- }
66
-
67
- static getAllObjects(): ServiceObject[] {
68
- return this.listItems<ServiceObject>('object');
69
- }
70
-
71
- /**
72
- * App Helpers
73
- */
74
- static registerApp(app: App) {
75
- this.registerItem('app', app, 'name');
76
- }
77
-
78
- static getApp(name: string): App | undefined {
79
- return this.getItem<App>('app', name);
80
- }
81
-
82
- static getAllApps(): App[] {
83
- return this.listItems<App>('app');
84
- }
85
-
86
- /**
87
- * Plugin Helpers
88
- */
89
- static registerPlugin(manifest: ObjectStackManifest) {
90
- this.registerItem('plugin', manifest, 'id');
91
- }
92
-
93
- static getAllPlugins(): ObjectStackManifest[] {
94
- return this.listItems<ObjectStackManifest>('plugin');
95
- }
96
-
97
- /**
98
- * Kind (Metadata Type) Helpers
99
- */
100
- static registerKind(kind: { id: string, globs: string[] }) {
101
- this.registerItem('kind', kind, 'id');
102
- }
103
-
104
- static getAllKinds(): { id: string, globs: string[] }[] {
105
- return this.listItems('kind');
106
- }
107
- }