-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathexample.ts
More file actions
145 lines (119 loc) · 3.17 KB
/
example.ts
File metadata and controls
145 lines (119 loc) · 3.17 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
/**
* TypeScript usage example for RailJS
* This file demonstrates type-safe usage of the Rail API
*/
import { Rail, RailModule, RailOptions } from './rail.js';
// Define typed event data interfaces
interface UserLoginData {
email: string;
password: string;
}
interface AuthSuccessData {
token: string;
user: {
id: number;
email: string;
name: string;
};
}
interface AuthFailedData {
email: string;
error: string;
}
// Create a typed Rail instance
const options: RailOptions = {
name: 'typed-app',
debug: true,
clone: true,
};
const rail = new Rail(options);
// Define a typed module
const authModule: RailModule = {
name: 'auth',
connect(rail: Rail) {
// Type-safe event listener
rail.on<UserLoginData>(
'user.login',
(data) => {
console.log('Login attempt:', data.email);
// TypeScript knows data has email and password properties
// Emit typed response
const response: AuthSuccessData = {
token: 'jwt-token',
user: {
id: 1,
email: data.email,
name: 'John Doe',
},
};
rail.emit<AuthSuccessData>('auth.success', response);
},
'auth'
);
},
disconnect(rail: Rail) {
console.log('Auth module disconnecting');
},
};
// Define an async module
const databaseModule: RailModule = {
name: 'database',
connect(rail: Rail) {
// Async event handler with typed data
rail.on<AuthSuccessData>(
'auth.success',
async (data) => {
console.log('Saving session for user:', data.user.id);
// Simulate async database operation
await new Promise((resolve) => setTimeout(resolve, 100));
return { sessionId: 'session-123', userId: data.user.id };
},
'database'
);
},
};
// Attach modules with chaining
rail.attach(authModule).attach(databaseModule);
// Emit events with type safety
const loginData: UserLoginData = {
email: 'user@example.com',
password: 'secret',
};
rail.emit<UserLoginData>('user.login', loginData);
// Use async emit with typed results
async function loginUser(email: string, password: string) {
const loginData: UserLoginData = { email, password };
const results = await rail.emitAsync<
UserLoginData,
{ sessionId: string; userId: number }
>('user.login', loginData);
// TypeScript knows the shape of results
results.forEach((result) => {
if (result.error) {
console.error(`Module ${result.module} failed:`, result.error);
} else if (result.result) {
console.log(
`Module ${result.module} returned:`,
result.result.sessionId
);
}
});
}
// Wait for events with types
async function waitForAuth() {
const authData = await rail.waitFor<AuthSuccessData>('auth.success', 5000);
console.log('Auth succeeded for user:', authData.user.name);
}
// Get statistics with proper typing
const stats = rail.getStats();
console.log(`Rail has ${stats.modules} modules and ${stats.events} events`);
// Get module list
const modules: string[] = rail.getModules();
console.log('Attached modules:', modules);
// Type-safe unsubscribe
const unsubscribe = rail.on<UserLoginData>('user.login', (data) => {
console.log('This handler will be removed');
});
unsubscribe(); // Type-safe unsubscribe function
// Export for other files
export { rail, authModule, databaseModule };