@objectstack/runtime 0.4.2 → 0.6.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/src/index.ts CHANGED
@@ -1,8 +1,11 @@
1
- // Export core engine
2
- export { ObjectQL, SchemaRegistry } from '@objectstack/objectql';
3
- export { ObjectStackKernel } from './kernel';
4
- export { ObjectQLPlugin } from './objectql-plugin';
5
- export { ObjectStackRuntimeProtocol } from './protocol';
1
+ // Export Kernels
2
+ export { ObjectKernel } from '@objectstack/core';
3
+
4
+ // Export Plugins
5
+ export { DriverPlugin } from './driver-plugin';
6
+ export { AppPlugin } from './app-plugin';
7
+
8
+ // Export Types
9
+ export * from '@objectstack/core';
6
10
 
7
- export * from './types';
8
11
 
package/dist/kernel.d.ts DELETED
@@ -1,147 +0,0 @@
1
- import { ObjectQL } from '@objectstack/objectql';
2
- /**
3
- * ObjectStack Kernel (Microkernel)
4
- *
5
- * The central container orchestrating the application lifecycle,
6
- * plugins, and the core ObjectQL engine.
7
- */
8
- export declare class ObjectStackKernel {
9
- ql?: ObjectQL;
10
- private plugins;
11
- constructor(plugins?: any[]);
12
- /**
13
- * Ensure ObjectQL engine is initialized
14
- * @throws Error if ObjectQL is not available
15
- */
16
- private ensureObjectQL;
17
- start(): Promise<void>;
18
- seed(): Promise<void>;
19
- find(objectName: string, query: any): Promise<{
20
- value: any;
21
- count: any;
22
- }>;
23
- get(objectName: string, id: string): Promise<any>;
24
- create(objectName: string, data: any): Promise<any>;
25
- update(objectName: string, id: string, data: any): Promise<any>;
26
- delete(objectName: string, id: string): Promise<any>;
27
- getMetadata(objectName: string): {
28
- fields: Record<string, {
29
- type: "number" | "boolean" | "code" | "date" | "text" | "textarea" | "email" | "url" | "phone" | "password" | "markdown" | "html" | "richtext" | "currency" | "percent" | "datetime" | "time" | "toggle" | "select" | "multiselect" | "radio" | "checkboxes" | "lookup" | "master_detail" | "tree" | "image" | "file" | "avatar" | "video" | "audio" | "formula" | "summary" | "autonumber" | "location" | "address" | "json" | "color" | "rating" | "slider" | "signature" | "qrcode" | "progress" | "tags" | "vector";
30
- required: boolean;
31
- searchable: boolean;
32
- multiple: boolean;
33
- unique: boolean;
34
- deleteBehavior: "set_null" | "cascade" | "restrict";
35
- hidden: boolean;
36
- readonly: boolean;
37
- encryption: boolean;
38
- index: boolean;
39
- externalId: boolean;
40
- options?: {
41
- value: string;
42
- label: string;
43
- color?: string | undefined;
44
- default?: boolean | undefined;
45
- }[] | undefined;
46
- min?: number | undefined;
47
- max?: number | undefined;
48
- formula?: string | undefined;
49
- label?: string | undefined;
50
- precision?: number | undefined;
51
- name?: string | undefined;
52
- description?: string | undefined;
53
- format?: string | undefined;
54
- defaultValue?: any;
55
- maxLength?: number | undefined;
56
- minLength?: number | undefined;
57
- scale?: number | undefined;
58
- reference?: string | undefined;
59
- referenceFilters?: string[] | undefined;
60
- writeRequiresMasterRead?: boolean | undefined;
61
- expression?: string | undefined;
62
- summaryOperations?: {
63
- object: string;
64
- function: "count" | "sum" | "avg" | "min" | "max";
65
- field: string;
66
- } | undefined;
67
- language?: string | undefined;
68
- theme?: string | undefined;
69
- lineNumbers?: boolean | undefined;
70
- maxRating?: number | undefined;
71
- allowHalf?: boolean | undefined;
72
- displayMap?: boolean | undefined;
73
- allowGeocoding?: boolean | undefined;
74
- addressFormat?: "us" | "uk" | "international" | undefined;
75
- colorFormat?: "hex" | "rgb" | "rgba" | "hsl" | undefined;
76
- allowAlpha?: boolean | undefined;
77
- presetColors?: string[] | undefined;
78
- step?: number | undefined;
79
- showValue?: boolean | undefined;
80
- marks?: Record<string, string> | undefined;
81
- barcodeFormat?: "qr" | "ean13" | "ean8" | "code128" | "code39" | "upca" | "upce" | undefined;
82
- qrErrorCorrection?: "L" | "M" | "Q" | "H" | undefined;
83
- displayValue?: boolean | undefined;
84
- allowScanning?: boolean | undefined;
85
- currencyConfig?: {
86
- precision: number;
87
- currencyMode: "dynamic" | "fixed";
88
- defaultCurrency: string;
89
- } | undefined;
90
- vectorConfig?: {
91
- dimensions: number;
92
- distanceMetric: "cosine" | "euclidean" | "dotProduct" | "manhattan";
93
- normalized: boolean;
94
- indexed: boolean;
95
- indexType?: "flat" | "hnsw" | "ivfflat" | undefined;
96
- } | undefined;
97
- }>;
98
- name: string;
99
- active: boolean;
100
- isSystem: boolean;
101
- abstract: boolean;
102
- datasource: string;
103
- tags?: string[] | undefined;
104
- label?: string | undefined;
105
- description?: string | undefined;
106
- search?: {
107
- fields: string[];
108
- displayFields?: string[] | undefined;
109
- filters?: string[] | undefined;
110
- } | undefined;
111
- pluralLabel?: string | undefined;
112
- icon?: string | undefined;
113
- tableName?: string | undefined;
114
- indexes?: {
115
- fields: string[];
116
- type?: "hash" | "btree" | "gin" | "gist" | undefined;
117
- name?: string | undefined;
118
- unique?: boolean | undefined;
119
- }[] | undefined;
120
- validations?: any[] | undefined;
121
- titleFormat?: string | undefined;
122
- compactLayout?: string[] | undefined;
123
- enable?: {
124
- searchable: boolean;
125
- trackHistory: boolean;
126
- apiEnabled: boolean;
127
- files: boolean;
128
- feeds: boolean;
129
- activities: boolean;
130
- trash: boolean;
131
- mru: boolean;
132
- clone: boolean;
133
- apiMethods?: ("update" | "delete" | "get" | "list" | "create" | "upsert" | "bulk" | "aggregate" | "history" | "search" | "restore" | "purge" | "import" | "export")[] | undefined;
134
- } | undefined;
135
- };
136
- getView(objectName: string, viewType?: 'list' | 'form'): {
137
- type: string;
138
- title: string;
139
- columns: {
140
- field: string;
141
- label: string;
142
- width: number;
143
- }[];
144
- actions: string[];
145
- } | null;
146
- private ensureSchema;
147
- }
package/dist/kernel.js DELETED
@@ -1,173 +0,0 @@
1
- import { SchemaRegistry, ObjectQL } from '@objectstack/objectql';
2
- /**
3
- * ObjectStack Kernel (Microkernel)
4
- *
5
- * The central container orchestrating the application lifecycle,
6
- * plugins, and the core ObjectQL engine.
7
- */
8
- export class ObjectStackKernel {
9
- constructor(plugins = []) {
10
- this.plugins = plugins;
11
- // Check if any plugin provides ObjectQL via type: 'objectql'
12
- // This aligns with the manifest schema that supports objectql as a package type
13
- const hasObjectQLPlugin = plugins.some(p => p && typeof p === 'object' && p.type === 'objectql');
14
- if (!hasObjectQLPlugin) {
15
- // Backward compatibility: Initialize ObjectQL directly if no plugin provides it
16
- console.warn('[Kernel] No ObjectQL plugin found, using default initialization. Consider using ObjectQLPlugin.');
17
- this.ql = new ObjectQL({
18
- env: process.env.NODE_ENV || 'development'
19
- });
20
- }
21
- }
22
- /**
23
- * Ensure ObjectQL engine is initialized
24
- * @throws Error if ObjectQL is not available
25
- */
26
- ensureObjectQL() {
27
- if (!this.ql) {
28
- throw new Error('[Kernel] ObjectQL engine not initialized. Ensure ObjectQLPlugin is registered or kernel is properly initialized.');
29
- }
30
- return this.ql;
31
- }
32
- async start() {
33
- console.log('[Kernel] Starting...');
34
- // 0. Register Provided Plugins
35
- for (const p of this.plugins) {
36
- // Check if it is a Runtime Plugin (System Capability)
37
- if ('onStart' in p || 'install' in p) {
38
- console.log(`[Kernel] Loading Runtime Plugin: ${p.name}`);
39
- if (p.install)
40
- await p.install({ engine: this });
41
- continue;
42
- }
43
- // Otherwise treat as App Manifest
44
- console.log(`[Kernel] Loading App Manifest: ${p.id || p.name}`);
45
- SchemaRegistry.registerPlugin(p);
46
- // Register Objects from App/Plugin
47
- if (p.objects) {
48
- for (const obj of p.objects) {
49
- SchemaRegistry.registerObject(obj);
50
- console.log(`[Kernel] Registered Object: ${obj.name}`);
51
- }
52
- }
53
- }
54
- // 1. Load Drivers (Default to Memory if none provided in plugins)
55
- // TODO: Detect driver from plugins. For now, we still hard load memory driver if needed?
56
- // In strict mode, user should pass driver in plugins array (DriverManifest).
57
- // check if driver is registered
58
- // For Backwards Compat / Easy Dev, try dynamic import of memory driver if installed
59
- try {
60
- // @ts-ignore
61
- const { InMemoryDriver } = await import('@objectstack/driver-memory');
62
- const driver = new InMemoryDriver();
63
- this.ensureObjectQL().registerDriver(driver);
64
- }
65
- catch (e) {
66
- // Ignore if not present
67
- }
68
- // 2. Initialize Engine
69
- await this.ensureObjectQL().init();
70
- // 3. Seed Data
71
- await this.seed();
72
- // 4. Start Runtime Plugins
73
- for (const p of this.plugins) {
74
- if (('onStart' in p) && typeof p.onStart === 'function') {
75
- console.log(`[Kernel] Starting Plugin: ${p.name}`);
76
- await p.onStart({ engine: this });
77
- }
78
- }
79
- }
80
- async seed() {
81
- // If no driver registered yet, this might fail or wait.
82
- // In real world, we wait for 'ready' event.
83
- try {
84
- // Mock System Table
85
- try {
86
- // We don't have SystemStatus defined in schema usually, skipping for general engine
87
- // await this.ql.insert('SystemStatus', { status: 'OK', uptime: 0 });
88
- }
89
- catch { }
90
- // Iterate over all registered plugins/apps and check for 'data' property in manifest
91
- const plugins = SchemaRegistry.getRegisteredTypes(); // This returns types like 'plugin', 'app'
92
- // This is a bit hacky because we don't have a direct "getAllManifests" API exposed easily
93
- // We will iterate known apps for now, or improve Registry API later.
94
- // Actually, SchemaRegistry.listItems('app') returns the manifests!
95
- const apps = [...SchemaRegistry.listItems('app'), ...SchemaRegistry.listItems('plugin')];
96
- for (const appItem of apps) {
97
- const app = appItem; // Cast to access data prop safely
98
- if (app.data && Array.isArray(app.data)) {
99
- console.log(`[Kernel] Seeding data for ${app.name || app.id}...`);
100
- for (const seed of app.data) {
101
- try {
102
- // Check if data exists
103
- const existing = await this.ensureObjectQL().find(seed.object, { top: 1 });
104
- if (existing.length === 0) {
105
- console.log(`[Kernel] Inserting ${seed.records.length} records into ${seed.object}`);
106
- for (const record of seed.records) {
107
- await this.ensureObjectQL().insert(seed.object, record);
108
- }
109
- }
110
- }
111
- catch (e) {
112
- console.warn(`[Kernel] Failed to seed ${seed.object}`, e);
113
- }
114
- }
115
- }
116
- }
117
- }
118
- catch (e) {
119
- console.warn('Seed failed (driver might not be ready):', e);
120
- }
121
- }
122
- // Forward methods to ObjectQL
123
- async find(objectName, query) {
124
- this.ensureSchema(objectName);
125
- const results = await this.ensureObjectQL().find(objectName, { top: 100 });
126
- return { value: results, count: results.length };
127
- }
128
- async get(objectName, id) {
129
- this.ensureSchema(objectName);
130
- // Find One
131
- const results = await this.ensureObjectQL().find(objectName, { top: 1 }); // Mock implementation
132
- return results[0];
133
- }
134
- async create(objectName, data) {
135
- this.ensureSchema(objectName);
136
- return this.ensureObjectQL().insert(objectName, data);
137
- }
138
- async update(objectName, id, data) {
139
- this.ensureSchema(objectName);
140
- return this.ensureObjectQL().update(objectName, id, data);
141
- }
142
- async delete(objectName, id) {
143
- this.ensureSchema(objectName);
144
- return this.ensureObjectQL().delete(objectName, id);
145
- }
146
- // [New Methods for ObjectUI]
147
- getMetadata(objectName) {
148
- return this.ensureSchema(objectName);
149
- }
150
- getView(objectName, viewType = 'list') {
151
- const schema = this.ensureSchema(objectName);
152
- // Auto-Scaffold Default View
153
- if (viewType === 'list') {
154
- return {
155
- type: 'datagrid',
156
- title: `${schema.label || objectName} List`,
157
- columns: Object.keys(schema.fields || {}).map(key => ({
158
- field: key,
159
- label: schema.fields?.[key]?.label || key,
160
- width: 150
161
- })),
162
- actions: ['create', 'edit', 'delete']
163
- };
164
- }
165
- return null;
166
- }
167
- ensureSchema(name) {
168
- const schema = SchemaRegistry.getObject(name);
169
- if (!schema)
170
- throw new Error(`Unknown object: ${name}`);
171
- return schema;
172
- }
173
- }
@@ -1,27 +0,0 @@
1
- import { ObjectQL } from '@objectstack/objectql';
2
- import { RuntimePlugin, RuntimeContext } from '@objectstack/types';
3
- /**
4
- * ObjectQL Engine Plugin
5
- *
6
- * Registers the ObjectQL engine instance with the kernel.
7
- * This allows users to provide their own ObjectQL implementation or configuration.
8
- *
9
- * Usage:
10
- * - new ObjectQLPlugin() - Creates new ObjectQL with default settings
11
- * - new ObjectQLPlugin(existingQL) - Uses existing ObjectQL instance
12
- * - new ObjectQLPlugin(undefined, { custom: 'context' }) - Creates new ObjectQL with custom context
13
- */
14
- export declare class ObjectQLPlugin implements RuntimePlugin {
15
- name: string;
16
- type: "objectql";
17
- private ql;
18
- /**
19
- * @param ql - Existing ObjectQL instance to use (optional)
20
- * @param hostContext - Host context for new ObjectQL instance (ignored if ql is provided)
21
- */
22
- constructor(ql?: ObjectQL, hostContext?: Record<string, any>);
23
- /**
24
- * Install the ObjectQL engine into the kernel
25
- */
26
- install(ctx: RuntimeContext): Promise<void>;
27
- }
@@ -1,41 +0,0 @@
1
- import { ObjectQL } from '@objectstack/objectql';
2
- /**
3
- * ObjectQL Engine Plugin
4
- *
5
- * Registers the ObjectQL engine instance with the kernel.
6
- * This allows users to provide their own ObjectQL implementation or configuration.
7
- *
8
- * Usage:
9
- * - new ObjectQLPlugin() - Creates new ObjectQL with default settings
10
- * - new ObjectQLPlugin(existingQL) - Uses existing ObjectQL instance
11
- * - new ObjectQLPlugin(undefined, { custom: 'context' }) - Creates new ObjectQL with custom context
12
- */
13
- export class ObjectQLPlugin {
14
- /**
15
- * @param ql - Existing ObjectQL instance to use (optional)
16
- * @param hostContext - Host context for new ObjectQL instance (ignored if ql is provided)
17
- */
18
- constructor(ql, hostContext) {
19
- this.name = 'com.objectstack.engine.objectql';
20
- this.type = 'objectql';
21
- if (ql && hostContext) {
22
- console.warn('[ObjectQLPlugin] Both ql and hostContext provided. hostContext will be ignored.');
23
- }
24
- if (ql) {
25
- this.ql = ql;
26
- }
27
- else {
28
- this.ql = new ObjectQL(hostContext || {
29
- env: process.env.NODE_ENV || 'development'
30
- });
31
- }
32
- }
33
- /**
34
- * Install the ObjectQL engine into the kernel
35
- */
36
- async install(ctx) {
37
- // Attach the ObjectQL engine to the kernel
38
- ctx.engine.ql = this.ql;
39
- console.log('[ObjectQLPlugin] ObjectQL engine registered');
40
- }
41
- }
@@ -1,68 +0,0 @@
1
- import { ObjectStackKernel } from './kernel';
2
- export interface ApiRequest {
3
- params: Record<string, string>;
4
- query: Record<string, string | string[]>;
5
- body?: any;
6
- }
7
- export declare class ObjectStackRuntimeProtocol {
8
- private engine;
9
- constructor(engine: ObjectStackKernel);
10
- getDiscovery(): {
11
- name: string;
12
- version: string;
13
- environment: string;
14
- routes: {
15
- discovery: string;
16
- metadata: string;
17
- data: string;
18
- auth: string;
19
- ui: string;
20
- };
21
- capabilities: {
22
- search: boolean;
23
- files: boolean;
24
- };
25
- };
26
- getMetaTypes(): {
27
- data: {
28
- type: string;
29
- href: string;
30
- count: number;
31
- }[];
32
- };
33
- getMetaItems(typePlural: string): {
34
- data: {
35
- self: string;
36
- path?: string | undefined;
37
- id: any;
38
- name: any;
39
- label: any;
40
- type: any;
41
- icon: any;
42
- description: any;
43
- }[];
44
- };
45
- getMetaItem(typePlural: string, name: string): {};
46
- getUiView(objectName: string, type: 'list' | 'form'): {
47
- type: string;
48
- title: string;
49
- columns: {
50
- field: string;
51
- label: string;
52
- width: number;
53
- }[];
54
- actions: string[];
55
- };
56
- findData(objectName: string, query: any): Promise<{
57
- value: any;
58
- count: any;
59
- }>;
60
- queryData(objectName: string, body: any): Promise<{
61
- value: any;
62
- count: any;
63
- }>;
64
- getData(objectName: string, id: string): Promise<any>;
65
- createData(objectName: string, body: any): Promise<any>;
66
- updateData(objectName: string, id: string, body: any): Promise<any>;
67
- deleteData(objectName: string, id: string): Promise<any>;
68
- }
package/dist/protocol.js DELETED
@@ -1,108 +0,0 @@
1
- import { SchemaRegistry } from '@objectstack/objectql';
2
- export class ObjectStackRuntimeProtocol {
3
- constructor(engine) {
4
- this.engine = engine;
5
- }
6
- // 1. Discovery
7
- getDiscovery() {
8
- return {
9
- name: 'ObjectOS Server',
10
- version: '1.0.0',
11
- environment: process.env.NODE_ENV || 'development',
12
- routes: {
13
- discovery: '/api/v1',
14
- metadata: '/api/v1/meta',
15
- data: '/api/v1/data',
16
- auth: '/api/v1/auth',
17
- ui: '/api/v1/ui'
18
- },
19
- capabilities: {
20
- search: true,
21
- files: true
22
- }
23
- };
24
- }
25
- // 2. Metadata: List Types
26
- getMetaTypes() {
27
- const types = SchemaRegistry.getRegisteredTypes();
28
- return {
29
- data: types.map(type => ({
30
- type,
31
- href: `/api/v1/meta/${type}s`,
32
- count: SchemaRegistry.listItems(type).length
33
- }))
34
- };
35
- }
36
- // 3. Metadata: List Items by Type
37
- getMetaItems(typePlural) {
38
- // Simple Singularization Mapping
39
- const typeMap = {
40
- 'objects': 'object',
41
- 'apps': 'app',
42
- 'flows': 'flow',
43
- 'reports': 'report',
44
- 'plugins': 'plugin',
45
- 'kinds': 'kind'
46
- };
47
- const type = typeMap[typePlural] || typePlural;
48
- const items = SchemaRegistry.listItems(type);
49
- const summaries = items.map((item) => ({
50
- id: item.id,
51
- name: item.name,
52
- label: item.label,
53
- type: item.type,
54
- icon: item.icon,
55
- description: item.description,
56
- ...(type === 'object' ? { path: `/api/v1/data/${item.name}` } : {}),
57
- self: `/api/v1/meta/${typePlural}/${item.name || item.id}`
58
- }));
59
- return { data: summaries };
60
- }
61
- // 4. Metadata: Get Single Item
62
- getMetaItem(typePlural, name) {
63
- const typeMap = {
64
- 'objects': 'object',
65
- 'apps': 'app',
66
- 'flows': 'flow',
67
- 'reports': 'report',
68
- 'plugins': 'plugin',
69
- 'kinds': 'kind'
70
- };
71
- const type = typeMap[typePlural] || typePlural;
72
- const item = SchemaRegistry.getItem(type, name);
73
- if (!item)
74
- throw new Error(`Metadata not found: ${type}/${name}`);
75
- return item;
76
- }
77
- // 5. UI: View Definition
78
- getUiView(objectName, type) {
79
- const view = this.engine.getView(objectName, type);
80
- if (!view)
81
- throw new Error('View not generated');
82
- return view;
83
- }
84
- // 6. Data: Find
85
- async findData(objectName, query) {
86
- return await this.engine.find(objectName, query);
87
- }
88
- // 7. Data: Query (Advanced AST)
89
- async queryData(objectName, body) {
90
- return await this.engine.find(objectName, body);
91
- }
92
- // 8. Data: Get
93
- async getData(objectName, id) {
94
- return await this.engine.get(objectName, id);
95
- }
96
- // 9. Data: Create
97
- async createData(objectName, body) {
98
- return await this.engine.create(objectName, body);
99
- }
100
- // 10. Data: Update
101
- async updateData(objectName, id, body) {
102
- return await this.engine.update(objectName, id, body);
103
- }
104
- // 11. Data: Delete
105
- async deleteData(objectName, id) {
106
- return await this.engine.delete(objectName, id);
107
- }
108
- }
package/dist/types.d.ts DELETED
@@ -1,9 +0,0 @@
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 DELETED
@@ -1 +0,0 @@
1
- export {};