Skip to content

Commit f2dc51f

Browse files
committed
重构服务器启动逻辑,整合 Hono 框架以支持 API 路由和中间件;删除旧的 DataEngine 实现并添加 ObjectStackRuntimeProtocol 以处理数据操作
1 parent ab2acf2 commit f2dc51f

File tree

4 files changed

+254
-182
lines changed

4 files changed

+254
-182
lines changed

examples/server/src/index.ts

Lines changed: 124 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,134 @@
1-
import { ObjectStackServer } from '@objectstack/server';
2-
import { InMemoryDriver } from '@objectstack/driver-memory';
1+
import { serve } from '@hono/node-server';
2+
import { serveStatic } from '@hono/node-server/serve-static';
3+
import { Hono } from 'hono';
4+
import { cors } from 'hono/cors';
5+
import { logger } from 'hono/logger';
36

4-
// Standard Plugins
7+
// 1. 引入核心内核 (The Kernel)
8+
import { DataEngine, ObjectStackRuntimeProtocol } from '@objectstack/runtime';
9+
// 2. 引入驱动 (The Driver)
10+
import { InMemoryDriver } from '@objectstack/driver-memory';
11+
// 3. 引入业务插件 (The Apps)
512
import CrmApp from '@objectstack/example-crm/objectstack.config';
613
import TodoApp from '@objectstack/example-todo/objectstack.config';
714
import BiPluginManifest from '@objectstack/plugin-bi/objectstack.config';
815

916
(async () => {
10-
const server = new ObjectStackServer({
11-
port: 3004,
12-
static: {
13-
root: './public',
14-
path: 'index.html'
15-
},
16-
plugins: [
17-
CrmApp,
18-
TodoApp,
19-
BiPluginManifest
20-
]
17+
console.log('🚀 Starting ObjectStack in Raw Kernel Mode...');
18+
19+
// --- A. 初始化内核 (Kernel Layer) ---
20+
21+
// 1. 创建数据引擎,加载业务插件
22+
const engine = new DataEngine([
23+
CrmApp,
24+
TodoApp,
25+
BiPluginManifest
26+
]);
27+
28+
// 2. 注册驱动 (显式注入)
29+
engine.ql.registerDriver(new InMemoryDriver());
30+
31+
// 3. 创建协议处理器 (Protocol Layer)
32+
// 这是 HTTP 和 Kernel 之间的翻译官
33+
const protocol = new ObjectStackRuntimeProtocol(engine);
34+
35+
// 4. 启动内核 (执行数据初始化/Seed)
36+
await engine.start();
37+
38+
39+
// --- B. 初始化宿主 (Host Layer / Server Shell) ---
40+
41+
const app = new Hono();
42+
43+
// 中间件
44+
app.use('*', logger());
45+
app.use('*', cors());
46+
47+
// --- C. 路由映射 (Wiring) ---
48+
// 这里展示了 "Server 只是个壳":它只负责把 Request 转给 Protocol
49+
50+
// 1. Discovery
51+
app.get('/api/v1', (c) => c.json(protocol.getDiscovery()));
52+
53+
// 2. Meta API
54+
app.get('/api/v1/meta', (c) => c.json(protocol.getMetaTypes()));
55+
app.get('/api/v1/meta/:type', (c) => c.json(protocol.getMetaItems(c.req.param('type'))));
56+
app.get('/api/v1/meta/:type/:name', (c) => {
57+
try {
58+
return c.json(protocol.getMetaItem(c.req.param('type'), c.req.param('name')));
59+
} catch (e: any) {
60+
return c.json({ error: e.message }, 404);
61+
}
62+
});
63+
64+
// 3. Data API (CRUD)
65+
app.get('/api/v1/data/:object', async (c) => {
66+
// 将 URL Query (HTTP) 转换为 Protocol Query
67+
try {
68+
const result = await protocol.findData(c.req.param('object'), c.req.query());
69+
return c.json(result);
70+
} catch (e: any) {
71+
return c.json({ error: e.message }, 400);
72+
}
73+
});
74+
75+
app.get('/api/v1/data/:object/:id', async (c) => {
76+
try {
77+
const result = await protocol.getData(c.req.param('object'), c.req.param('id'));
78+
return c.json(result);
79+
} catch (e: any) {
80+
return c.json({ error: e.message }, 404);
81+
}
82+
});
83+
84+
app.post('/api/v1/data/:object', async (c) => {
85+
try {
86+
const body = await c.req.json();
87+
const result = await protocol.createData(c.req.param('object'), body);
88+
return c.json(result, 201);
89+
} catch (e: any) {
90+
return c.json({ error: e.message }, 400);
91+
}
92+
});
93+
94+
app.patch('/api/v1/data/:object/:id', async (c) => {
95+
try {
96+
const body = await c.req.json();
97+
const result = await protocol.updateData(c.req.param('object'), c.req.param('id'), body);
98+
return c.json(result);
99+
} catch (e: any) {
100+
return c.json({ error: e.message }, 400);
101+
}
21102
});
22103

23-
// Explicitly register the driver
24-
const driver = new InMemoryDriver();
25-
server.engine.ql.registerDriver(driver);
104+
app.delete('/api/v1/data/:object/:id', async (c) => {
105+
try {
106+
const result = await protocol.deleteData(c.req.param('object'), c.req.param('id'));
107+
return c.json(result);
108+
} catch (e: any) {
109+
return c.json({ error: e.message }, 400);
110+
}
111+
});
112+
113+
// 4. UI Protocol
114+
app.get('/api/v1/ui/view/:object', (c) => {
115+
try {
116+
// @ts-ignore
117+
const view = protocol.getUiView(c.req.param('object'), c.req.query('type') || 'list');
118+
return c.json(view);
119+
} catch (e: any) {
120+
return c.json({ error: e.message }, 404);
121+
}
122+
});
123+
124+
// --- D. 静态资源 (前端宿主) ---
125+
app.get('/', serveStatic({ root: './public', path: 'index.html' }));
126+
app.get('/index.html', serveStatic({ root: './public', path: 'index.html' }));
127+
128+
129+
// --- E. 启动监听 ---
130+
const port = 3004;
131+
console.log(`✅ Server is running on http://localhost:${port}`);
132+
serve({ fetch: app.fetch, port });
26133

27-
await server.start();
28134
})();

examples/server/src/kernel/engine.ts

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

packages/runtime/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
export { ObjectQL } from './engine';
33
export { SchemaRegistry } from './registry';
44
export { DataEngine } from './data-engine';
5+
export { ObjectStackRuntimeProtocol } from './protocol';
56

67

78

0 commit comments

Comments
 (0)