Skip to content

Commit 4a79bc4

Browse files
committed
docs(runtime): Introduce @globe/dart_source_generator as the recommended approach
- reclassify existing methods as alternatives.
1 parent 7ce82e0 commit 4a79bc4

File tree

1 file changed

+125
-10
lines changed

1 file changed

+125
-10
lines changed

packages/globe_runtime/README.md

Lines changed: 125 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -480,18 +480,133 @@ In your JavaScript modules, you have access to:
480480

481481
Globe Runtime supports using NPM packages through a bundling approach. This allows you to use any JavaScript library in your Dart applications.
482482

483-
### Why Bundle Instead of FileModule?
483+
### Recommended Approach: Using @globe/dart_source_generator (Easiest)
484484

485-
When using NPM packages, you **cannot** use `FileModule` directly because:
485+
The **recommended way** to create Globe Runtime SDKs is using the `@globe/dart_source_generator` CLI with `@globe/runtime_types`. This provides:
486486

487-
1. **Module Resolution**: Globe Runtime's internal module resolver expects proper `file://` URLs, but npm packages use different import mechanisms
488-
2. **Dependency Management**: NPM packages have their own dependencies that need to be resolved and bundled together
489-
3. **Browser Environment**: Globe Runtime runs in a browser-like environment, not Node.js, so packages need to be bundled for browser compatibility
490-
4. **Import/Export Compatibility**: ES modules and CommonJS modules need to be properly transformed for the runtime environment
487+
- **Type-safe SDK definitions** with full TypeScript support
488+
- **Automatic bundling** of your code with all dependencies
489+
- **Seamless Dart integration** with generated wrapper classes
490+
- **Hot reload support** in watch mode during development
491491

492-
The bundling approach ensures all dependencies are included and properly formatted for Globe Runtime.
492+
#### Step 1: Set up your TypeScript SDK
493493

494-
### Approach 1: Using esbuild (JavaScript - Simpler)
494+
Create a new directory for your SDK and initialize it:
495+
496+
```bash
497+
mkdir my_sdk
498+
cd my_sdk
499+
npm init -y
500+
npm install @globe/runtime_types @globe/dart_source_generator -D
501+
```
502+
503+
#### Step 2: Define your SDK in TypeScript
504+
505+
Create `src/sdk.ts`:
506+
507+
```typescript
508+
import { defineSdk, returnString, streamString } from "@globe/runtime_types";
509+
510+
type ModuleState = {
511+
apiUrl: string;
512+
timeout: number;
513+
};
514+
515+
const fetchUsers = streamString(
516+
async (state: ModuleState, callbackId: number) => {
517+
try {
518+
const url = `${state.apiUrl}/users`;
519+
const response = await fetch(url, {
520+
signal: AbortSignal.timeout(state.timeout)
521+
});
522+
523+
for await (const chunk of response.body!.values()) {
524+
Dart.stream_value(callbackId, chunk);
525+
}
526+
527+
Dart.stream_value_end(callbackId);
528+
} catch (error) {
529+
Dart.send_error(callbackId, `Stream failed: ${error.message}`);
530+
}
531+
}
532+
);
533+
534+
const calculatePrice = returnInt(
535+
(state: ModuleState, quantity: number, price: number, callbackId: number) => {
536+
const total = quantity * price;
537+
Dart.send_value(callbackId, new TextEncoder().encode(total.toString()));
538+
}
539+
);
540+
541+
export default defineSdk({
542+
init(apiUrl: string = "https://api.example.com", timeout: number = 5000): ModuleState {
543+
return { apiUrl, timeout };
544+
},
545+
functions: {
546+
fetchUsers,
547+
calculatePrice,
548+
},
549+
});
550+
```
551+
552+
#### Step 3: Generate Dart source files
553+
554+
Run the generator:
555+
556+
```bash
557+
npx @globe/dart_source_generator --files src/sdk.ts --output lib/generated/
558+
```
559+
560+
This generates `lib/generated/sdk_source.dart` containing the bundled JavaScript code.
561+
562+
#### Step 4: Use in your Dart project
563+
564+
Add to your `pubspec.yaml`:
565+
566+
```yaml
567+
dependencies:
568+
globe_runtime: ^1.0.7
569+
```
570+
571+
Then use in your Dart code:
572+
573+
```dart
574+
import 'dart:async';
575+
import 'package:your_package/generated/sdk_source.dart';
576+
577+
void main() async {
578+
// Create an instance of your SDK with initialization parameters
579+
final sdk = await Sdk.create(
580+
apiUrl: 'https://api.custom.com',
581+
timeout: 10000,
582+
);
583+
584+
// Call single-value functions (returns a Future)
585+
final price = await sdk.calculatePrice(10, 99);
586+
print('Total Price: $price');
587+
588+
// Call streaming functions (returns a Stream)
589+
final userStream = await sdk.fetchUsers();
590+
591+
final completer = Completer<void>();
592+
userStream.listen((user) {
593+
print('User: $user');
594+
}, onDone: completer.complete);
595+
596+
await completer.future;
597+
598+
// Clean up when done
599+
sdk.dispose();
600+
}
601+
```
602+
603+
The `@globe/dart_source_generator` automatically generates the SDK wrapper class with type-safe methods that handle all the Dart FFI interop boilerplate. You simply call methods and get properly typed `Future` or `Stream` objects back.
604+
605+
For more details, see the [@globe/dart_source_generator documentation](https://www.npmjs.com/package/@globe/dart_source_generator) and [@globe/runtime_types documentation](https://www.npmjs.com/package/@globe/runtime_types).
606+
607+
---
608+
609+
### Alternative Approach 1: Using esbuild (JavaScript - Simpler)
495610

496611
#### Step 1: Create package.json
497612

@@ -633,7 +748,7 @@ void main() async {
633748
}
634749
```
635750

636-
### Approach 2: Using tsup (TypeScript - Recommended)
751+
### Alternative Approach 2: Using tsup (TypeScript)
637752

638753
#### Step 1: Create package.json
639754

@@ -786,7 +901,7 @@ void main() async {
786901

787902
### Why This Approach Works
788903

789-
1. **Bundling**: `tsup` bundles all NPM dependencies into a single JavaScript file
904+
1. **Bundling**: Bundlers like `tsup` or `esbuild` bundle all NPM dependencies into a single JavaScript file
790905
2. **TypeScript Support**: Full type safety and IntelliSense
791906
3. **No external dependencies**: The bundled file contains everything needed
792907
4. **InlinedModule**: Uses the bundled code directly, avoiding file path and module resolution issues

0 commit comments

Comments
 (0)