Skip to content

Commit c1aea83

Browse files
committed
更新 BI 插件配置,添加运行时入口和缓存设置,增强插件功能和路由支持
1 parent dd24b59 commit c1aea83

File tree

3 files changed

+143
-19
lines changed

3 files changed

+143
-19
lines changed

content/docs/concepts/plugin-architecture.mdx

Lines changed: 85 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,43 +18,113 @@ This separation ensures the platform remains lightweight and un-opinionated, all
1818

1919
## 2. Anatomy of a Plugin
2020

21-
A plugin is defined by its `Manifest` (objectstack.config.ts). The most critical part of a modern ObjectStack plugin is the `contributes` section.
21+
A plugin is defined by its `Manifest` (objectstack.config.ts) and its runtime `Entry` (index.ts).
2222

23-
### The `contributes` Protocol
23+
### The Manifest (`objectstack.config.ts`)
2424

25-
Inspired by VS Code, we use a declarative approach to register capabilities.
25+
Critically, the manifest declares **Dependencies**, **Configuration Rules**, and **Contributions**.
2626

2727
```typescript
2828
// objectstack.config.ts
29-
export default {
29+
import { ObjectStackManifest } from '@objectstack/spec';
30+
31+
const plugin: ObjectStackManifest = {
3032
id: 'com.vendor.bi',
33+
version: '1.0.0',
3134
type: 'plugin',
3235

33-
// DECLARATIVE: "I bring these new capabilities"
36+
// 1. Configuration Schema (Settings)
37+
configuration: {
38+
title: 'BI Engine Settings',
39+
properties: {
40+
'fullQueryMode': {
41+
type: 'boolean',
42+
default: false,
43+
description: 'Allow unrestricted SQL queries'
44+
},
45+
'apiKey': {
46+
type: 'string',
47+
secret: true
48+
}
49+
}
50+
},
51+
52+
// 2. Dependencies
53+
dependencies: {
54+
'com.objectstack.core': '^2.0.0'
55+
},
56+
57+
// 3. Contributions (Declarative Capabilities)
3458
contributes: {
35-
// 1. Define new Metadata Kinds (File Types)
59+
// Define new Metadata Kinds (File Types)
3660
kinds: [
3761
{
3862
id: 'bi.dataset',
3963
globs: ['**/*.dataset.json'],
40-
description: 'BI Dataset Definition'
64+
description: 'BI Dataset Definition'
4165
}
4266
],
43-
// 2. Define new UI Locations
44-
views: [
45-
{
46-
id: 'bi.chart_renderer',
47-
location: 'dashboard.widget'
67+
// UI Contributions
68+
menus: {
69+
'global/toolbar': [
70+
{ id: 'open_dashboard', label: 'Open BI Dashboard', command: 'bi.open' }
71+
]
72+
},
73+
// Server Actions (Exposed to Flows/API)
74+
actions: [
75+
{
76+
name: 'generate_forecast',
77+
label: 'Generate Sales Forecast',
78+
input: { startDate: 'date' }
4879
}
4980
]
5081
},
5182

52-
// IMPERATIVE: "Here is the code to handle them"
53-
lifecycle: './src/index.ts'
83+
// 4. Runtime Entry
84+
extensions: {
85+
runtime: { entry: './src/index.ts' }
86+
}
87+
}
88+
```
89+
90+
## 3. Runtime Context
91+
92+
Plugins receive a rich strictly-typed `PluginContext` during their lifecycle. This context is the bridge to the host operating system.
93+
94+
```typescript
95+
// src/index.ts
96+
import { PluginDefinition, PluginContextData } from '@objectstack/spec';
97+
98+
const definition: PluginDefinition = {
99+
id: 'com.vendor.bi',
100+
101+
onEnable: async (context: PluginContextData) => {
102+
// A. Access Type-Safe Context
103+
const { logger, ql, os, app, storage, i18n } = context;
104+
105+
logger.info('Starting BI Engine...');
106+
107+
// B. Use Scoped Storage (KV Store)
108+
const lastRun = await storage.get('last_run_timestamp');
109+
110+
// C. Register Runtime Routes
111+
app.router.get('/bi/stats', async () => {
112+
return { active_reports: 10 };
113+
});
114+
115+
// D. Interact with Core Data
116+
const data = await ql.object('account').find({ industry: 'Tech' });
117+
118+
// E. Read Configuration
119+
const config = await os.getConfig('com.vendor.bi');
120+
if (config.fullQueryMode) {
121+
logger.warn('Running in Full Query Mode');
122+
}
123+
}
54124
}
55125
```
56126

57-
## 3. Extension Capabilities
127+
## 4. Extension Capabilities
58128

59129
### A. New Metadata Kinds (CRDs)
60130

examples/plugin-bi/objectstack.config.ts

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,24 @@ const BiPlugin: ObjectStackManifest = {
77
type: 'plugin',
88
description: 'Provides BI capabilities, dataset definitions, and chart rendering.',
99

10-
// Register Capabilities
10+
// 1. Configuration (Settings)
11+
configuration: {
12+
title: 'BI Plugin Configuration',
13+
properties: {
14+
enableCache: {
15+
type: 'boolean',
16+
default: true,
17+
description: 'Enable in-memory caching for query results'
18+
},
19+
maxRows: {
20+
type: 'number',
21+
default: 1000,
22+
description: 'Maximum rows returned per query'
23+
}
24+
}
25+
},
26+
27+
// 2. Capabilities
1128
contributes: {
1229
kinds: [
1330
{
@@ -20,10 +37,23 @@ const BiPlugin: ObjectStackManifest = {
2037
globs: ['**/*.bi-dash.json'],
2138
description: 'Advanced BI Dashboard'
2239
}
40+
],
41+
menus: {
42+
'sidebar/tools': [
43+
{ id: 'open_bi_studio', label: 'BI Studio', command: 'bi.openStudio' }
44+
]
45+
},
46+
actions: [
47+
{
48+
name: 'refresh_dataset',
49+
label: 'Refresh Dataset',
50+
description: 'Manually trigger a dataset refresh',
51+
input: { datasetId: 'string' }
52+
}
2353
]
2454
},
2555

26-
// Lifecycle Entry Point
56+
// 3. Lifecycle Entry Point
2757
// in a real scenario, this would be a path or module name
2858
extensions: {
2959
runtime: {

examples/plugin-bi/src/index.ts

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,18 +20,42 @@ const plugin: PluginDefinition = {
2020
version: '1.0.0',
2121

2222
onEnable: async (context: PluginContextData) => {
23-
const logger = context.logger || console;
23+
// 1. Destructure strict APIs
24+
const { logger, ql, os, app, storage, i18n } = context;
25+
2426
logger.info('[BI Plugin] Enabling BI Plugin...');
2527

26-
// Register Service
28+
// 2. Use Configuration
29+
const config = await os.getConfig('com.objectstack.bi');
30+
if (config?.enableCache) {
31+
logger.info('Caching Enabled');
32+
}
33+
34+
// 3. Register Service
2735
const engine = new BiEngine();
2836

2937
// Access runtime capabilities not in strict schema
38+
// In a real implementation module augmentation would be used
3039
const runtime = context as any;
3140
if (runtime.services) {
3241
runtime.services.register('bi.engine', engine);
3342
}
3443

44+
// 4. Register Route
45+
app.router.get('/bi/status', async () => {
46+
return { status: 'running', engine: 'v1' };
47+
});
48+
49+
// 5. Use Storage
50+
await storage.set('started_at', Date.now());
51+
52+
// 6. Demonstrate i18n & Data Access
53+
// (In a real app, this would be used in a route or job)
54+
if (Date.now() % 1000 === 0) {
55+
console.log(i18n.t('hello_world', {}));
56+
await ql.object('account').query('SELECT count() FROM account');
57+
}
58+
3559
logger.info('[BI Plugin] Services registered.');
3660
}
3761
};

0 commit comments

Comments
 (0)