(eventType, callback)
| 517 | } |
| 518 | |
| 519 | async on(eventType, callback) { |
| 520 | if (typeof callback !== "function") { |
| 521 | throw new Error("Callback must be a function"); |
| 522 | } |
| 523 | |
| 524 | await this.connect(); |
| 525 | |
| 526 | if (!this.subscriptions.has(eventType)) { |
| 527 | const isWildcard = hasWildcardPattern(eventType); |
| 528 | const eventPattern = isWildcard ? compileEventPattern(eventType) : null; |
| 529 | const handler = (...args) => { |
| 530 | const entry = this.subscriptions.get(eventType); |
| 531 | if (!entry) return; |
| 532 | const currentIsWildcard = Boolean(entry.eventPattern); |
| 533 | const payload = isWildcard ? args[1] : args[0]; |
| 534 | const incomingEventType = isWildcard ? args[0] : eventType; |
| 535 | if (currentIsWildcard) { |
| 536 | if (typeof incomingEventType !== "string") return; |
| 537 | if (!entry.eventPattern.test(incomingEventType)) return; |
| 538 | } |
| 539 | let envelope; |
| 540 | try { |
| 541 | envelope = validateServerEnvelope(payload); |
| 542 | } catch (error) { |
| 543 | console.error("WebSocket envelope validation failed:", error); |
| 544 | this.invokeErrorCallbacks(error); |
| 545 | return; |
| 546 | } |
| 547 | |
| 548 | entry.callbacks.forEach((cb) => { |
| 549 | try { |
| 550 | if (currentIsWildcard) { |
| 551 | cb(incomingEventType, envelope); |
| 552 | return; |
| 553 | } |
| 554 | cb(envelope); |
| 555 | } catch (error) { |
| 556 | console.error("WebSocket callback error:", error); |
| 557 | } |
| 558 | }); |
| 559 | }; |
| 560 | |
| 561 | this.subscriptions.set(eventType, { |
| 562 | eventPattern, |
| 563 | handler, |
| 564 | callbacks: new Set(), |
| 565 | }); |
| 566 | |
| 567 | if (isWildcard) { |
| 568 | this.socket.onAny(handler); |
| 569 | } else { |
| 570 | this.socket.on(eventType, handler); |
| 571 | } |
| 572 | } |
| 573 | |
| 574 | const entry = this.subscriptions.get(eventType); |
| 575 | entry.callbacks.add(callback); |
| 576 | } |
no test coverage detected