topsyde-utils 1.3.1 → 2.0.0
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/dist/index.d.ts +2 -31
- package/dist/index.js +1 -27
- package/dist/index.js.map +1 -1
- package/dist/utils/Lib.d.ts +0 -12
- package/dist/utils/Lib.js +0 -65
- package/dist/utils/Lib.js.map +1 -1
- package/dist/websocket.shared.types.d.ts +25 -0
- package/dist/websocket.shared.types.js +4 -0
- package/dist/websocket.shared.types.js.map +1 -0
- package/package.json +1 -22
- package/src/index.ts +2 -51
- package/src/utils/Lib.ts +0 -77
- package/src/websocket.shared.types.ts +27 -0
- package/dist/application.d.ts +0 -18
- package/dist/application.js +0 -60
- package/dist/application.js.map +0 -1
- package/dist/server/base/base.database.d.ts +0 -10
- package/dist/server/base/base.database.js +0 -23
- package/dist/server/base/base.database.js.map +0 -1
- package/dist/server/base/index.d.ts +0 -2
- package/dist/server/base/index.js +0 -5
- package/dist/server/base/index.js.map +0 -1
- package/dist/server/bun/index.d.ts +0 -3
- package/dist/server/bun/index.js +0 -6
- package/dist/server/bun/index.js.map +0 -1
- package/dist/server/bun/router/controller-discovery.d.ts +0 -13
- package/dist/server/bun/router/controller-discovery.js +0 -83
- package/dist/server/bun/router/controller-discovery.js.map +0 -1
- package/dist/server/bun/router/index.d.ts +0 -6
- package/dist/server/bun/router/index.js +0 -9
- package/dist/server/bun/router/index.js.map +0 -1
- package/dist/server/bun/router/router.d.ts +0 -12
- package/dist/server/bun/router/router.internal.d.ts +0 -15
- package/dist/server/bun/router/router.internal.js +0 -51
- package/dist/server/bun/router/router.internal.js.map +0 -1
- package/dist/server/bun/router/router.js +0 -38
- package/dist/server/bun/router/router.js.map +0 -1
- package/dist/server/bun/router/routes.d.ts +0 -5
- package/dist/server/bun/router/routes.js +0 -2
- package/dist/server/bun/router/routes.js.map +0 -1
- package/dist/server/bun/websocket/Channel.d.ts +0 -68
- package/dist/server/bun/websocket/Channel.js +0 -263
- package/dist/server/bun/websocket/Channel.js.map +0 -1
- package/dist/server/bun/websocket/Client.d.ts +0 -87
- package/dist/server/bun/websocket/Client.js +0 -193
- package/dist/server/bun/websocket/Client.js.map +0 -1
- package/dist/server/bun/websocket/Message.d.ts +0 -10
- package/dist/server/bun/websocket/Message.js +0 -103
- package/dist/server/bun/websocket/Message.js.map +0 -1
- package/dist/server/bun/websocket/Websocket.d.ts +0 -171
- package/dist/server/bun/websocket/Websocket.js +0 -336
- package/dist/server/bun/websocket/Websocket.js.map +0 -1
- package/dist/server/bun/websocket/index.d.ts +0 -11
- package/dist/server/bun/websocket/index.js +0 -14
- package/dist/server/bun/websocket/index.js.map +0 -1
- package/dist/server/bun/websocket/websocket.enums.d.ts +0 -27
- package/dist/server/bun/websocket/websocket.enums.js +0 -31
- package/dist/server/bun/websocket/websocket.enums.js.map +0 -1
- package/dist/server/bun/websocket/websocket.guards.d.ts +0 -3
- package/dist/server/bun/websocket/websocket.guards.js +0 -17
- package/dist/server/bun/websocket/websocket.guards.js.map +0 -1
- package/dist/server/bun/websocket/websocket.types.d.ts +0 -235
- package/dist/server/bun/websocket/websocket.types.js +0 -2
- package/dist/server/bun/websocket/websocket.types.js.map +0 -1
- package/dist/server/controller.d.ts +0 -62
- package/dist/server/controller.js +0 -55
- package/dist/server/controller.js.map +0 -1
- package/dist/server/index.d.ts +0 -4
- package/dist/server/index.js +0 -7
- package/dist/server/index.js.map +0 -1
- package/dist/server/service.d.ts +0 -5
- package/dist/server/service.js +0 -38
- package/dist/server/service.js.map +0 -1
- package/src/application.ts +0 -73
- package/src/server/base/base.database.ts +0 -31
- package/src/server/base/index.ts +0 -5
- package/src/server/bun/index.ts +0 -6
- package/src/server/bun/router/controller-discovery.ts +0 -94
- package/src/server/bun/router/index.ts +0 -9
- package/src/server/bun/router/router.internal.ts +0 -64
- package/src/server/bun/router/router.ts +0 -51
- package/src/server/bun/router/routes.ts +0 -7
- package/src/server/bun/websocket/Channel.ts +0 -310
- package/src/server/bun/websocket/Client.ts +0 -243
- package/src/server/bun/websocket/ISSUES.md +0 -1175
- package/src/server/bun/websocket/Message.ts +0 -120
- package/src/server/bun/websocket/Websocket.ts +0 -402
- package/src/server/bun/websocket/index.ts +0 -14
- package/src/server/bun/websocket/websocket.enums.ts +0 -29
- package/src/server/bun/websocket/websocket.guards.ts +0 -22
- package/src/server/bun/websocket/websocket.types.ts +0 -252
- package/src/server/controller.ts +0 -121
- package/src/server/index.ts +0 -7
- package/src/server/service.ts +0 -36
|
@@ -1,243 +0,0 @@
|
|
|
1
|
-
import { ServerWebSocket } from "bun";
|
|
2
|
-
import type {
|
|
3
|
-
I_WebsocketClient,
|
|
4
|
-
WebsocketEntityData,
|
|
5
|
-
WebsocketChannel,
|
|
6
|
-
WebsocketStructuredMessage,
|
|
7
|
-
I_WebsocketEntity,
|
|
8
|
-
I_WebsocketChannel,
|
|
9
|
-
WebsocketMessageOptions,
|
|
10
|
-
WebsocketMessage,
|
|
11
|
-
} from "./websocket.types";
|
|
12
|
-
import { E_WebsocketMessageType, E_ClientState } from "./websocket.enums";
|
|
13
|
-
import { Guards, Lib } from "../../../utils";
|
|
14
|
-
import Message from "./Message";
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Client - Connected WebSocket client with channel membership
|
|
18
|
-
*
|
|
19
|
-
* ## Channel Membership
|
|
20
|
-
* - Maintains own channel list and handles Bun pub/sub subscriptions
|
|
21
|
-
* - `joinChannel()` adds to channel, subscribes, and handles rollback on failure
|
|
22
|
-
* - Always use `channel.addMember(client)` in application code, not `client.joinChannel()` directly
|
|
23
|
-
*
|
|
24
|
-
* @example
|
|
25
|
-
* // ✅ Correct
|
|
26
|
-
* channel.addMember(client);
|
|
27
|
-
*
|
|
28
|
-
* // ❌ Incorrect - internal use only
|
|
29
|
-
* client.joinChannel(channel);
|
|
30
|
-
*/
|
|
31
|
-
export default class Client implements I_WebsocketClient {
|
|
32
|
-
private _id: string;
|
|
33
|
-
private _name: string;
|
|
34
|
-
private _ws: ServerWebSocket<WebsocketEntityData>;
|
|
35
|
-
private _channels: WebsocketChannel<I_WebsocketChannel>;
|
|
36
|
-
private _state: E_ClientState;
|
|
37
|
-
private _connectedAt?: Date;
|
|
38
|
-
private _disconnectedAt?: Date;
|
|
39
|
-
|
|
40
|
-
private set ws(value: ServerWebSocket<WebsocketEntityData>) {
|
|
41
|
-
this._ws = value;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
public get ws(): ServerWebSocket<WebsocketEntityData> {
|
|
45
|
-
return this._ws;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
private set id(value: string) {
|
|
49
|
-
this._id = value;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
public get id(): string {
|
|
53
|
-
return this._id;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
public get name(): string {
|
|
57
|
-
return this._name;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
private set name(value: string) {
|
|
61
|
-
this._name = value;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
private set channels(value: WebsocketChannel<I_WebsocketChannel>) {
|
|
65
|
-
this._channels = value;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
public get channels(): WebsocketChannel<I_WebsocketChannel> {
|
|
69
|
-
return this._channels;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
public get state(): E_ClientState {
|
|
73
|
-
return this._state;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
constructor(entity: I_WebsocketEntity) {
|
|
77
|
-
this._id = entity.id;
|
|
78
|
-
this._name = entity.name;
|
|
79
|
-
this._ws = entity.ws;
|
|
80
|
-
this._channels = new Map();
|
|
81
|
-
this._state = E_ClientState.CONNECTING;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
public canReceiveMessages(): boolean {
|
|
85
|
-
return this._state === E_ClientState.CONNECTED || this._state === E_ClientState.DISCONNECTING;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
public markConnected(): void {
|
|
89
|
-
this._state = E_ClientState.CONNECTED;
|
|
90
|
-
this._connectedAt = new Date();
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
public markDisconnecting(): void {
|
|
94
|
-
this._state = E_ClientState.DISCONNECTING;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
public markDisconnected(): void {
|
|
98
|
-
this._state = E_ClientState.DISCONNECTED;
|
|
99
|
-
this._disconnectedAt = new Date();
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
public getConnectionInfo() {
|
|
103
|
-
return {
|
|
104
|
-
id: this.id,
|
|
105
|
-
name: this.name,
|
|
106
|
-
state: this._state,
|
|
107
|
-
connectedAt: this._connectedAt,
|
|
108
|
-
disconnectedAt: this._disconnectedAt,
|
|
109
|
-
uptime: this._connectedAt ? Date.now() - this._connectedAt.getTime() : 0,
|
|
110
|
-
channelCount: this._channels.size,
|
|
111
|
-
};
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
/**
|
|
115
|
-
* HELPER: Track channel on client side (for channel.addMember coordination)
|
|
116
|
-
* Allows channel to update client's internal channel map
|
|
117
|
-
* @internal Used by channel.addMember()
|
|
118
|
-
*/
|
|
119
|
-
public trackChannel(channel: I_WebsocketChannel): void {
|
|
120
|
-
this.channels.set(channel.getId(), channel);
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
/**
|
|
124
|
-
* HELPER: Untrack channel on client side (for channel.addMember rollback)
|
|
125
|
-
* Allows channel to remove from client's internal channel map during rollback
|
|
126
|
-
* @internal Used by channel.addMember() error handling
|
|
127
|
-
*/
|
|
128
|
-
public untrackChannel(channel: I_WebsocketChannel): void {
|
|
129
|
-
this.channels.delete(channel.getId());
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
/**
|
|
133
|
-
* Join a channel (thin wrapper that delegates to channel.addMember)
|
|
134
|
-
* channel.addMember() handles all coordination: membership + subscription + tracking + notification
|
|
135
|
-
*/
|
|
136
|
-
public joinChannel(channel: I_WebsocketChannel, send: boolean = true): { success: boolean; reason: string } {
|
|
137
|
-
const channel_id = channel.getId();
|
|
138
|
-
|
|
139
|
-
// Check if already joined
|
|
140
|
-
if (this.channels.has(channel_id)) {
|
|
141
|
-
return { success: false, reason: "already_member" };
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
// Delegate to channel (which now handles full coordination)
|
|
145
|
-
const result = channel.addMember(this, { notify: send });
|
|
146
|
-
|
|
147
|
-
if (!result.success) {
|
|
148
|
-
return { success: false, reason: result.reason };
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
return { success: true, reason: "" };
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
/**
|
|
155
|
-
* Leave a channel (thin wrapper that delegates to channel.removeMember)
|
|
156
|
-
* channel.removeMember() handles all coordination: membership removal + unsubscription + tracking removal + notification
|
|
157
|
-
*/
|
|
158
|
-
public leaveChannel(channel: I_WebsocketChannel, send: boolean = true) {
|
|
159
|
-
const channel_id = channel.getId();
|
|
160
|
-
|
|
161
|
-
// Check if we're in the channel
|
|
162
|
-
if (!this.channels.has(channel_id)) {
|
|
163
|
-
return;
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
// Delegate to channel (which now handles full coordination)
|
|
167
|
-
channel.removeMember(this, { notify: send });
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
public joinChannels(channels: I_WebsocketChannel[], send: boolean = true) {
|
|
171
|
-
channels.forEach((channel) => {
|
|
172
|
-
this.joinChannel(channel, false);
|
|
173
|
-
});
|
|
174
|
-
if (send) this.send({ type: E_WebsocketMessageType.CLIENT_JOIN_CHANNELS, content: { channels }, client: this.whoami() });
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
public leaveChannels(channels?: I_WebsocketChannel[], send: boolean = true) {
|
|
178
|
-
if (!channels) channels = Array.from(this.channels.values());
|
|
179
|
-
channels.forEach((channel) => {
|
|
180
|
-
this.leaveChannel(channel, false);
|
|
181
|
-
});
|
|
182
|
-
if (send) this.send({ type: E_WebsocketMessageType.CLIENT_LEAVE_CHANNELS, content: { channels }, client: this.whoami() });
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
public whoami(): { id: string; name: string } {
|
|
186
|
-
return { id: this.id, name: this.name };
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
public send(message: string, options?: WebsocketMessageOptions): void;
|
|
190
|
-
public send(message: WebsocketStructuredMessage): void;
|
|
191
|
-
public send(message: WebsocketStructuredMessage | string, options?: WebsocketMessageOptions): void {
|
|
192
|
-
// Check state before sending
|
|
193
|
-
if (!this.canReceiveMessages()) {
|
|
194
|
-
Lib.Warn(`Cannot send to client ${this.id} in state ${this._state}`);
|
|
195
|
-
return;
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
try {
|
|
199
|
-
if (Guards.IsString(message)) {
|
|
200
|
-
const msg: WebsocketMessage = {
|
|
201
|
-
type: "message",
|
|
202
|
-
content: { message },
|
|
203
|
-
};
|
|
204
|
-
message = Message.Create(msg, options);
|
|
205
|
-
}
|
|
206
|
-
this.ws.send(JSON.stringify({ client: this.whoami(), ...message }));
|
|
207
|
-
} catch (error) {
|
|
208
|
-
Lib.Warn(`Failed to send message to client ${this.id}:`, error);
|
|
209
|
-
if (error instanceof Error && error.message.includes("closed")) {
|
|
210
|
-
this.markDisconnected();
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
public subscribe(channel: string): void {
|
|
216
|
-
this.ws.subscribe(channel);
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
public unsubscribe(channel: string): void {
|
|
220
|
-
this.ws.unsubscribe(channel);
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
public static GetClientType(clients: Map<string, I_WebsocketClient> | undefined): typeof Client {
|
|
224
|
-
if (!clients) return Client;
|
|
225
|
-
if (clients.size > 0) {
|
|
226
|
-
const firstClient = clients.values().next().value;
|
|
227
|
-
if (firstClient) {
|
|
228
|
-
return firstClient.constructor as typeof Client;
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
// Fallback to default Client class
|
|
233
|
-
Lib.Warn("Clients map is empty, using default client class");
|
|
234
|
-
return Client;
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
public static System() {
|
|
238
|
-
return <WebsocketEntityData>{
|
|
239
|
-
id: "system",
|
|
240
|
-
name: "System",
|
|
241
|
-
};
|
|
242
|
-
}
|
|
243
|
-
}
|