Skip to content

Commit d1fe645

Browse files
Copilothuangyiirene
andcommitted
Move plugin type definitions from core to plugin packages
This addresses the architectural concern that plugin types should be owned by the plugin packages themselves, not the core platform. This allows third-party developers to create plugins without modifying core packages. Changes: - Removed packages/types/src/plugin.ts (no longer needed) - Reverted packages/types/src/index.ts to remove plugin type exports - Added packages/plugin-editor/src/types.ts with CodeEditorSchema - Added packages/plugin-charts/src/types.ts with BarChartSchema - Updated plugin packages to export their types via index.tsx - Added @object-ui/types as dependency for plugins (for BaseSchema) - Updated documentation to explain plugin-owned types pattern Co-authored-by: huangyiirene <7665279+huangyiirene@users.noreply.github.com>
1 parent 00ed8c6 commit d1fe645

12 files changed

Lines changed: 247 additions & 129 deletions

File tree

docs/lazy-loaded-plugins.md

Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,32 @@ export const editorComponents = {
8080
};
8181
```
8282

83-
### 3. Build Configuration (`vite.config.ts`)
83+
### 3. Type Definitions (`types.ts`)
84+
```typescript
85+
// packages/plugin-editor/src/types.ts
86+
import type { BaseSchema } from '@object-ui/types';
87+
88+
/**
89+
* Code Editor component schema.
90+
* These types are self-contained within the plugin package.
91+
*/
92+
export interface CodeEditorSchema extends BaseSchema {
93+
type: 'code-editor';
94+
value?: string;
95+
language?: string;
96+
theme?: 'vs-dark' | 'light';
97+
height?: string;
98+
readOnly?: boolean;
99+
onChange?: (value: string | undefined) => void;
100+
}
101+
```
102+
103+
**Key Points:**
104+
- Plugin types are defined in the plugin package, not in `@object-ui/types`
105+
- This allows third-party developers to create plugins without modifying core packages
106+
- Types are exported from the plugin's main entry point for consumers to use
107+
108+
### 4. Build Configuration (`vite.config.ts`)
84109
```typescript
85110
export default defineConfig({
86111
build: {
@@ -96,6 +121,52 @@ export default defineConfig({
96121
});
97122
```
98123

124+
## Type System Design
125+
126+
### Plugin-Owned Types (✅ Recommended)
127+
128+
Each plugin package owns its type definitions:
129+
130+
```typescript
131+
// In @object-ui/plugin-editor
132+
export interface CodeEditorSchema extends BaseSchema {
133+
type: 'code-editor';
134+
// ... plugin-specific properties
135+
}
136+
```
137+
138+
**Benefits:**
139+
- **Decoupling**: Third-party developers don't need to modify core packages
140+
- **Independent Versioning**: Plugins can evolve their schemas independently
141+
- **Self-Contained**: Each plugin is a complete, standalone package
142+
143+
**Usage:**
144+
```typescript
145+
// Application code
146+
import type { CodeEditorSchema } from '@object-ui/plugin-editor';
147+
import type { BarChartSchema } from '@object-ui/plugin-charts';
148+
149+
const editor: CodeEditorSchema = { type: 'code-editor', value: '...' };
150+
const chart: BarChartSchema = { type: 'chart-bar', data: [...] };
151+
```
152+
153+
### Platform-Owned Types (❌ Not Recommended for Plugins)
154+
155+
Defining plugin types in `@object-ui/types` creates tight coupling:
156+
157+
```typescript
158+
// In @object-ui/types (DON'T DO THIS for plugins)
159+
export interface CodeEditorSchema extends BaseSchema {
160+
type: 'code-editor';
161+
// ...
162+
}
163+
```
164+
165+
**Problems:**
166+
- Third-party developers must submit PRs to core package
167+
- Creates version coupling between plugins and platform
168+
- Violates the plugin architecture principle
169+
99170
## Bundle Analysis
100171

101172
### Plugin-Editor Build Output

packages/plugin-charts/README.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,25 @@ Object.entries(chartComponents).forEach(([type, component]) => {
4949
});
5050
```
5151

52+
### TypeScript Support
53+
54+
The plugin exports TypeScript types for full type safety:
55+
56+
```typescript
57+
import type { BarChartSchema } from '@object-ui/plugin-charts';
58+
59+
const schema: BarChartSchema = {
60+
type: 'chart-bar',
61+
data: [
62+
{ name: 'Jan', value: 400 },
63+
{ name: 'Feb', value: 300 }
64+
],
65+
dataKey: 'value',
66+
xAxisKey: 'name',
67+
height: 400
68+
};
69+
```
70+
5271
## Schema API
5372

5473
```typescript

packages/plugin-charts/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@
2121
"recharts": "^3.6.0",
2222
"@object-ui/components": "workspace:*",
2323
"@object-ui/core": "workspace:*",
24-
"@object-ui/react": "workspace:*"
24+
"@object-ui/react": "workspace:*",
25+
"@object-ui/types": "workspace:*"
2526
},
2627
"peerDependencies": {
2728
"react": "^18.0.0 || ^19.0.0",

packages/plugin-charts/src/index.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ import React, { Suspense } from 'react';
22
import { ComponentRegistry } from '@object-ui/core';
33
import { Skeleton } from '@object-ui/components';
44

5+
// Export types for external use
6+
export type { BarChartSchema } from './types';
7+
58
// 🚀 Lazy load the implementation file
69
// This ensures Recharts is only loaded when the component is actually rendered
710
const LazyChart = React.lazy(() => import('./ChartImpl'));
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/**
2+
* TypeScript type definitions for @object-ui/plugin-charts
3+
*
4+
* These types can be imported by applications using this plugin
5+
* to get full TypeScript support for chart schemas.
6+
*/
7+
8+
import type { BaseSchema } from '@object-ui/types';
9+
10+
/**
11+
* Bar Chart component schema.
12+
* Renders a bar chart using Recharts library.
13+
*
14+
* @example
15+
* ```typescript
16+
* import type { BarChartSchema } from '@object-ui/plugin-charts';
17+
*
18+
* const chartSchema: BarChartSchema = {
19+
* type: 'chart-bar',
20+
* data: [
21+
* { name: 'Jan', value: 400 },
22+
* { name: 'Feb', value: 300 }
23+
* ],
24+
* dataKey: 'value',
25+
* xAxisKey: 'name'
26+
* }
27+
* ```
28+
*/
29+
export interface BarChartSchema extends BaseSchema {
30+
type: 'chart-bar';
31+
32+
/**
33+
* Array of data points to display in the chart.
34+
*/
35+
data?: Array<Record<string, any>>;
36+
37+
/**
38+
* Key in the data object for the Y-axis values.
39+
* @default 'value'
40+
*/
41+
dataKey?: string;
42+
43+
/**
44+
* Key in the data object for the X-axis labels.
45+
* @default 'name'
46+
*/
47+
xAxisKey?: string;
48+
49+
/**
50+
* Height of the chart in pixels.
51+
* @default 400
52+
*/
53+
height?: number;
54+
55+
/**
56+
* Color of the bars.
57+
* @default '#8884d8'
58+
*/
59+
color?: string;
60+
}

packages/plugin-editor/README.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,22 @@ Object.entries(editorComponents).forEach(([type, component]) => {
4545
});
4646
```
4747

48+
### TypeScript Support
49+
50+
The plugin exports TypeScript types for full type safety:
51+
52+
```typescript
53+
import type { CodeEditorSchema } from '@object-ui/plugin-editor';
54+
55+
const schema: CodeEditorSchema = {
56+
type: 'code-editor',
57+
value: 'console.log("Hello, World!");',
58+
language: 'javascript',
59+
theme: 'vs-dark',
60+
height: '400px'
61+
};
62+
```
63+
4864
## Schema API
4965

5066
```typescript

packages/plugin-editor/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@
2121
"@monaco-editor/react": "^4.6.0",
2222
"@object-ui/components": "workspace:*",
2323
"@object-ui/core": "workspace:*",
24-
"@object-ui/react": "workspace:*"
24+
"@object-ui/react": "workspace:*",
25+
"@object-ui/types": "workspace:*"
2526
},
2627
"peerDependencies": {
2728
"react": "^18.0.0 || ^19.0.0",

packages/plugin-editor/src/index.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ import React, { Suspense } from 'react';
22
import { ComponentRegistry } from '@object-ui/core';
33
import { Skeleton } from '@object-ui/components';
44

5+
// Export types for external use
6+
export type { CodeEditorSchema } from './types';
7+
58
// 🚀 Lazy load the implementation file
69
// This ensures Monaco Editor is only loaded when the component is actually rendered
710
const LazyMonacoEditor = React.lazy(() => import('./MonacoImpl'));
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/**
2+
* TypeScript type definitions for @object-ui/plugin-editor
3+
*
4+
* These types can be imported by applications using this plugin
5+
* to get full TypeScript support for code-editor schemas.
6+
*/
7+
8+
import type { BaseSchema } from '@object-ui/types';
9+
10+
/**
11+
* Code Editor component schema.
12+
* Renders a Monaco-based code editor with syntax highlighting.
13+
*
14+
* @example
15+
* ```typescript
16+
* import type { CodeEditorSchema } from '@object-ui/plugin-editor';
17+
*
18+
* const editorSchema: CodeEditorSchema = {
19+
* type: 'code-editor',
20+
* value: 'console.log("Hello, World!");',
21+
* language: 'javascript',
22+
* theme: 'vs-dark',
23+
* height: '400px'
24+
* }
25+
* ```
26+
*/
27+
export interface CodeEditorSchema extends BaseSchema {
28+
type: 'code-editor';
29+
30+
/**
31+
* The code content to display in the editor.
32+
*/
33+
value?: string;
34+
35+
/**
36+
* Programming language for syntax highlighting.
37+
* @default 'javascript'
38+
*/
39+
language?: 'javascript' | 'typescript' | 'python' | 'json' | 'html' | 'css' | 'markdown' | string;
40+
41+
/**
42+
* Color theme for the editor.
43+
* @default 'vs-dark'
44+
*/
45+
theme?: 'vs-dark' | 'light';
46+
47+
/**
48+
* Height of the editor.
49+
* @default '400px'
50+
*/
51+
height?: string;
52+
53+
/**
54+
* Whether the editor is read-only.
55+
* @default false
56+
*/
57+
readOnly?: boolean;
58+
59+
/**
60+
* Callback when the code content changes.
61+
*/
62+
onChange?: (value: string | undefined) => void;
63+
}

packages/types/src/index.ts

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -215,14 +215,6 @@ export type {
215215
APIError,
216216
} from './data';
217217

218-
// ============================================================================
219-
// Plugin Components - Lazy-Loaded Heavy Components
220-
// ============================================================================
221-
export type {
222-
CodeEditorSchema,
223-
BarChartSchema,
224-
} from './plugin';
225-
226218
// ============================================================================
227219
// Union Types - Discriminated Unions for All Schemas
228220
// ============================================================================
@@ -236,7 +228,6 @@ import type { DisclosureSchema } from './disclosure';
236228
import type { OverlaySchema } from './overlay';
237229
import type { NavigationSchema } from './navigation';
238230
import type { ComplexSchema } from './complex';
239-
import type { CodeEditorSchema, BarChartSchema } from './plugin';
240231

241232
/**
242233
* Union of all component schemas.
@@ -251,9 +242,7 @@ export type AnySchema =
251242
| DisclosureSchema
252243
| OverlaySchema
253244
| NavigationSchema
254-
| ComplexSchema
255-
| CodeEditorSchema
256-
| BarChartSchema;
245+
| ComplexSchema;
257246

258247
/**
259248
* Utility type to extract the schema type from a type string.

0 commit comments

Comments
 (0)