Skip to content

Commit 46e16ce

Browse files
Copilothuangyiirene
andcommitted
Remove flat exports, enforce namespace-only imports
Co-authored-by: huangyiirene <7665279+huangyiirene@users.noreply.github.com>
1 parent fe6524c commit 46e16ce

5 files changed

Lines changed: 287 additions & 242 deletions

File tree

packages/spec/EXPORT_ORGANIZATION.md

Lines changed: 60 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -7,26 +7,27 @@ The `@objectstack/spec` package exports many schemas and types. As the API surfa
77
2. **Poor discoverability**: With 200+ exports in a flat namespace, it's hard to find what you need
88
3. **Unclear domain boundaries**: Not obvious which exports belong to which protocol
99

10-
## Solution: Dual Export Strategy
10+
## Solution: Namespace-Only Exports
1111

12-
We now support **both flat and namespaced imports** to give developers flexibility while preventing future naming conflicts.
12+
This package **does NOT export types at the root level** to prevent naming conflicts. All exports are organized by protocol domain using namespaces.
1313

14-
### 1. Flat Exports (Backward Compatible)
14+
### Import Styles
1515

16-
All existing imports continue to work:
16+
#### Style 1: Namespace Imports from Root
1717

1818
```typescript
19-
import { Field, User, App, Agent } from '@objectstack/spec';
19+
import { Data, UI, System, AI, API } from '@objectstack/spec';
20+
21+
const field: Data.Field = { /* ... */ };
22+
const user: System.User = { /* ... */ };
2023
```
2124

2225
**When to use:**
23-
- Migrating existing code
24-
- Importing a few specific types
25-
- Quick prototyping
26+
- Need multiple protocols in one file
27+
- Want single import statement
28+
- Clear namespace boundaries
2629

27-
### 2. Namespaced Exports (Recommended)
28-
29-
Import by protocol domain for better organization:
30+
#### Style 2: Namespace Imports via Subpath
3031

3132
```typescript
3233
import * as Data from '@objectstack/spec/data';
@@ -40,10 +41,24 @@ const user: System.User = { /* ... */ };
4041
```
4142

4243
**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
44+
- Better tree-shaking (only imports needed protocols)
45+
- Explicit about which protocols are used
46+
- Working with many types from same protocol
47+
48+
#### Style 3: Direct Subpath Imports
49+
50+
```typescript
51+
import { Field, FieldType } from '@objectstack/spec/data';
52+
import { User, Session } from '@objectstack/spec/system';
53+
54+
const field: Field = { /* ... */ };
55+
const user: User = { /* ... */ };
56+
```
57+
58+
**When to use:**
59+
- Most concise syntax
60+
- Importing specific types only
61+
- No namespace prefix needed
4762

4863
## Protocol Domains
4964

@@ -85,48 +100,51 @@ API contracts and envelopes:
85100

86101
## Migration Guide
87102

88-
### For Library Maintainers
103+
### Breaking Change Notice
89104

90-
You don't need to change anything! All existing exports remain available. However, you may want to adopt namespaced imports in new code:
105+
**This is a breaking change.** Flat imports are no longer supported.
91106

92-
**Before:**
107+
**Before (v0.1.x):**
93108
```typescript
94109
import { Field, User, App } from '@objectstack/spec';
95110
```
96111

97-
**After (optional):**
112+
**After (v0.2.x+):**
98113
```typescript
114+
// Option 1: Namespace from root
115+
import { Data, System, UI } from '@objectstack/spec';
116+
const field: Data.Field = { /* ... */ };
117+
const user: System.User = { /* ... */ };
118+
119+
// Option 2: Namespace via subpath
99120
import * as Data from '@objectstack/spec/data';
100121
import * as System from '@objectstack/spec/system';
101-
import * as UI from '@objectstack/spec/ui';
102-
103122
const field: Data.Field = { /* ... */ };
104123
const user: System.User = { /* ... */ };
105-
const app: UI.App = { /* ... */ };
106-
```
107124

108-
### For Application Developers
125+
// Option 3: Direct subpath imports
126+
import { Field } from '@objectstack/spec/data';
127+
import { User } from '@objectstack/spec/system';
128+
const field: Field = { /* ... */ };
129+
const user: User = { /* ... */ };
130+
```
109131

110-
Choose the style that fits your needs:
132+
### Migration Steps
111133

112-
```typescript
113-
// Option 1: Flat imports (quick and simple)
114-
import { ObjectSchema, Field } from '@objectstack/spec';
134+
1. **Find all imports from `@objectstack/spec`:**
135+
```bash
136+
grep -r "from '@objectstack/spec'" src/
137+
```
115138

116-
// Option 2: Namespaced imports (organized and safe)
117-
import * as Data from '@objectstack/spec/data';
118-
const result = Data.ObjectSchema.parse(config);
139+
2. **Replace with one of the three styles above**
119140

120-
// Option 3: Mixed approach
121-
import { Field } from '@objectstack/spec';
122-
import * as System from '@objectstack/spec/system';
123-
```
141+
3. **Test your application** to ensure all types are accessible
124142

125143
## Implementation Details
126144

127145
### Package.json Exports
128146

129-
The `package.json` now includes export mappings:
147+
The `package.json` includes export mappings:
130148

131149
```json
132150
{
@@ -151,22 +169,23 @@ Each protocol domain has an `index.ts` barrel file that re-exports all schemas a
151169
- `src/ai/index.ts` - AI Protocol
152170
- `src/api/index.ts` - API Protocol
153171

154-
The root `src/index.ts` continues to re-export everything for backward compatibility.
172+
The root `src/index.ts` exports only protocol namespaces (no flat exports).
155173

156174
## Benefits
157175

158-
1. **Zero Breaking Changes**: All existing code continues to work
159-
2. **Prevents Conflicts**: Clear namespace boundaries prevent naming collisions
176+
1. **Eliminates Naming Conflicts**: Namespace boundaries prevent all naming collisions
177+
2. **Clear Protocol Boundaries**: Immediately obvious which protocol a type belongs to
160178
3. **Better IDE Support**: Autocomplete shows all types in a namespace
161179
4. **Self-Documenting**: Code clearly shows which protocol is being used
162180
5. **Scalable**: Can easily add new protocols without conflict risk
181+
6. **Tree-Shakeable**: Modern bundlers can better optimize imports
163182

164183
## Future Considerations
165184

166185
As the API grows, we can:
167186
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
187+
2. Add convenience exports for commonly-used combinations
188+
3. Further organize large protocol domains into sub-categories
170189

171190
## Questions?
172191

packages/spec/PR_SUMMARY.md

Lines changed: 63 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
## Solution Overview
1010

11-
Implemented a **dual export strategy** that prevents naming conflicts while maintaining 100% backward compatibility.
11+
Implemented a **namespace-only export strategy** that completely eliminates naming conflicts. This is a **breaking change** that enforces organized imports by protocol domain.
1212

1313
## Key Changes
1414

@@ -25,7 +25,19 @@ packages/spec/src/
2525
└── api/index.ts # API Protocol (Contracts, Requests, etc.)
2626
```
2727

28-
### 2. Updated package.json
28+
### 2. Updated Root Index
29+
30+
**Removed all flat exports** from `src/index.ts` and replaced with namespace exports:
31+
32+
```typescript
33+
export * as Data from './data';
34+
export * as UI from './ui';
35+
export * as System from './system';
36+
export * as AI from './ai';
37+
export * as API from './api';
38+
```
39+
40+
### 3. Updated package.json
2941

3042
Added export mappings for each namespace:
3143

@@ -42,45 +54,73 @@ Added export mappings for each namespace:
4254
}
4355
```
4456

45-
### 3. Enhanced Documentation
57+
### 4. Enhanced Documentation
4658

47-
- **README.md**: Added comprehensive section on import styles
48-
- **EXPORT_ORGANIZATION.md**: Detailed guide on the new organization
49-
- **examples/**: Code examples demonstrating both import styles
59+
- **README.md**: Updated with three supported import styles
60+
- **EXPORT_ORGANIZATION.md**: Detailed migration guide
61+
- **examples/**: Updated code examples
5062

5163
## Import Styles Supported
5264

53-
### Style 1: Flat Imports (Backward Compatible)
65+
### Style 1: Namespace Imports from Root
5466

5567
```typescript
56-
import { Field, User, App, Agent } from '@objectstack/spec';
57-
```
68+
import { Data, UI, System, AI, API } from '@objectstack/spec';
5869

59-
✅ All 36 existing imports in the codebase continue to work
70+
const field: Data.Field = { /* ... */ };
71+
const user: System.User = { /* ... */ };
72+
```
6073

61-
### Style 2: Namespaced Imports (Recommended)
74+
### Style 2: Namespace Imports via Subpath
6275

6376
```typescript
6477
import * as Data from '@objectstack/spec/data';
6578
import * as UI from '@objectstack/spec/ui';
6679
import * as System from '@objectstack/spec/system';
67-
import * as AI from '@objectstack/spec/ai';
68-
import * as API from '@objectstack/spec/api';
6980

7081
const field: Data.Field = { /* ... */ };
7182
const user: System.User = { /* ... */ };
7283
```
7384

85+
### Style 3: Direct Subpath Imports
86+
87+
```typescript
88+
import { Field, FieldType } from '@objectstack/spec/data';
89+
import { User, Session } from '@objectstack/spec/system';
90+
91+
const field: Field = { /* ... */ };
92+
const user: User = { /* ... */ };
93+
```
94+
7495
## Benefits
7596

76-
1. **Zero Breaking Changes**: All existing code continues to work without modification
77-
2. **Prevents Future Conflicts**: Namespaces prevent naming collisions as API grows
97+
1. **Eliminates All Naming Conflicts**: Namespace boundaries completely prevent collisions
98+
2. **Clear Protocol Boundaries**: Immediately obvious which protocol a type belongs to
7899
3. **✅ Better Developer Experience**:
79100
- Clear domain boundaries
80101
- Improved IDE autocomplete
81102
- Self-documenting code
82103
4. **✅ Scalable Architecture**: Easy to add new protocols without risk
83-
5. **✅ Flexible**: Developers can choose their preferred import style
104+
5. **✅ Tree-Shakeable**: Better optimization by modern bundlers
105+
106+
## Breaking Change Notice
107+
108+
**This is a breaking change.** Flat imports from the root are no longer supported.
109+
110+
### Migration Required
111+
112+
All imports like:
113+
```typescript
114+
import { Field, User, App } from '@objectstack/spec';
115+
```
116+
117+
Must be changed to one of the three supported styles (see above).
118+
119+
### Migration Steps
120+
121+
1. Find all imports: `grep -r "from '@objectstack/spec'" src/`
122+
2. Replace with one of the three styles
123+
3. Test your application
84124

85125
## Verification Results
86126

@@ -92,58 +132,35 @@ const user: System.User = { /* ... */ };
92132
- **Status**: ✅ Passed
93133
- **Vulnerabilities**: 0
94134

95-
### Backward Compatibility
96-
- **Existing Imports Checked**: 36 files
97-
- **Breaking Changes**: 0
98-
- **Status**: ✅ 100% Compatible
99-
100135
### TypeScript Compilation
101136
- **Status**: ✅ No export errors
102137
- **Circular Dependencies**: None detected
103138

104139
## Files Changed
105140

106-
-`packages/spec/src/index.ts` - Added documentation and reorganized exports
141+
-`packages/spec/src/index.ts` - Removed flat exports, added namespace exports
107142
-`packages/spec/src/data/index.ts` - New barrel export
108143
-`packages/spec/src/ui/index.ts` - New barrel export
109144
-`packages/spec/src/system/index.ts` - New barrel export
110145
-`packages/spec/src/ai/index.ts` - New barrel export
111146
-`packages/spec/src/api/index.ts` - New barrel export
112147
-`packages/spec/package.json` - Added export mappings
113-
-`packages/spec/README.md` - Enhanced documentation
114-
-`packages/spec/EXPORT_ORGANIZATION.md` - New comprehensive guide
115-
-`packages/spec/examples/namespaced-imports.example.ts` - Example code
148+
-`packages/spec/README.md` - Updated documentation
149+
-`packages/spec/EXPORT_ORGANIZATION.md` - Updated with migration guide
150+
-`packages/spec/examples/namespaced-imports.example.ts` - Updated examples
116151
-`packages/spec/examples/README.md` - Examples documentation
117152

118-
## Migration Path
119-
120-
### For Existing Code
121-
**No migration required!** All existing imports continue to work.
122-
123-
### For New Code
124-
Recommended to use namespaced imports for better organization:
125-
126-
```typescript
127-
// Before (still works)
128-
import { Field, User, App } from '@objectstack/spec';
129-
130-
// After (recommended)
131-
import * as Data from '@objectstack/spec/data';
132-
import * as System from '@objectstack/spec/system';
133-
import * as UI from '@objectstack/spec/ui';
134-
```
135-
136153
## Future Considerations
137154

138155
1. **Add Sub-namespaces**: Can create deeper organization (e.g., `@objectstack/spec/data/query`)
139-
2. **Deprecation Path**: If conflicts arise, can mark specific flat exports as deprecated
140-
3. **Convention Exports**: Can add convenience exports for commonly-used combinations
156+
2. **Convention Exports**: Can add convenience exports for commonly-used combinations
157+
3. **Further Categorization**: Organize large protocol domains into sub-categories
141158

142159
## Questions & Support
143160

144161
See the following documentation for more details:
145162
- [README.md](README.md) - Quick start and usage examples
146-
- [EXPORT_ORGANIZATION.md](EXPORT_ORGANIZATION.md) - Comprehensive guide
163+
- [EXPORT_ORGANIZATION.md](EXPORT_ORGANIZATION.md) - Comprehensive migration guide
147164
- [examples/](examples/) - Working code examples
148165

149166
## Conclusion

0 commit comments

Comments
 (0)