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.
Files changed (94) hide show
  1. package/dist/index.d.ts +2 -31
  2. package/dist/index.js +1 -27
  3. package/dist/index.js.map +1 -1
  4. package/dist/utils/Lib.d.ts +0 -12
  5. package/dist/utils/Lib.js +0 -65
  6. package/dist/utils/Lib.js.map +1 -1
  7. package/dist/websocket.shared.types.d.ts +25 -0
  8. package/dist/websocket.shared.types.js +4 -0
  9. package/dist/websocket.shared.types.js.map +1 -0
  10. package/package.json +1 -22
  11. package/src/index.ts +2 -51
  12. package/src/utils/Lib.ts +0 -77
  13. package/src/websocket.shared.types.ts +27 -0
  14. package/dist/application.d.ts +0 -18
  15. package/dist/application.js +0 -60
  16. package/dist/application.js.map +0 -1
  17. package/dist/server/base/base.database.d.ts +0 -10
  18. package/dist/server/base/base.database.js +0 -23
  19. package/dist/server/base/base.database.js.map +0 -1
  20. package/dist/server/base/index.d.ts +0 -2
  21. package/dist/server/base/index.js +0 -5
  22. package/dist/server/base/index.js.map +0 -1
  23. package/dist/server/bun/index.d.ts +0 -3
  24. package/dist/server/bun/index.js +0 -6
  25. package/dist/server/bun/index.js.map +0 -1
  26. package/dist/server/bun/router/controller-discovery.d.ts +0 -13
  27. package/dist/server/bun/router/controller-discovery.js +0 -83
  28. package/dist/server/bun/router/controller-discovery.js.map +0 -1
  29. package/dist/server/bun/router/index.d.ts +0 -6
  30. package/dist/server/bun/router/index.js +0 -9
  31. package/dist/server/bun/router/index.js.map +0 -1
  32. package/dist/server/bun/router/router.d.ts +0 -12
  33. package/dist/server/bun/router/router.internal.d.ts +0 -15
  34. package/dist/server/bun/router/router.internal.js +0 -51
  35. package/dist/server/bun/router/router.internal.js.map +0 -1
  36. package/dist/server/bun/router/router.js +0 -38
  37. package/dist/server/bun/router/router.js.map +0 -1
  38. package/dist/server/bun/router/routes.d.ts +0 -5
  39. package/dist/server/bun/router/routes.js +0 -2
  40. package/dist/server/bun/router/routes.js.map +0 -1
  41. package/dist/server/bun/websocket/Channel.d.ts +0 -68
  42. package/dist/server/bun/websocket/Channel.js +0 -263
  43. package/dist/server/bun/websocket/Channel.js.map +0 -1
  44. package/dist/server/bun/websocket/Client.d.ts +0 -87
  45. package/dist/server/bun/websocket/Client.js +0 -193
  46. package/dist/server/bun/websocket/Client.js.map +0 -1
  47. package/dist/server/bun/websocket/Message.d.ts +0 -10
  48. package/dist/server/bun/websocket/Message.js +0 -103
  49. package/dist/server/bun/websocket/Message.js.map +0 -1
  50. package/dist/server/bun/websocket/Websocket.d.ts +0 -171
  51. package/dist/server/bun/websocket/Websocket.js +0 -336
  52. package/dist/server/bun/websocket/Websocket.js.map +0 -1
  53. package/dist/server/bun/websocket/index.d.ts +0 -11
  54. package/dist/server/bun/websocket/index.js +0 -14
  55. package/dist/server/bun/websocket/index.js.map +0 -1
  56. package/dist/server/bun/websocket/websocket.enums.d.ts +0 -27
  57. package/dist/server/bun/websocket/websocket.enums.js +0 -31
  58. package/dist/server/bun/websocket/websocket.enums.js.map +0 -1
  59. package/dist/server/bun/websocket/websocket.guards.d.ts +0 -3
  60. package/dist/server/bun/websocket/websocket.guards.js +0 -17
  61. package/dist/server/bun/websocket/websocket.guards.js.map +0 -1
  62. package/dist/server/bun/websocket/websocket.types.d.ts +0 -235
  63. package/dist/server/bun/websocket/websocket.types.js +0 -2
  64. package/dist/server/bun/websocket/websocket.types.js.map +0 -1
  65. package/dist/server/controller.d.ts +0 -62
  66. package/dist/server/controller.js +0 -55
  67. package/dist/server/controller.js.map +0 -1
  68. package/dist/server/index.d.ts +0 -4
  69. package/dist/server/index.js +0 -7
  70. package/dist/server/index.js.map +0 -1
  71. package/dist/server/service.d.ts +0 -5
  72. package/dist/server/service.js +0 -38
  73. package/dist/server/service.js.map +0 -1
  74. package/src/application.ts +0 -73
  75. package/src/server/base/base.database.ts +0 -31
  76. package/src/server/base/index.ts +0 -5
  77. package/src/server/bun/index.ts +0 -6
  78. package/src/server/bun/router/controller-discovery.ts +0 -94
  79. package/src/server/bun/router/index.ts +0 -9
  80. package/src/server/bun/router/router.internal.ts +0 -64
  81. package/src/server/bun/router/router.ts +0 -51
  82. package/src/server/bun/router/routes.ts +0 -7
  83. package/src/server/bun/websocket/Channel.ts +0 -310
  84. package/src/server/bun/websocket/Client.ts +0 -243
  85. package/src/server/bun/websocket/ISSUES.md +0 -1175
  86. package/src/server/bun/websocket/Message.ts +0 -120
  87. package/src/server/bun/websocket/Websocket.ts +0 -402
  88. package/src/server/bun/websocket/index.ts +0 -14
  89. package/src/server/bun/websocket/websocket.enums.ts +0 -29
  90. package/src/server/bun/websocket/websocket.guards.ts +0 -22
  91. package/src/server/bun/websocket/websocket.types.ts +0 -252
  92. package/src/server/controller.ts +0 -121
  93. package/src/server/index.ts +0 -7
  94. 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
- }