@principal-ai/control-tower-core 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +84 -0
- package/dist/abstractions/AuthAdapter.d.ts +9 -0
- package/dist/abstractions/AuthAdapter.d.ts.map +1 -0
- package/dist/abstractions/AuthAdapter.js +1 -0
- package/dist/abstractions/DefaultLockManager.d.ts +18 -0
- package/dist/abstractions/DefaultLockManager.d.ts.map +1 -0
- package/dist/abstractions/DefaultLockManager.js +152 -0
- package/dist/abstractions/DefaultRoomManager.d.ts +15 -0
- package/dist/abstractions/DefaultRoomManager.d.ts.map +1 -0
- package/dist/abstractions/DefaultRoomManager.js +91 -0
- package/dist/abstractions/EventEmitter.d.ts +14 -0
- package/dist/abstractions/EventEmitter.d.ts.map +1 -0
- package/dist/abstractions/EventEmitter.js +56 -0
- package/dist/abstractions/LockManager.d.ts +16 -0
- package/dist/abstractions/LockManager.d.ts.map +1 -0
- package/dist/abstractions/LockManager.js +9 -0
- package/dist/abstractions/RoomManager.d.ts +15 -0
- package/dist/abstractions/RoomManager.d.ts.map +1 -0
- package/dist/abstractions/RoomManager.js +5 -0
- package/dist/abstractions/StorageAdapter.d.ts +25 -0
- package/dist/abstractions/StorageAdapter.d.ts.map +1 -0
- package/dist/abstractions/StorageAdapter.js +1 -0
- package/dist/abstractions/TransportAdapter.d.ts +17 -0
- package/dist/abstractions/TransportAdapter.d.ts.map +1 -0
- package/dist/abstractions/TransportAdapter.js +1 -0
- package/dist/abstractions/index.d.ts +9 -0
- package/dist/abstractions/index.d.ts.map +1 -0
- package/dist/abstractions/index.js +5 -0
- package/dist/adapters/mock/MockAuthAdapter.d.ts +27 -0
- package/dist/adapters/mock/MockAuthAdapter.d.ts.map +1 -0
- package/dist/adapters/mock/MockAuthAdapter.js +161 -0
- package/dist/adapters/mock/MockStorageAdapter.d.ts +27 -0
- package/dist/adapters/mock/MockStorageAdapter.d.ts.map +1 -0
- package/dist/adapters/mock/MockStorageAdapter.js +162 -0
- package/dist/adapters/mock/MockTransportAdapter.d.ts +31 -0
- package/dist/adapters/mock/MockTransportAdapter.d.ts.map +1 -0
- package/dist/adapters/mock/MockTransportAdapter.js +90 -0
- package/dist/adapters/mock/index.d.ts +4 -0
- package/dist/adapters/mock/index.d.ts.map +1 -0
- package/dist/adapters/mock/index.js +3 -0
- package/dist/adapters/websocket/WebSocketTransportAdapter.d.ts +40 -0
- package/dist/adapters/websocket/WebSocketTransportAdapter.d.ts.map +1 -0
- package/dist/adapters/websocket/WebSocketTransportAdapter.js +204 -0
- package/dist/adapters/websocket/index.d.ts +2 -0
- package/dist/adapters/websocket/index.d.ts.map +1 -0
- package/dist/adapters/websocket/index.js +1 -0
- package/dist/client/BaseClient.d.ts +103 -0
- package/dist/client/BaseClient.d.ts.map +1 -0
- package/dist/client/BaseClient.js +282 -0
- package/dist/client/ClientBuilder.d.ts +16 -0
- package/dist/client/ClientBuilder.d.ts.map +1 -0
- package/dist/client/ClientBuilder.js +37 -0
- package/dist/client/index.d.ts +3 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +3 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -1205
- package/dist/index.js.map +23 -6
- package/dist/server/BaseServer.d.ts +116 -0
- package/dist/server/BaseServer.d.ts.map +1 -0
- package/dist/server/BaseServer.js +422 -0
- package/dist/server/ServerBuilder.d.ts +32 -0
- package/dist/server/ServerBuilder.d.ts.map +1 -0
- package/dist/server/ServerBuilder.js +66 -0
- package/dist/server/index.d.ts +3 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +3 -0
- package/dist/types/auth.d.ts +40 -0
- package/dist/types/auth.d.ts.map +1 -0
- package/dist/types/auth.js +1 -0
- package/dist/types/events.d.ts +66 -0
- package/dist/types/events.d.ts.map +1 -0
- package/dist/types/events.js +1 -0
- package/dist/types/index.d.ts +23 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +1 -0
- package/dist/types/lock.d.ts +35 -0
- package/dist/types/lock.d.ts.map +1 -0
- package/dist/types/lock.js +1 -0
- package/dist/types/room.d.ts +40 -0
- package/dist/types/room.d.ts.map +1 -0
- package/dist/types/room.js +1 -0
- package/package.json +7 -3
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
export class MockAuthAdapter {
|
|
2
|
+
constructor(options) {
|
|
3
|
+
this.tokens = new Map();
|
|
4
|
+
this.revokedTokens = new Set();
|
|
5
|
+
this.users = new Map();
|
|
6
|
+
this.simulateLatency = 0;
|
|
7
|
+
this.shouldFailAuth = false;
|
|
8
|
+
this.tokenCounter = 0;
|
|
9
|
+
this.simulateLatency = options?.simulateLatency ?? 0;
|
|
10
|
+
this.shouldFailAuth = options?.shouldFailAuth ?? false;
|
|
11
|
+
// Add some default test users
|
|
12
|
+
this.addUser('testuser', 'password123', {
|
|
13
|
+
userId: 'user-1',
|
|
14
|
+
email: 'test@example.com',
|
|
15
|
+
username: 'testuser',
|
|
16
|
+
permissions: ['read', 'write']
|
|
17
|
+
});
|
|
18
|
+
this.addUser('admin', 'admin123', {
|
|
19
|
+
userId: 'user-admin',
|
|
20
|
+
email: 'admin@example.com',
|
|
21
|
+
username: 'admin',
|
|
22
|
+
permissions: ['read', 'write', 'admin']
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
async validateToken(token) {
|
|
26
|
+
await this.simulateDelay();
|
|
27
|
+
if (this.shouldFailAuth) {
|
|
28
|
+
throw new Error('Mock auth validation failed');
|
|
29
|
+
}
|
|
30
|
+
if (this.revokedTokens.has(token)) {
|
|
31
|
+
throw new Error('Token has been revoked');
|
|
32
|
+
}
|
|
33
|
+
const payload = this.tokens.get(token);
|
|
34
|
+
if (!payload) {
|
|
35
|
+
throw new Error('Invalid token');
|
|
36
|
+
}
|
|
37
|
+
// Check expiration
|
|
38
|
+
if (payload.expiresAt && payload.expiresAt < Date.now()) {
|
|
39
|
+
this.tokens.delete(token);
|
|
40
|
+
throw new Error('Token expired');
|
|
41
|
+
}
|
|
42
|
+
return payload;
|
|
43
|
+
}
|
|
44
|
+
async generateToken(payload) {
|
|
45
|
+
await this.simulateDelay();
|
|
46
|
+
if (this.shouldFailAuth) {
|
|
47
|
+
throw new Error('Mock token generation failed');
|
|
48
|
+
}
|
|
49
|
+
const token = `mock-token-${++this.tokenCounter}`;
|
|
50
|
+
// Set default expiration to 1 hour if not specified
|
|
51
|
+
const expiresAt = payload.expiresAt ?? Date.now() + 3600000;
|
|
52
|
+
this.tokens.set(token, { ...payload, expiresAt });
|
|
53
|
+
return token;
|
|
54
|
+
}
|
|
55
|
+
async refreshToken(token) {
|
|
56
|
+
await this.simulateDelay();
|
|
57
|
+
if (this.shouldFailAuth) {
|
|
58
|
+
throw new Error('Mock token refresh failed');
|
|
59
|
+
}
|
|
60
|
+
const payload = await this.validateToken(token);
|
|
61
|
+
// Revoke old token
|
|
62
|
+
await this.revokeToken(token);
|
|
63
|
+
// Generate new token with extended expiration
|
|
64
|
+
const newPayload = {
|
|
65
|
+
...payload,
|
|
66
|
+
expiresAt: Date.now() + 3600000 // 1 hour from now
|
|
67
|
+
};
|
|
68
|
+
return this.generateToken(newPayload);
|
|
69
|
+
}
|
|
70
|
+
async revokeToken(token) {
|
|
71
|
+
await this.simulateDelay();
|
|
72
|
+
if (this.shouldFailAuth) {
|
|
73
|
+
throw new Error('Mock token revocation failed');
|
|
74
|
+
}
|
|
75
|
+
this.tokens.delete(token);
|
|
76
|
+
this.revokedTokens.add(token);
|
|
77
|
+
}
|
|
78
|
+
async authenticate(credentials) {
|
|
79
|
+
await this.simulateDelay();
|
|
80
|
+
if (this.shouldFailAuth) {
|
|
81
|
+
throw new Error('Mock authentication failed');
|
|
82
|
+
}
|
|
83
|
+
switch (credentials.type) {
|
|
84
|
+
case 'password': {
|
|
85
|
+
if (!credentials.username || !credentials.password) {
|
|
86
|
+
throw new Error('Username and password required');
|
|
87
|
+
}
|
|
88
|
+
const user = this.users.get(credentials.username);
|
|
89
|
+
if (!user || user.password !== credentials.password) {
|
|
90
|
+
throw new Error('Invalid credentials');
|
|
91
|
+
}
|
|
92
|
+
const token = await this.generateToken(user.payload);
|
|
93
|
+
const refreshToken = `refresh-${token}`;
|
|
94
|
+
this.tokens.set(refreshToken, user.payload);
|
|
95
|
+
return {
|
|
96
|
+
token,
|
|
97
|
+
refreshToken,
|
|
98
|
+
user: user.payload,
|
|
99
|
+
expiresIn: 3600
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
case 'token': {
|
|
103
|
+
if (!credentials.token) {
|
|
104
|
+
throw new Error('Token required');
|
|
105
|
+
}
|
|
106
|
+
const payload = await this.validateToken(credentials.token);
|
|
107
|
+
return {
|
|
108
|
+
token: credentials.token,
|
|
109
|
+
user: payload,
|
|
110
|
+
expiresIn: 3600
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
case 'oauth': {
|
|
114
|
+
// Simulate OAuth flow
|
|
115
|
+
if (!credentials.code) {
|
|
116
|
+
throw new Error('OAuth code required');
|
|
117
|
+
}
|
|
118
|
+
// Create a mock OAuth user
|
|
119
|
+
const payload = {
|
|
120
|
+
userId: `oauth-user-${Date.now()}`,
|
|
121
|
+
email: 'oauth@example.com',
|
|
122
|
+
username: 'oauthuser',
|
|
123
|
+
permissions: ['read', 'write']
|
|
124
|
+
};
|
|
125
|
+
const token = await this.generateToken(payload);
|
|
126
|
+
return {
|
|
127
|
+
token,
|
|
128
|
+
user: payload,
|
|
129
|
+
expiresIn: 3600
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
default:
|
|
133
|
+
throw new Error('Unsupported credential type');
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
// Test helper methods
|
|
137
|
+
async simulateDelay() {
|
|
138
|
+
if (this.simulateLatency > 0) {
|
|
139
|
+
await new Promise(resolve => setTimeout(resolve, this.simulateLatency));
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
addUser(username, password, payload) {
|
|
143
|
+
this.users.set(username, { password, payload });
|
|
144
|
+
}
|
|
145
|
+
removeUser(username) {
|
|
146
|
+
this.users.delete(username);
|
|
147
|
+
}
|
|
148
|
+
getTokenCount() {
|
|
149
|
+
return this.tokens.size;
|
|
150
|
+
}
|
|
151
|
+
getRevokedTokenCount() {
|
|
152
|
+
return this.revokedTokens.size;
|
|
153
|
+
}
|
|
154
|
+
clearTokens() {
|
|
155
|
+
this.tokens.clear();
|
|
156
|
+
this.revokedTokens.clear();
|
|
157
|
+
}
|
|
158
|
+
setFailAuth(fail) {
|
|
159
|
+
this.shouldFailAuth = fail;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { IStorageAdapter, StorageOperation } from '../../abstractions/StorageAdapter';
|
|
2
|
+
interface StorageItem {
|
|
3
|
+
value: unknown;
|
|
4
|
+
expiresAt?: number;
|
|
5
|
+
}
|
|
6
|
+
export declare class MockStorageAdapter implements IStorageAdapter {
|
|
7
|
+
private storage;
|
|
8
|
+
private simulateLatency;
|
|
9
|
+
private shouldFailOperations;
|
|
10
|
+
constructor(options?: {
|
|
11
|
+
simulateLatency?: number;
|
|
12
|
+
shouldFailOperations?: boolean;
|
|
13
|
+
});
|
|
14
|
+
get<T>(key: string): Promise<T | null>;
|
|
15
|
+
set<T>(key: string, value: T, ttl?: number): Promise<void>;
|
|
16
|
+
delete(key: string): Promise<void>;
|
|
17
|
+
exists(key: string): Promise<boolean>;
|
|
18
|
+
scan(pattern: string): Promise<string[]>;
|
|
19
|
+
clear(): Promise<void>;
|
|
20
|
+
transaction<T>(operations: StorageOperation[]): Promise<T>;
|
|
21
|
+
private simulateDelay;
|
|
22
|
+
getSize(): number;
|
|
23
|
+
getRawStorage(): Map<string, StorageItem>;
|
|
24
|
+
setFailOperations(fail: boolean): void;
|
|
25
|
+
}
|
|
26
|
+
export {};
|
|
27
|
+
//# sourceMappingURL=MockStorageAdapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MockStorageAdapter.d.ts","sourceRoot":"","sources":["../../../src/adapters/mock/MockStorageAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AAE3F,UAAU,WAAW;IACnB,KAAK,EAAE,OAAO,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,qBAAa,kBAAmB,YAAW,eAAe;IACxD,OAAO,CAAC,OAAO,CAAuC;IACtD,OAAO,CAAC,eAAe,CAAa;IACpC,OAAO,CAAC,oBAAoB,CAAkB;gBAElC,OAAO,CAAC,EAAE;QACpB,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,oBAAoB,CAAC,EAAE,OAAO,CAAC;KAChC;IAKK,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;IAmBtC,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAe1D,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAUlC,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAmBrC,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAiCxC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAUtB,WAAW,CAAC,CAAC,EAAE,UAAU,EAAE,gBAAgB,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC;YA6DlD,aAAa;IAM3B,OAAO,IAAI,MAAM;IAIjB,aAAa,IAAI,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC;IAIzC,iBAAiB,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI;CAGvC"}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
export class MockStorageAdapter {
|
|
2
|
+
constructor(options) {
|
|
3
|
+
this.storage = new Map();
|
|
4
|
+
this.simulateLatency = 0;
|
|
5
|
+
this.shouldFailOperations = false;
|
|
6
|
+
this.simulateLatency = options?.simulateLatency ?? 0;
|
|
7
|
+
this.shouldFailOperations = options?.shouldFailOperations ?? false;
|
|
8
|
+
}
|
|
9
|
+
async get(key) {
|
|
10
|
+
await this.simulateDelay();
|
|
11
|
+
if (this.shouldFailOperations) {
|
|
12
|
+
throw new Error('Mock storage operation failed');
|
|
13
|
+
}
|
|
14
|
+
const item = this.storage.get(key);
|
|
15
|
+
if (!item)
|
|
16
|
+
return null;
|
|
17
|
+
// Check expiration
|
|
18
|
+
if (item.expiresAt && item.expiresAt < Date.now()) {
|
|
19
|
+
this.storage.delete(key);
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
return item.value;
|
|
23
|
+
}
|
|
24
|
+
async set(key, value, ttl) {
|
|
25
|
+
await this.simulateDelay();
|
|
26
|
+
if (this.shouldFailOperations) {
|
|
27
|
+
throw new Error('Mock storage operation failed');
|
|
28
|
+
}
|
|
29
|
+
const item = {
|
|
30
|
+
value,
|
|
31
|
+
expiresAt: ttl ? Date.now() + ttl : undefined
|
|
32
|
+
};
|
|
33
|
+
this.storage.set(key, item);
|
|
34
|
+
}
|
|
35
|
+
async delete(key) {
|
|
36
|
+
await this.simulateDelay();
|
|
37
|
+
if (this.shouldFailOperations) {
|
|
38
|
+
throw new Error('Mock storage operation failed');
|
|
39
|
+
}
|
|
40
|
+
this.storage.delete(key);
|
|
41
|
+
}
|
|
42
|
+
async exists(key) {
|
|
43
|
+
await this.simulateDelay();
|
|
44
|
+
if (this.shouldFailOperations) {
|
|
45
|
+
throw new Error('Mock storage operation failed');
|
|
46
|
+
}
|
|
47
|
+
const item = this.storage.get(key);
|
|
48
|
+
if (!item)
|
|
49
|
+
return false;
|
|
50
|
+
// Check expiration
|
|
51
|
+
if (item.expiresAt && item.expiresAt < Date.now()) {
|
|
52
|
+
this.storage.delete(key);
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
return true;
|
|
56
|
+
}
|
|
57
|
+
async scan(pattern) {
|
|
58
|
+
await this.simulateDelay();
|
|
59
|
+
if (this.shouldFailOperations) {
|
|
60
|
+
throw new Error('Mock storage operation failed');
|
|
61
|
+
}
|
|
62
|
+
// Convert pattern to regex (simple glob to regex conversion)
|
|
63
|
+
const regexPattern = pattern
|
|
64
|
+
.replace(/\*/g, '.*')
|
|
65
|
+
.replace(/\?/g, '.')
|
|
66
|
+
.replace(/\[!/g, '[^')
|
|
67
|
+
.replace(/\[/g, '[')
|
|
68
|
+
.replace(/\]/g, ']');
|
|
69
|
+
const regex = new RegExp(`^${regexPattern}$`);
|
|
70
|
+
const keys = [];
|
|
71
|
+
for (const [key, item] of this.storage.entries()) {
|
|
72
|
+
// Skip expired items
|
|
73
|
+
if (item.expiresAt && item.expiresAt < Date.now()) {
|
|
74
|
+
this.storage.delete(key);
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
if (regex.test(key)) {
|
|
78
|
+
keys.push(key);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return keys;
|
|
82
|
+
}
|
|
83
|
+
async clear() {
|
|
84
|
+
await this.simulateDelay();
|
|
85
|
+
if (this.shouldFailOperations) {
|
|
86
|
+
throw new Error('Mock storage operation failed');
|
|
87
|
+
}
|
|
88
|
+
this.storage.clear();
|
|
89
|
+
}
|
|
90
|
+
async transaction(operations) {
|
|
91
|
+
await this.simulateDelay();
|
|
92
|
+
if (this.shouldFailOperations) {
|
|
93
|
+
throw new Error('Mock storage operation failed');
|
|
94
|
+
}
|
|
95
|
+
const results = [];
|
|
96
|
+
const rollback = [];
|
|
97
|
+
try {
|
|
98
|
+
for (const op of operations) {
|
|
99
|
+
switch (op.type) {
|
|
100
|
+
case 'get': {
|
|
101
|
+
const value = await this.get(op.key);
|
|
102
|
+
results.push(value);
|
|
103
|
+
break;
|
|
104
|
+
}
|
|
105
|
+
case 'set': {
|
|
106
|
+
const oldValue = await this.get(op.key);
|
|
107
|
+
await this.set(op.key, op.value, op.ttl);
|
|
108
|
+
rollback.push(() => {
|
|
109
|
+
if (oldValue !== null) {
|
|
110
|
+
this.storage.set(op.key, { value: oldValue });
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
this.storage.delete(op.key);
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
results.push(true);
|
|
117
|
+
break;
|
|
118
|
+
}
|
|
119
|
+
case 'delete': {
|
|
120
|
+
const oldValue = await this.get(op.key);
|
|
121
|
+
await this.delete(op.key);
|
|
122
|
+
rollback.push(() => {
|
|
123
|
+
if (oldValue !== null) {
|
|
124
|
+
this.storage.set(op.key, { value: oldValue });
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
results.push(true);
|
|
128
|
+
break;
|
|
129
|
+
}
|
|
130
|
+
case 'exists': {
|
|
131
|
+
const exists = await this.exists(op.key);
|
|
132
|
+
results.push(exists);
|
|
133
|
+
break;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
return results;
|
|
138
|
+
}
|
|
139
|
+
catch (error) {
|
|
140
|
+
// Rollback on error
|
|
141
|
+
for (const rollbackFn of rollback.reverse()) {
|
|
142
|
+
rollbackFn();
|
|
143
|
+
}
|
|
144
|
+
throw error;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
// Test helper methods
|
|
148
|
+
async simulateDelay() {
|
|
149
|
+
if (this.simulateLatency > 0) {
|
|
150
|
+
await new Promise(resolve => setTimeout(resolve, this.simulateLatency));
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
getSize() {
|
|
154
|
+
return this.storage.size;
|
|
155
|
+
}
|
|
156
|
+
getRawStorage() {
|
|
157
|
+
return new Map(this.storage);
|
|
158
|
+
}
|
|
159
|
+
setFailOperations(fail) {
|
|
160
|
+
this.shouldFailOperations = fail;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { ITransportAdapter } from '../../abstractions/TransportAdapter';
|
|
2
|
+
import type { ConnectionState, ConnectionOptions, Message, MessageHandler, ErrorHandler, CloseHandler } from '../../types';
|
|
3
|
+
export declare class MockTransportAdapter implements ITransportAdapter {
|
|
4
|
+
private state;
|
|
5
|
+
private messageHandlers;
|
|
6
|
+
private errorHandlers;
|
|
7
|
+
private closeHandlers;
|
|
8
|
+
private messageQueue;
|
|
9
|
+
private simulateLatency;
|
|
10
|
+
private shouldFailConnection;
|
|
11
|
+
private connectedUrl;
|
|
12
|
+
constructor(options?: {
|
|
13
|
+
simulateLatency?: number;
|
|
14
|
+
shouldFailConnection?: boolean;
|
|
15
|
+
});
|
|
16
|
+
connect(url: string, _options?: ConnectionOptions): Promise<void>;
|
|
17
|
+
disconnect(): Promise<void>;
|
|
18
|
+
send(message: Message): Promise<void>;
|
|
19
|
+
onMessage(handler: MessageHandler): void;
|
|
20
|
+
onError(handler: ErrorHandler): void;
|
|
21
|
+
onClose(handler: CloseHandler): void;
|
|
22
|
+
getState(): ConnectionState;
|
|
23
|
+
isConnected(): boolean;
|
|
24
|
+
simulateMessage(message: Message): void;
|
|
25
|
+
simulateError(error: Error): void;
|
|
26
|
+
simulateClose(code: number, reason: string): void;
|
|
27
|
+
getMessageQueue(): Message[];
|
|
28
|
+
clearMessageQueue(): void;
|
|
29
|
+
getConnectedUrl(): string | null;
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=MockTransportAdapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MockTransportAdapter.d.ts","sourceRoot":"","sources":["../../../src/adapters/mock/MockTransportAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qCAAqC,CAAC;AAC7E,OAAO,KAAK,EACV,eAAe,EACf,iBAAiB,EACjB,OAAO,EACP,cAAc,EACd,YAAY,EACZ,YAAY,EACb,MAAM,aAAa,CAAC;AAErB,qBAAa,oBAAqB,YAAW,iBAAiB;IAC5D,OAAO,CAAC,KAAK,CAAmC;IAChD,OAAO,CAAC,eAAe,CAAkC;IACzD,OAAO,CAAC,aAAa,CAAgC;IACrD,OAAO,CAAC,aAAa,CAAgC;IACrD,OAAO,CAAC,YAAY,CAAiB;IACrC,OAAO,CAAC,eAAe,CAAa;IACpC,OAAO,CAAC,oBAAoB,CAAkB;IAC9C,OAAO,CAAC,YAAY,CAAuB;gBAE/B,OAAO,CAAC,EAAE;QACpB,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,oBAAoB,CAAC,EAAE,OAAO,CAAC;KAChC;IAKK,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAmBjE,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAgB3B,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAa3C,SAAS,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI;IAIxC,OAAO,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI;IAIpC,OAAO,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI;IAIpC,QAAQ,IAAI,eAAe;IAI3B,WAAW,IAAI,OAAO;IAKtB,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAOvC,aAAa,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;IAIjC,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAKjD,eAAe,IAAI,OAAO,EAAE;IAI5B,iBAAiB,IAAI,IAAI;IAIzB,eAAe,IAAI,MAAM,GAAG,IAAI;CAGjC"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
export class MockTransportAdapter {
|
|
2
|
+
constructor(options) {
|
|
3
|
+
this.state = 'disconnected';
|
|
4
|
+
this.messageHandlers = new Set();
|
|
5
|
+
this.errorHandlers = new Set();
|
|
6
|
+
this.closeHandlers = new Set();
|
|
7
|
+
this.messageQueue = [];
|
|
8
|
+
this.simulateLatency = 0;
|
|
9
|
+
this.shouldFailConnection = false;
|
|
10
|
+
this.connectedUrl = null;
|
|
11
|
+
this.simulateLatency = options?.simulateLatency ?? 0;
|
|
12
|
+
this.shouldFailConnection = options?.shouldFailConnection ?? false;
|
|
13
|
+
}
|
|
14
|
+
async connect(url, _options) {
|
|
15
|
+
if (this.shouldFailConnection) {
|
|
16
|
+
this.state = 'disconnected';
|
|
17
|
+
const error = new Error('Mock connection failed');
|
|
18
|
+
this.errorHandlers.forEach(handler => handler(error));
|
|
19
|
+
throw error;
|
|
20
|
+
}
|
|
21
|
+
this.state = 'connecting';
|
|
22
|
+
this.connectedUrl = url;
|
|
23
|
+
// Simulate connection delay
|
|
24
|
+
if (this.simulateLatency > 0) {
|
|
25
|
+
await new Promise(resolve => setTimeout(resolve, this.simulateLatency));
|
|
26
|
+
}
|
|
27
|
+
this.state = 'connected';
|
|
28
|
+
}
|
|
29
|
+
async disconnect() {
|
|
30
|
+
if (this.state === 'disconnected')
|
|
31
|
+
return;
|
|
32
|
+
this.state = 'disconnecting';
|
|
33
|
+
// Simulate disconnect delay
|
|
34
|
+
if (this.simulateLatency > 0) {
|
|
35
|
+
await new Promise(resolve => setTimeout(resolve, this.simulateLatency / 2));
|
|
36
|
+
}
|
|
37
|
+
this.state = 'disconnected';
|
|
38
|
+
this.connectedUrl = null;
|
|
39
|
+
this.closeHandlers.forEach(handler => handler(1000, 'Normal closure'));
|
|
40
|
+
this.messageQueue = [];
|
|
41
|
+
}
|
|
42
|
+
async send(message) {
|
|
43
|
+
if (this.state !== 'connected') {
|
|
44
|
+
throw new Error('Not connected');
|
|
45
|
+
}
|
|
46
|
+
// Simulate send latency
|
|
47
|
+
if (this.simulateLatency > 0) {
|
|
48
|
+
await new Promise(resolve => setTimeout(resolve, this.simulateLatency));
|
|
49
|
+
}
|
|
50
|
+
this.messageQueue.push(message);
|
|
51
|
+
}
|
|
52
|
+
onMessage(handler) {
|
|
53
|
+
this.messageHandlers.add(handler);
|
|
54
|
+
}
|
|
55
|
+
onError(handler) {
|
|
56
|
+
this.errorHandlers.add(handler);
|
|
57
|
+
}
|
|
58
|
+
onClose(handler) {
|
|
59
|
+
this.closeHandlers.add(handler);
|
|
60
|
+
}
|
|
61
|
+
getState() {
|
|
62
|
+
return this.state;
|
|
63
|
+
}
|
|
64
|
+
isConnected() {
|
|
65
|
+
return this.state === 'connected';
|
|
66
|
+
}
|
|
67
|
+
// Test helper methods
|
|
68
|
+
simulateMessage(message) {
|
|
69
|
+
if (this.state !== 'connected') {
|
|
70
|
+
throw new Error('Cannot simulate message when not connected');
|
|
71
|
+
}
|
|
72
|
+
this.messageHandlers.forEach(handler => handler(message));
|
|
73
|
+
}
|
|
74
|
+
simulateError(error) {
|
|
75
|
+
this.errorHandlers.forEach(handler => handler(error));
|
|
76
|
+
}
|
|
77
|
+
simulateClose(code, reason) {
|
|
78
|
+
this.state = 'disconnected';
|
|
79
|
+
this.closeHandlers.forEach(handler => handler(code, reason));
|
|
80
|
+
}
|
|
81
|
+
getMessageQueue() {
|
|
82
|
+
return [...this.messageQueue];
|
|
83
|
+
}
|
|
84
|
+
clearMessageQueue() {
|
|
85
|
+
this.messageQueue = [];
|
|
86
|
+
}
|
|
87
|
+
getConnectedUrl() {
|
|
88
|
+
return this.connectedUrl;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/adapters/mock/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { ITransportAdapter } from '../../abstractions/TransportAdapter';
|
|
2
|
+
import type { ConnectionState, ConnectionOptions, Message, MessageHandler, ErrorHandler, CloseHandler } from '../../types';
|
|
3
|
+
import type { Server as HttpServer } from 'http';
|
|
4
|
+
import type { Server as HttpsServer } from 'https';
|
|
5
|
+
import { WebSocketServer, WebSocket } from 'ws';
|
|
6
|
+
interface ClientConnection {
|
|
7
|
+
id: string;
|
|
8
|
+
ws: WebSocket;
|
|
9
|
+
userId?: string;
|
|
10
|
+
}
|
|
11
|
+
export declare class WebSocketTransportAdapter implements ITransportAdapter {
|
|
12
|
+
private state;
|
|
13
|
+
private messageHandlers;
|
|
14
|
+
private errorHandlers;
|
|
15
|
+
private closeHandlers;
|
|
16
|
+
private wss?;
|
|
17
|
+
private serverUrl?;
|
|
18
|
+
private attachedServer?;
|
|
19
|
+
private attachedWss?;
|
|
20
|
+
private webSocketPath?;
|
|
21
|
+
private clients;
|
|
22
|
+
private mode;
|
|
23
|
+
connect(url: string, _options?: ConnectionOptions): Promise<void>;
|
|
24
|
+
attach(server: HttpServer | HttpsServer, path?: string): Promise<void>;
|
|
25
|
+
attachToWebSocketServer(wss: WebSocketServer): Promise<void>;
|
|
26
|
+
private handleConnection;
|
|
27
|
+
disconnect(): Promise<void>;
|
|
28
|
+
send(message: Message): Promise<void>;
|
|
29
|
+
onMessage(handler: MessageHandler): void;
|
|
30
|
+
onError(handler: ErrorHandler): void;
|
|
31
|
+
onClose(handler: CloseHandler): void;
|
|
32
|
+
getState(): ConnectionState;
|
|
33
|
+
isConnected(): boolean;
|
|
34
|
+
getConnectedClients(): ClientConnection[];
|
|
35
|
+
getClientCount(): number;
|
|
36
|
+
getMode(): 'standalone' | 'integration';
|
|
37
|
+
private generateId;
|
|
38
|
+
}
|
|
39
|
+
export {};
|
|
40
|
+
//# sourceMappingURL=WebSocketTransportAdapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WebSocketTransportAdapter.d.ts","sourceRoot":"","sources":["../../../src/adapters/websocket/WebSocketTransportAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qCAAqC,CAAC;AAC7E,OAAO,KAAK,EACV,eAAe,EACf,iBAAiB,EACjB,OAAO,EACP,cAAc,EACd,YAAY,EACZ,YAAY,EACb,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,MAAM,IAAI,UAAU,EAAE,MAAM,MAAM,CAAC;AACjD,OAAO,KAAK,EAAE,MAAM,IAAI,WAAW,EAAE,MAAM,OAAO,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AAEhD,UAAU,gBAAgB;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,SAAS,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,qBAAa,yBAA0B,YAAW,iBAAiB;IACjE,OAAO,CAAC,KAAK,CAAmC;IAChD,OAAO,CAAC,eAAe,CAAkC;IACzD,OAAO,CAAC,aAAa,CAAgC;IACrD,OAAO,CAAC,aAAa,CAAgC;IAGrD,OAAO,CAAC,GAAG,CAAC,CAAkB;IAC9B,OAAO,CAAC,SAAS,CAAC,CAAS;IAG3B,OAAO,CAAC,cAAc,CAAC,CAA2B;IAClD,OAAO,CAAC,WAAW,CAAC,CAAkB;IACtC,OAAO,CAAC,aAAa,CAAC,CAAS;IAG/B,OAAO,CAAC,OAAO,CAAuC;IACtD,OAAO,CAAC,IAAI,CAA8C;IAGpD,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAsCjE,MAAM,CAAC,MAAM,EAAE,UAAU,GAAG,WAAW,EAAE,IAAI,GAAE,MAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAiC7E,uBAAuB,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IA2BlE,OAAO,CAAC,gBAAgB;IAqClB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IA8B3B,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IA8B3C,SAAS,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI;IAIxC,OAAO,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI;IAIpC,OAAO,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI;IAIpC,QAAQ,IAAI,eAAe;IAI3B,WAAW,IAAI,OAAO;IAKtB,mBAAmB,IAAI,gBAAgB,EAAE;IAIzC,cAAc,IAAI,MAAM;IAIxB,OAAO,IAAI,YAAY,GAAG,aAAa;IAIvC,OAAO,CAAC,UAAU;CAGnB"}
|