Skip to content

Commit b67c855

Browse files
Copilothuangyiirene
andcommitted
Add namespaced exports to prevent naming conflicts
Co-authored-by: huangyiirene <7665279+huangyiirene@users.noreply.github.com>
1 parent 7cfd9bd commit b67c855

9 files changed

Lines changed: 426 additions & 11 deletions

File tree

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
# Export Organization Guide
2+
3+
## Problem Statement
4+
5+
The `@objectstack/spec` package exports many schemas and types. As the API surface grows, there's a risk of:
6+
1. **Naming conflicts**: Different protocols might want to use similar names
7+
2. **Poor discoverability**: With 200+ exports in a flat namespace, it's hard to find what you need
8+
3. **Unclear domain boundaries**: Not obvious which exports belong to which protocol
9+
10+
## Solution: Dual Export Strategy
11+
12+
We now support **both flat and namespaced imports** to give developers flexibility while preventing future naming conflicts.
13+
14+
### 1. Flat Exports (Backward Compatible)
15+
16+
All existing imports continue to work:
17+
18+
```typescript
19+
import { Field, User, App, Agent } from '@objectstack/spec';
20+
```
21+
22+
**When to use:**
23+
- Migrating existing code
24+
- Importing a few specific types
25+
- Quick prototyping
26+
27+
### 2. Namespaced Exports (Recommended)
28+
29+
Import by protocol domain for better organization:
30+
31+
```typescript
32+
import * as Data from '@objectstack/spec/data';
33+
import * as UI from '@objectstack/spec/ui';
34+
import * as System from '@objectstack/spec/system';
35+
import * as AI from '@objectstack/spec/ai';
36+
import * as API from '@objectstack/spec/api';
37+
38+
const field: Data.Field = { /* ... */ };
39+
const user: System.User = { /* ... */ };
40+
```
41+
42+
**When to use:**
43+
- New code
44+
- Working with many types from the same protocol
45+
- Want to avoid any risk of naming conflicts
46+
- Want clear domain boundaries in your code
47+
48+
## Protocol Domains
49+
50+
### `@objectstack/spec/data` - Data Protocol
51+
Core business logic and data modeling:
52+
- `Object`, `Field`, `FieldType`
53+
- `Query`, `Filter`, `Sort`
54+
- `Validation`, `Permission`, `Sharing`
55+
- `Flow`, `Workflow`, `Trigger`
56+
- `Dataset`, `Mapping`
57+
58+
### `@objectstack/spec/ui` - UI Protocol
59+
Presentation and interaction:
60+
- `App`, `View`, `Page`
61+
- `Dashboard`, `Report`, `Widget`
62+
- `Action`, `Theme`
63+
64+
### `@objectstack/spec/system` - System Protocol
65+
Runtime configuration and security:
66+
- `Manifest`, `Datasource`, `Driver`
67+
- `User`, `Account`, `Session`
68+
- `Organization`, `Role`, `Permission`
69+
- `Auth`, `Policy`, `Territory`
70+
- `Webhook`, `License`, `Translation`
71+
- `Plugin`
72+
73+
### `@objectstack/spec/ai` - AI Protocol
74+
AI/ML capabilities:
75+
- `Agent`, `AITool`, `AIKnowledge`
76+
- `ModelRegistry`, `ModelProvider`
77+
- `RAGPipeline`, `VectorStore`
78+
- `NLQRequest`, `QueryIntent`
79+
80+
### `@objectstack/spec/api` - API Protocol
81+
API contracts and envelopes:
82+
- `CreateRequest`, `UpdateRequest`
83+
- `ApiError`, `BaseResponse`
84+
- `ExportRequest`, `BulkRequest`
85+
86+
## Migration Guide
87+
88+
### For Library Maintainers
89+
90+
You don't need to change anything! All existing exports remain available. However, you may want to adopt namespaced imports in new code:
91+
92+
**Before:**
93+
```typescript
94+
import { Field, User, App } from '@objectstack/spec';
95+
```
96+
97+
**After (optional):**
98+
```typescript
99+
import * as Data from '@objectstack/spec/data';
100+
import * as System from '@objectstack/spec/system';
101+
import * as UI from '@objectstack/spec/ui';
102+
103+
const field: Data.Field = { /* ... */ };
104+
const user: System.User = { /* ... */ };
105+
const app: UI.App = { /* ... */ };
106+
```
107+
108+
### For Application Developers
109+
110+
Choose the style that fits your needs:
111+
112+
```typescript
113+
// Option 1: Flat imports (quick and simple)
114+
import { ObjectSchema, Field } from '@objectstack/spec';
115+
116+
// Option 2: Namespaced imports (organized and safe)
117+
import * as Data from '@objectstack/spec/data';
118+
const result = Data.ObjectSchema.parse(config);
119+
120+
// Option 3: Mixed approach
121+
import { Field } from '@objectstack/spec';
122+
import * as System from '@objectstack/spec/system';
123+
```
124+
125+
## Implementation Details
126+
127+
### Package.json Exports
128+
129+
The `package.json` now includes export mappings:
130+
131+
```json
132+
{
133+
"exports": {
134+
".": "./dist/index.js",
135+
"./data": "./dist/data/index.js",
136+
"./ui": "./dist/ui/index.js",
137+
"./system": "./dist/system/index.js",
138+
"./ai": "./dist/ai/index.js",
139+
"./api": "./dist/api/index.js"
140+
}
141+
}
142+
```
143+
144+
### Barrel Files
145+
146+
Each protocol domain has an `index.ts` barrel file that re-exports all schemas and types from that domain:
147+
148+
- `src/data/index.ts` - Data Protocol
149+
- `src/ui/index.ts` - UI Protocol
150+
- `src/system/index.ts` - System Protocol
151+
- `src/ai/index.ts` - AI Protocol
152+
- `src/api/index.ts` - API Protocol
153+
154+
The root `src/index.ts` continues to re-export everything for backward compatibility.
155+
156+
## Benefits
157+
158+
1. **Zero Breaking Changes**: All existing code continues to work
159+
2. **Prevents Conflicts**: Clear namespace boundaries prevent naming collisions
160+
3. **Better IDE Support**: Autocomplete shows all types in a namespace
161+
4. **Self-Documenting**: Code clearly shows which protocol is being used
162+
5. **Scalable**: Can easily add new protocols without conflict risk
163+
164+
## Future Considerations
165+
166+
As the API grows, we can:
167+
1. Add sub-namespaces (e.g., `@objectstack/spec/data/query` for query-specific types)
168+
2. Mark certain flat exports as deprecated if conflicts arise
169+
3. Add convenience exports for commonly-used combinations
170+
171+
## Questions?
172+
173+
See the main README for usage examples, or check the TypeScript definitions in your IDE for available exports in each namespace.

packages/spec/README.md

Lines changed: 107 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,89 @@ The specification is divided into three protocols:
4444

4545
## 📚 Usage
4646

47+
### Import Styles
48+
49+
The package supports two import styles to prevent naming conflicts and improve code organization:
50+
51+
#### 1. Flat Imports (Backward Compatible)
52+
53+
All schemas and types can be imported directly from the package root:
54+
55+
```typescript
56+
import { ObjectSchema, Field, User, App, Agent } from '@objectstack/spec';
57+
58+
const result = ObjectSchema.safeParse(userConfig);
59+
if (!result.success) {
60+
console.error("Invalid Object definition", result.error);
61+
}
62+
```
63+
64+
**Pros:**
65+
- Simple, concise imports
66+
- Backward compatible with existing code
67+
- Good for importing a few specific types
68+
69+
**Cons:**
70+
- Risk of naming conflicts as the API grows
71+
- Less clear which protocol domain a type belongs to
72+
73+
#### 2. Namespaced Imports (Recommended for New Code)
74+
75+
Import entire protocol domains for better organization:
76+
77+
```typescript
78+
// Import protocol namespaces
79+
import * as Data from '@objectstack/spec/data';
80+
import * as UI from '@objectstack/spec/ui';
81+
import * as System from '@objectstack/spec/system';
82+
import * as AI from '@objectstack/spec/ai';
83+
import * as API from '@objectstack/spec/api';
84+
85+
// Use with namespace prefix
86+
const user: System.User = {
87+
id: 'user_123',
88+
email: 'user@example.com',
89+
// ...
90+
};
91+
92+
const field: Data.Field = {
93+
name: 'task_name',
94+
type: 'text',
95+
label: 'Task Name',
96+
// ...
97+
};
98+
99+
const agent: AI.Agent = {
100+
name: 'sales_assistant',
101+
// ...
102+
};
103+
```
104+
105+
**Pros:**
106+
- Clear organization by protocol domain
107+
- Eliminates naming conflict concerns
108+
- Better IDE autocomplete (shows all types in a namespace)
109+
- Self-documenting code (immediately clear which protocol is being used)
110+
111+
**Cons:**
112+
- Slightly more verbose
113+
- Requires namespace prefix for each type
114+
115+
#### 3. Mixed Approach
116+
117+
You can also mix both styles:
118+
119+
```typescript
120+
// Import frequently used types directly
121+
import { Field, ObjectSchema } from '@objectstack/spec';
122+
123+
// Import less common types via namespace
124+
import * as System from '@objectstack/spec/system';
125+
126+
const field: Field = { /* ... */ };
127+
const user: System.User = { /* ... */ };
128+
```
129+
47130
### Validation (Runtime)
48131

49132
```typescript
@@ -55,17 +138,37 @@ if (!result.success) {
55138
}
56139
```
57140

141+
Or using namespaced imports:
142+
143+
```typescript
144+
import * as Data from '@objectstack/spec/data';
145+
146+
const result = Data.ObjectSchema.safeParse(userConfig);
147+
```
148+
58149
### Type Definitions (Compile Time)
59150

60151
```typescript
61-
import type { Object, Field } from '@objectstack/spec';
152+
import type { Field } from '@objectstack/spec';
153+
// Or: import type { Field } from '@objectstack/spec/data';
62154

63-
const myObject: Object = {
64-
name: "project_task",
65-
fields: { ... }
155+
const myField: Field = {
156+
name: "task_name",
157+
type: "text",
158+
label: "Task Name"
66159
};
67160
```
68161

162+
Using namespaced imports for better organization:
163+
164+
```typescript
165+
import type * as Data from '@objectstack/spec/data';
166+
import type * as UI from '@objectstack/spec/ui';
167+
168+
const field: Data.Field = { /* ... */ };
169+
const view: UI.View = { /* ... */ };
170+
```
171+
69172
### JSON Schema (Tooling)
70173
The package includes valid JSON Schemas in the `/json-schema` directory.
71174
These can be used with:

packages/spec/package.json

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,32 @@
44
"description": "ObjectStack Protocol & Specification - TypeScript Interfaces, JSON Schemas, and Convention Configurations",
55
"main": "dist/index.js",
66
"types": "dist/index.d.ts",
7+
"exports": {
8+
".": {
9+
"types": "./dist/index.d.ts",
10+
"default": "./dist/index.js"
11+
},
12+
"./data": {
13+
"types": "./dist/data/index.d.ts",
14+
"default": "./dist/data/index.js"
15+
},
16+
"./ui": {
17+
"types": "./dist/ui/index.d.ts",
18+
"default": "./dist/ui/index.js"
19+
},
20+
"./system": {
21+
"types": "./dist/system/index.d.ts",
22+
"default": "./dist/system/index.js"
23+
},
24+
"./ai": {
25+
"types": "./dist/ai/index.d.ts",
26+
"default": "./dist/ai/index.js"
27+
},
28+
"./api": {
29+
"types": "./dist/api/index.d.ts",
30+
"default": "./dist/api/index.js"
31+
}
32+
},
733
"files": [
834
"dist",
935
"json-schema",

packages/spec/src/ai/index.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/**
2+
* AI Protocol Exports
3+
*
4+
* AI/ML Capabilities
5+
* - Agent Configuration
6+
* - Model Registry & Selection
7+
* - RAG Pipeline
8+
* - Natural Language Query (NLQ)
9+
*/
10+
11+
export * from './agent.zod';
12+
export * from './model-registry.zod';
13+
export * from './rag-pipeline.zod';
14+
export * from './nlq.zod';

packages/spec/src/api/index.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/**
2+
* API Protocol Exports
3+
*
4+
* API Contracts & Envelopes
5+
* - Request/Response schemas
6+
* - Error handling
7+
*/
8+
9+
export * from './contract.zod';

packages/spec/src/data/index.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/**
2+
* Data Protocol Exports
3+
*
4+
* Core Business Logic & Data Modeling
5+
* - Object, Field, Validation
6+
* - Query (AST), Mapping (ETL)
7+
* - Permission, Sharing, Flow
8+
*/
9+
10+
export * from './field.zod';
11+
export * from './object.zod';
12+
export * from './validation.zod';
13+
export * from './permission.zod';
14+
export * from './sharing.zod';
15+
export * from './workflow.zod';
16+
export * from './flow.zod';
17+
export * from './dataset.zod';
18+
export * from './query.zod';
19+
export * from './filter.zod';
20+
export * from './mapping.zod';
21+
export * from './trigger.zod';

0 commit comments

Comments
 (0)