Skip to content

Commit 94cbeec

Browse files
committed
update doc
1 parent c4ffd43 commit 94cbeec

File tree

2 files changed

+61
-74
lines changed

2 files changed

+61
-74
lines changed

docs/PLATFORM_ISOLATION.md

Lines changed: 60 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,14 @@ export const __platforms = ['node']; // Node.js only
2424
export const __platforms = ['react_native']; // React Native only
2525
```
2626

27-
**For multi-platform files (but not all):**
27+
**For multi-platform files:**
2828

2929
```typescript
3030
// lib/utils/web-features.ts
3131
export const __platforms = ['browser', 'react_native'];
3232

3333
// Your code that works on both browser and react_native
34-
export function getWindowSize() {
34+
export function makeHttpRequest() {
3535
// Implementation that works on both platforms
3636
}
3737
```
@@ -42,7 +42,7 @@ Valid platform identifiers: `'browser'`, `'node'`, `'react_native'`, `'__univers
4242

4343
### File Naming Convention (Optional)
4444

45-
While not enforced, you may optionally use file name suffixes for clarity:
45+
While not enforced, you should use file name suffixes for clarity:
4646
- `.browser.ts` - Typically browser-specific
4747
- `.node.ts` - Typically Node.js-specific
4848
- `.react_native.ts` - Typically React Native-specific
@@ -107,21 +107,22 @@ import { NodeRequestHandler } from './utils/http_request_handler/request_handler
107107
```
108108

109109
```typescript
110-
// In lib/index.react_native.ts (React Native platform only)
111-
import { Config } from './shared_types'; // ✅ Universal file
112-
113-
// If web-features.ts has: __platforms = ['browser', 'react_native']
114-
import { getWindowSize } from './utils/web-features'; // ✅ Compatible (supports react_native)
110+
// In lib/vuid/vuid_manager_factory.react_native.ts (React Native platform only)
111+
import { AsyncStorageCache } from '../utils/cache/async_storage_cache.react_native'; // ✅ Compatible (react_native only)
115112
```
116113

117-
```typescript
118-
// In lib/utils/web-api.ts
119-
// export const __platforms = ['browser', 'react_native'];
120114

121-
import { Config } from './shared_types'; // ✅ Universal file
122115

123-
// If dom-helpers.ts has: __platforms = ['browser', 'react_native']
124-
import { helpers } from './dom-helpers'; // ✅ Compatible (supports BOTH browser and react_native)
116+
```typescript
117+
// In lib/event_processor/event_processor_factory.browser.ts (Browser platform only)
118+
import { Config } from '../shared_types'; // ✅ Universal file
119+
import defaultEventDispatcher from './event_dispatcher/default_dispatcher.browser'; // ✅ Compatible (browser + react_native, includes browser)
120+
```
121+
122+
```typescript
123+
// In lib/event_processor/event_dispatcher/default_dispatcher.browser.ts (Multi-platform: browser + react_native)
124+
import { Config } from '../../shared_types'; // ✅ Universal file
125+
import { BrowserRequestHandler } from '../../utils/http_request_handler/request_handler.browser'; // ✅ Compatible (also browser + react_native)
125126
```
126127

127128
**Invalid Imports**
@@ -133,24 +134,17 @@ import { NodeRequestHandler } from './utils/http_request_handler/request_handler
133134

134135
```typescript
135136
// In lib/index.node.ts (Node platform only)
136-
// If web-features.ts has: __platforms = ['browser', 'react_native']
137-
import { getWindowSize } from './utils/web-features'; // ❌ Not compatible with Node
137+
import { BrowserRequestHandler } from './utils/http_request_handler/request_handler.browser'; // ❌ browser + react_native, doesn't support node
138138
```
139139

140140
```typescript
141141
// In lib/shared_types.ts (Universal file)
142-
// export const __platforms = ['__universal__'];
143-
144-
import { helper } from './helper.browser'; // ❌ Browser-only, universal file needs imports that work everywhere
142+
import { AsyncStorageCache } from './utils/cache/async_storage_cache.react_native'; // ❌ React Native only, universal file needs imports that work everywhere
145143
```
146144

147145
```typescript
148-
// In lib/utils/web-api.ts
149-
// export const __platforms = ['browser', 'react_native'];
150-
151-
// If helper.browser.ts is browser-only
152-
import { helper } from './helper.browser'; // ❌ Browser-only, doesn't support react_native
153-
146+
// In lib/event_processor/event_dispatcher/default_dispatcher.browser.ts
147+
import { NodeRequestHandler } from '../../utils/http_request_handler/request_handler.node'; // ❌ Node-only, doesn't support browser or react_native
154148
// This file needs imports that work in BOTH browser AND react_native
155149
```
156150

@@ -172,7 +166,7 @@ npm run build
172166

173167
The validation script (`scripts/validate-platform-isolation-ts.js`):
174168

175-
1. Scans all source files in the `lib/` directory (excluding tests)
169+
1. Scans all TypeScript/JavaScript files configured in the in the `.platform-isolation.config.js` config file.
176170
2. **Verifies every file has a `__platforms` export** - fails immediately if any file is missing this
177171
3. **Validates all platform values** - ensures values in `__platforms` arrays are valid (read from Platform type)
178172
4. Parses import statements using TypeScript AST (ES6 imports, require, dynamic imports)
@@ -199,21 +193,44 @@ If platform isolation is violated, the build will fail with a detailed error mes
199193
- What platform the file belongs to
200194
- What platform it's incorrectly importing from
201195

202-
## Creating New Platform-Specific Code
203196

204-
When creating new platform-specific implementations:
205197

206-
### Single Platform
198+
## Creating New Modules
199+
200+
### Universal Code
201+
202+
For code that works across all platforms, use `['__universal__']`:
203+
204+
**Example: Universal utility function**
205+
206+
```typescript
207+
// lib/utils/string-helpers.ts
208+
export const __platforms = ['__universal__'];
209+
210+
// Pure JavaScript that works everywhere
211+
export function capitalize(str: string): string {
212+
return str.charAt(0).toUpperCase() + str.slice(1);
213+
}
214+
215+
export function sanitizeKey(key: string): string {
216+
return key.replace(/[^a-zA-Z0-9_]/g, '_');
217+
}
218+
```
219+
220+
### Platform-Specific Code
221+
222+
**Single Platform**
207223

208224
1. **Add `__platforms` export** declaring the platform (e.g., `export const __platforms = ['browser'];`)
209-
2. Optionally name the file with a platform suffix for clarity (e.g., `my-feature.browser.ts`)
225+
2. Name the file with a platform suffix for clarity (e.g., `my-feature.browser.ts`)
210226
3. Only import from universal or compatible platform files
211-
4. Create a universal factory or interface if multiple platforms need different implementations
212227

213228
**Example:**
214229

215230
```typescript
216231
// lib/features/my-feature.ts (universal interface)
232+
export const __platforms = ['__universal__'];
233+
217234
export interface MyFeature {
218235
doSomething(): void;
219236
}
@@ -235,64 +252,34 @@ export class NodeMyFeature implements MyFeature {
235252
// Node.js-specific implementation
236253
}
237254
}
238-
239-
// lib/features/factory.browser.ts
240-
import { BrowserMyFeature } from './my-feature.browser';
241-
export const createMyFeature = () => new BrowserMyFeature();
242-
243-
// lib/features/factory.node.ts
244-
import { NodeMyFeature } from './my-feature.node';
245-
export const createMyFeature = () => new NodeMyFeature();
246255
```
247256

248-
### Multiple Platforms (But Not All)
257+
**Multiple Platforms (But Not Universal)**
249258

250-
For code that works on multiple platforms but not all, use the `__platforms` export:
259+
For code that works on multiple platforms but is not universal, use the `__platforms` export to decalre the list of supported platforms:
251260

252261
**Example: Browser + React Native only**
253262

254263
```typescript
255-
// lib/utils/dom-helpers.ts
264+
// lib/utils/http-helpers.ts
256265
export const __platforms = ['browser', 'react_native'];
257266

258267
// This code works on both browser and react_native, but not node
259-
export function getElementById(id: string): Element | null {
260-
if (typeof document !== 'undefined') {
261-
return document.getElementById(id);
262-
}
263-
// React Native polyfill or alternative
264-
return null;
268+
export function makeRequest(url: string): Promise<string> {
269+
// XMLHttpRequest is available in both browser and react_native
270+
return new Promise((resolve, reject) => {
271+
const xhr = new XMLHttpRequest();
272+
xhr.open('GET', url);
273+
xhr.onload = () => resolve(xhr.responseText);
274+
xhr.onerror = () => reject(new Error('Request failed'));
275+
xhr.send();
276+
});
265277
}
266278
```
267279

268-
**Example: Node + React Native only**
269-
270-
```typescript
271-
// lib/utils/native-crypto.ts
272-
export const __platforms = ['node', 'react_native'];
273-
274-
import crypto from 'crypto'; // Available in both Node and React Native
275-
276-
export function generateHash(data: string): string {
277-
return crypto.createHash('sha256').update(data).digest('hex');
278-
}
279-
```
280-
281-
## Troubleshooting
282-
283-
If you encounter a platform isolation error:
284-
285-
1. **Check the error message** - It will tell you which file and line has the violation
286-
2. **Identify the issue** - Look at the import statement on that line
287-
3. **Fix the import**:
288-
- If the code should be universal, remove the platform suffix from the imported file
289-
- If the code must be platform-specific, create separate implementations for each platform
290-
- Use factory patterns to abstract platform-specific instantiation
291-
292280
## Benefits
293281

294282
- ✅ Prevents runtime errors from platform-incompatible code
295283
- ✅ Catches issues at build time, not in production
296284
- ✅ Makes platform boundaries explicit and maintainable
297285
- ✅ Ensures each bundle only includes relevant code
298-
- ✅ Works independently of linting tools (ESLint, Biome, etc.)

scripts/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ npm run build
2525

2626
The script:
2727
1. Scans all TypeScript/JavaScript files configured in the in the `.platform-isolation.config.js` config file.
28-
2. **Requires every file to export `__platforms` array** declaring supported platforms
28+
2. **Requires every configured file to export `__platforms` array** declaring supported platforms
2929
3. **Validates platform values** by reading the Platform type definition from `platform_support.ts`
3030
4. Parses import statements (ES6 imports, require(), dynamic imports) using TypeScript AST
3131
5. **Validates import compatibility**: For each import, ensures the imported file supports ALL platforms that the importing file runs on

0 commit comments

Comments
 (0)