@grest-ts/websocket 0.0.23 → 0.0.24

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 (67) hide show
  1. package/README.md +150 -40
  2. package/dist/src/adapter/NodeSocketAdapter.d.ts +2 -0
  3. package/dist/src/adapter/NodeSocketAdapter.d.ts.map +1 -1
  4. package/dist/src/adapter/NodeSocketAdapter.js +6 -0
  5. package/dist/src/adapter/NodeSocketAdapter.js.map +1 -1
  6. package/dist/src/client/GGSocketPool.d.ts +21 -0
  7. package/dist/src/client/GGSocketPool.d.ts.map +1 -1
  8. package/dist/src/client/GGSocketPool.js +82 -63
  9. package/dist/src/client/GGSocketPool.js.map +1 -1
  10. package/dist/src/client/GGWebSocketSchema.createClient.d.ts +154 -0
  11. package/dist/src/client/GGWebSocketSchema.createClient.d.ts.map +1 -0
  12. package/dist/src/client/GGWebSocketSchema.createClient.js +345 -0
  13. package/dist/src/client/GGWebSocketSchema.createClient.js.map +1 -0
  14. package/dist/src/index-browser.d.ts +2 -1
  15. package/dist/src/index-browser.d.ts.map +1 -1
  16. package/dist/src/index-browser.js +3 -1
  17. package/dist/src/index-browser.js.map +1 -1
  18. package/dist/src/index-node.d.ts +2 -1
  19. package/dist/src/index-node.d.ts.map +1 -1
  20. package/dist/src/index-node.js +2 -1
  21. package/dist/src/index-node.js.map +1 -1
  22. package/dist/src/schema/GGWebSocketMiddleware.d.ts +12 -0
  23. package/dist/src/schema/GGWebSocketMiddleware.d.ts.map +1 -1
  24. package/dist/src/schema/GGWebSocketMiddleware.js +0 -4
  25. package/dist/src/schema/GGWebSocketMiddleware.js.map +1 -1
  26. package/dist/src/schema/GGWebSocketSchema.d.ts +4 -3
  27. package/dist/src/schema/GGWebSocketSchema.d.ts.map +1 -1
  28. package/dist/src/schema/GGWebSocketSchema.js +3 -1
  29. package/dist/src/schema/GGWebSocketSchema.js.map +1 -1
  30. package/dist/src/schema/webSocketSchema.d.ts +12 -6
  31. package/dist/src/schema/webSocketSchema.d.ts.map +1 -1
  32. package/dist/src/schema/webSocketSchema.js +9 -2
  33. package/dist/src/schema/webSocketSchema.js.map +1 -1
  34. package/dist/src/server/GGSocketServer.d.ts.map +1 -1
  35. package/dist/src/server/GGSocketServer.js +36 -2
  36. package/dist/src/server/GGSocketServer.js.map +1 -1
  37. package/dist/src/server/GGWebSocketSchema.startServer.d.ts +5 -3
  38. package/dist/src/server/GGWebSocketSchema.startServer.d.ts.map +1 -1
  39. package/dist/src/server/GGWebSocketSchema.startServer.js +7 -5
  40. package/dist/src/server/GGWebSocketSchema.startServer.js.map +1 -1
  41. package/dist/src/socket/GGSocket.d.ts +13 -1
  42. package/dist/src/socket/GGSocket.d.ts.map +1 -1
  43. package/dist/src/socket/GGSocket.js +52 -2
  44. package/dist/src/socket/GGSocket.js.map +1 -1
  45. package/dist/src/socket/SocketAdapter.d.ts +11 -0
  46. package/dist/src/socket/SocketAdapter.d.ts.map +1 -1
  47. package/dist/testkit/client/GGWebSocketSchema.callOn.d.ts +1 -1
  48. package/dist/testkit/client/GGWebSocketSchema.callOn.d.ts.map +1 -1
  49. package/dist/tsconfig.publish.tsbuildinfo +1 -1
  50. package/package.json +11 -11
  51. package/src/adapter/NodeSocketAdapter.ts +8 -0
  52. package/src/client/GGSocketPool.ts +90 -73
  53. package/src/client/GGWebSocketSchema.createClient.ts +534 -0
  54. package/src/index-browser.ts +5 -2
  55. package/src/index-node.ts +2 -1
  56. package/src/schema/GGWebSocketMiddleware.ts +14 -0
  57. package/src/schema/GGWebSocketSchema.ts +7 -3
  58. package/src/schema/webSocketSchema.ts +18 -8
  59. package/src/server/GGSocketServer.ts +51 -2
  60. package/src/server/GGWebSocketSchema.startServer.ts +14 -10
  61. package/src/socket/GGSocket.ts +56 -2
  62. package/src/socket/SocketAdapter.ts +13 -0
  63. package/dist/src/client/GGSocketClient.d.ts +0 -10
  64. package/dist/src/client/GGSocketClient.d.ts.map +0 -1
  65. package/dist/src/client/GGSocketClient.js +0 -17
  66. package/dist/src/client/GGSocketClient.js.map +0 -1
  67. package/src/client/GGSocketClient.ts +0 -25
package/README.md CHANGED
@@ -209,6 +209,88 @@ export const ChatApi = webSocketSchema(ChatApiContract)
209
209
 
210
210
  Middlewares run in order during connection establishment.
211
211
 
212
+ ### Sharing middleware with HTTP APIs (one class, two transports)
213
+
214
+ Most apps are HTTP-first and add WebSockets later. You'll often want the *same* auth logic on both — same bearer-token shape, same verification, same user context key. The two middleware interfaces are deliberately separate (HTTP runs per-request; WS runs once at handshake — see the note below), but TypeScript structural typing lets **one class implement both interfaces** so you write the logic once and attach it to both schemas.
215
+
216
+ ```typescript
217
+ import { GGHttpTransportMiddleware, GGHttpRequest } from "@grest-ts/http"
218
+ import { GGWebSocketMiddleware, GGWebSocketHandshakeContext } from "@grest-ts/websocket"
219
+ import { GGContextKey } from "@grest-ts/context"
220
+ import { IsObject, IsString, NOT_AUTHORIZED } from "@grest-ts/schema"
221
+
222
+ export const IsAuthUser = IsObject({ id: IsString, role: IsString })
223
+ export type AuthUser = typeof IsAuthUser.infer
224
+ export const GG_AUTH_USER = new GGContextKey<AuthUser>("authUser", IsAuthUser)
225
+
226
+ /**
227
+ * Implements both middleware interfaces. Use the same instance on HTTP and
228
+ * WebSocket schemas — single source of truth for auth wiring.
229
+ */
230
+ export class BearerAuthMiddleware
231
+ implements GGHttpTransportMiddleware, GGWebSocketMiddleware {
232
+
233
+ constructor(private opts: {
234
+ /** Client-side: return the current token. Called on every HTTP request AND on every WS handshake. */
235
+ getToken: () => string | undefined
236
+ /** Server-side: verify the token and return the user. Throw/return undefined to reject. */
237
+ verify: (token: string) => AuthUser | undefined
238
+ }) {}
239
+
240
+ // ---- Client-side: attach the bearer header ----
241
+ updateRequest = (req: GGHttpRequest) =>
242
+ this.setHeader(req.headers as Record<string, string>)
243
+ updateHandshake = (ctx: GGWebSocketHandshakeContext) =>
244
+ this.setHeader(ctx.headers)
245
+
246
+ // ---- Server-side: extract + verify, populate context ----
247
+ parseRequest = (req: GGHttpRequest) =>
248
+ this.extract(req.headers as Record<string, string | string[]>)
249
+ parseHandshake = (ctx: GGWebSocketHandshakeContext) =>
250
+ this.extract(ctx.headers)
251
+
252
+ private setHeader(headers: Record<string, string>) {
253
+ const t = this.opts.getToken()
254
+ if (t) headers["authorization"] = "Bearer " + t
255
+ }
256
+ private extract(headers: Record<string, string | string[]>) {
257
+ const header = headers["authorization"]
258
+ if (typeof header !== "string" || !header.startsWith("Bearer ")) {
259
+ throw new NOT_AUTHORIZED({ displayMessage: "Missing bearer token" })
260
+ }
261
+ const user = this.opts.verify(header.substring(7))
262
+ if (!user) throw new NOT_AUTHORIZED({ displayMessage: "Invalid token" })
263
+ GG_AUTH_USER.set(user)
264
+ }
265
+ }
266
+
267
+ // One instance, used on both kinds of schema:
268
+ const auth = new BearerAuthMiddleware({
269
+ getToken: () => GG_AUTH_USER.get()?.id,
270
+ verify: (token) => validateTokenSync(token),
271
+ })
272
+
273
+ export const ItemApi = httpSchema(ItemContract).pathPrefix("api/items")
274
+ .use(auth) // acts as GGHttpTransportMiddleware
275
+ .routes({ ... })
276
+
277
+ export const ChatApi = webSocketSchema(ChatContract).path("ws/chat")
278
+ .use(auth) // acts as GGWebSocketMiddleware
279
+ .done()
280
+ ```
281
+
282
+ **Important — the rhythms are different:**
283
+
284
+ | | HTTP | WebSocket |
285
+ |---|---|---|
286
+ | When middleware runs | Per request | Once, at handshake |
287
+ | What it can do | Modify each request/response | Set connection-scoped context |
288
+ | Token refresh | Naturally handled: next request reads the new token | Not automatic — token is captured at connect time. If the token rotates mid-session, the old connection keeps its old identity until it's dropped and a fresh handshake runs |
289
+
290
+ This is why the interfaces aren't merged: forcing a single interface would make WS middleware silently not re-run on messages (a foot-gun). Keep the rhythms distinct and share *logic*, not *lifecycle*.
291
+
292
+ The server-side extraction logic here is identical for both transports — that's the common case and the reason this pattern pays off. If your HTTP flow needs per-request behavior that doesn't map to WS (say, modifying the HTTP response body), put those hooks on a separate HTTP-only middleware and apply both.
293
+
212
294
  ## Server Setup
213
295
 
214
296
  ### Connection Handler
@@ -314,65 +396,93 @@ protected compose(): void {
314
396
 
315
397
  ## Client
316
398
 
317
- ### Connecting via GGSocketPool
399
+ ### Typed Client via `createClient()`
318
400
 
319
- `GGSocketPool` manages WebSocket connections with automatic pooling connections are reused when the same URL + headers combination is requested.
401
+ `ChatApi.createClient()` returns a typed, contract-validated client. It mirrors the server's connection handler: `incoming.on(handlers)` for `serverToClient` messages, `outgoing.method(data)` for `clientToServer` methods.
320
402
 
321
403
  ```typescript
322
- import { GGSocketPool } from "@grest-ts/websocket"
404
+ import { ChatApi } from "./ChatApi"
323
405
 
324
- // Connect to the WebSocket server
325
- const socket = await GGSocketPool.getOrConnect({
326
- domain: "ws://localhost:3000",
327
- path: "/ws/chat",
328
- middlewares: ChatApi.middlewares // Runs updateHandshake for auth headers
406
+ // Create the client (disconnected)
407
+ const client = ChatApi.createClient({ url: "ws://localhost:3000" })
408
+
409
+ // Register handlers for serverToClient messages — Partial, only what you need
410
+ client.incoming.on({
411
+ newMessage: (message) => {
412
+ console.log("New message:", message)
413
+ },
414
+ typing: (event) => {
415
+ console.log(event.userId, "is typing")
416
+ },
417
+ // Server-requests-client RPC (has `success` in contract) — return a value
418
+ areYouThere: async () => true
329
419
  })
330
420
 
331
- // Send messages (see "Sending Messages" below)
332
- const response = await socket.send("ChatApi.sendMessage", {
421
+ // Lifecycle callbacks can be registered before connect
422
+ client.onClose(() => console.log("Disconnected"))
423
+ client.onError((err) => console.error("Socket error:", err))
424
+
425
+ // Establish the connection (runs handshake + applies pending handlers)
426
+ await client.connect()
427
+
428
+ // Call clientToServer methods — returns GGPromise like the HTTP client
429
+ const response = await client.outgoing.sendMessage({
333
430
  text: "Hello!",
334
431
  channelId: "general"
335
- }, true)
336
-
337
- // Register handler for server-to-client messages
338
- socket.registerHandler({
339
- path: "ChatApi.newMessage",
340
- handler: (message) => {
341
- console.log("New message:", message)
342
- }
343
432
  })
433
+ // response is typed: { success: true, messageId: "msg-456" }
434
+
435
+ // Fire-and-forget methods (no `success` in contract) — returns Promise<void>
436
+ await client.outgoing.markAsRead({ messageId: "msg-123" })
437
+ await client.outgoing.ping()
438
+
439
+ // Error handling — same GGPromise API as the HTTP client
440
+ const result = await client.outgoing.sendMessage({ text: "", channelId: "general" }).asResult()
441
+ if (result.success) {
442
+ console.log(result.data.messageId)
443
+ } else if (result.type === "VALIDATION_ERROR") {
444
+ showValidationErrors(result.data)
445
+ }
344
446
 
345
- // Lifecycle
346
- socket.onClose(() => console.log("Disconnected"))
347
- socket.onError((error) => console.error("Socket error:", error))
447
+ // Gracefully close (waits for pending requests), or close() for immediate termination
448
+ await client.disconnect()
449
+ ```
348
450
 
349
- // Close single connection
350
- socket.close()
451
+ ### Client Config
351
452
 
352
- // Or graceful teardown (waits for pending requests)
353
- await socket.teardown()
453
+ ```typescript
454
+ interface GGWebSocketClientConfig<TQuery> {
455
+ url?: string // "ws://host:port". If omitted, uses @grest-ts/discovery.
456
+ query?: TQuery // Query params on connect, typed from `.queryOnConnect<T>()`.
457
+ }
354
458
  ```
355
459
 
356
- ### Sending Messages
460
+ Omitting `url` triggers service discovery via `@grest-ts/discovery` (Node only). In browsers, pass an explicit URL (use `""` for same-origin).
461
+
462
+ ### Sending Modes (automatic from the contract)
463
+
464
+ - **Request-response** — methods with `success` defined return `GGPromise<Success, Errors>`. The client sends a `REQ` and waits up to 30s for a reply.
465
+ - **Fire-and-forget** — methods without `success` return `GGPromise<void, SERVER_ERROR>`. The client sends a `MSG` and resolves as soon as the message is handed to the socket.
357
466
 
358
- The third argument to `socket.send()` controls the sending mode:
467
+ Both apply symmetrically: the server can also send request-response messages via `serverToClient` methods that define `success`.
468
+
469
+ ### Direct socket access via `GGSocketPool`
470
+
471
+ If you need to bypass contract validation (e.g. writing a generic proxy, debugging the wire protocol), `GGSocketPool` is still available. Prefer `createClient()` in application code.
359
472
 
360
473
  ```typescript
361
- // Request-response: expectsResponse = true
362
- // Sends a REQ message, waits for the server to reply (30s timeout)
363
- const result = await socket.send("ChatApi.sendMessage", {
364
- text: "Hello!",
365
- channelId: "general"
366
- }, true)
367
- // result is the typed response: { success: true, messageId: "msg-456" }
474
+ import { GGSocketPool } from "@grest-ts/websocket"
368
475
 
369
- // Fire-and-forget: expectsResponse = false
370
- // Sends a MSG message, returns immediately
371
- socket.send("ChatApi.markAsRead", { messageId: "msg-123" }, false)
372
- socket.send("ChatApi.ping", undefined, false)
373
- ```
476
+ const socket = await GGSocketPool.getOrConnect({
477
+ domain: "ws://localhost:3000",
478
+ path: "/ws/chat",
479
+ middlewares: ChatApi.middlewares
480
+ })
374
481
 
375
- Which mode is used is determined by the contract — methods with `success` defined are request-response, methods without are fire-and-forget. This applies in both directions: the server can also send request-response messages to the client via `serverToClient` methods that define `success`.
482
+ const result = await socket.send("ChatApi.sendMessage", { text: "Hello!", channelId: "general" }, true)
483
+ socket.registerHandler({ path: "ChatApi.newMessage", handler: (msg) => { ... } })
484
+ socket.close()
485
+ ```
376
486
 
377
487
  ### Connection Pool Management
378
488
 
@@ -17,5 +17,7 @@ export declare class NodeSocketAdapter implements SocketAdapter {
17
17
  offMessage(handler: (data: string) => void): void;
18
18
  offClose(handler: () => void): void;
19
19
  offError(handler: (error: Error) => void): void;
20
+ ping(): void;
21
+ onPong(handler: () => void): void;
20
22
  }
21
23
  //# sourceMappingURL=NodeSocketAdapter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"NodeSocketAdapter.d.ts","sourceRoot":"","sources":["../../../src/adapter/NodeSocketAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,IAAI,CAAC;AAC3B,OAAO,EAAC,aAAa,EAAC,MAAM,yBAAyB,CAAC;AAEtD,MAAM,WAAW,wBAAwB;IACrC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACpC;AAED,qBAAa,iBAAkB,YAAW,aAAa;IACnD,OAAO,CAAC,EAAE,CAAY;IACtB,OAAO,CAAC,eAAe,CAAuE;gBAElF,WAAW,EAAE,MAAM,GAAG,SAAS,EAAE,OAAO,CAAC,EAAE,wBAAwB;IAU/E,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAI3B,KAAK,IAAI,IAAI;IAIb,MAAM,CAAC,OAAO,EAAE,MAAM,IAAI,GAAG,IAAI;IAIjC,SAAS,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI;IAMhD,OAAO,CAAC,OAAO,EAAE,MAAM,IAAI,GAAG,IAAI;IAIlC,OAAO,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,GAAG,IAAI;IAI9C,OAAO,CAAC,OAAO,EAAE,MAAM,IAAI,GAAG,IAAI;IAIlC,UAAU,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI;IAQjD,QAAQ,CAAC,OAAO,EAAE,MAAM,IAAI,GAAG,IAAI;IAInC,QAAQ,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,GAAG,IAAI;CAGlD"}
1
+ {"version":3,"file":"NodeSocketAdapter.d.ts","sourceRoot":"","sources":["../../../src/adapter/NodeSocketAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,IAAI,CAAC;AAC3B,OAAO,EAAC,aAAa,EAAC,MAAM,yBAAyB,CAAC;AAEtD,MAAM,WAAW,wBAAwB;IACrC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACpC;AAED,qBAAa,iBAAkB,YAAW,aAAa;IACnD,OAAO,CAAC,EAAE,CAAY;IACtB,OAAO,CAAC,eAAe,CAAuE;gBAElF,WAAW,EAAE,MAAM,GAAG,SAAS,EAAE,OAAO,CAAC,EAAE,wBAAwB;IAU/E,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAI3B,KAAK,IAAI,IAAI;IAIb,MAAM,CAAC,OAAO,EAAE,MAAM,IAAI,GAAG,IAAI;IAIjC,SAAS,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI;IAMhD,OAAO,CAAC,OAAO,EAAE,MAAM,IAAI,GAAG,IAAI;IAIlC,OAAO,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,GAAG,IAAI;IAI9C,OAAO,CAAC,OAAO,EAAE,MAAM,IAAI,GAAG,IAAI;IAIlC,UAAU,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI;IAQjD,QAAQ,CAAC,OAAO,EAAE,MAAM,IAAI,GAAG,IAAI;IAInC,QAAQ,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,GAAG,IAAI;IAI/C,IAAI,IAAI,IAAI;IAIZ,MAAM,CAAC,OAAO,EAAE,MAAM,IAAI,GAAG,IAAI;CAGpC"}
@@ -48,5 +48,11 @@ export class NodeSocketAdapter {
48
48
  offError(handler) {
49
49
  this.ws.off('error', handler);
50
50
  }
51
+ ping() {
52
+ this.ws.ping();
53
+ }
54
+ onPong(handler) {
55
+ this.ws.on('pong', handler);
56
+ }
51
57
  }
52
58
  //# sourceMappingURL=NodeSocketAdapter.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"NodeSocketAdapter.js","sourceRoot":"","sources":["../../../src/adapter/NodeSocketAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,IAAI,CAAC;AAO3B,MAAM,OAAO,iBAAiB;IAClB,EAAE,CAAY;IACd,eAAe,GAAG,IAAI,OAAO,EAAwD,CAAC;IAE9F,YAAY,WAA+B,EAAE,OAAkC;QAC3E,IAAI,OAAO,WAAW,KAAK,QAAQ,EAAE,CAAC;YAClC,IAAI,CAAC,EAAE,GAAG,IAAI,SAAS,CAAC,WAAW,EAAE;gBACjC,OAAO,EAAE,OAAO,EAAE,OAAO;aAC5B,CAAC,CAAC;QACP,CAAC;aAAM,CAAC;YACJ,IAAI,CAAC,EAAE,GAAG,WAAW,CAAC;QAC1B,CAAC;IACL,CAAC;IAED,IAAI,CAAC,OAAe;QAChB,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC1B,CAAC;IAED,KAAK;QACD,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC;IACpB,CAAC;IAED,MAAM,CAAC,OAAmB;QACtB,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,CAAC;IAED,SAAS,CAAC,OAA+B;QACrC,MAAM,OAAO,GAAG,CAAC,UAAkB,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAA;QACnE,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAC3C,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IACnC,CAAC;IAED,OAAO,CAAC,OAAmB;QACvB,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IACjC,CAAC;IAED,OAAO,CAAC,OAA+B;QACnC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IACjC,CAAC;IAED,OAAO,CAAC,OAAmB;QACvB,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,CAAC;IAED,UAAU,CAAC,OAA+B;QACtC,MAAM,OAAO,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAClD,IAAI,OAAO,EAAE,CAAC;YACV,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;YAChC,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACzC,CAAC;IACL,CAAC;IAED,QAAQ,CAAC,OAAmB;QACxB,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAClC,CAAC;IAED,QAAQ,CAAC,OAA+B;QACpC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAClC,CAAC;CACJ"}
1
+ {"version":3,"file":"NodeSocketAdapter.js","sourceRoot":"","sources":["../../../src/adapter/NodeSocketAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,IAAI,CAAC;AAO3B,MAAM,OAAO,iBAAiB;IAClB,EAAE,CAAY;IACd,eAAe,GAAG,IAAI,OAAO,EAAwD,CAAC;IAE9F,YAAY,WAA+B,EAAE,OAAkC;QAC3E,IAAI,OAAO,WAAW,KAAK,QAAQ,EAAE,CAAC;YAClC,IAAI,CAAC,EAAE,GAAG,IAAI,SAAS,CAAC,WAAW,EAAE;gBACjC,OAAO,EAAE,OAAO,EAAE,OAAO;aAC5B,CAAC,CAAC;QACP,CAAC;aAAM,CAAC;YACJ,IAAI,CAAC,EAAE,GAAG,WAAW,CAAC;QAC1B,CAAC;IACL,CAAC;IAED,IAAI,CAAC,OAAe;QAChB,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC1B,CAAC;IAED,KAAK;QACD,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC;IACpB,CAAC;IAED,MAAM,CAAC,OAAmB;QACtB,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,CAAC;IAED,SAAS,CAAC,OAA+B;QACrC,MAAM,OAAO,GAAG,CAAC,UAAkB,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAA;QACnE,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAC3C,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IACnC,CAAC;IAED,OAAO,CAAC,OAAmB;QACvB,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IACjC,CAAC;IAED,OAAO,CAAC,OAA+B;QACnC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IACjC,CAAC;IAED,OAAO,CAAC,OAAmB;QACvB,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,CAAC;IAED,UAAU,CAAC,OAA+B;QACtC,MAAM,OAAO,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAClD,IAAI,OAAO,EAAE,CAAC;YACV,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;YAChC,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACzC,CAAC;IACL,CAAC;IAED,QAAQ,CAAC,OAAmB;QACxB,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAClC,CAAC;IAED,QAAQ,CAAC,OAA+B;QACpC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAClC,CAAC;IAED,IAAI;QACA,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC;IACnB,CAAC;IAED,MAAM,CAAC,OAAmB;QACtB,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,CAAC;CACJ"}
@@ -59,5 +59,26 @@ export declare class GGSocketPool {
59
59
  */
60
60
  private static buildHeaders;
61
61
  static getOrConnect<Query>(config: GGSocketPoolConfig<Query>): Promise<GGSocket>;
62
+ /**
63
+ * Establish a fresh, un-pooled WebSocket connection.
64
+ *
65
+ * Unlike `getOrConnect`, this never reuses or caches connections — every
66
+ * call produces a dedicated socket with its own close lifecycle. Use this
67
+ * when you want each logical client to own its connection (the common
68
+ * case for `createClient()` users).
69
+ */
70
+ static connect<Query>(config: GGSocketPoolConfig<Query>): Promise<GGSocket>;
71
+ /**
72
+ * Reconstruct the typed error the server threw during handshake.
73
+ *
74
+ * The server sends `error.toJSON()` which has `{success:false, type, data?, context?}`.
75
+ * System errors (NOT_AUTHORIZED, FORBIDDEN, VALIDATION_ERROR, etc.) are reconstructed
76
+ * as real instances so callers can `.toBeError(NOT_AUTHORIZED)`. Anything we can't
77
+ * identify (non-ERROR throw, custom error class the client doesn't know) falls back
78
+ * to SERVER_ERROR carrying the original payload for inspection.
79
+ */
80
+ private static handshakeErrorFrom;
81
+ private static buildUrl;
82
+ private static openSocket;
62
83
  }
63
84
  //# sourceMappingURL=GGSocketPool.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"GGSocketPool.d.ts","sourceRoot":"","sources":["../../../src/client/GGSocketPool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAC,MAAM,oBAAoB,CAAC;AAC5C,OAAO,EAA8B,qBAAqB,EAAC,MAAM,iCAAiC,CAAC;AACnG,OAAO,EAAC,aAAa,EAAC,MAAM,yBAAyB,CAAC;AAGtD,OAAO,EAAC,WAAW,EAAe,MAAM,kBAAkB,CAAC;AAM3D,MAAM,WAAW,kBAAkB,CAAC,KAAK;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,KAAK,CAAA;IACb,cAAc,CAAC,EAAE,WAAW,CAAC,KAAK,CAAC,CAAA;IACnC,WAAW,CAAC,EAAE,SAAS,qBAAqB,EAAE,CAAA;CACjD;AAED;;;GAGG;AACH,qBAAa,YAAY;IACrB,OAAO,CAAC,MAAM,CAAC,OAAO,CAA+B;IACrD,OAAO,CAAC,MAAM,CAAC,cAAc,CAAwC;IACrE,OAAO,CAAC,MAAM,CAAC,OAAO,CAAa;IACnC,OAAO,CAAC,MAAM,CAAC,cAAc,CAA6B;IAE1D;;OAEG;IACH,WAAkB,IAAI,IAAI,MAAM,CAE/B;IAED;;OAEG;IACH,WAAkB,WAAW,IAAI,MAAM,CAEtC;IAED;;;;;OAKG;WACiB,QAAQ,CAAC,QAAQ,GAAE,OAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAqBrE;;;;OAIG;WACW,iBAAiB,IAAI,IAAI;IAOvC;;;;OAIG;WACW,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAIlD;;OAEG;WACW,iBAAiB,IAAI,MAAM,EAAE;IAI3C;;OAEG;mBACkB,aAAa;WAcpB,UAAU,CAAC,OAAO,EAAE,KAAI,IAAI,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE,GAAG,KAAK,aAAa;IAKhF;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,YAAY;WAiBd,YAAY,CAAC,KAAK,EAC3B,MAAM,EAAE,kBAAkB,CAAC,KAAK,CAAC,GAClC,OAAO,CAAC,QAAQ,CAAC;CAqGvB"}
1
+ {"version":3,"file":"GGSocketPool.d.ts","sourceRoot":"","sources":["../../../src/client/GGSocketPool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAC,MAAM,oBAAoB,CAAC;AAC5C,OAAO,EAA8B,qBAAqB,EAAC,MAAM,iCAAiC,CAAC;AACnG,OAAO,EAAC,aAAa,EAAC,MAAM,yBAAyB,CAAC;AAGtD,OAAO,EAAqB,WAAW,EAAe,MAAM,kBAAkB,CAAC;AAM/E,MAAM,WAAW,kBAAkB,CAAC,KAAK;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,KAAK,CAAA;IACb,cAAc,CAAC,EAAE,WAAW,CAAC,KAAK,CAAC,CAAA;IACnC,WAAW,CAAC,EAAE,SAAS,qBAAqB,EAAE,CAAA;CACjD;AAED;;;GAGG;AACH,qBAAa,YAAY;IACrB,OAAO,CAAC,MAAM,CAAC,OAAO,CAA+B;IACrD,OAAO,CAAC,MAAM,CAAC,cAAc,CAAwC;IACrE,OAAO,CAAC,MAAM,CAAC,OAAO,CAAa;IACnC,OAAO,CAAC,MAAM,CAAC,cAAc,CAA6B;IAE1D;;OAEG;IACH,WAAkB,IAAI,IAAI,MAAM,CAE/B;IAED;;OAEG;IACH,WAAkB,WAAW,IAAI,MAAM,CAEtC;IAED;;;;;OAKG;WACiB,QAAQ,CAAC,QAAQ,GAAE,OAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAqBrE;;;;OAIG;WACW,iBAAiB,IAAI,IAAI;IAOvC;;;;OAIG;WACW,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAIlD;;OAEG;WACW,iBAAiB,IAAI,MAAM,EAAE;IAI3C;;OAEG;mBACkB,aAAa;WAcpB,UAAU,CAAC,OAAO,EAAE,KAAI,IAAI,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE,GAAG,KAAK,aAAa;IAKhF;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,YAAY;WAiBd,YAAY,CAAC,KAAK,EAC3B,MAAM,EAAE,kBAAkB,CAAC,KAAK,CAAC,GAClC,OAAO,CAAC,QAAQ,CAAC;IAgCpB;;;;;;;OAOG;WACU,OAAO,CAAC,KAAK,EACtB,MAAM,EAAE,kBAAkB,CAAC,KAAK,CAAC,GAClC,OAAO,CAAC,QAAQ,CAAC;IAIpB;;;;;;;;OAQG;IACH,OAAO,CAAC,MAAM,CAAC,kBAAkB;IAUjC,OAAO,CAAC,MAAM,CAAC,QAAQ;mBASF,UAAU;CA4ClC"}
@@ -1,7 +1,7 @@
1
1
  import { GGSocket } from '../socket/GGSocket.js';
2
2
  import { GG_WS_CONNECTION } from "../server/GG_WS_CONNECTION.js";
3
3
  import { Message, MessageType } from "../socket/SocketMessage.js";
4
- import { SERVER_ERROR } from "@grest-ts/schema";
4
+ import { GGContractExecutor, SERVER_ERROR } from "@grest-ts/schema";
5
5
  import { withTimeout } from "@grest-ts/common";
6
6
  import { GGContext } from "@grest-ts/context";
7
7
  import { GG_TRACE } from "@grest-ts/trace";
@@ -112,92 +112,111 @@ export class GGSocketPool {
112
112
  return handshakeContext.headers;
113
113
  }
114
114
  static async getOrConnect(config) {
115
- // Build headers from middlewares
116
115
  const headers = this.buildHeaders(config);
117
- // Build full URL with query string if provided
118
- let fullUrl = config.domain + config.path;
119
- if (config.query) {
120
- const queryEntries = Object.entries(config.query).map(([key, value]) => [key, String(value)]);
121
- fullUrl += '?' + new URLSearchParams(queryEntries).toString();
122
- }
116
+ const fullUrl = this.buildUrl(config);
123
117
  // Create connection key based on URL + headers
124
118
  const headerKey = Object.entries(headers).sort().map(([k, v]) => `${k}=${v}`).join('&');
125
119
  const key = fullUrl + "::" + headerKey;
126
- // Check for existing connection first
127
120
  if (this.sockets.has(key)) {
128
121
  return this.sockets.get(key);
129
122
  }
130
123
  if (this.pendingSockets.has(key)) {
131
124
  return this.pendingSockets.get(key);
132
125
  }
133
- // Create the connection promise BEFORE any async operations to prevent race conditions
134
- // This ensures that concurrent calls will see the pending promise
135
- const connectionPromise = (async () => {
136
- // Ensure adapter is loaded (this is async but safely inside the promise)
137
- const adapterClass = await this.ensureAdapter();
138
- return new Promise((resolve, reject) => {
139
- const adapter = new adapterClass(fullUrl);
140
- adapter.onOpen(async () => {
141
- try {
142
- const context = new GGContext("ws-client-connection");
143
- await context.run(async () => {
144
- GG_TRACE.init();
145
- GG_WS_CONNECTION.set({
146
- port: undefined,
147
- path: config.domain
148
- });
149
- // Send handshake with headers
150
- adapter.send(Message.create(MessageType.HANDSHAKE, "", "", headers));
151
- // Wait for handshake response
152
- await withTimeout(new Promise((handshakeResolve, handshakeReject) => {
153
- const onMessage = (data) => {
154
- const msg = Message.parse(data);
155
- if (!msg)
156
- return;
157
- if (msg.type === MessageType.HANDSHAKE_OK) {
158
- adapter.offMessage(onMessage);
159
- handshakeResolve();
160
- }
161
- else if (msg.type === MessageType.HANDSHAKE_ERR) {
162
- adapter.offMessage(onMessage);
163
- handshakeReject(new SERVER_ERROR({
164
- displayMessage: 'WebSocket handshake failed',
165
- originalError: msg.data
166
- }));
167
- }
168
- };
169
- adapter.onMessage(onMessage);
170
- }), 5000, 'Handshake timeout');
171
- resolve(new GGSocket(adapter, { connectionContext: context }));
172
- });
173
- }
174
- catch (error) {
175
- reject(error);
176
- }
177
- });
178
- adapter.onError((error) => {
179
- reject(error);
180
- });
181
- });
182
- })();
183
- // Store the pending promise IMMEDIATELY (before awaiting)
126
+ const connectionPromise = this.openSocket(fullUrl, headers, config.domain);
184
127
  this.pendingSockets.set(key, connectionPromise);
185
128
  try {
186
129
  const socket = await connectionPromise;
187
- // Store the connection
188
130
  this.sockets.set(key, socket);
189
131
  this.pendingSockets.delete(key);
190
- // Clean up on close
191
132
  socket.onClose(() => {
192
133
  this.sockets.delete(key);
193
134
  });
194
135
  return socket;
195
136
  }
196
137
  catch (error) {
197
- // Clean up failed connection attempt
198
138
  this.pendingSockets.delete(key);
199
139
  throw error;
200
140
  }
201
141
  }
142
+ /**
143
+ * Establish a fresh, un-pooled WebSocket connection.
144
+ *
145
+ * Unlike `getOrConnect`, this never reuses or caches connections — every
146
+ * call produces a dedicated socket with its own close lifecycle. Use this
147
+ * when you want each logical client to own its connection (the common
148
+ * case for `createClient()` users).
149
+ */
150
+ static async connect(config) {
151
+ return this.openSocket(this.buildUrl(config), this.buildHeaders(config), config.domain);
152
+ }
153
+ /**
154
+ * Reconstruct the typed error the server threw during handshake.
155
+ *
156
+ * The server sends `error.toJSON()` which has `{success:false, type, data?, context?}`.
157
+ * System errors (NOT_AUTHORIZED, FORBIDDEN, VALIDATION_ERROR, etc.) are reconstructed
158
+ * as real instances so callers can `.toBeError(NOT_AUTHORIZED)`. Anything we can't
159
+ * identify (non-ERROR throw, custom error class the client doesn't know) falls back
160
+ * to SERVER_ERROR carrying the original payload for inspection.
161
+ */
162
+ static handshakeErrorFrom(payload) {
163
+ if (payload && typeof payload === 'object' && typeof payload.type === 'string') {
164
+ return GGContractExecutor.createErrorObj(payload);
165
+ }
166
+ return new SERVER_ERROR({
167
+ displayMessage: 'WebSocket handshake failed',
168
+ originalError: payload,
169
+ });
170
+ }
171
+ static buildUrl(config) {
172
+ let fullUrl = config.domain + config.path;
173
+ if (config.query) {
174
+ const queryEntries = Object.entries(config.query).map(([key, value]) => [key, String(value)]);
175
+ fullUrl += '?' + new URLSearchParams(queryEntries).toString();
176
+ }
177
+ return fullUrl;
178
+ }
179
+ static async openSocket(fullUrl, headers, domain) {
180
+ const adapterClass = await this.ensureAdapter();
181
+ return new Promise((resolve, reject) => {
182
+ const adapter = new adapterClass(fullUrl);
183
+ adapter.onOpen(async () => {
184
+ try {
185
+ const context = new GGContext("ws-client-connection");
186
+ await context.run(async () => {
187
+ GG_TRACE.init();
188
+ GG_WS_CONNECTION.set({
189
+ port: undefined,
190
+ path: domain
191
+ });
192
+ adapter.send(Message.create(MessageType.HANDSHAKE, "", "", headers));
193
+ await withTimeout(new Promise((handshakeResolve, handshakeReject) => {
194
+ const onMessage = (data) => {
195
+ const msg = Message.parse(data);
196
+ if (!msg)
197
+ return;
198
+ if (msg.type === MessageType.HANDSHAKE_OK) {
199
+ adapter.offMessage(onMessage);
200
+ handshakeResolve();
201
+ }
202
+ else if (msg.type === MessageType.HANDSHAKE_ERR) {
203
+ adapter.offMessage(onMessage);
204
+ handshakeReject(this.handshakeErrorFrom(msg.data));
205
+ }
206
+ };
207
+ adapter.onMessage(onMessage);
208
+ }), 5000, 'Handshake timeout');
209
+ resolve(new GGSocket(adapter, { connectionContext: context }));
210
+ });
211
+ }
212
+ catch (error) {
213
+ reject(error);
214
+ }
215
+ });
216
+ adapter.onError((error) => {
217
+ reject(error);
218
+ });
219
+ });
220
+ }
202
221
  }
203
222
  //# sourceMappingURL=GGSocketPool.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"GGSocketPool.js","sourceRoot":"","sources":["../../../src/client/GGSocketPool.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"GGSocketPool.js","sourceRoot":"","sources":["../../../src/client/GGSocketPool.ts"],"names":[],"mappings":"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"}