Skip to content

Commit 675e155

Browse files
committed
refactor: update README and restructure kernel package; remove registry and loader, add ObjectOS plugin
1 parent 5c19750 commit 675e155

File tree

4 files changed

+103
-245
lines changed

4 files changed

+103
-245
lines changed

packages/kernel/README.md

Lines changed: 47 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
11
# @objectos/kernel
22

3-
The metadata management system for ObjectOS. This package provides a generic framework for discovering, loading, and managing metadata from various sources (files, npm packages, etc.).
4-
5-
While it includes plugins specifically for ObjectOS schemas (Objects, Apps, Hooks), it is designed to be extensible for any metadata-driven application.
3+
The core runtime for ObjectOS, extending ObjectQL with application-specific capabilities.
64

75
## Features
86

9-
- **MetadataRegistry**: A central in-memory store for all loaded metadata.
10-
- **MetadataLoader**: A plugin-based file scanner that populates the registry.
11-
- **Dynamic Loading**: Support for loading metadata from local directories or NPM packages at runtime.
12-
- **ObjectQL Plugins**: Built-in support for loading `.object.yml`, `.app.yml`, `.hook.ts`, etc.
7+
- **ObjectOS Runtime**: Extends `ObjectQL` to provide a full application kernel.
8+
- **App Metadata**: Built-in support for loading `.app.yml` for application configuration and navigation.
9+
- **Data Loading**: Built-in support for loading `.data.yml` for seed data.
10+
- **MetadataRegistry**: Inherits the central metadata store from ObjectQL.
1311

1412
## Installation
1513

@@ -21,123 +19,59 @@ npm install @objectos/kernel
2119

2220
### Basic Usage
2321

22+
`ObjectOS` is a drop-in replacement for `ObjectQL`. It automatically registers plugins to handle ObjectOS specific metadata formats.
23+
2424
```typescript
25-
import { MetadataRegistry, MetadataLoader } from '@objectos/kernel';
26-
27-
const registry = new MetadataRegistry();
28-
const loader = new MetadataLoader(registry);
29-
30-
// Register custom plugin (optional)
31-
loader.use({
32-
name: 'custom-report',
33-
glob: ['**/*.report.yml'],
34-
handler: (ctx) => {
35-
// parsing logic...
36-
ctx.registry.register('report', { ... });
25+
import { ObjectOS } from '@objectos/kernel';
26+
27+
const kernel = new ObjectOS({
28+
datasources: {
29+
'default': {
30+
client: 'sqlite3',
31+
connection: { filename: ':memory:' }
32+
}
3733
}
3834
});
3935

40-
// Load from a directory
41-
loader.load('/path/to/project');
36+
// Initialize (connects to DB, loads plugins)
37+
await kernel.init();
4238

43-
// Access metadata
44-
const reports = registry.list('report');
39+
// Use standard ObjectQL methods
40+
const users = await kernel.find('user', {});
4541
```
4642

47-
### Loading ObjectQL Schemas
48-
49-
If you are building a system that needs to understand ObjectQL schemas without running the full ORM:
50-
51-
```typescript
52-
import { MetadataRegistry, MetadataLoader, registerObjectQLPlugins } from '@objectos/kernel';
53-
54-
const registry = new MetadataRegistry();
55-
const loader = new MetadataLoader(registry);
56-
57-
// Register standard ObjectQL plugins (objects, apps, hooks, data)
58-
registerObjectQLPlugins(loader);
43+
### Metadata Loading
44+
45+
The kernel automatically scans for:
46+
- `*.object.yml` (Standard ObjectQL)
47+
- `*.app.yml` (ObjectOS Apps)
48+
- `*.data.yml` (ObjectOS Data Seeding)
49+
50+
```yaml
51+
# my-app.app.yml
52+
code: my_crm
53+
name: CRM
54+
icon: users
55+
menu:
56+
- type: header
57+
label: Sales
58+
- type: object
59+
object: lead
60+
```
5961
60-
// Load standard schemas
61-
loader.load('./src');
62+
## API
6263
63-
const objects = registry.list('object');
64-
console.log(objects.map(o => o.name));
65-
```
64+
### `ObjectOS`
6665

67-
### Working with App Metadata and Menus
66+
Extends `ObjectQL` class.
6867

69-
Apps can define custom navigation menus, similar to Airtable interfaces:
68+
- `constructor(config)`
69+
- `config.datasources`: Database connections.
70+
- `config.packages`: List of NPM packages to scan for metadata.
7071

71-
```typescript
72-
import {
73-
MetadataRegistry,
74-
MetadataLoader,
75-
registerObjectQLPlugins,
76-
AppConfig,
77-
AppMenuItem,
78-
isAppMenuSection
79-
} from '@objectos/kernel';
80-
81-
const registry = new MetadataRegistry();
82-
const loader = new MetadataLoader(registry);
83-
84-
registerObjectQLPlugins(loader);
85-
loader.load('./src');
86-
87-
// Get app configuration
88-
const app = registry.get('app', 'MyApp') as AppConfig;
89-
90-
if (app && app.menu) {
91-
// Render menu sections or items
92-
app.menu.forEach((entry) => {
93-
// Use type guard to determine if it's a section or direct item
94-
if (isAppMenuSection(entry)) {
95-
// It's a menu section
96-
console.log(`Section: ${entry.label || 'Unnamed'}`);
97-
console.log(` Collapsible: ${entry.collapsible}`);
98-
99-
entry.items.forEach((item) => {
100-
renderMenuItem(item);
101-
});
102-
} else {
103-
// It's a direct menu item
104-
renderMenuItem(entry);
105-
}
106-
});
107-
}
108-
109-
function renderMenuItem(item: AppMenuItem) {
110-
console.log(` - ${item.label} (${item.type || 'page'})`);
111-
112-
// Handle different menu item types
113-
switch (item.type) {
114-
case 'object':
115-
console.log(` Object: ${item.object}`);
116-
break;
117-
case 'page':
118-
console.log(` Page: ${item.url}`);
119-
break;
120-
case 'url':
121-
console.log(` URL: ${item.url}`);
122-
break;
123-
}
124-
125-
if (item.badge) {
126-
console.log(` Badge: ${item.badge}`);
127-
}
128-
}
129-
```
72+
### Plugins
13073

131-
## API
74+
Internal plugins are automatically registered:
13275

133-
### `MetadataRegistry`
134-
- `register(type, metadata)`
135-
- `unregister(type, id)`
136-
- `unregisterPackage(packageName)`
137-
- `get(type, id)`
138-
- `list(type)`
139-
140-
### `MetadataLoader`
141-
- `use(plugin)`
142-
- `load(dir)`
143-
- `loadPackage(packageName)`
76+
- **AppPlugin**: Loads `**/*.app.yml`
77+
- **DataPlugin**: Loads `**/*.data.yml`

packages/kernel/src/index.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
export * from './registry';
2-
export * from './loader';
31
export * from './objectos';
42

53
// Re-export specific types if needed to avoid conflicts
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import * as yaml from 'js-yaml';
2+
import * as path from 'path';
3+
4+
export const ObjectOSPlugin = {
5+
name: 'objectos-core',
6+
setup(app: any) {
7+
// Apps
8+
app.addLoader({
9+
name: 'app',
10+
glob: ['**/*.app.yml', '**/*.app.yaml'],
11+
handler: (ctx: any) => {
12+
try {
13+
const doc = yaml.load(ctx.content) as any;
14+
const id = doc.code || doc.id || doc.name;
15+
if (id) {
16+
ctx.registry.register('app', {
17+
type: 'app',
18+
id: id,
19+
path: ctx.file,
20+
package: ctx.packageName,
21+
content: doc
22+
});
23+
}
24+
} catch (e) {
25+
console.error(`Error loading app from ${ctx.file}:`, e);
26+
}
27+
}
28+
});
29+
30+
// Data
31+
app.addLoader({
32+
name: 'data',
33+
glob: ['**/*.data.yml', '**/*.data.yaml'],
34+
handler: (ctx: any) => {
35+
try {
36+
const content = ctx.content;
37+
const data = yaml.load(content);
38+
if (!Array.isArray(data)) return;
39+
40+
const basename = path.basename(ctx.file);
41+
const objectName = basename.replace(/\.data\.ya?ml$/, '');
42+
43+
const entry = ctx.registry.getEntry('object', objectName);
44+
if (entry) {
45+
const config = entry.content as any;
46+
config.data = data;
47+
} else {
48+
console.warn(`Found data for unknown object '${objectName}' in ${ctx.file}`);
49+
}
50+
} catch (e) {
51+
console.error(`Error loading data from ${ctx.file}:`, e);
52+
}
53+
}
54+
});
55+
}
56+
}

packages/kernel/src/registry.ts

Lines changed: 0 additions & 130 deletions
This file was deleted.

0 commit comments

Comments
 (0)