@rlanz/socket 0.0.1-0 → 0.0.1-10

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 +594 -90
  2. package/build/base_channel-DKmR3Z0l.d.ts +476 -0
  3. package/build/chunk-55EIQ2VV.js +152 -0
  4. package/build/chunk-55EIQ2VV.js.map +1 -0
  5. package/build/chunk-6PJ4ALJD.js +115 -0
  6. package/build/chunk-6PJ4ALJD.js.map +1 -0
  7. package/build/chunk-BLRAKPXW.js +7 -0
  8. package/build/chunk-BLRAKPXW.js.map +1 -0
  9. package/build/chunk-E6ILCRL3.js +182 -0
  10. package/build/chunk-E6ILCRL3.js.map +1 -0
  11. package/build/{chunk-XUDFDJME.js → chunk-G75J233Z.js} +12 -9
  12. package/build/chunk-G75J233Z.js.map +1 -0
  13. package/build/chunk-IUQ3GYZZ.js +140 -0
  14. package/build/chunk-IUQ3GYZZ.js.map +1 -0
  15. package/build/chunk-K243S3QP.js +131 -0
  16. package/build/chunk-K243S3QP.js.map +1 -0
  17. package/build/chunk-NUPBNOP3.js +61 -0
  18. package/build/chunk-NUPBNOP3.js.map +1 -0
  19. package/build/chunk-O6UYCGTV.js +914 -0
  20. package/build/chunk-O6UYCGTV.js.map +1 -0
  21. package/build/framework-16ypv4Ss.d.ts +13 -0
  22. package/build/index-8jB5RG6v.d.ts +150 -0
  23. package/build/index.d.ts +29 -8
  24. package/build/index.js +39 -15
  25. package/build/index.js.map +1 -1
  26. package/build/providers/socket_provider.d.ts +6 -3
  27. package/build/providers/socket_provider.js +2156 -45
  28. package/build/providers/socket_provider.js.map +1 -1
  29. package/build/services/socket.d.ts +6 -3
  30. package/build/{shared_types-Dw9AphfO.d.ts → shared_types-DE86M136.d.ts} +5 -4
  31. package/build/socket_service-C1JM64_9.d.ts +106 -0
  32. package/build/src/assembler_hook.d.ts +15 -0
  33. package/build/src/assembler_hook.js +238 -0
  34. package/build/src/assembler_hook.js.map +1 -0
  35. package/build/src/client/index.d.ts +3 -106
  36. package/build/src/client/index.js +6 -667
  37. package/build/src/client/index.js.map +1 -1
  38. package/build/src/client/react.d.ts +30 -0
  39. package/build/src/client/react.js +86 -0
  40. package/build/src/client/react.js.map +1 -0
  41. package/build/src/client/types.d.ts +62 -9
  42. package/build/src/client/vue.d.ts +32 -0
  43. package/build/src/client/vue.js +100 -0
  44. package/build/src/client/vue.js.map +1 -0
  45. package/build/src/decorators.d.ts +7 -4
  46. package/build/src/decorators.js +1 -1
  47. package/build/src/health_check.d.ts +6 -3
  48. package/build/src/health_check.js +14 -3
  49. package/build/src/health_check.js.map +1 -1
  50. package/build/src/otel.d.ts +1 -0
  51. package/build/src/otel.js +187 -32
  52. package/build/src/otel.js.map +1 -1
  53. package/build/src/testing.d.ts +45 -0
  54. package/build/src/testing.js +7 -0
  55. package/build/src/testing.js.map +1 -0
  56. package/build/src/types/tracing_channels.d.ts +1 -2
  57. package/build/src/types.d.ts +4 -2
  58. package/package.json +36 -11
  59. package/build/chunk-4UPUCRVG.js +0 -1772
  60. package/build/chunk-4UPUCRVG.js.map +0 -1
  61. package/build/chunk-GKAD2UOA.js +0 -18
  62. package/build/chunk-GKAD2UOA.js.map +0 -1
  63. package/build/chunk-HK7Z65DA.js +0 -19
  64. package/build/chunk-HK7Z65DA.js.map +0 -1
  65. package/build/chunk-XUDFDJME.js.map +0 -1
  66. package/build/socket_service-jxIaH5Rs.d.ts +0 -144
  67. package/build/types-C0rDwbry.d.ts +0 -393
package/build/src/otel.js CHANGED
@@ -3,13 +3,153 @@ import {
3
3
  channelMessageChannel,
4
4
  connectChannel,
5
5
  disconnectChannel,
6
+ setTracingOperationRunner,
6
7
  subscribeChannel,
7
8
  unsubscribeChannel
8
- } from "../chunk-GKAD2UOA.js";
9
+ } from "../chunk-NUPBNOP3.js";
9
10
 
10
11
  // src/otel.ts
11
- import { SpanKind, SpanStatusCode } from "@opentelemetry/api";
12
+ import {
13
+ context,
14
+ SpanKind,
15
+ SpanStatusCode,
16
+ trace
17
+ } from "@opentelemetry/api";
12
18
  import { InstrumentationBase } from "@opentelemetry/instrumentation";
19
+
20
+ // package.json
21
+ var package_default = {
22
+ name: "@rlanz/socket",
23
+ version: "0.0.1-10",
24
+ description: "WebSocket integration for AdonisJS",
25
+ type: "module",
26
+ main: "./build/index.js",
27
+ types: "./build/index.d.ts",
28
+ license: "MIT",
29
+ engines: {
30
+ node: ">=24.0.0"
31
+ },
32
+ packageManager: "yarn@4.18.0",
33
+ files: [
34
+ "build"
35
+ ],
36
+ exports: {
37
+ ".": "./build/index.js",
38
+ "./provider": "./build/providers/socket_provider.js",
39
+ "./assembler_hook": "./build/src/assembler_hook.js",
40
+ "./services/main": "./build/services/socket.js",
41
+ "./decorators": "./build/src/decorators.js",
42
+ "./health_check": "./build/src/health_check.js",
43
+ "./otel": "./build/src/otel.js",
44
+ "./testing": "./build/src/testing.js",
45
+ "./types": "./build/src/types.js",
46
+ "./types/tracing_channels": "./build/src/types/tracing_channels.js",
47
+ "./client": "./build/src/client/index.js",
48
+ "./client/types": "./build/src/client/types.js",
49
+ "./client/react": "./build/src/client/react.js",
50
+ "./client/vue": "./build/src/client/vue.js"
51
+ },
52
+ scripts: {
53
+ build: "npm run compile",
54
+ clean: "del-cli build",
55
+ compile: "npm run clean && tsup-node",
56
+ lint: "oxlint",
57
+ "lint:fix": "oxlint --fix",
58
+ format: "oxfmt --check .",
59
+ "format:fix": "oxfmt --write .",
60
+ prepublishOnly: "npm run build",
61
+ release: "release-it",
62
+ test: "node --import=@poppinss/ts-exec --enable-source-maps bin/test.ts",
63
+ typecheck: "tsc --noEmit",
64
+ version: "npm run build"
65
+ },
66
+ dependencies: {
67
+ "@boringnode/bus": "^0.9.1",
68
+ "@lukeed/ms": "^2.0.2",
69
+ emittery: "^1.2.0",
70
+ ws: "^8.21.0"
71
+ },
72
+ devDependencies: {
73
+ "@adonisjs/assembler": "^8.0.0",
74
+ "@adonisjs/core": "^7.0.1",
75
+ "@adonisjs/tsconfig": "^2.0.0",
76
+ "@japa/assert": "^4.2.0",
77
+ "@japa/runner": "^5.3.0",
78
+ "@opentelemetry/api": "^1.9.1",
79
+ "@opentelemetry/context-async-hooks": "^2.7.1",
80
+ "@opentelemetry/core": "^2.7.1",
81
+ "@opentelemetry/instrumentation": "^0.218.0",
82
+ "@opentelemetry/sdk-metrics": "^2.7.1",
83
+ "@opentelemetry/sdk-trace-base": "^2.7.1",
84
+ "@poppinss/ts-exec": "^1.4.4",
85
+ "@types/node": "^24.0.0",
86
+ "@types/react": "^19.1.9",
87
+ "@types/react-test-renderer": "^19.1.0",
88
+ "@types/scheduler": "^0",
89
+ "@types/ws": "^8.18.1",
90
+ "del-cli": "^7.0.0",
91
+ oxfmt: "^0.38.0",
92
+ oxlint: "^1.53.0",
93
+ react: "^19.1.1",
94
+ "react-test-renderer": "^19.1.1",
95
+ "reflect-metadata": "^0.2.2",
96
+ "release-it": "^19.2.4",
97
+ scheduler: "^0.27.0",
98
+ tsup: "^8.5.1",
99
+ typescript: "^5.9.3",
100
+ vue: "^3.5.18"
101
+ },
102
+ peerDependencies: {
103
+ "@adonisjs/assembler": "^8.0.0",
104
+ "@adonisjs/core": "^7.0.1",
105
+ "@opentelemetry/api": "^1.9.0",
106
+ "@opentelemetry/instrumentation": "^0.200.0",
107
+ react: "^18.0.0 || ^19.0.0",
108
+ typescript: "^5.9.0 || ^6.0.0",
109
+ vue: "^3.3.0"
110
+ },
111
+ peerDependenciesMeta: {
112
+ "@adonisjs/assembler": {
113
+ optional: true
114
+ },
115
+ "@opentelemetry/api": {
116
+ optional: true
117
+ },
118
+ "@opentelemetry/instrumentation": {
119
+ optional: true
120
+ },
121
+ react: {
122
+ optional: true
123
+ },
124
+ typescript: {
125
+ optional: true
126
+ },
127
+ vue: {
128
+ optional: true
129
+ }
130
+ },
131
+ keywords: [
132
+ "adonisjs",
133
+ "adonis",
134
+ "websocket",
135
+ "realtime"
136
+ ],
137
+ homepage: "https://github.com/rlanz/socket#readme",
138
+ repository: {
139
+ type: "git",
140
+ url: "git+https://github.com/rlanz/socket.git"
141
+ },
142
+ bugs: {
143
+ url: "https://github.com/rlanz/socket/issues"
144
+ },
145
+ author: "Romain Lanz <romain.lanz@pm.me>",
146
+ publishConfig: {
147
+ access: "public",
148
+ tag: "latest"
149
+ }
150
+ };
151
+
152
+ // src/otel.ts
13
153
  var SocketInstrumentation = class extends InstrumentationBase {
14
154
  subscribed = false;
15
155
  spans = /* @__PURE__ */ new WeakMap();
@@ -19,32 +159,18 @@ var SocketInstrumentation = class extends InstrumentationBase {
19
159
  unsubscribeHandlers;
20
160
  messageHandlers;
21
161
  broadcastHandlers;
22
- #connectionCounter = this.meter.createCounter("rlanz_socket_connections_total", {
23
- description: "Total number of accepted socket connections"
24
- });
25
- #disconnectionCounter = this.meter.createCounter("rlanz_socket_disconnections_total", {
26
- description: "Total number of closed socket connections"
27
- });
28
- #activeConnections = this.meter.createUpDownCounter("rlanz_socket_connections_active", {
29
- description: "Number of currently active socket connections"
30
- });
31
- #subscriptionCounter = this.meter.createCounter("rlanz_socket_subscriptions_total", {
32
- description: "Total number of successful channel subscriptions"
33
- });
34
- #activeSubscriptions = this.meter.createUpDownCounter("rlanz_socket_subscriptions_active", {
35
- description: "Number of currently active channel subscriptions"
36
- });
37
- #messageCounter = this.meter.createCounter("rlanz_socket_messages_total", {
38
- description: "Total number of channel messages received from clients"
39
- });
40
- #broadcastCounter = this.meter.createCounter("rlanz_socket_broadcasts_total", {
41
- description: "Total number of broadcast operations"
42
- });
43
- #broadcastDeliveryCounter = this.meter.createCounter("rlanz_socket_broadcast_deliveries_total", {
44
- description: "Total number of socket deliveries made by broadcast operations"
45
- });
162
+ #connectionCounter;
163
+ #disconnectionCounter;
164
+ #activeConnections;
165
+ #subscriptionCounter;
166
+ #activeSubscriptions;
167
+ #messageCounter;
168
+ #broadcastCounter;
169
+ #broadcastDeliveryCounter;
46
170
  constructor(config = {}) {
47
- super("@rlanz/socket", "0.0.1", config);
171
+ super("@rlanz/socket", package_default.version, config);
172
+ this._updateMetricInstruments();
173
+ if (this.isEnabled()) this.enable();
48
174
  }
49
175
  get #messagingSystem() {
50
176
  return this.getConfig().messagingSystem ?? "@rlanz/socket";
@@ -52,6 +178,35 @@ var SocketInstrumentation = class extends InstrumentationBase {
52
178
  init() {
53
179
  return void 0;
54
180
  }
181
+ _updateMetricInstruments() {
182
+ if (this.subscribed === void 0) return;
183
+ this.#connectionCounter = this.meter.createCounter("rlanz_socket_connections_total", {
184
+ description: "Total number of accepted socket connections"
185
+ });
186
+ this.#disconnectionCounter = this.meter.createCounter("rlanz_socket_disconnections_total", {
187
+ description: "Total number of closed socket connections"
188
+ });
189
+ this.#activeConnections = this.meter.createUpDownCounter("rlanz_socket_connections_active", {
190
+ description: "Number of currently active socket connections"
191
+ });
192
+ this.#subscriptionCounter = this.meter.createCounter("rlanz_socket_subscriptions_total", {
193
+ description: "Total number of successful channel subscriptions"
194
+ });
195
+ this.#activeSubscriptions = this.meter.createUpDownCounter(
196
+ "rlanz_socket_subscriptions_active",
197
+ { description: "Number of currently active channel subscriptions" }
198
+ );
199
+ this.#messageCounter = this.meter.createCounter("rlanz_socket_messages_total", {
200
+ description: "Total number of channel messages received from clients"
201
+ });
202
+ this.#broadcastCounter = this.meter.createCounter("rlanz_socket_broadcasts_total", {
203
+ description: "Total number of broadcast operations"
204
+ });
205
+ this.#broadcastDeliveryCounter = this.meter.createCounter(
206
+ "rlanz_socket_broadcast_deliveries_total",
207
+ { description: "Total number of socket deliveries made by broadcast operations" }
208
+ );
209
+ }
55
210
  enable() {
56
211
  super.enable();
57
212
  if (this.subscribed !== void 0) this.#subscribe();
@@ -168,6 +323,8 @@ var SocketInstrumentation = class extends InstrumentationBase {
168
323
  }
169
324
  });
170
325
  this.spans.set(message, span);
326
+ const spanContext = trace.setSpan(context.active(), span);
327
+ setTracingOperationRunner(message, (operation) => context.with(spanContext, operation));
171
328
  }
172
329
  #handleDisconnectEnd(message) {
173
330
  this.#disconnectionCounter.add(1, { "socket.disconnect.reason": message.reason });
@@ -238,14 +395,13 @@ var SocketInstrumentation = class extends InstrumentationBase {
238
395
  this.spans.delete(message);
239
396
  }
240
397
  #endSpanWithOutcome(message, attributes) {
241
- this.#endSpan(message, attributes);
398
+ this.#endSpan(message, attributes, message);
242
399
  }
243
- #endSpan(message, attributes = {}) {
400
+ #endSpan(message, attributes = {}, outcome) {
244
401
  const span = this.spans.get(message);
245
402
  if (!span) return;
246
403
  span.setAttributes(attributes);
247
- const outcome = message;
248
- if (outcome.ok === false) {
404
+ if (outcome?.ok === false) {
249
405
  span.setStatus({ code: SpanStatusCode.ERROR, message: outcome.error });
250
406
  if (outcome.error) {
251
407
  span.setAttribute("error.type", outcome.error);
@@ -265,7 +421,6 @@ var SocketInstrumentation = class extends InstrumentationBase {
265
421
  "socket.broadcast.via": message.via
266
422
  };
267
423
  if (message.channel) attributes["messaging.destination.name"] = message.channel;
268
- if (message.room) attributes["socket.user.room"] = message.room;
269
424
  if (message.except) attributes["socket.broadcast.except_count"] = message.except.length;
270
425
  return attributes;
271
426
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/otel.ts"],"sourcesContent":["import { SpanKind, SpanStatusCode, type Span } from '@opentelemetry/api'\nimport type { TracingChannelSubscribers } from 'node:diagnostics_channel'\nimport { InstrumentationBase } from '@opentelemetry/instrumentation'\nimport type { InstrumentationConfig } from '@opentelemetry/instrumentation'\nimport {\n broadcastChannel,\n channelMessageChannel,\n connectChannel,\n disconnectChannel,\n subscribeChannel,\n unsubscribeChannel,\n} from './tracing_channels.js'\nimport type {\n SocketBroadcastMessage,\n SocketChannelMessage,\n SocketConnectMessage,\n SocketDisconnectMessage,\n SocketSubscribeMessage,\n SocketUnsubscribeMessage,\n} from './types/tracing_channels.js'\n\nexport interface SocketInstrumentationConfig extends InstrumentationConfig {\n /**\n * The messaging system identifier.\n *\n * @default '@rlanz/socket'\n */\n messagingSystem?: string\n}\n\ntype AttributeValue = string | number | boolean\n\nexport class SocketInstrumentation extends InstrumentationBase<SocketInstrumentationConfig> {\n protected subscribed = false\n protected spans = new WeakMap<object, Span>()\n protected connectHandlers?: TracingChannelSubscribers<SocketConnectMessage>\n protected disconnectHandlers?: TracingChannelSubscribers<SocketDisconnectMessage>\n protected subscribeHandlers?: TracingChannelSubscribers<SocketSubscribeMessage>\n protected unsubscribeHandlers?: TracingChannelSubscribers<SocketUnsubscribeMessage>\n protected messageHandlers?: TracingChannelSubscribers<SocketChannelMessage>\n protected broadcastHandlers?: TracingChannelSubscribers<SocketBroadcastMessage>\n\n #connectionCounter = this.meter.createCounter('rlanz_socket_connections_total', {\n description: 'Total number of accepted socket connections',\n })\n #disconnectionCounter = this.meter.createCounter('rlanz_socket_disconnections_total', {\n description: 'Total number of closed socket connections',\n })\n #activeConnections = this.meter.createUpDownCounter('rlanz_socket_connections_active', {\n description: 'Number of currently active socket connections',\n })\n #subscriptionCounter = this.meter.createCounter('rlanz_socket_subscriptions_total', {\n description: 'Total number of successful channel subscriptions',\n })\n #activeSubscriptions = this.meter.createUpDownCounter('rlanz_socket_subscriptions_active', {\n description: 'Number of currently active channel subscriptions',\n })\n #messageCounter = this.meter.createCounter('rlanz_socket_messages_total', {\n description: 'Total number of channel messages received from clients',\n })\n #broadcastCounter = this.meter.createCounter('rlanz_socket_broadcasts_total', {\n description: 'Total number of broadcast operations',\n })\n #broadcastDeliveryCounter = this.meter.createCounter('rlanz_socket_broadcast_deliveries_total', {\n description: 'Total number of socket deliveries made by broadcast operations',\n })\n\n constructor(config: SocketInstrumentationConfig = {}) {\n super('@rlanz/socket', '0.0.1', config)\n }\n\n get #messagingSystem(): string {\n return this.getConfig().messagingSystem ?? '@rlanz/socket'\n }\n\n protected init() {\n return undefined\n }\n\n enable() {\n super.enable()\n // `InstrumentationBase` calls `enable()` from its constructor, before this\n // subclass's fields and private methods are installed on the instance.\n // During that premature call `this.subscribed` is still `undefined`, so the\n // guard prevents calling `#subscribe()` on a not-yet-branded instance.\n if (this.subscribed !== undefined) this.#subscribe()\n }\n\n disable() {\n if (this.subscribed !== undefined) this.#unsubscribe()\n super.disable()\n }\n\n manuallyRegister() {\n this.#subscribe()\n }\n\n #subscribe() {\n if (this.subscribed) return\n if (!this.isEnabled()) return\n\n this.subscribed = true\n\n this.connectHandlers = {\n start: (message) =>\n this.#startSpan(message, 'socket connect', SpanKind.SERVER, {\n 'network.transport': 'websocket',\n }),\n end: (message) => this.#handleConnectEnd(message as SocketConnectMessage),\n asyncStart: () => {},\n asyncEnd: () => {},\n error: (message) => this.#recordError(message as SocketConnectMessage & { error: unknown }),\n }\n\n this.disconnectHandlers = {\n start: (message) =>\n this.#startSpan(message, 'socket disconnect', SpanKind.INTERNAL, {\n 'socket.disconnect.reason': message.reason,\n 'socket.disconnect.subscriptions': message.subscriptions ?? 0,\n }),\n end: () => {},\n asyncStart: () => {},\n asyncEnd: (message) => this.#handleDisconnectEnd(message as SocketDisconnectMessage),\n error: (message) =>\n this.#recordError(message as SocketDisconnectMessage & { error: unknown }),\n }\n\n this.subscribeHandlers = {\n start: (message) =>\n this.#startSpan(message, `socket subscribe ${message.channel}`, SpanKind.SERVER, {\n 'messaging.destination.name': message.channel,\n 'messaging.operation.name': 'subscribe',\n 'messaging.operation.type': 'receive',\n }),\n end: () => {},\n asyncStart: () => {},\n asyncEnd: (message) => this.#handleSubscribeEnd(message as SocketSubscribeMessage),\n error: (message) => this.#recordError(message as SocketSubscribeMessage & { error: unknown }),\n }\n\n this.unsubscribeHandlers = {\n start: (message) =>\n this.#startSpan(message, `socket unsubscribe ${message.channel}`, SpanKind.SERVER, {\n 'messaging.destination.name': message.channel,\n 'messaging.operation.name': 'unsubscribe',\n 'messaging.operation.type': 'receive',\n }),\n end: () => {},\n asyncStart: () => {},\n asyncEnd: (message) => this.#handleUnsubscribeEnd(message as SocketUnsubscribeMessage),\n error: (message) =>\n this.#recordError(message as SocketUnsubscribeMessage & { error: unknown }),\n }\n\n this.messageHandlers = {\n start: (message) =>\n this.#startSpan(message, `socket message ${message.channel}`, SpanKind.SERVER, {\n 'messaging.destination.name': message.channel,\n 'messaging.operation.name': 'process',\n 'messaging.operation.type': 'receive',\n 'messaging.event.name': message.event,\n }),\n end: () => {},\n asyncStart: () => {},\n asyncEnd: (message) => this.#handleMessageEnd(message as SocketChannelMessage),\n error: (message) => this.#recordError(message as SocketChannelMessage & { error: unknown }),\n }\n\n this.broadcastHandlers = {\n start: (message) =>\n this.#startSpan(message, `socket broadcast ${message.target}`, SpanKind.PRODUCER, {\n ...this.#broadcastAttributes(message),\n }),\n end: (message) => this.#handleBroadcastEnd(message as SocketBroadcastMessage),\n asyncStart: () => {},\n asyncEnd: () => {},\n error: (message) => this.#recordError(message as SocketBroadcastMessage & { error: unknown }),\n }\n\n connectChannel.subscribe(this.connectHandlers as any)\n disconnectChannel.subscribe(this.disconnectHandlers as any)\n subscribeChannel.subscribe(this.subscribeHandlers as any)\n unsubscribeChannel.subscribe(this.unsubscribeHandlers as any)\n channelMessageChannel.subscribe(this.messageHandlers as any)\n broadcastChannel.subscribe(this.broadcastHandlers as any)\n }\n\n #unsubscribe() {\n if (!this.subscribed) return\n\n if (this.connectHandlers) connectChannel.unsubscribe(this.connectHandlers as any)\n if (this.disconnectHandlers) disconnectChannel.unsubscribe(this.disconnectHandlers as any)\n if (this.subscribeHandlers) subscribeChannel.unsubscribe(this.subscribeHandlers as any)\n if (this.unsubscribeHandlers) unsubscribeChannel.unsubscribe(this.unsubscribeHandlers as any)\n if (this.messageHandlers) channelMessageChannel.unsubscribe(this.messageHandlers as any)\n if (this.broadcastHandlers) broadcastChannel.unsubscribe(this.broadcastHandlers as any)\n\n this.subscribed = false\n this.spans = new WeakMap()\n }\n\n #startSpan(\n message: object,\n name: string,\n kind: SpanKind,\n attributes: Record<string, AttributeValue> = {}\n ) {\n const span = this.tracer.startSpan(name, {\n kind,\n attributes: {\n 'messaging.system': this.#messagingSystem,\n ...attributes,\n },\n })\n\n this.spans.set(message, span)\n }\n\n #handleDisconnectEnd(message: SocketDisconnectMessage) {\n this.#disconnectionCounter.add(1, { 'socket.disconnect.reason': message.reason })\n this.#activeConnections.add(-1)\n if (message.subscriptions) {\n this.#activeSubscriptions.add(-message.subscriptions)\n }\n\n this.#endSpan(message)\n }\n\n #handleConnectEnd(message: SocketConnectMessage) {\n this.#connectionCounter.add(1)\n this.#activeConnections.add(1)\n this.#endSpan(message)\n }\n\n #handleSubscribeEnd(message: SocketSubscribeMessage) {\n const attributes = {\n 'messaging.destination.name': message.channel,\n 'socket.subscription.created': Boolean(message.created),\n }\n\n if (message.ok) {\n this.#subscriptionCounter.add(1, attributes)\n if (message.created) this.#activeSubscriptions.add(1, attributes)\n }\n\n this.#endSpanWithOutcome(message, attributes)\n }\n\n #handleUnsubscribeEnd(message: SocketUnsubscribeMessage) {\n const attributes = {\n 'messaging.destination.name': message.channel,\n 'socket.subscription.removed': Boolean(message.removed),\n }\n\n if (message.ok && message.removed) {\n this.#activeSubscriptions.add(-1, attributes)\n }\n\n this.#endSpanWithOutcome(message, attributes)\n }\n\n #handleMessageEnd(message: SocketChannelMessage) {\n const attributes = {\n 'messaging.destination.name': message.channel,\n 'messaging.event.name': message.event,\n }\n\n this.#messageCounter.add(1, {\n ...attributes,\n 'socket.message.ok': Boolean(message.ok),\n })\n\n this.#endSpanWithOutcome(message, attributes)\n }\n\n #handleBroadcastEnd(message: SocketBroadcastMessage) {\n const attributes = this.#broadcastAttributes(message)\n\n this.#broadcastCounter.add(1, attributes)\n if (message.delivered !== undefined) {\n this.#broadcastDeliveryCounter.add(message.delivered, attributes)\n }\n\n this.#endSpan(message, {\n ...attributes,\n ...(message.delivered !== undefined\n ? { 'socket.broadcast.delivered': message.delivered }\n : {}),\n })\n }\n\n #recordError(message: object & { error: unknown }) {\n const span = this.spans.get(message)\n if (!span) return\n\n if (message.error instanceof Error) {\n span.recordException(message.error)\n span.setStatus({ code: SpanStatusCode.ERROR, message: message.error.message })\n } else {\n span.setStatus({ code: SpanStatusCode.ERROR })\n }\n\n span.end()\n this.spans.delete(message)\n }\n\n #endSpanWithOutcome(\n message: SocketSubscribeMessage | SocketUnsubscribeMessage | SocketChannelMessage,\n attributes: Record<string, AttributeValue>\n ) {\n this.#endSpan(message, attributes)\n }\n\n #endSpan(message: object, attributes: Record<string, AttributeValue> = {}) {\n const span = this.spans.get(message)\n if (!span) return\n\n span.setAttributes(attributes)\n\n const outcome = message as {\n ok?: boolean\n error?: string\n }\n\n if (outcome.ok === false) {\n span.setStatus({ code: SpanStatusCode.ERROR, message: outcome.error })\n if (outcome.error) {\n span.setAttribute('error.type', outcome.error)\n }\n } else {\n span.setStatus({ code: SpanStatusCode.OK })\n }\n\n span.end()\n this.spans.delete(message)\n }\n\n #broadcastAttributes(message: SocketBroadcastMessage): Record<string, AttributeValue> {\n const attributes: Record<string, AttributeValue> = {\n 'messaging.operation.name': 'publish',\n 'messaging.operation.type': 'send',\n 'messaging.event.name': message.event,\n 'socket.broadcast.target': message.target,\n 'socket.broadcast.via': message.via,\n }\n\n if (message.channel) attributes['messaging.destination.name'] = message.channel\n if (message.room) attributes['socket.user.room'] = message.room\n if (message.except) attributes['socket.broadcast.except_count'] = message.except.length\n\n return attributes\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/otel.ts","../../package.json"],"sourcesContent":["import {\n context,\n SpanKind,\n SpanStatusCode,\n trace,\n type Counter,\n type Span,\n type UpDownCounter,\n} from '@opentelemetry/api'\nimport type { TracingChannelSubscribers } from 'node:diagnostics_channel'\nimport { InstrumentationBase } from '@opentelemetry/instrumentation'\nimport type { InstrumentationConfig } from '@opentelemetry/instrumentation'\nimport packageJson from '../package.json' with { type: 'json' }\nimport {\n broadcastChannel,\n channelMessageChannel,\n connectChannel,\n disconnectChannel,\n subscribeChannel,\n setTracingOperationRunner,\n unsubscribeChannel,\n} from './tracing_channels.js'\nimport type {\n SocketBroadcastMessage,\n SocketChannelMessage,\n SocketConnectMessage,\n SocketDisconnectMessage,\n SocketSubscribeMessage,\n SocketUnsubscribeMessage,\n} from './types/tracing_channels.js'\n\nexport interface SocketInstrumentationConfig extends InstrumentationConfig {\n /**\n * The messaging system identifier.\n *\n * @default '@rlanz/socket'\n */\n messagingSystem?: string\n}\n\ntype AttributeValue = string | number | boolean\n\nexport class SocketInstrumentation extends InstrumentationBase<SocketInstrumentationConfig> {\n protected subscribed = false\n protected spans = new WeakMap<object, Span>()\n protected connectHandlers?: TracingChannelSubscribers<SocketConnectMessage>\n protected disconnectHandlers?: TracingChannelSubscribers<SocketDisconnectMessage>\n protected subscribeHandlers?: TracingChannelSubscribers<SocketSubscribeMessage>\n protected unsubscribeHandlers?: TracingChannelSubscribers<SocketUnsubscribeMessage>\n protected messageHandlers?: TracingChannelSubscribers<SocketChannelMessage>\n protected broadcastHandlers?: TracingChannelSubscribers<SocketBroadcastMessage>\n\n #connectionCounter!: Counter\n #disconnectionCounter!: Counter\n #activeConnections!: UpDownCounter\n #subscriptionCounter!: Counter\n #activeSubscriptions!: UpDownCounter\n #messageCounter!: Counter\n #broadcastCounter!: Counter\n #broadcastDeliveryCounter!: Counter\n\n constructor(config: SocketInstrumentationConfig = {}) {\n super('@rlanz/socket', packageJson.version, config)\n this._updateMetricInstruments()\n if (this.isEnabled()) this.enable()\n }\n\n get #messagingSystem(): string {\n return this.getConfig().messagingSystem ?? '@rlanz/socket'\n }\n\n protected init() {\n return undefined\n }\n\n protected _updateMetricInstruments() {\n if (this.subscribed === undefined) return\n\n this.#connectionCounter = this.meter.createCounter('rlanz_socket_connections_total', {\n description: 'Total number of accepted socket connections',\n })\n this.#disconnectionCounter = this.meter.createCounter('rlanz_socket_disconnections_total', {\n description: 'Total number of closed socket connections',\n })\n this.#activeConnections = this.meter.createUpDownCounter('rlanz_socket_connections_active', {\n description: 'Number of currently active socket connections',\n })\n this.#subscriptionCounter = this.meter.createCounter('rlanz_socket_subscriptions_total', {\n description: 'Total number of successful channel subscriptions',\n })\n this.#activeSubscriptions = this.meter.createUpDownCounter(\n 'rlanz_socket_subscriptions_active',\n { description: 'Number of currently active channel subscriptions' }\n )\n this.#messageCounter = this.meter.createCounter('rlanz_socket_messages_total', {\n description: 'Total number of channel messages received from clients',\n })\n this.#broadcastCounter = this.meter.createCounter('rlanz_socket_broadcasts_total', {\n description: 'Total number of broadcast operations',\n })\n this.#broadcastDeliveryCounter = this.meter.createCounter(\n 'rlanz_socket_broadcast_deliveries_total',\n { description: 'Total number of socket deliveries made by broadcast operations' }\n )\n }\n\n enable() {\n super.enable()\n // `InstrumentationBase` calls `enable()` from its constructor, before this\n // subclass's fields and private methods are installed on the instance.\n // During that premature call `this.subscribed` is still `undefined`, so the\n // guard prevents calling `#subscribe()` on a not-yet-branded instance.\n if (this.subscribed !== undefined) this.#subscribe()\n }\n\n disable() {\n if (this.subscribed !== undefined) this.#unsubscribe()\n super.disable()\n }\n\n manuallyRegister() {\n this.#subscribe()\n }\n\n #subscribe() {\n if (this.subscribed) return\n if (!this.isEnabled()) return\n\n this.subscribed = true\n\n this.connectHandlers = {\n start: (message) =>\n this.#startSpan(message, 'socket connect', SpanKind.SERVER, {\n 'network.transport': 'websocket',\n }),\n end: (message) => this.#handleConnectEnd(message),\n asyncStart: () => {},\n asyncEnd: () => {},\n error: (message) => this.#recordError(message),\n }\n\n this.disconnectHandlers = {\n start: (message) =>\n this.#startSpan(message, 'socket disconnect', SpanKind.INTERNAL, {\n 'socket.disconnect.reason': message.reason,\n 'socket.disconnect.subscriptions': message.subscriptions ?? 0,\n }),\n end: () => {},\n asyncStart: () => {},\n asyncEnd: (message) => this.#handleDisconnectEnd(message),\n error: (message) => this.#recordError(message),\n }\n\n this.subscribeHandlers = {\n start: (message) =>\n this.#startSpan(message, `socket subscribe ${message.channel}`, SpanKind.SERVER, {\n 'messaging.destination.name': message.channel,\n 'messaging.operation.name': 'subscribe',\n 'messaging.operation.type': 'receive',\n }),\n end: () => {},\n asyncStart: () => {},\n asyncEnd: (message) => this.#handleSubscribeEnd(message),\n error: (message) => this.#recordError(message),\n }\n\n this.unsubscribeHandlers = {\n start: (message) =>\n this.#startSpan(message, `socket unsubscribe ${message.channel}`, SpanKind.SERVER, {\n 'messaging.destination.name': message.channel,\n 'messaging.operation.name': 'unsubscribe',\n 'messaging.operation.type': 'receive',\n }),\n end: () => {},\n asyncStart: () => {},\n asyncEnd: (message) => this.#handleUnsubscribeEnd(message),\n error: (message) => this.#recordError(message),\n }\n\n this.messageHandlers = {\n start: (message) =>\n this.#startSpan(message, `socket message ${message.channel}`, SpanKind.SERVER, {\n 'messaging.destination.name': message.channel,\n 'messaging.operation.name': 'process',\n 'messaging.operation.type': 'receive',\n 'messaging.event.name': message.event,\n }),\n end: () => {},\n asyncStart: () => {},\n asyncEnd: (message) => this.#handleMessageEnd(message),\n error: (message) => this.#recordError(message),\n }\n\n this.broadcastHandlers = {\n start: (message) =>\n this.#startSpan(message, `socket broadcast ${message.target}`, SpanKind.PRODUCER, {\n ...this.#broadcastAttributes(message),\n }),\n end: (message) => this.#handleBroadcastEnd(message),\n asyncStart: () => {},\n asyncEnd: () => {},\n error: (message) => this.#recordError(message),\n }\n\n connectChannel.subscribe(this.connectHandlers)\n disconnectChannel.subscribe(this.disconnectHandlers)\n subscribeChannel.subscribe(this.subscribeHandlers)\n unsubscribeChannel.subscribe(this.unsubscribeHandlers)\n channelMessageChannel.subscribe(this.messageHandlers)\n broadcastChannel.subscribe(this.broadcastHandlers)\n }\n\n #unsubscribe() {\n if (!this.subscribed) return\n\n if (this.connectHandlers) connectChannel.unsubscribe(this.connectHandlers)\n if (this.disconnectHandlers) disconnectChannel.unsubscribe(this.disconnectHandlers)\n if (this.subscribeHandlers) subscribeChannel.unsubscribe(this.subscribeHandlers)\n if (this.unsubscribeHandlers) unsubscribeChannel.unsubscribe(this.unsubscribeHandlers)\n if (this.messageHandlers) channelMessageChannel.unsubscribe(this.messageHandlers)\n if (this.broadcastHandlers) broadcastChannel.unsubscribe(this.broadcastHandlers)\n\n this.subscribed = false\n this.spans = new WeakMap()\n }\n\n #startSpan(\n message: object,\n name: string,\n kind: SpanKind,\n attributes: Record<string, AttributeValue> = {}\n ) {\n const span = this.tracer.startSpan(name, {\n kind,\n attributes: {\n 'messaging.system': this.#messagingSystem,\n ...attributes,\n },\n })\n\n this.spans.set(message, span)\n const spanContext = trace.setSpan(context.active(), span)\n setTracingOperationRunner(message, (operation) => context.with(spanContext, operation))\n }\n\n #handleDisconnectEnd(message: SocketDisconnectMessage) {\n this.#disconnectionCounter.add(1, { 'socket.disconnect.reason': message.reason })\n this.#activeConnections.add(-1)\n if (message.subscriptions) {\n this.#activeSubscriptions.add(-message.subscriptions)\n }\n\n this.#endSpan(message)\n }\n\n #handleConnectEnd(message: SocketConnectMessage) {\n this.#connectionCounter.add(1)\n this.#activeConnections.add(1)\n this.#endSpan(message)\n }\n\n #handleSubscribeEnd(message: SocketSubscribeMessage) {\n const attributes = {\n 'messaging.destination.name': message.channel,\n 'socket.subscription.created': Boolean(message.created),\n }\n\n if (message.ok) {\n this.#subscriptionCounter.add(1, attributes)\n if (message.created) this.#activeSubscriptions.add(1, attributes)\n }\n\n this.#endSpanWithOutcome(message, attributes)\n }\n\n #handleUnsubscribeEnd(message: SocketUnsubscribeMessage) {\n const attributes = {\n 'messaging.destination.name': message.channel,\n 'socket.subscription.removed': Boolean(message.removed),\n }\n\n if (message.ok && message.removed) {\n this.#activeSubscriptions.add(-1, attributes)\n }\n\n this.#endSpanWithOutcome(message, attributes)\n }\n\n #handleMessageEnd(message: SocketChannelMessage) {\n const attributes = {\n 'messaging.destination.name': message.channel,\n 'messaging.event.name': message.event,\n }\n\n this.#messageCounter.add(1, {\n ...attributes,\n 'socket.message.ok': Boolean(message.ok),\n })\n\n this.#endSpanWithOutcome(message, attributes)\n }\n\n #handleBroadcastEnd(message: SocketBroadcastMessage) {\n const attributes = this.#broadcastAttributes(message)\n\n this.#broadcastCounter.add(1, attributes)\n if (message.delivered !== undefined) {\n this.#broadcastDeliveryCounter.add(message.delivered, attributes)\n }\n\n this.#endSpan(message, {\n ...attributes,\n ...(message.delivered !== undefined\n ? { 'socket.broadcast.delivered': message.delivered }\n : {}),\n })\n }\n\n #recordError(message: object & { error: unknown }) {\n const span = this.spans.get(message)\n if (!span) return\n\n if (message.error instanceof Error) {\n span.recordException(message.error)\n span.setStatus({ code: SpanStatusCode.ERROR, message: message.error.message })\n } else {\n span.setStatus({ code: SpanStatusCode.ERROR })\n }\n\n span.end()\n this.spans.delete(message)\n }\n\n #endSpanWithOutcome(\n message: SocketSubscribeMessage | SocketUnsubscribeMessage | SocketChannelMessage,\n attributes: Record<string, AttributeValue>\n ) {\n this.#endSpan(message, attributes, message)\n }\n\n #endSpan(\n message: object,\n attributes: Record<string, AttributeValue> = {},\n outcome?: { ok?: boolean; error?: string }\n ) {\n const span = this.spans.get(message)\n if (!span) return\n\n span.setAttributes(attributes)\n\n if (outcome?.ok === false) {\n span.setStatus({ code: SpanStatusCode.ERROR, message: outcome.error })\n if (outcome.error) {\n span.setAttribute('error.type', outcome.error)\n }\n } else {\n span.setStatus({ code: SpanStatusCode.OK })\n }\n\n span.end()\n this.spans.delete(message)\n }\n\n #broadcastAttributes(message: SocketBroadcastMessage): Record<string, AttributeValue> {\n const attributes: Record<string, AttributeValue> = {\n 'messaging.operation.name': 'publish',\n 'messaging.operation.type': 'send',\n 'messaging.event.name': message.event,\n 'socket.broadcast.target': message.target,\n 'socket.broadcast.via': message.via,\n }\n\n if (message.channel) attributes['messaging.destination.name'] = message.channel\n if (message.except) attributes['socket.broadcast.except_count'] = message.except.length\n\n return attributes\n }\n}\n","{\n \"name\": \"@rlanz/socket\",\n \"version\": \"0.0.1-10\",\n \"description\": \"WebSocket integration for AdonisJS\",\n \"type\": \"module\",\n \"main\": \"./build/index.js\",\n \"types\": \"./build/index.d.ts\",\n \"license\": \"MIT\",\n \"engines\": {\n \"node\": \">=24.0.0\"\n },\n \"packageManager\": \"yarn@4.18.0\",\n \"files\": [\n \"build\"\n ],\n \"exports\": {\n \".\": \"./build/index.js\",\n \"./provider\": \"./build/providers/socket_provider.js\",\n \"./assembler_hook\": \"./build/src/assembler_hook.js\",\n \"./services/main\": \"./build/services/socket.js\",\n \"./decorators\": \"./build/src/decorators.js\",\n \"./health_check\": \"./build/src/health_check.js\",\n \"./otel\": \"./build/src/otel.js\",\n \"./testing\": \"./build/src/testing.js\",\n \"./types\": \"./build/src/types.js\",\n \"./types/tracing_channels\": \"./build/src/types/tracing_channels.js\",\n \"./client\": \"./build/src/client/index.js\",\n \"./client/types\": \"./build/src/client/types.js\",\n \"./client/react\": \"./build/src/client/react.js\",\n \"./client/vue\": \"./build/src/client/vue.js\"\n },\n \"scripts\": {\n \"build\": \"npm run compile\",\n \"clean\": \"del-cli build\",\n \"compile\": \"npm run clean && tsup-node\",\n \"lint\": \"oxlint\",\n \"lint:fix\": \"oxlint --fix\",\n \"format\": \"oxfmt --check .\",\n \"format:fix\": \"oxfmt --write .\",\n \"prepublishOnly\": \"npm run build\",\n \"release\": \"release-it\",\n \"test\": \"node --import=@poppinss/ts-exec --enable-source-maps bin/test.ts\",\n \"typecheck\": \"tsc --noEmit\",\n \"version\": \"npm run build\"\n },\n \"dependencies\": {\n \"@boringnode/bus\": \"^0.9.1\",\n \"@lukeed/ms\": \"^2.0.2\",\n \"emittery\": \"^1.2.0\",\n \"ws\": \"^8.21.0\"\n },\n \"devDependencies\": {\n \"@adonisjs/assembler\": \"^8.0.0\",\n \"@adonisjs/core\": \"^7.0.1\",\n \"@adonisjs/tsconfig\": \"^2.0.0\",\n \"@japa/assert\": \"^4.2.0\",\n \"@japa/runner\": \"^5.3.0\",\n \"@opentelemetry/api\": \"^1.9.1\",\n \"@opentelemetry/context-async-hooks\": \"^2.7.1\",\n \"@opentelemetry/core\": \"^2.7.1\",\n \"@opentelemetry/instrumentation\": \"^0.218.0\",\n \"@opentelemetry/sdk-metrics\": \"^2.7.1\",\n \"@opentelemetry/sdk-trace-base\": \"^2.7.1\",\n \"@poppinss/ts-exec\": \"^1.4.4\",\n \"@types/node\": \"^24.0.0\",\n \"@types/react\": \"^19.1.9\",\n \"@types/react-test-renderer\": \"^19.1.0\",\n \"@types/scheduler\": \"^0\",\n \"@types/ws\": \"^8.18.1\",\n \"del-cli\": \"^7.0.0\",\n \"oxfmt\": \"^0.38.0\",\n \"oxlint\": \"^1.53.0\",\n \"react\": \"^19.1.1\",\n \"react-test-renderer\": \"^19.1.1\",\n \"reflect-metadata\": \"^0.2.2\",\n \"release-it\": \"^19.2.4\",\n \"scheduler\": \"^0.27.0\",\n \"tsup\": \"^8.5.1\",\n \"typescript\": \"^5.9.3\",\n \"vue\": \"^3.5.18\"\n },\n \"peerDependencies\": {\n \"@adonisjs/assembler\": \"^8.0.0\",\n \"@adonisjs/core\": \"^7.0.1\",\n \"@opentelemetry/api\": \"^1.9.0\",\n \"@opentelemetry/instrumentation\": \"^0.200.0\",\n \"react\": \"^18.0.0 || ^19.0.0\",\n \"typescript\": \"^5.9.0 || ^6.0.0\",\n \"vue\": \"^3.3.0\"\n },\n \"peerDependenciesMeta\": {\n \"@adonisjs/assembler\": {\n \"optional\": true\n },\n \"@opentelemetry/api\": {\n \"optional\": true\n },\n \"@opentelemetry/instrumentation\": {\n \"optional\": true\n },\n \"react\": {\n \"optional\": true\n },\n \"typescript\": {\n \"optional\": true\n },\n \"vue\": {\n \"optional\": true\n }\n },\n \"keywords\": [\n \"adonisjs\",\n \"adonis\",\n \"websocket\",\n \"realtime\"\n ],\n \"homepage\": \"https://github.com/rlanz/socket#readme\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/rlanz/socket.git\"\n },\n \"bugs\": {\n \"url\": \"https://github.com/rlanz/socket/issues\"\n },\n \"author\": \"Romain Lanz <romain.lanz@pm.me>\",\n \"publishConfig\": {\n \"access\": \"public\",\n \"tag\": \"latest\"\n }\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,45 @@
1
+ type SocketEmission = {
2
+ target: 'global';
3
+ event: string;
4
+ data: unknown;
5
+ } | {
6
+ target: 'channel';
7
+ channel: string;
8
+ event: string;
9
+ data: unknown;
10
+ except?: string[];
11
+ };
12
+ type SocketEmissionTarget = SocketEmission['target'];
13
+ interface SocketEmissionSink {
14
+ dispatch(emission: SocketEmission): void;
15
+ }
16
+
17
+ type SocketFakeTarget = SocketEmissionTarget;
18
+ type SocketFakeEmission = SocketEmission;
19
+ type SocketFakeMatcher<Value> = Value | ((value: Value) => boolean);
20
+ interface SocketFakeEmissionQuery {
21
+ data?: unknown | ((data: unknown) => boolean);
22
+ except?: SocketFakeMatcher<string[] | undefined>;
23
+ }
24
+ interface SocketFakeCountQuery extends SocketFakeEmissionQuery {
25
+ target?: SocketFakeTarget;
26
+ event?: string;
27
+ channel?: string;
28
+ }
29
+ declare class SocketFake implements SocketEmissionSink {
30
+ #private;
31
+ constructor(restore: () => void);
32
+ get emissions(): SocketFakeEmission[];
33
+ record(emission: SocketFakeEmission): void;
34
+ dispatch(emission: SocketFakeEmission): void;
35
+ clear(): void;
36
+ restore(): void;
37
+ [Symbol.dispose](): void;
38
+ assertBroadcasted(event: string, query?: SocketFakeEmissionQuery): void;
39
+ assertNotBroadcasted(event: string, query?: SocketFakeEmissionQuery): void;
40
+ assertEmittedTo(channel: string, event: string, query?: SocketFakeEmissionQuery): void;
41
+ assertNotEmittedTo(channel: string, event: string, query?: SocketFakeEmissionQuery): void;
42
+ assertCount(count: number, query?: SocketFakeCountQuery): void;
43
+ }
44
+
45
+ export { SocketFake, type SocketFakeCountQuery, type SocketFakeEmission, type SocketFakeEmissionQuery, type SocketFakeTarget };
@@ -0,0 +1,7 @@
1
+ import {
2
+ SocketFake
3
+ } from "../chunk-IUQ3GYZZ.js";
4
+ export {
5
+ SocketFake
6
+ };
7
+ //# sourceMappingURL=testing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -28,10 +28,9 @@ interface SocketChannelMessage {
28
28
  error?: string;
29
29
  }
30
30
  interface SocketBroadcastMessage {
31
- target: 'channel' | 'user' | 'global';
31
+ target: 'channel' | 'global';
32
32
  event: string;
33
33
  channel?: string;
34
- room?: string;
35
34
  except?: string[];
36
35
  via: 'local' | 'bus';
37
36
  delivered?: number;
@@ -1,5 +1,7 @@
1
- export { A as AuthenticatedSocket, C as ChannelEventMap, h as ChannelHandlerFn, a as ChannelHandlerMap, b as ChannelMatch, d as ChannelOptions, M as Middleware, i as MiddlewareClass, j as MiddlewareContext, k as MiddlewareFn, l as PresenceMember, R as RawSocket, m as SocketAuthenticationDetails, n as SocketAuthenticationHandler, o as SocketAuthenticationResult, e as SocketConfig, S as SocketEvents, g as SocketHealthSnapshot, p as SocketHttpContextFactory, f as SocketServiceStatus, q as SocketUpgradeContext } from '../types-C0rDwbry.js';
1
+ export { A as AuthenticatedSocket, u as ChannelMatch, C as ChannelOptions, D as Duration, M as Middleware, b as MiddlewareClass, c as MiddlewareConstructor, d as MiddlewareContext, e as MiddlewareFn, f as PresenceInfo, g as PresenceMember, R as RawSocket, S as SocketAuthenticationHandler, h as SocketAuthenticationResult, a as SocketConfig, i as SocketEvents, j as SocketHealthSnapshot, k as SocketHttpMiddleware, l as SocketOriginResolver, m as SocketOriginValues, o as SocketRetryQueueConfig, p as SocketServiceStatus, q as SocketTransportConfig, r as SocketUpgradeContext } from '../base_channel-DKmR3Z0l.js';
2
2
  import 'ws';
3
3
  import 'node:http';
4
- export { C as ChannelAck, a as ChannelMessage } from '../shared_types-Dw9AphfO.js';
4
+ import '@adonisjs/core/types/http';
5
+ import '@adonisjs/core/http';
6
+ export { a as ChannelAck, b as ChannelMessage, C as ChannelServerEventsOf } from '../shared_types-DE86M136.js';
5
7
  import '@boringnode/bus/types/main';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rlanz/socket",
3
- "version": "0.0.1-0",
3
+ "version": "0.0.1-10",
4
4
  "description": "WebSocket integration for AdonisJS",
5
5
  "type": "module",
6
6
  "main": "./build/index.js",
@@ -9,12 +9,14 @@
9
9
  "engines": {
10
10
  "node": ">=24.0.0"
11
11
  },
12
+ "packageManager": "yarn@4.18.0",
12
13
  "files": [
13
14
  "build"
14
15
  ],
15
16
  "exports": {
16
17
  ".": "./build/index.js",
17
18
  "./provider": "./build/providers/socket_provider.js",
19
+ "./assembler_hook": "./build/src/assembler_hook.js",
18
20
  "./services/main": "./build/services/socket.js",
19
21
  "./decorators": "./build/src/decorators.js",
20
22
  "./health_check": "./build/src/health_check.js",
@@ -23,7 +25,9 @@
23
25
  "./types": "./build/src/types.js",
24
26
  "./types/tracing_channels": "./build/src/types/tracing_channels.js",
25
27
  "./client": "./build/src/client/index.js",
26
- "./client/types": "./build/src/client/types.js"
28
+ "./client/types": "./build/src/client/types.js",
29
+ "./client/react": "./build/src/client/react.js",
30
+ "./client/vue": "./build/src/client/vue.js"
27
31
  },
28
32
  "scripts": {
29
33
  "build": "npm run compile",
@@ -40,12 +44,13 @@
40
44
  "version": "npm run build"
41
45
  },
42
46
  "dependencies": {
43
- "@boringnode/bus": "^0.9.0",
44
- "@poppinss/matchit": "^3.2.0",
47
+ "@boringnode/bus": "^0.9.1",
48
+ "@lukeed/ms": "^2.0.2",
45
49
  "emittery": "^1.2.0",
46
50
  "ws": "^8.21.0"
47
51
  },
48
52
  "devDependencies": {
53
+ "@adonisjs/assembler": "^8.0.0",
49
54
  "@adonisjs/core": "^7.0.1",
50
55
  "@adonisjs/tsconfig": "^2.0.0",
51
56
  "@japa/assert": "^4.2.0",
@@ -57,29 +62,50 @@
57
62
  "@opentelemetry/sdk-metrics": "^2.7.1",
58
63
  "@opentelemetry/sdk-trace-base": "^2.7.1",
59
64
  "@poppinss/ts-exec": "^1.4.4",
65
+ "@types/node": "^24.0.0",
66
+ "@types/react": "^19.1.9",
67
+ "@types/react-test-renderer": "^19.1.0",
68
+ "@types/scheduler": "^0",
60
69
  "@types/ws": "^8.18.1",
61
70
  "del-cli": "^7.0.0",
62
71
  "oxfmt": "^0.38.0",
63
72
  "oxlint": "^1.53.0",
73
+ "react": "^19.1.1",
74
+ "react-test-renderer": "^19.1.1",
75
+ "reflect-metadata": "^0.2.2",
64
76
  "release-it": "^19.2.4",
77
+ "scheduler": "^0.27.0",
65
78
  "tsup": "^8.5.1",
66
- "typescript": "^5.9.3"
79
+ "typescript": "^5.9.3",
80
+ "vue": "^3.5.18"
67
81
  },
68
82
  "peerDependencies": {
83
+ "@adonisjs/assembler": "^8.0.0",
69
84
  "@adonisjs/core": "^7.0.1",
70
85
  "@opentelemetry/api": "^1.9.0",
71
- "@opentelemetry/core": "^1.30.0 || ^2.0.0",
72
- "@opentelemetry/instrumentation": "^0.200.0"
86
+ "@opentelemetry/instrumentation": "^0.200.0",
87
+ "react": "^18.0.0 || ^19.0.0",
88
+ "typescript": "^5.9.0 || ^6.0.0",
89
+ "vue": "^3.3.0"
73
90
  },
74
91
  "peerDependenciesMeta": {
75
- "@opentelemetry/api": {
92
+ "@adonisjs/assembler": {
76
93
  "optional": true
77
94
  },
78
- "@opentelemetry/core": {
95
+ "@opentelemetry/api": {
79
96
  "optional": true
80
97
  },
81
98
  "@opentelemetry/instrumentation": {
82
99
  "optional": true
100
+ },
101
+ "react": {
102
+ "optional": true
103
+ },
104
+ "typescript": {
105
+ "optional": true
106
+ },
107
+ "vue": {
108
+ "optional": true
83
109
  }
84
110
  },
85
111
  "keywords": [
@@ -100,6 +126,5 @@
100
126
  "publishConfig": {
101
127
  "access": "public",
102
128
  "tag": "latest"
103
- },
104
- "packageManager": "yarn@4.11.0"
129
+ }
105
130
  }