@trigger.dev/core 0.0.0-prerelease-20240603154820 → 0.0.0-prerelease-20240723165848
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api-Pl9fxB8v.d.mts +13879 -0
- package/dist/api-sNoooMbT.d.ts +13879 -0
- package/dist/{catalog-dRKTgwQ7.d.ts → catalog-H7yFiZ60.d.mts} +52 -52
- package/dist/{catalog-XTlJQaMn.d.mts → catalog-h79CG5Wy.d.ts} +52 -52
- package/dist/{manager-JkbddlcO.d.mts → common-CLW82lkt.d.mts} +280 -16
- package/dist/{manager-JkbddlcO.d.ts → common-CLW82lkt.d.ts} +280 -16
- package/dist/{eventFilterMatches-2kHImluE.d.mts → eventFilter-66NaBAMi.d.mts} +1 -3
- package/dist/{eventFilterMatches-2kHImluE.d.ts → eventFilter-66NaBAMi.d.ts} +1 -3
- package/dist/eventFilterMatches.d.mts +6 -0
- package/dist/eventFilterMatches.d.ts +6 -0
- package/dist/eventFilterMatches.js +165 -0
- package/dist/eventFilterMatches.js.map +1 -0
- package/dist/eventFilterMatches.mjs +163 -0
- package/dist/eventFilterMatches.mjs.map +1 -0
- package/dist/index.d.mts +14 -16716
- package/dist/index.d.ts +14 -16716
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/dist/json-DBPEJQRe.d.mts +16 -0
- package/dist/json-DBPEJQRe.d.ts +16 -0
- package/dist/manager-KvCabW1a.d.mts +18 -0
- package/dist/manager-OBA35PzR.d.ts +18 -0
- package/dist/{messages-6_-q72KG.d.mts → messages-JvHJ83wv.d.mts} +2978 -291
- package/dist/{messages-6_-q72KG.d.ts → messages-JvHJ83wv.d.ts} +2978 -291
- package/dist/replacements.d.mts +22 -0
- package/dist/replacements.d.ts +22 -0
- package/dist/replacements.js +33 -0
- package/dist/replacements.js.map +1 -0
- package/dist/replacements.mjs +28 -0
- package/dist/replacements.mjs.map +1 -0
- package/dist/requestFilter-HNZQEpQb.d.ts +180 -0
- package/dist/requestFilter-b5W2_1oP.d.mts +180 -0
- package/dist/requestFilterMatches.d.mts +13 -0
- package/dist/requestFilterMatches.d.ts +13 -0
- package/dist/requestFilterMatches.js +238 -0
- package/dist/requestFilterMatches.js.map +1 -0
- package/dist/requestFilterMatches.mjs +235 -0
- package/dist/requestFilterMatches.mjs.map +1 -0
- package/dist/retry.d.mts +10 -0
- package/dist/retry.d.ts +10 -0
- package/dist/retry.js +100 -0
- package/dist/retry.js.map +1 -0
- package/dist/retry.mjs +97 -0
- package/dist/retry.mjs.map +1 -0
- package/dist/schemas/index.d.mts +2611 -0
- package/dist/schemas/index.d.ts +2611 -0
- package/dist/schemas/index.js +1630 -0
- package/dist/schemas/index.js.map +1 -0
- package/dist/schemas/index.mjs +1463 -0
- package/dist/schemas/index.mjs.map +1 -0
- package/dist/{schemas-r4ZP9S-F.d.mts → schemas-C9ssfehv.d.mts} +270 -33
- package/dist/{schemas-r4ZP9S-F.d.ts → schemas-C9ssfehv.d.ts} +270 -33
- package/dist/taskLogger-CzADe4je.d.ts +33 -0
- package/dist/taskLogger-r_AFTX45.d.mts +33 -0
- package/dist/tracer-N0p2Fuuv.d.mts +23 -0
- package/dist/tracer-N0p2Fuuv.d.ts +23 -0
- package/dist/types.d.mts +11 -0
- package/dist/types.d.ts +11 -0
- package/dist/types.js +4 -0
- package/dist/types.js.map +1 -0
- package/dist/types.mjs +3 -0
- package/dist/types.mjs.map +1 -0
- package/dist/utils.d.mts +7 -0
- package/dist/utils.d.ts +7 -0
- package/dist/utils.js +33 -0
- package/dist/utils.js.map +1 -0
- package/dist/utils.mjs +30 -0
- package/dist/utils.mjs.map +1 -0
- package/dist/v3/dev/index.d.mts +2 -1
- package/dist/v3/dev/index.d.ts +2 -1
- package/dist/v3/dev/index.js.map +1 -1
- package/dist/v3/dev/index.mjs.map +1 -1
- package/dist/v3/errors.d.mts +39 -0
- package/dist/v3/errors.d.ts +39 -0
- package/dist/v3/errors.js +204 -0
- package/dist/v3/errors.js.map +1 -0
- package/dist/v3/errors.mjs +195 -0
- package/dist/v3/errors.mjs.map +1 -0
- package/dist/v3/index.d.mts +172 -4737
- package/dist/v3/index.d.ts +172 -4737
- package/dist/v3/index.js +871 -620
- package/dist/v3/index.js.map +1 -1
- package/dist/v3/index.mjs +856 -620
- package/dist/v3/index.mjs.map +1 -1
- package/dist/v3/logger-api.d.mts +24 -0
- package/dist/v3/logger-api.d.ts +24 -0
- package/dist/v3/logger-api.js +118 -0
- package/dist/v3/logger-api.js.map +1 -0
- package/dist/v3/logger-api.mjs +116 -0
- package/dist/v3/logger-api.mjs.map +1 -0
- package/dist/v3/otel/index.js +36 -12
- package/dist/v3/otel/index.js.map +1 -1
- package/dist/v3/otel/index.mjs +36 -12
- package/dist/v3/otel/index.mjs.map +1 -1
- package/dist/v3/prod/index.d.mts +4 -3
- package/dist/v3/prod/index.d.ts +4 -3
- package/dist/v3/prod/index.js +7 -131
- package/dist/v3/prod/index.js.map +1 -1
- package/dist/v3/prod/index.mjs +7 -131
- package/dist/v3/prod/index.mjs.map +1 -1
- package/dist/v3/schemas/index.d.mts +4807 -0
- package/dist/v3/schemas/index.d.ts +4807 -0
- package/dist/v3/schemas/index.js +2065 -0
- package/dist/v3/schemas/index.js.map +1 -0
- package/dist/v3/schemas/index.mjs +1924 -0
- package/dist/v3/schemas/index.mjs.map +1 -0
- package/dist/v3/semanticInternalAttributes.d.mts +56 -0
- package/dist/v3/semanticInternalAttributes.d.ts +56 -0
- package/dist/v3/semanticInternalAttributes.js +61 -0
- package/dist/v3/semanticInternalAttributes.js.map +1 -0
- package/dist/v3/semanticInternalAttributes.mjs +59 -0
- package/dist/v3/semanticInternalAttributes.mjs.map +1 -0
- package/dist/v3/utils/durations.d.mts +15 -0
- package/dist/v3/utils/durations.d.ts +15 -0
- package/dist/v3/utils/durations.js +93 -0
- package/dist/v3/utils/durations.js.map +1 -0
- package/dist/v3/utils/durations.mjs +82 -0
- package/dist/v3/utils/durations.mjs.map +1 -0
- package/dist/v3/utils/flattenAttributes.d.mts +8 -0
- package/dist/v3/utils/flattenAttributes.d.ts +8 -0
- package/dist/v3/utils/flattenAttributes.js +131 -0
- package/dist/v3/utils/flattenAttributes.js.map +1 -0
- package/dist/v3/utils/flattenAttributes.mjs +126 -0
- package/dist/v3/utils/flattenAttributes.mjs.map +1 -0
- package/dist/v3/utils/ioSerialization.d.mts +21 -0
- package/dist/v3/utils/ioSerialization.d.ts +21 -0
- package/dist/v3/utils/ioSerialization.js +2403 -0
- package/dist/v3/utils/ioSerialization.js.map +1 -0
- package/dist/v3/utils/ioSerialization.mjs +2394 -0
- package/dist/v3/utils/ioSerialization.mjs.map +1 -0
- package/dist/v3/utils/omit.d.mts +3 -0
- package/dist/v3/utils/omit.d.ts +3 -0
- package/dist/v3/utils/omit.js +20 -0
- package/dist/v3/utils/omit.js.map +1 -0
- package/dist/v3/utils/omit.mjs +18 -0
- package/dist/v3/utils/omit.mjs.map +1 -0
- package/dist/v3/utils/retries.d.mts +46 -0
- package/dist/v3/utils/retries.d.ts +46 -0
- package/dist/v3/utils/retries.js +118 -0
- package/dist/v3/utils/retries.js.map +1 -0
- package/dist/v3/utils/retries.mjs +113 -0
- package/dist/v3/utils/retries.mjs.map +1 -0
- package/dist/v3/utils/timers.d.mts +6 -0
- package/dist/v3/utils/timers.d.ts +6 -0
- package/dist/v3/utils/timers.js +31 -0
- package/dist/v3/utils/timers.js.map +1 -0
- package/dist/v3/utils/timers.mjs +28 -0
- package/dist/v3/utils/timers.mjs.map +1 -0
- package/dist/v3/workers/index.d.mts +56 -8
- package/dist/v3/workers/index.d.ts +56 -8
- package/dist/v3/workers/index.js +755 -279
- package/dist/v3/workers/index.js.map +1 -1
- package/dist/v3/workers/index.mjs +753 -280
- package/dist/v3/workers/index.mjs.map +1 -1
- package/dist/v3/zodIpc.js.map +1 -1
- package/dist/v3/zodIpc.mjs.map +1 -1
- package/dist/v3/zodMessageHandler.d.mts +16 -3
- package/dist/v3/zodMessageHandler.d.ts +16 -3
- package/dist/v3/zodMessageHandler.js +77 -23
- package/dist/v3/zodMessageHandler.js.map +1 -1
- package/dist/v3/zodMessageHandler.mjs +77 -23
- package/dist/v3/zodMessageHandler.mjs.map +1 -1
- package/dist/v3/zodNamespace.js +59 -28
- package/dist/v3/zodNamespace.js.map +1 -1
- package/dist/v3/zodNamespace.mjs +60 -29
- package/dist/v3/zodNamespace.mjs.map +1 -1
- package/dist/v3/zodSocket.d.mts +8 -3
- package/dist/v3/zodSocket.d.ts +8 -3
- package/dist/v3/zodSocket.js +56 -25
- package/dist/v3/zodSocket.js.map +1 -1
- package/dist/v3/zodSocket.mjs +57 -26
- package/dist/v3/zodSocket.mjs.map +1 -1
- package/dist/v3/zodfetch.d.mts +15 -58
- package/dist/v3/zodfetch.d.ts +15 -58
- package/dist/v3/zodfetch.js +246 -156
- package/dist/v3/zodfetch.js.map +1 -1
- package/dist/v3/zodfetch.mjs +244 -149
- package/dist/v3/zodfetch.mjs.map +1 -1
- package/dist/versions.d.mts +11 -0
- package/dist/versions.d.ts +11 -0
- package/dist/versions.js +31 -0
- package/dist/versions.js.map +1 -0
- package/dist/versions.mjs +27 -0
- package/dist/versions.mjs.map +1 -0
- package/package.json +154 -10
package/dist/v3/zodNamespace.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { z
|
|
1
|
+
import { z } from 'zod';
|
|
2
2
|
import 'socket.io-client';
|
|
3
3
|
import { fromZodError } from 'zod-validation-error';
|
|
4
4
|
|
|
@@ -57,11 +57,15 @@ var _ZodMessageSender = class _ZodMessageSender {
|
|
|
57
57
|
if (!parsedPayload.success) {
|
|
58
58
|
throw new ZodSchemaParsedError(parsedPayload.error, payload);
|
|
59
59
|
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
60
|
+
try {
|
|
61
|
+
await __privateGet(this, _sender).call(this, {
|
|
62
|
+
type,
|
|
63
|
+
payload,
|
|
64
|
+
version: "v1"
|
|
65
|
+
});
|
|
66
|
+
} catch (error) {
|
|
67
|
+
console.error("[ZodMessageSender] Failed to send message", error);
|
|
68
|
+
}
|
|
65
69
|
}
|
|
66
70
|
async forwardMessage(message) {
|
|
67
71
|
const parsedMessage = ZodMessageSchema.safeParse(message);
|
|
@@ -76,11 +80,15 @@ var _ZodMessageSender = class _ZodMessageSender {
|
|
|
76
80
|
if (!parsedPayload.success) {
|
|
77
81
|
throw new Error(`Failed to parse message payload: ${JSON.stringify(parsedPayload.error)}`);
|
|
78
82
|
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
83
|
+
try {
|
|
84
|
+
await __privateGet(this, _sender).call(this, {
|
|
85
|
+
type: parsedMessage.data.type,
|
|
86
|
+
payload: parsedPayload.data,
|
|
87
|
+
version: "v1"
|
|
88
|
+
});
|
|
89
|
+
} catch (error) {
|
|
90
|
+
console.error("[ZodMessageSender] Failed to forward message", error);
|
|
91
|
+
}
|
|
84
92
|
}
|
|
85
93
|
};
|
|
86
94
|
_schema = new WeakMap();
|
|
@@ -159,35 +167,51 @@ var messageSchema = z.object({
|
|
|
159
167
|
type: z.string(),
|
|
160
168
|
payload: z.unknown()
|
|
161
169
|
});
|
|
162
|
-
var _schema2, _handlers;
|
|
170
|
+
var _schema2, _handlers, _logger;
|
|
163
171
|
var _ZodSocketMessageHandler = class _ZodSocketMessageHandler {
|
|
164
172
|
constructor(options) {
|
|
165
173
|
__privateAdd(this, _schema2, void 0);
|
|
166
174
|
__privateAdd(this, _handlers, void 0);
|
|
175
|
+
__privateAdd(this, _logger, void 0);
|
|
167
176
|
__privateSet(this, _schema2, options.schema);
|
|
168
177
|
__privateSet(this, _handlers, options.handlers);
|
|
178
|
+
__privateSet(this, _logger, options.logger ?? new SimpleStructuredLogger("socket-message-handler", LogLevel.info));
|
|
169
179
|
}
|
|
170
180
|
async handleMessage(message) {
|
|
171
|
-
const
|
|
181
|
+
const parseResult = this.parseMessage(message);
|
|
182
|
+
if (!parseResult.success) {
|
|
183
|
+
__privateGet(this, _logger).error("Failed to parse message, skipping handler", {
|
|
184
|
+
rawMessage: message,
|
|
185
|
+
error: parseResult.reason
|
|
186
|
+
});
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
172
189
|
if (!__privateGet(this, _handlers)) {
|
|
173
190
|
throw new Error("No handlers provided");
|
|
174
191
|
}
|
|
175
|
-
const
|
|
192
|
+
const { type, payload } = parseResult.data;
|
|
193
|
+
const handler = __privateGet(this, _handlers)[type];
|
|
176
194
|
if (!handler) {
|
|
177
|
-
console.error(`No handler for message type: ${String(
|
|
195
|
+
console.error(`No handler for message type: ${String(type)}`);
|
|
178
196
|
return;
|
|
179
197
|
}
|
|
180
|
-
const ack = await handler(
|
|
198
|
+
const ack = await handler(payload);
|
|
181
199
|
return ack;
|
|
182
200
|
}
|
|
183
201
|
parseMessage(message) {
|
|
184
202
|
const parsedMessage = messageSchema.safeParse(message);
|
|
185
203
|
if (!parsedMessage.success) {
|
|
186
|
-
|
|
204
|
+
return {
|
|
205
|
+
success: false,
|
|
206
|
+
reason: `Failed to parse message: ${fromZodError(parsedMessage.error).toString()}`
|
|
207
|
+
};
|
|
187
208
|
}
|
|
188
209
|
const schema = __privateGet(this, _schema2)[parsedMessage.data.type]["message"];
|
|
189
210
|
if (!schema) {
|
|
190
|
-
|
|
211
|
+
return {
|
|
212
|
+
success: false,
|
|
213
|
+
reason: `Unknown message type: ${parsedMessage.data.type}`
|
|
214
|
+
};
|
|
191
215
|
}
|
|
192
216
|
const messageWithVersion = {
|
|
193
217
|
version: parsedMessage.data.version,
|
|
@@ -199,11 +223,17 @@ var _ZodSocketMessageHandler = class _ZodSocketMessageHandler {
|
|
|
199
223
|
message,
|
|
200
224
|
payload: messageWithVersion
|
|
201
225
|
});
|
|
202
|
-
|
|
226
|
+
return {
|
|
227
|
+
success: false,
|
|
228
|
+
reason: fromZodError(parsedPayload.error).toString()
|
|
229
|
+
};
|
|
203
230
|
}
|
|
204
231
|
return {
|
|
205
|
-
|
|
206
|
-
|
|
232
|
+
success: true,
|
|
233
|
+
data: {
|
|
234
|
+
type: parsedMessage.data.type,
|
|
235
|
+
payload: parsedPayload.data
|
|
236
|
+
}
|
|
207
237
|
};
|
|
208
238
|
}
|
|
209
239
|
registerHandlers(emitter, logger) {
|
|
@@ -251,16 +281,17 @@ var _ZodSocketMessageHandler = class _ZodSocketMessageHandler {
|
|
|
251
281
|
};
|
|
252
282
|
_schema2 = new WeakMap();
|
|
253
283
|
_handlers = new WeakMap();
|
|
284
|
+
_logger = new WeakMap();
|
|
254
285
|
__name(_ZodSocketMessageHandler, "ZodSocketMessageHandler");
|
|
255
286
|
var ZodSocketMessageHandler = _ZodSocketMessageHandler;
|
|
256
287
|
|
|
257
288
|
// src/v3/zodNamespace.ts
|
|
258
|
-
var
|
|
289
|
+
var _logger2, _handler;
|
|
259
290
|
var _ZodNamespace = class _ZodNamespace {
|
|
260
291
|
constructor(opts) {
|
|
261
|
-
__privateAdd(this,
|
|
292
|
+
__privateAdd(this, _logger2, void 0);
|
|
262
293
|
__privateAdd(this, _handler, void 0);
|
|
263
|
-
__privateSet(this,
|
|
294
|
+
__privateSet(this, _logger2, opts.logger ?? new SimpleStructuredLogger(opts.name));
|
|
264
295
|
__privateSet(this, _handler, new ZodSocketMessageHandler({
|
|
265
296
|
schema: opts.clientMessages,
|
|
266
297
|
handlers: opts.handlers
|
|
@@ -282,7 +313,7 @@ var _ZodNamespace = class _ZodNamespace {
|
|
|
282
313
|
});
|
|
283
314
|
if (opts.preAuth) {
|
|
284
315
|
this.namespace.use(async (socket, next) => {
|
|
285
|
-
const logger = __privateGet(this,
|
|
316
|
+
const logger = __privateGet(this, _logger2).child({
|
|
286
317
|
socketId: socket.id,
|
|
287
318
|
socketStage: "preAuth"
|
|
288
319
|
});
|
|
@@ -293,7 +324,7 @@ var _ZodNamespace = class _ZodNamespace {
|
|
|
293
324
|
}
|
|
294
325
|
if (opts.authToken) {
|
|
295
326
|
this.namespace.use((socket, next) => {
|
|
296
|
-
const logger = __privateGet(this,
|
|
327
|
+
const logger = __privateGet(this, _logger2).child({
|
|
297
328
|
socketId: socket.id,
|
|
298
329
|
socketStage: "auth"
|
|
299
330
|
});
|
|
@@ -312,7 +343,7 @@ var _ZodNamespace = class _ZodNamespace {
|
|
|
312
343
|
}
|
|
313
344
|
if (opts.postAuth) {
|
|
314
345
|
this.namespace.use(async (socket, next) => {
|
|
315
|
-
const logger = __privateGet(this,
|
|
346
|
+
const logger = __privateGet(this, _logger2).child({
|
|
316
347
|
socketId: socket.id,
|
|
317
348
|
socketStage: "auth"
|
|
318
349
|
});
|
|
@@ -322,7 +353,7 @@ var _ZodNamespace = class _ZodNamespace {
|
|
|
322
353
|
});
|
|
323
354
|
}
|
|
324
355
|
this.namespace.on("connection", async (socket) => {
|
|
325
|
-
const logger = __privateGet(this,
|
|
356
|
+
const logger = __privateGet(this, _logger2).child({
|
|
326
357
|
socketId: socket.id,
|
|
327
358
|
socketStage: "connection"
|
|
328
359
|
});
|
|
@@ -354,7 +385,7 @@ var _ZodNamespace = class _ZodNamespace {
|
|
|
354
385
|
return this.namespace.fetchSockets();
|
|
355
386
|
}
|
|
356
387
|
};
|
|
357
|
-
|
|
388
|
+
_logger2 = new WeakMap();
|
|
358
389
|
_handler = new WeakMap();
|
|
359
390
|
__name(_ZodNamespace, "ZodNamespace");
|
|
360
391
|
var ZodNamespace = _ZodNamespace;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/v3/zodMessageHandler.ts","../../src/v3/zodSocket.ts","../../src/v3/utils/structuredLogger.ts","../../src/v3/zodNamespace.ts"],"names":["z","ZodSchemaParsedError","Error","constructor","error","payload","message","ZodMessageSchema","object","version","literal","default","type","string","unknown","ZodMessageSender","options","schema","sender","send","parsedPayload","safeParse","success","forwardMessage","parsedMessage","JSON","stringify","data","io","ZodError","LogLevel","SimpleStructuredLogger","name","level","includes","process","env","DEBUG","debug","info","fields","child","log","args","console","warn","loggerFunction","structuredLog","length","timestamp","Date","fromZodError","messageSchema","_schema","ZodSocketMessageHandler","handlers","handleMessage","parseMessage","handler","String","ack","messageWithVersion","registerHandlers","emitter","logger","eventName","Object","keys","on","callback","hasCallback","stack","ZodNamespace","opts","clientMessages","namespace","of","serverMessages","Promise","resolve","reject","emit","err","preAuth","use","socket","next","socketId","id","socketStage","authToken","auth","handshake","disconnect","token","postAuth","reason","description","onDisconnect","onError","onConnection","fetchSockets"],"mappings":"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","sourcesContent":["import { z } from \"zod\";\nimport { StructuredLogger } from \"./utils/structuredLogger\";\n\nexport class ZodSchemaParsedError extends Error {\n constructor(\n public error: z.ZodError,\n public payload: unknown\n ) {\n super(error.message);\n }\n}\n\nexport type ZodMessageValueSchema<TDiscriminatedUnion extends z.ZodDiscriminatedUnion<any, any>> =\n | z.ZodFirstPartySchemaTypes\n | TDiscriminatedUnion;\n\nexport interface ZodMessageCatalogSchema {\n [key: string]: ZodMessageValueSchema<any>;\n}\n\nexport type ZodMessageHandlers<TCatalogSchema extends ZodMessageCatalogSchema> = Partial<{\n [K in keyof TCatalogSchema]: (payload: z.infer<TCatalogSchema[K]>) => Promise<any>;\n}>;\n\nexport type ZodMessageHandlerOptions<TMessageCatalog extends ZodMessageCatalogSchema> = {\n schema: TMessageCatalog;\n messages?: ZodMessageHandlers<TMessageCatalog>;\n};\n\nexport type MessageFromSchema<\n K extends keyof TMessageCatalog,\n TMessageCatalog extends ZodMessageCatalogSchema,\n> = {\n type: K;\n payload: z.input<TMessageCatalog[K]>;\n};\n\nexport type MessageFromCatalog<TMessageCatalog extends ZodMessageCatalogSchema> = {\n [K in keyof TMessageCatalog]: MessageFromSchema<K, TMessageCatalog>;\n}[keyof TMessageCatalog];\n\nexport const ZodMessageSchema = z.object({\n version: z.literal(\"v1\").default(\"v1\"),\n type: z.string(),\n payload: z.unknown(),\n});\n\nexport interface EventEmitterLike {\n on(eventName: string | symbol, listener: (...args: any[]) => void): this;\n}\n\nexport class ZodMessageHandler<TMessageCatalog extends ZodMessageCatalogSchema> {\n #schema: TMessageCatalog;\n #handlers: ZodMessageHandlers<TMessageCatalog> | undefined;\n\n constructor(options: ZodMessageHandlerOptions<TMessageCatalog>) {\n this.#schema = options.schema;\n this.#handlers = options.messages;\n }\n\n public async handleMessage(message: unknown) {\n const parsedMessage = this.parseMessage(message);\n\n if (!this.#handlers) {\n throw new Error(\"No handlers provided\");\n }\n\n const handler = this.#handlers[parsedMessage.type];\n\n if (!handler) {\n console.error(`No handler for message type: ${String(parsedMessage.type)}`);\n return;\n }\n\n const ack = await handler(parsedMessage.payload);\n\n return ack;\n }\n\n public parseMessage(message: unknown): MessageFromCatalog<TMessageCatalog> {\n const parsedMessage = ZodMessageSchema.safeParse(message);\n\n if (!parsedMessage.success) {\n throw new Error(`Failed to parse message: ${JSON.stringify(parsedMessage.error)}`);\n }\n\n const schema = this.#schema[parsedMessage.data.type];\n\n if (!schema) {\n throw new Error(`Unknown message type: ${parsedMessage.data.type}`);\n }\n\n const parsedPayload = schema.safeParse(parsedMessage.data.payload);\n\n if (!parsedPayload.success) {\n throw new Error(`Failed to parse message payload: ${JSON.stringify(parsedPayload.error)}`);\n }\n\n return {\n type: parsedMessage.data.type,\n payload: parsedPayload.data,\n };\n }\n\n public registerHandlers(emitter: EventEmitterLike, logger?: StructuredLogger) {\n const log = logger ?? console;\n\n if (!this.#handlers) {\n log.info(\"No handlers provided\");\n return;\n }\n\n for (const eventName of Object.keys(this.#schema)) {\n emitter.on(eventName, async (message: any, callback?: any): Promise<void> => {\n log.info(`handling ${eventName}`, {\n payload: message,\n hasCallback: !!callback,\n });\n\n let ack;\n\n // FIXME: this only works if the message doesn't have genuine payload prop\n if (\"payload\" in message) {\n ack = await this.handleMessage({ type: eventName, ...message });\n } else {\n // Handle messages not sent by ZodMessageSender\n const { version, ...payload } = message;\n ack = await this.handleMessage({ type: eventName, version, payload });\n }\n\n if (callback && typeof callback === \"function\") {\n callback(ack);\n }\n });\n }\n }\n}\n\ntype ZodMessageSenderCallback<TMessageCatalog extends ZodMessageCatalogSchema> = (message: {\n type: keyof TMessageCatalog;\n payload: z.infer<TMessageCatalog[keyof TMessageCatalog]>;\n version: \"v1\";\n}) => Promise<void>;\n\nexport type ZodMessageSenderOptions<TMessageCatalog extends ZodMessageCatalogSchema> = {\n schema: TMessageCatalog;\n sender: ZodMessageSenderCallback<TMessageCatalog>;\n};\n\nexport class ZodMessageSender<TMessageCatalog extends ZodMessageCatalogSchema> {\n #schema: TMessageCatalog;\n #sender: ZodMessageSenderCallback<TMessageCatalog>;\n\n constructor(options: ZodMessageSenderOptions<TMessageCatalog>) {\n this.#schema = options.schema;\n this.#sender = options.sender;\n }\n\n public async send<K extends keyof TMessageCatalog>(\n type: K,\n payload: z.input<TMessageCatalog[K]>\n ) {\n const schema = this.#schema[type];\n\n if (!schema) {\n throw new Error(`Unknown message type: ${type as string}`);\n }\n\n const parsedPayload = schema.safeParse(payload);\n\n if (!parsedPayload.success) {\n throw new ZodSchemaParsedError(parsedPayload.error, payload);\n }\n\n await this.#sender({ type, payload, version: \"v1\" });\n }\n\n public async forwardMessage(message: unknown) {\n const parsedMessage = ZodMessageSchema.safeParse(message);\n\n if (!parsedMessage.success) {\n throw new Error(`Failed to parse message: ${JSON.stringify(parsedMessage.error)}`);\n }\n\n const schema = this.#schema[parsedMessage.data.type];\n\n if (!schema) {\n throw new Error(`Unknown message type: ${parsedMessage.data.type}`);\n }\n\n const parsedPayload = schema.safeParse(parsedMessage.data.payload);\n\n if (!parsedPayload.success) {\n throw new Error(`Failed to parse message payload: ${JSON.stringify(parsedPayload.error)}`);\n }\n\n await this.#sender({\n type: parsedMessage.data.type,\n payload: parsedPayload.data,\n version: \"v1\",\n });\n }\n}\n\nexport type MessageCatalogToSocketIoEvents<TCatalog extends ZodMessageCatalogSchema> = {\n [K in keyof TCatalog]: (message: z.infer<TCatalog[K]>) => void;\n};\n","import type { Socket } from \"socket.io-client\";\nimport { io } from \"socket.io-client\";\nimport { ZodError, z } from \"zod\";\nimport { EventEmitterLike, ZodMessageValueSchema } from \"./zodMessageHandler\";\nimport { LogLevel, SimpleStructuredLogger, StructuredLogger } from \"./utils/structuredLogger\";\nimport { fromZodError } from \"zod-validation-error\";\n\nexport interface ZodSocketMessageCatalogSchema {\n [key: string]:\n | {\n message: ZodMessageValueSchema<any>;\n }\n | {\n message: ZodMessageValueSchema<any>;\n callback?: ZodMessageValueSchema<any>;\n };\n}\n\nexport type ZodMessageCatalogToSocketIoEvents<TCatalog extends ZodSocketMessageCatalogSchema> = {\n [K in keyof TCatalog]: SocketMessageHasCallback<TCatalog, K> extends true\n ? (\n message: z.infer<GetSocketMessageSchema<TCatalog, K>>,\n callback: (ack: z.infer<GetSocketCallbackSchema<TCatalog, K>>) => void\n ) => void\n : (message: z.infer<GetSocketMessageSchema<TCatalog, K>>) => void;\n};\n\nexport type GetSocketMessageSchema<\n TRPCCatalog extends ZodSocketMessageCatalogSchema,\n TMessageType extends keyof TRPCCatalog,\n> = TRPCCatalog[TMessageType][\"message\"];\n\nexport type InferSocketMessageSchema<\n TRPCCatalog extends ZodSocketMessageCatalogSchema,\n TMessageType extends keyof TRPCCatalog,\n> = z.infer<GetSocketMessageSchema<TRPCCatalog, TMessageType>>;\n\nexport type GetSocketCallbackSchema<\n TRPCCatalog extends ZodSocketMessageCatalogSchema,\n TMessageType extends keyof TRPCCatalog,\n> = TRPCCatalog[TMessageType] extends { callback: any }\n ? TRPCCatalog[TMessageType][\"callback\"]\n : never;\n\nexport type InferSocketCallbackSchema<\n TRPCCatalog extends ZodSocketMessageCatalogSchema,\n TMessageType extends keyof TRPCCatalog,\n> = z.infer<GetSocketCallbackSchema<TRPCCatalog, TMessageType>>;\n\nexport type SocketMessageHasCallback<\n TRPCCatalog extends ZodSocketMessageCatalogSchema,\n TMessageType extends keyof TRPCCatalog,\n> = GetSocketCallbackSchema<TRPCCatalog, TMessageType> extends never ? false : true;\n\nexport type ZodSocketMessageHandlers<TCatalogSchema extends ZodSocketMessageCatalogSchema> =\n Partial<{\n [K in keyof TCatalogSchema]: (\n payload: z.infer<GetSocketMessageSchema<TCatalogSchema, K>>\n ) => Promise<\n SocketMessageHasCallback<TCatalogSchema, K> extends true\n ? z.input<GetSocketCallbackSchema<TCatalogSchema, K>>\n : void\n >;\n }>;\n\nexport type ZodSocketMessageHandlerOptions<TMessageCatalog extends ZodSocketMessageCatalogSchema> =\n {\n schema: TMessageCatalog;\n handlers?: ZodSocketMessageHandlers<TMessageCatalog>;\n };\n\ntype MessageFromSocketSchema<\n K extends keyof TMessageCatalog,\n TMessageCatalog extends ZodSocketMessageCatalogSchema,\n> = {\n type: K;\n payload: z.input<GetSocketMessageSchema<TMessageCatalog, K>>;\n};\n\nexport type MessagesFromSocketCatalog<TMessageCatalog extends ZodSocketMessageCatalogSchema> = {\n [K in keyof TMessageCatalog]: MessageFromSocketSchema<K, TMessageCatalog>;\n}[keyof TMessageCatalog];\n\nconst messageSchema = z.object({\n version: z.string(),\n type: z.string(),\n payload: z.unknown(),\n});\n\nexport class ZodSocketMessageHandler<TRPCCatalog extends ZodSocketMessageCatalogSchema> {\n #schema: TRPCCatalog;\n #handlers: ZodSocketMessageHandlers<TRPCCatalog> | undefined;\n\n constructor(options: ZodSocketMessageHandlerOptions<TRPCCatalog>) {\n this.#schema = options.schema;\n this.#handlers = options.handlers;\n }\n\n public async handleMessage(message: unknown) {\n const parsedMessage = this.parseMessage(message);\n\n if (!this.#handlers) {\n throw new Error(\"No handlers provided\");\n }\n\n const handler = this.#handlers[parsedMessage.type];\n\n if (!handler) {\n console.error(`No handler for message type: ${String(parsedMessage.type)}`);\n return;\n }\n\n const ack = await handler(parsedMessage.payload);\n\n return ack;\n }\n\n public parseMessage(message: unknown): MessagesFromSocketCatalog<TRPCCatalog> {\n const parsedMessage = messageSchema.safeParse(message);\n\n if (!parsedMessage.success) {\n throw new Error(`Failed to parse message: ${JSON.stringify(parsedMessage.error)}`);\n }\n\n const schema = this.#schema[parsedMessage.data.type][\"message\"];\n\n if (!schema) {\n throw new Error(`Unknown message type: ${parsedMessage.data.type}`);\n }\n\n const messageWithVersion = {\n version: parsedMessage.data.version,\n ...(typeof parsedMessage.data.payload === \"object\" ? parsedMessage.data.payload : {}),\n };\n\n const parsedPayload = schema.safeParse(messageWithVersion);\n\n if (!parsedPayload.success) {\n console.error(\"Failed to parse message payload\", {\n message,\n payload: messageWithVersion,\n });\n\n throw parsedPayload.error instanceof ZodError\n ? fromZodError(parsedPayload.error)\n : parsedPayload.error;\n }\n\n return {\n type: parsedMessage.data.type,\n payload: parsedPayload.data,\n };\n }\n\n public registerHandlers(emitter: EventEmitterLike, logger?: StructuredLogger) {\n const log = logger ?? console;\n\n if (!this.#handlers) {\n log.info(\"No handlers provided\");\n return;\n }\n\n for (const eventName of Object.keys(this.#handlers)) {\n emitter.on(eventName, async (message: any, callback?: any): Promise<void> => {\n log.info(`handling ${eventName}`, {\n payload: message,\n hasCallback: !!callback,\n });\n\n let ack;\n\n try {\n // FIXME: this only works if the message doesn't have genuine payload prop\n if (\"payload\" in message) {\n ack = await this.handleMessage({ type: eventName, ...message });\n } else {\n // Handle messages not sent by ZodMessageSender\n const { version, ...payload } = message;\n ack = await this.handleMessage({ type: eventName, version, payload });\n }\n } catch (error) {\n log.error(\"Error while handling message\", {\n error:\n error instanceof Error\n ? {\n message: error.message,\n stack: error.stack,\n }\n : error,\n });\n return;\n }\n\n if (callback && typeof callback === \"function\") {\n callback(ack);\n }\n });\n }\n }\n}\n\nexport type ZodSocketMessageSenderOptions<TMessageCatalog extends ZodSocketMessageCatalogSchema> = {\n schema: TMessageCatalog;\n socket: ZodSocket<any, TMessageCatalog>;\n};\n\nexport type GetSocketMessagesWithCallback<TMessageCatalog extends ZodSocketMessageCatalogSchema> = {\n [K in keyof TMessageCatalog]: SocketMessageHasCallback<TMessageCatalog, K> extends true\n ? K\n : never;\n}[keyof TMessageCatalog];\n\nexport type GetSocketMessagesWithoutCallback<\n TMessageCatalog extends ZodSocketMessageCatalogSchema,\n> = {\n [K in keyof TMessageCatalog]: SocketMessageHasCallback<TMessageCatalog, K> extends true\n ? never\n : K;\n}[keyof TMessageCatalog];\n\nexport class ZodSocketMessageSender<TMessageCatalog extends ZodSocketMessageCatalogSchema> {\n #schema: TMessageCatalog;\n #socket: ZodSocket<any, TMessageCatalog>;\n\n constructor(options: ZodSocketMessageSenderOptions<TMessageCatalog>) {\n this.#schema = options.schema;\n this.#socket = options.socket;\n }\n\n public send<K extends GetSocketMessagesWithoutCallback<TMessageCatalog>>(\n type: K,\n payload: z.input<GetSocketMessageSchema<TMessageCatalog, K>>\n ): void {\n const schema = this.#schema[type][\"message\"];\n\n if (!schema) {\n throw new Error(`Unknown message type: ${type as string}`);\n }\n\n const parsedPayload = schema.safeParse(payload);\n\n if (!parsedPayload.success) {\n throw new Error(`Failed to parse message payload: ${JSON.stringify(parsedPayload.error)}`);\n }\n\n // @ts-expect-error\n this.#socket.emit(type, { payload, version: \"v1\" });\n\n return;\n }\n\n public async sendWithAck<K extends GetSocketMessagesWithCallback<TMessageCatalog>>(\n type: K,\n payload: z.input<GetSocketMessageSchema<TMessageCatalog, K>>\n ): Promise<z.infer<GetSocketCallbackSchema<TMessageCatalog, K>>> {\n const schema = this.#schema[type][\"message\"];\n\n if (!schema) {\n throw new Error(`Unknown message type: ${type as string}`);\n }\n\n const parsedPayload = schema.safeParse(payload);\n\n if (!parsedPayload.success) {\n throw new Error(`Failed to parse message payload: ${JSON.stringify(parsedPayload.error)}`);\n }\n\n // @ts-expect-error\n const callbackResult = await this.#socket.emitWithAck(type, { payload, version: \"v1\" });\n\n return callbackResult;\n }\n}\n\nexport type ZodSocket<\n TListenEvents extends ZodSocketMessageCatalogSchema,\n TEmitEvents extends ZodSocketMessageCatalogSchema,\n> = Socket<\n ZodMessageCatalogToSocketIoEvents<TListenEvents>,\n ZodMessageCatalogToSocketIoEvents<TEmitEvents>\n>;\n\ninterface ZodSocketConnectionOptions<\n TClientMessages extends ZodSocketMessageCatalogSchema,\n TServerMessages extends ZodSocketMessageCatalogSchema,\n> {\n host: string;\n port?: number;\n secure?: boolean;\n namespace: string;\n clientMessages: TClientMessages;\n serverMessages: TServerMessages;\n extraHeaders?: {\n [header: string]: string;\n };\n handlers?: ZodSocketMessageHandlers<TServerMessages>;\n authToken?: string;\n onConnection?: (\n socket: ZodSocket<TServerMessages, TClientMessages>,\n handler: ZodSocketMessageHandler<TServerMessages>,\n sender: ZodSocketMessageSender<TClientMessages>,\n logger: StructuredLogger\n ) => Promise<void>;\n onDisconnect?: (\n socket: ZodSocket<TServerMessages, TClientMessages>,\n reason: Socket.DisconnectReason,\n description: any,\n logger: StructuredLogger\n ) => Promise<void>;\n onError?: (\n socket: ZodSocket<TServerMessages, TClientMessages>,\n err: Error,\n logger: StructuredLogger\n ) => Promise<void>;\n}\n\nexport class ZodSocketConnection<\n TClientMessages extends ZodSocketMessageCatalogSchema,\n TServerMessages extends ZodSocketMessageCatalogSchema,\n> {\n #sender: ZodSocketMessageSender<TClientMessages>;\n socket: ZodSocket<TServerMessages, TClientMessages>;\n\n #handler: ZodSocketMessageHandler<TServerMessages>;\n #logger: StructuredLogger;\n\n constructor(opts: ZodSocketConnectionOptions<TClientMessages, TServerMessages>) {\n const uri = `${opts.secure ? \"wss\" : \"ws\"}://${opts.host}:${\n opts.port ?? (opts.secure ? \"443\" : \"80\")\n }/${opts.namespace}`;\n\n const logger = new SimpleStructuredLogger(opts.namespace, LogLevel.info);\n logger.log(\"new zod socket\", { uri });\n\n this.socket = io(uri, {\n transports: [\"websocket\"],\n auth: {\n token: opts.authToken,\n },\n extraHeaders: opts.extraHeaders,\n reconnectionDelay: 500,\n reconnectionDelayMax: 1000,\n });\n\n this.#logger = logger.child({\n socketId: this.socket.id,\n });\n\n this.#handler = new ZodSocketMessageHandler({\n schema: opts.serverMessages,\n handlers: opts.handlers,\n });\n this.#handler.registerHandlers(this.socket, this.#logger);\n\n this.#sender = new ZodSocketMessageSender({\n schema: opts.clientMessages,\n socket: this.socket,\n });\n\n this.socket.on(\"connect_error\", async (error) => {\n this.#logger.error(`connect_error: ${error}`);\n\n if (opts.onError) {\n await opts.onError(this.socket, error, this.#logger);\n }\n });\n\n this.socket.on(\"connect\", async () => {\n this.#logger.info(\"connect\");\n\n if (opts.onConnection) {\n await opts.onConnection(this.socket, this.#handler, this.#sender, this.#logger);\n }\n });\n\n this.socket.on(\"disconnect\", async (reason, description) => {\n this.#logger.info(\"disconnect\", { reason, description });\n\n if (opts.onDisconnect) {\n await opts.onDisconnect(this.socket, reason, description, this.#logger);\n }\n });\n }\n\n close() {\n this.socket.close();\n }\n\n connect() {\n this.socket.connect();\n }\n\n get send() {\n return this.#sender.send.bind(this.#sender);\n }\n\n get sendWithAck() {\n return this.#sender.sendWithAck.bind(this.#sender);\n }\n}\n\nfunction createLogger(prefix: string) {\n return (...args: any[]) => console.log(prefix, ...args);\n}\n","type StructuredArgs = (Record<string, unknown> | undefined)[];\n\nexport interface StructuredLogger {\n log: (message: string, ...args: StructuredArgs) => any;\n error: (message: string, ...args: StructuredArgs) => any;\n warn: (message: string, ...args: StructuredArgs) => any;\n info: (message: string, ...args: StructuredArgs) => any;\n debug: (message: string, ...args: StructuredArgs) => any;\n child: (fields: Record<string, unknown>) => StructuredLogger;\n}\n\nexport enum LogLevel {\n \"log\",\n \"error\",\n \"warn\",\n \"info\",\n \"debug\",\n}\n\nexport class SimpleStructuredLogger implements StructuredLogger {\n constructor(\n private name: string,\n private level: LogLevel = [\"1\", \"true\"].includes(process.env.DEBUG ?? \"\")\n ? LogLevel.debug\n : LogLevel.info,\n private fields?: Record<string, unknown>\n ) {}\n\n child(fields: Record<string, unknown>, level?: LogLevel) {\n return new SimpleStructuredLogger(this.name, level, { ...this.fields, ...fields });\n }\n\n log(message: string, ...args: StructuredArgs) {\n if (this.level < LogLevel.log) return;\n\n this.#structuredLog(console.log, message, \"log\", ...args);\n }\n\n error(message: string, ...args: StructuredArgs) {\n if (this.level < LogLevel.error) return;\n\n this.#structuredLog(console.error, message, \"error\", ...args);\n }\n\n warn(message: string, ...args: StructuredArgs) {\n if (this.level < LogLevel.warn) return;\n\n this.#structuredLog(console.warn, message, \"warn\", ...args);\n }\n\n info(message: string, ...args: StructuredArgs) {\n if (this.level < LogLevel.info) return;\n\n this.#structuredLog(console.info, message, \"info\", ...args);\n }\n\n debug(message: string, ...args: StructuredArgs) {\n if (this.level < LogLevel.debug) return;\n\n this.#structuredLog(console.debug, message, \"debug\", ...args);\n }\n\n #structuredLog(\n loggerFunction: (message: string, ...args: any[]) => void,\n message: string,\n level: string,\n ...args: StructuredArgs\n ) {\n const structuredLog = {\n ...(args.length === 1 ? args[0] : args),\n ...this.fields,\n timestamp: new Date(),\n name: this.name,\n message,\n level,\n };\n\n loggerFunction(JSON.stringify(structuredLog));\n }\n}\n","import type { DisconnectReason, Namespace, Server, Socket } from \"socket.io\";\nimport { ZodMessageSender } from \"./zodMessageHandler\";\nimport {\n ZodMessageCatalogToSocketIoEvents,\n ZodSocketMessageCatalogSchema,\n ZodSocketMessageHandler,\n ZodSocketMessageHandlers,\n} from \"./zodSocket\";\nimport type { DefaultEventsMap, EventsMap } from \"socket.io/dist/typed-events\";\nimport { z } from \"zod\";\nimport { SimpleStructuredLogger, StructuredLogger } from \"./utils/structuredLogger\";\n\ninterface ExtendedError extends Error {\n data?: any;\n}\n\nexport type ZodNamespaceSocket<\n TClientMessages extends ZodSocketMessageCatalogSchema,\n TServerMessages extends ZodSocketMessageCatalogSchema,\n TServerSideEvents extends EventsMap = DefaultEventsMap,\n TSocketData extends z.ZodObject<any, any, any> = any,\n> = Socket<\n ZodMessageCatalogToSocketIoEvents<TClientMessages>,\n ZodMessageCatalogToSocketIoEvents<TServerMessages>,\n TServerSideEvents,\n z.infer<TSocketData>\n>;\n\ninterface ZodNamespaceOptions<\n TClientMessages extends ZodSocketMessageCatalogSchema,\n TServerMessages extends ZodSocketMessageCatalogSchema,\n TServerSideEvents extends EventsMap = DefaultEventsMap,\n TSocketData extends z.ZodObject<any, any, any> = any,\n> {\n io: Server;\n name: string;\n clientMessages: TClientMessages;\n serverMessages: TServerMessages;\n socketData?: TSocketData;\n handlers?: ZodSocketMessageHandlers<TClientMessages>;\n authToken?: string;\n logger?: StructuredLogger;\n preAuth?: (\n socket: ZodNamespaceSocket<TClientMessages, TServerMessages, TServerSideEvents, TSocketData>,\n next: (err?: ExtendedError) => void,\n logger: StructuredLogger\n ) => Promise<void>;\n postAuth?: (\n socket: ZodNamespaceSocket<TClientMessages, TServerMessages, TServerSideEvents, TSocketData>,\n next: (err?: ExtendedError) => void,\n logger: StructuredLogger\n ) => Promise<void>;\n onConnection?: (\n socket: ZodNamespaceSocket<TClientMessages, TServerMessages, TServerSideEvents, TSocketData>,\n handler: ZodSocketMessageHandler<TClientMessages>,\n sender: ZodMessageSender<TServerMessages>,\n logger: StructuredLogger\n ) => Promise<void>;\n onDisconnect?: (\n socket: ZodNamespaceSocket<TClientMessages, TServerMessages, TServerSideEvents, TSocketData>,\n reason: DisconnectReason,\n description: any,\n logger: StructuredLogger\n ) => Promise<void>;\n onError?: (\n socket: ZodNamespaceSocket<TClientMessages, TServerMessages, TServerSideEvents, TSocketData>,\n err: Error,\n logger: StructuredLogger\n ) => Promise<void>;\n}\n\nexport class ZodNamespace<\n TClientMessages extends ZodSocketMessageCatalogSchema,\n TServerMessages extends ZodSocketMessageCatalogSchema,\n TSocketData extends z.ZodObject<any, any, any> = any,\n TServerSideEvents extends EventsMap = DefaultEventsMap,\n> {\n #logger: StructuredLogger;\n #handler: ZodSocketMessageHandler<TClientMessages>;\n sender: ZodMessageSender<TServerMessages>;\n\n io: Server;\n namespace: Namespace<\n ZodMessageCatalogToSocketIoEvents<TClientMessages>,\n ZodMessageCatalogToSocketIoEvents<TServerMessages>,\n TServerSideEvents,\n z.infer<TSocketData>\n >;\n\n constructor(\n opts: ZodNamespaceOptions<TClientMessages, TServerMessages, TServerSideEvents, TSocketData>\n ) {\n this.#logger = opts.logger ?? new SimpleStructuredLogger(opts.name);\n\n this.#handler = new ZodSocketMessageHandler({\n schema: opts.clientMessages,\n handlers: opts.handlers,\n });\n\n this.io = opts.io;\n\n this.namespace = this.io.of(opts.name);\n\n // FIXME: There's a bug here, this sender should not accept Socket schemas with callbacks\n this.sender = new ZodMessageSender({\n schema: opts.serverMessages,\n sender: async (message) => {\n return new Promise((resolve, reject) => {\n try {\n // @ts-expect-error\n this.namespace.emit(message.type, message.payload);\n resolve();\n } catch (err) {\n reject(err);\n }\n });\n },\n });\n\n if (opts.preAuth) {\n this.namespace.use(async (socket, next) => {\n const logger = this.#logger.child({ socketId: socket.id, socketStage: \"preAuth\" });\n\n if (typeof opts.preAuth === \"function\") {\n await opts.preAuth(socket, next, logger);\n }\n });\n }\n\n if (opts.authToken) {\n this.namespace.use((socket, next) => {\n const logger = this.#logger.child({ socketId: socket.id, socketStage: \"auth\" });\n\n const { auth } = socket.handshake;\n\n if (!(\"token\" in auth)) {\n logger.error(\"no token\");\n return socket.disconnect(true);\n }\n\n if (auth.token !== opts.authToken) {\n logger.error(\"invalid token\");\n return socket.disconnect(true);\n }\n\n logger.info(\"success\");\n\n next();\n });\n }\n\n if (opts.postAuth) {\n this.namespace.use(async (socket, next) => {\n const logger = this.#logger.child({ socketId: socket.id, socketStage: \"auth\" });\n\n if (typeof opts.postAuth === \"function\") {\n await opts.postAuth(socket, next, logger);\n }\n });\n }\n\n this.namespace.on(\"connection\", async (socket) => {\n const logger = this.#logger.child({ socketId: socket.id, socketStage: \"connection\" });\n logger.info(\"connected\");\n\n this.#handler.registerHandlers(socket, logger);\n\n socket.on(\"disconnect\", async (reason, description) => {\n logger.info(\"disconnect\", { reason, description });\n\n if (opts.onDisconnect) {\n await opts.onDisconnect(socket, reason, description, logger);\n }\n });\n\n socket.on(\"error\", async (error) => {\n logger.error(\"error\", { error });\n\n if (opts.onError) {\n await opts.onError(socket, error, logger);\n }\n });\n\n if (opts.onConnection) {\n await opts.onConnection(socket, this.#handler, this.sender, logger);\n }\n });\n }\n\n fetchSockets() {\n return this.namespace.fetchSockets();\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/v3/zodMessageHandler.ts","../../src/v3/zodSocket.ts","../../src/v3/utils/structuredLogger.ts","../../src/v3/zodNamespace.ts"],"names":["z","ZodSchemaParsedError","Error","constructor","error","payload","message","ZodMessageSchema","object","version","literal","default","type","string","unknown","ZodMessageSender","options","schema","sender","send","parsedPayload","safeParse","success","console","forwardMessage","parsedMessage","JSON","stringify","data","io","LogLevel","SimpleStructuredLogger","name","level","includes","process","env","DEBUG","debug","info","fields","child","log","args","warn","loggerFunction","structuredLog","length","timestamp","Date","fromZodError","messageSchema","_schema","ZodSocketMessageHandler","handlers","logger","handleMessage","parseResult","parseMessage","rawMessage","reason","handler","String","ack","toString","messageWithVersion","registerHandlers","emitter","eventName","Object","keys","on","callback","hasCallback","stack","_logger","ZodNamespace","opts","clientMessages","namespace","of","serverMessages","Promise","resolve","reject","emit","err","preAuth","use","socket","next","socketId","id","socketStage","authToken","auth","handshake","disconnect","token","postAuth","description","onDisconnect","onError","onConnection","fetchSockets"],"mappings":"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","sourcesContent":["import { z } from \"zod\";\nimport { StructuredLogger } from \"./utils/structuredLogger\";\n\nexport class ZodSchemaParsedError extends Error {\n constructor(\n public error: z.ZodError,\n public payload: unknown\n ) {\n super(error.message);\n }\n}\n\nexport type ZodMessageValueSchema<TDiscriminatedUnion extends z.ZodDiscriminatedUnion<any, any>> =\n | z.ZodFirstPartySchemaTypes\n | TDiscriminatedUnion;\n\nexport interface ZodMessageCatalogSchema {\n [key: string]: ZodMessageValueSchema<any>;\n}\n\nexport type ZodMessageHandlers<TCatalogSchema extends ZodMessageCatalogSchema> = Partial<{\n [K in keyof TCatalogSchema]: (payload: z.infer<TCatalogSchema[K]>) => Promise<any>;\n}>;\n\nexport type ZodMessageHandlerOptions<TMessageCatalog extends ZodMessageCatalogSchema> = {\n schema: TMessageCatalog;\n messages?: ZodMessageHandlers<TMessageCatalog>;\n logger?: StructuredLogger;\n};\n\nexport type MessageFromSchema<\n K extends keyof TMessageCatalog,\n TMessageCatalog extends ZodMessageCatalogSchema,\n> = {\n type: K;\n payload: z.input<TMessageCatalog[K]>;\n};\n\nexport type MessageFromCatalog<TMessageCatalog extends ZodMessageCatalogSchema> = {\n [K in keyof TMessageCatalog]: MessageFromSchema<K, TMessageCatalog>;\n}[keyof TMessageCatalog];\n\nexport const ZodMessageSchema = z.object({\n version: z.literal(\"v1\").default(\"v1\"),\n type: z.string(),\n payload: z.unknown(),\n});\n\nexport interface EventEmitterLike {\n on(eventName: string | symbol, listener: (...args: any[]) => void): this;\n}\n\nexport class ZodMessageHandler<TMessageCatalog extends ZodMessageCatalogSchema> {\n #schema: TMessageCatalog;\n #handlers: ZodMessageHandlers<TMessageCatalog> | undefined;\n #logger: StructuredLogger | Console;\n\n constructor(options: ZodMessageHandlerOptions<TMessageCatalog>) {\n this.#schema = options.schema;\n this.#handlers = options.messages;\n this.#logger = options.logger ?? console;\n }\n\n public async handleMessage(message: unknown): Promise<\n | {\n success: true;\n data: unknown;\n }\n | {\n success: false;\n error: string;\n }\n > {\n const parsedMessage = this.parseMessage(message);\n\n if (!parsedMessage.success) {\n this.#logger.error(parsedMessage.error, { message });\n\n return {\n success: false,\n error: parsedMessage.error,\n };\n }\n\n if (!this.#handlers) {\n this.#logger.error(\"No handlers provided\", { message });\n\n return {\n success: false,\n error: \"No handlers provided\",\n };\n }\n\n const handler = this.#handlers[parsedMessage.data.type];\n\n if (!handler) {\n const error = `No handler for message type: ${String(parsedMessage.data.type)}`;\n\n this.#logger.error(error, { message });\n\n return {\n success: false,\n error,\n };\n }\n\n const ack = await handler(parsedMessage.data.payload);\n\n return {\n success: true,\n data: ack,\n };\n }\n\n public parseMessage(message: unknown):\n | {\n success: true;\n data: MessageFromCatalog<TMessageCatalog>;\n }\n | {\n success: false;\n error: string;\n } {\n const parsedMessage = ZodMessageSchema.safeParse(message);\n\n if (!parsedMessage.success) {\n return {\n success: false,\n error: `Failed to parse message: ${JSON.stringify(parsedMessage.error)}`,\n };\n }\n\n const schema = this.#schema[parsedMessage.data.type];\n\n if (!schema) {\n return {\n success: false,\n error: `Unknown message type: ${parsedMessage.data.type}`,\n };\n }\n\n const parsedPayload = schema.safeParse(parsedMessage.data.payload);\n\n if (!parsedPayload.success) {\n return {\n success: false,\n error: `Failed to parse message payload: ${JSON.stringify(parsedPayload.error)}`,\n };\n }\n\n return {\n success: true,\n data: {\n type: parsedMessage.data.type,\n payload: parsedPayload.data,\n },\n };\n }\n\n public registerHandlers(emitter: EventEmitterLike, logger?: StructuredLogger) {\n const log = logger ?? console;\n\n if (!this.#handlers) {\n log.info(\"No handlers provided\");\n return;\n }\n\n for (const eventName of Object.keys(this.#schema)) {\n emitter.on(eventName, async (message: any, callback?: any): Promise<void> => {\n log.info(`handling ${eventName}`, {\n payload: message,\n hasCallback: !!callback,\n });\n\n let ack: Awaited<ReturnType<ZodMessageHandler<TMessageCatalog>[\"handleMessage\"]>>;\n\n // FIXME: this only works if the message doesn't have genuine payload prop\n if (\"payload\" in message) {\n ack = await this.handleMessage({ type: eventName, ...message });\n } else {\n // Handle messages not sent by ZodMessageSender\n const { version, ...payload } = message;\n ack = await this.handleMessage({ type: eventName, version, payload });\n }\n\n if (callback && typeof callback === \"function\") {\n if (!ack.success) {\n // We don't know the callback type, so we can't do anything else - not all callbacks may accept a success prop\n log.error(\"Failed to handle message, skipping callback\", { message, error: ack.error });\n return;\n }\n\n callback(ack.data);\n }\n });\n }\n }\n}\n\ntype ZodMessageSenderCallback<TMessageCatalog extends ZodMessageCatalogSchema> = (message: {\n type: keyof TMessageCatalog;\n payload: z.infer<TMessageCatalog[keyof TMessageCatalog]>;\n version: \"v1\";\n}) => Promise<void>;\n\nexport type ZodMessageSenderOptions<TMessageCatalog extends ZodMessageCatalogSchema> = {\n schema: TMessageCatalog;\n sender: ZodMessageSenderCallback<TMessageCatalog>;\n};\n\nexport class ZodMessageSender<TMessageCatalog extends ZodMessageCatalogSchema> {\n #schema: TMessageCatalog;\n #sender: ZodMessageSenderCallback<TMessageCatalog>;\n\n constructor(options: ZodMessageSenderOptions<TMessageCatalog>) {\n this.#schema = options.schema;\n this.#sender = options.sender;\n }\n\n public async send<K extends keyof TMessageCatalog>(\n type: K,\n payload: z.input<TMessageCatalog[K]>\n ) {\n const schema = this.#schema[type];\n\n if (!schema) {\n throw new Error(`Unknown message type: ${type as string}`);\n }\n\n const parsedPayload = schema.safeParse(payload);\n\n if (!parsedPayload.success) {\n throw new ZodSchemaParsedError(parsedPayload.error, payload);\n }\n\n try {\n await this.#sender({ type, payload, version: \"v1\" });\n } catch (error) {\n console.error(\"[ZodMessageSender] Failed to send message\", error);\n }\n }\n\n public async forwardMessage(message: unknown) {\n const parsedMessage = ZodMessageSchema.safeParse(message);\n\n if (!parsedMessage.success) {\n throw new Error(`Failed to parse message: ${JSON.stringify(parsedMessage.error)}`);\n }\n\n const schema = this.#schema[parsedMessage.data.type];\n\n if (!schema) {\n throw new Error(`Unknown message type: ${parsedMessage.data.type}`);\n }\n\n const parsedPayload = schema.safeParse(parsedMessage.data.payload);\n\n if (!parsedPayload.success) {\n throw new Error(`Failed to parse message payload: ${JSON.stringify(parsedPayload.error)}`);\n }\n\n try {\n await this.#sender({\n type: parsedMessage.data.type,\n payload: parsedPayload.data,\n version: \"v1\",\n });\n } catch (error) {\n console.error(\"[ZodMessageSender] Failed to forward message\", error);\n }\n }\n}\n\nexport type MessageCatalogToSocketIoEvents<TCatalog extends ZodMessageCatalogSchema> = {\n [K in keyof TCatalog]: (message: z.infer<TCatalog[K]>) => void;\n};\n","import type { ManagerOptions, Socket, SocketOptions } from \"socket.io-client\";\nimport { io } from \"socket.io-client\";\nimport { ZodError, z } from \"zod\";\nimport { EventEmitterLike, ZodMessageValueSchema } from \"./zodMessageHandler\";\nimport { LogLevel, SimpleStructuredLogger, StructuredLogger } from \"./utils/structuredLogger\";\nimport { fromZodError } from \"zod-validation-error\";\n\nexport interface ZodSocketMessageCatalogSchema {\n [key: string]:\n | {\n message: ZodMessageValueSchema<any>;\n }\n | {\n message: ZodMessageValueSchema<any>;\n callback?: ZodMessageValueSchema<any>;\n };\n}\n\nexport type ZodMessageCatalogToSocketIoEvents<TCatalog extends ZodSocketMessageCatalogSchema> = {\n [K in keyof TCatalog]: SocketMessageHasCallback<TCatalog, K> extends true\n ? (\n message: z.infer<GetSocketMessageSchema<TCatalog, K>>,\n callback: (ack: z.infer<GetSocketCallbackSchema<TCatalog, K>>) => void\n ) => void\n : (message: z.infer<GetSocketMessageSchema<TCatalog, K>>) => void;\n};\n\nexport type GetSocketMessageSchema<\n TRPCCatalog extends ZodSocketMessageCatalogSchema,\n TMessageType extends keyof TRPCCatalog,\n> = TRPCCatalog[TMessageType][\"message\"];\n\nexport type InferSocketMessageSchema<\n TRPCCatalog extends ZodSocketMessageCatalogSchema,\n TMessageType extends keyof TRPCCatalog,\n> = z.infer<GetSocketMessageSchema<TRPCCatalog, TMessageType>>;\n\nexport type GetSocketCallbackSchema<\n TRPCCatalog extends ZodSocketMessageCatalogSchema,\n TMessageType extends keyof TRPCCatalog,\n> = TRPCCatalog[TMessageType] extends { callback: any }\n ? TRPCCatalog[TMessageType][\"callback\"]\n : never;\n\nexport type InferSocketCallbackSchema<\n TRPCCatalog extends ZodSocketMessageCatalogSchema,\n TMessageType extends keyof TRPCCatalog,\n> = z.infer<GetSocketCallbackSchema<TRPCCatalog, TMessageType>>;\n\nexport type SocketMessageHasCallback<\n TRPCCatalog extends ZodSocketMessageCatalogSchema,\n TMessageType extends keyof TRPCCatalog,\n> = GetSocketCallbackSchema<TRPCCatalog, TMessageType> extends never ? false : true;\n\nexport type ZodSocketMessageHandlers<TCatalogSchema extends ZodSocketMessageCatalogSchema> =\n Partial<{\n [K in keyof TCatalogSchema]: (\n payload: z.infer<GetSocketMessageSchema<TCatalogSchema, K>>\n ) => Promise<\n SocketMessageHasCallback<TCatalogSchema, K> extends true\n ? z.input<GetSocketCallbackSchema<TCatalogSchema, K>>\n : void\n >;\n }>;\n\nexport type ZodSocketMessageHandlerOptions<TMessageCatalog extends ZodSocketMessageCatalogSchema> =\n {\n schema: TMessageCatalog;\n handlers?: ZodSocketMessageHandlers<TMessageCatalog>;\n logger?: StructuredLogger;\n };\n\ntype MessageFromSocketSchema<\n K extends keyof TMessageCatalog,\n TMessageCatalog extends ZodSocketMessageCatalogSchema,\n> = {\n type: K;\n payload: z.input<GetSocketMessageSchema<TMessageCatalog, K>>;\n};\n\nexport type MessagesFromSocketCatalog<TMessageCatalog extends ZodSocketMessageCatalogSchema> = {\n [K in keyof TMessageCatalog]: MessageFromSocketSchema<K, TMessageCatalog>;\n}[keyof TMessageCatalog];\n\nconst messageSchema = z.object({\n version: z.string(),\n type: z.string(),\n payload: z.unknown(),\n});\n\nexport class ZodSocketMessageHandler<TRPCCatalog extends ZodSocketMessageCatalogSchema> {\n #schema: TRPCCatalog;\n #handlers: ZodSocketMessageHandlers<TRPCCatalog> | undefined;\n #logger: StructuredLogger;\n\n constructor(options: ZodSocketMessageHandlerOptions<TRPCCatalog>) {\n this.#schema = options.schema;\n this.#handlers = options.handlers;\n this.#logger =\n options.logger ?? new SimpleStructuredLogger(\"socket-message-handler\", LogLevel.info);\n }\n\n public async handleMessage(message: unknown) {\n const parseResult = this.parseMessage(message);\n\n if (!parseResult.success) {\n this.#logger.error(\"Failed to parse message, skipping handler\", {\n rawMessage: message,\n error: parseResult.reason,\n });\n return;\n }\n\n if (!this.#handlers) {\n throw new Error(\"No handlers provided\");\n }\n\n const { type, payload } = parseResult.data;\n\n const handler = this.#handlers[type];\n\n if (!handler) {\n console.error(`No handler for message type: ${String(type)}`);\n return;\n }\n\n const ack = await handler(payload);\n\n return ack;\n }\n\n private parseMessage(message: unknown):\n | {\n success: true;\n data: MessagesFromSocketCatalog<TRPCCatalog>;\n }\n | {\n success: false;\n reason?: string;\n } {\n const parsedMessage = messageSchema.safeParse(message);\n\n if (!parsedMessage.success) {\n return {\n success: false,\n reason: `Failed to parse message: ${fromZodError(parsedMessage.error).toString()}`,\n };\n }\n\n const schema = this.#schema[parsedMessage.data.type][\"message\"];\n\n if (!schema) {\n return {\n success: false,\n reason: `Unknown message type: ${parsedMessage.data.type}`,\n };\n }\n\n const messageWithVersion = {\n version: parsedMessage.data.version,\n ...(typeof parsedMessage.data.payload === \"object\" ? parsedMessage.data.payload : {}),\n };\n\n const parsedPayload = schema.safeParse(messageWithVersion);\n\n if (!parsedPayload.success) {\n console.error(\"Failed to parse message payload\", {\n message,\n payload: messageWithVersion,\n });\n\n return {\n success: false,\n reason: fromZodError(parsedPayload.error).toString(),\n };\n }\n\n return {\n success: true,\n data: {\n type: parsedMessage.data.type,\n payload: parsedPayload.data,\n },\n };\n }\n\n public registerHandlers(emitter: EventEmitterLike, logger?: StructuredLogger) {\n const log = logger ?? console;\n\n if (!this.#handlers) {\n log.info(\"No handlers provided\");\n return;\n }\n\n for (const eventName of Object.keys(this.#handlers)) {\n emitter.on(eventName, async (message: any, callback?: any): Promise<void> => {\n log.info(`handling ${eventName}`, {\n payload: message,\n hasCallback: !!callback,\n });\n\n let ack;\n\n try {\n // FIXME: this only works if the message doesn't have genuine payload prop\n if (\"payload\" in message) {\n ack = await this.handleMessage({ type: eventName, ...message });\n } else {\n // Handle messages not sent by ZodMessageSender\n const { version, ...payload } = message;\n ack = await this.handleMessage({ type: eventName, version, payload });\n }\n } catch (error) {\n log.error(\"Error while handling message\", {\n error:\n error instanceof Error\n ? {\n message: error.message,\n stack: error.stack,\n }\n : error,\n });\n return;\n }\n\n if (callback && typeof callback === \"function\") {\n callback(ack);\n }\n });\n }\n }\n}\n\nexport type ZodSocketMessageSenderOptions<TMessageCatalog extends ZodSocketMessageCatalogSchema> = {\n schema: TMessageCatalog;\n socket: ZodSocket<any, TMessageCatalog>;\n logger?: StructuredLogger;\n};\n\nexport type GetSocketMessagesWithCallback<TMessageCatalog extends ZodSocketMessageCatalogSchema> = {\n [K in keyof TMessageCatalog]: SocketMessageHasCallback<TMessageCatalog, K> extends true\n ? K\n : never;\n}[keyof TMessageCatalog];\n\nexport type GetSocketMessagesWithoutCallback<\n TMessageCatalog extends ZodSocketMessageCatalogSchema,\n> = {\n [K in keyof TMessageCatalog]: SocketMessageHasCallback<TMessageCatalog, K> extends true\n ? never\n : K;\n}[keyof TMessageCatalog];\n\nexport class ZodSocketMessageSender<TMessageCatalog extends ZodSocketMessageCatalogSchema> {\n #schema: TMessageCatalog;\n #socket: ZodSocket<any, TMessageCatalog>;\n #logger: StructuredLogger;\n\n constructor(options: ZodSocketMessageSenderOptions<TMessageCatalog>) {\n this.#schema = options.schema;\n this.#socket = options.socket;\n this.#logger = options.logger ?? new SimpleStructuredLogger(\"zod-socket-sender\", LogLevel.info);\n }\n\n public send<K extends GetSocketMessagesWithoutCallback<TMessageCatalog>>(\n type: K,\n payload: z.input<GetSocketMessageSchema<TMessageCatalog, K>>\n ): void {\n const schema = this.#schema[type][\"message\"];\n\n if (!schema) {\n throw new Error(`Unknown message type: ${type as string}`);\n }\n\n const parsedPayload = schema.safeParse(payload);\n\n if (!parsedPayload.success) {\n this.#logger.error(\"Failed to parse message payload, will not send\", {\n error: parsedPayload.error,\n });\n return;\n }\n\n // @ts-expect-error\n this.#socket.emit(type, { payload, version: \"v1\" });\n\n return;\n }\n\n public async sendWithAck<K extends GetSocketMessagesWithCallback<TMessageCatalog>>(\n type: K,\n payload: z.input<GetSocketMessageSchema<TMessageCatalog, K>>\n ): Promise<z.infer<GetSocketCallbackSchema<TMessageCatalog, K>>> {\n const schema = this.#schema[type][\"message\"];\n\n if (!schema) {\n throw new Error(`Unknown message type: ${type as string}`);\n }\n\n const parsedPayload = schema.safeParse(payload);\n\n if (!parsedPayload.success) {\n throw new Error(`Failed to parse message payload: ${JSON.stringify(parsedPayload.error)}`);\n }\n\n // @ts-expect-error\n const callbackResult = await this.#socket.emitWithAck(type, { payload, version: \"v1\" });\n\n return callbackResult;\n }\n}\n\nexport type ZodSocket<\n TListenEvents extends ZodSocketMessageCatalogSchema,\n TEmitEvents extends ZodSocketMessageCatalogSchema,\n> = Omit<\n Socket<\n ZodMessageCatalogToSocketIoEvents<TListenEvents>,\n ZodMessageCatalogToSocketIoEvents<TEmitEvents>\n >,\n \"timeout\"\n> & {\n timeout: (\n timeout: number\n ) => Socket<\n ZodMessageCatalogToSocketIoEvents<TListenEvents>,\n ZodMessageCatalogToSocketIoEvents<TEmitEvents>\n >;\n};\n\ninterface ZodSocketConnectionOptions<\n TClientMessages extends ZodSocketMessageCatalogSchema,\n TServerMessages extends ZodSocketMessageCatalogSchema,\n> {\n host: string;\n port?: number;\n secure?: boolean;\n namespace: string;\n clientMessages: TClientMessages;\n serverMessages: TServerMessages;\n extraHeaders?: {\n [header: string]: string;\n };\n handlers?: ZodSocketMessageHandlers<TServerMessages>;\n authToken?: string;\n ioOptions?: Partial<ManagerOptions & SocketOptions>;\n onConnection?: (\n socket: ZodSocket<TServerMessages, TClientMessages>,\n handler: ZodSocketMessageHandler<TServerMessages>,\n sender: ZodSocketMessageSender<TClientMessages>,\n logger: StructuredLogger\n ) => Promise<void>;\n onDisconnect?: (\n socket: ZodSocket<TServerMessages, TClientMessages>,\n reason: Socket.DisconnectReason,\n description: any,\n logger: StructuredLogger\n ) => Promise<void>;\n onError?: (\n socket: ZodSocket<TServerMessages, TClientMessages>,\n err: Error,\n logger: StructuredLogger\n ) => Promise<void>;\n}\n\nexport class ZodSocketConnection<\n TClientMessages extends ZodSocketMessageCatalogSchema,\n TServerMessages extends ZodSocketMessageCatalogSchema,\n> {\n #sender: ZodSocketMessageSender<TClientMessages>;\n socket: ZodSocket<TServerMessages, TClientMessages>;\n\n #handler: ZodSocketMessageHandler<TServerMessages>;\n #logger: StructuredLogger;\n\n constructor(opts: ZodSocketConnectionOptions<TClientMessages, TServerMessages>) {\n const uri = `${opts.secure ? \"wss\" : \"ws\"}://${opts.host}:${\n opts.port ?? (opts.secure ? \"443\" : \"80\")\n }/${opts.namespace}`;\n\n const logger = new SimpleStructuredLogger(opts.namespace, LogLevel.info);\n logger.log(\"new zod socket\", { uri });\n\n this.socket = io(uri, {\n transports: [\"websocket\"],\n auth: {\n token: opts.authToken,\n },\n extraHeaders: opts.extraHeaders,\n reconnectionDelay: 500,\n reconnectionDelayMax: 1000,\n ...opts.ioOptions,\n });\n\n this.#logger = logger.child({\n socketId: this.socket.id,\n });\n\n this.#handler = new ZodSocketMessageHandler({\n schema: opts.serverMessages,\n handlers: opts.handlers,\n });\n this.#handler.registerHandlers(this.socket, this.#logger);\n\n this.#sender = new ZodSocketMessageSender({\n schema: opts.clientMessages,\n socket: this.socket,\n logger: this.#logger,\n });\n\n this.socket.on(\"connect_error\", async (error) => {\n this.#logger.error(`connect_error: ${error}`);\n\n if (opts.onError) {\n await opts.onError(this.socket, error, this.#logger);\n }\n });\n\n this.socket.on(\"connect\", async () => {\n this.#logger.info(\"connect\");\n\n if (opts.onConnection) {\n await opts.onConnection(this.socket, this.#handler, this.#sender, this.#logger);\n }\n });\n\n this.socket.on(\"disconnect\", async (reason, description) => {\n this.#logger.info(\"disconnect\", { reason, description });\n\n if (opts.onDisconnect) {\n await opts.onDisconnect(this.socket, reason, description, this.#logger);\n }\n });\n }\n\n close() {\n this.socket.close();\n }\n\n connect() {\n this.socket.connect();\n }\n\n get send() {\n return this.#sender.send.bind(this.#sender);\n }\n\n get sendWithAck() {\n return this.#sender.sendWithAck.bind(this.#sender);\n }\n}\n","type StructuredArgs = (Record<string, unknown> | undefined)[];\n\nexport interface StructuredLogger {\n log: (message: string, ...args: StructuredArgs) => any;\n error: (message: string, ...args: StructuredArgs) => any;\n warn: (message: string, ...args: StructuredArgs) => any;\n info: (message: string, ...args: StructuredArgs) => any;\n debug: (message: string, ...args: StructuredArgs) => any;\n child: (fields: Record<string, unknown>) => StructuredLogger;\n}\n\nexport enum LogLevel {\n \"log\",\n \"error\",\n \"warn\",\n \"info\",\n \"debug\",\n}\n\nexport class SimpleStructuredLogger implements StructuredLogger {\n constructor(\n private name: string,\n private level: LogLevel = [\"1\", \"true\"].includes(process.env.DEBUG ?? \"\")\n ? LogLevel.debug\n : LogLevel.info,\n private fields?: Record<string, unknown>\n ) {}\n\n child(fields: Record<string, unknown>, level?: LogLevel) {\n return new SimpleStructuredLogger(this.name, level, { ...this.fields, ...fields });\n }\n\n log(message: string, ...args: StructuredArgs) {\n if (this.level < LogLevel.log) return;\n\n this.#structuredLog(console.log, message, \"log\", ...args);\n }\n\n error(message: string, ...args: StructuredArgs) {\n if (this.level < LogLevel.error) return;\n\n this.#structuredLog(console.error, message, \"error\", ...args);\n }\n\n warn(message: string, ...args: StructuredArgs) {\n if (this.level < LogLevel.warn) return;\n\n this.#structuredLog(console.warn, message, \"warn\", ...args);\n }\n\n info(message: string, ...args: StructuredArgs) {\n if (this.level < LogLevel.info) return;\n\n this.#structuredLog(console.info, message, \"info\", ...args);\n }\n\n debug(message: string, ...args: StructuredArgs) {\n if (this.level < LogLevel.debug) return;\n\n this.#structuredLog(console.debug, message, \"debug\", ...args);\n }\n\n #structuredLog(\n loggerFunction: (message: string, ...args: any[]) => void,\n message: string,\n level: string,\n ...args: StructuredArgs\n ) {\n const structuredLog = {\n ...(args.length === 1 ? args[0] : args),\n ...this.fields,\n timestamp: new Date(),\n name: this.name,\n message,\n level,\n };\n\n loggerFunction(JSON.stringify(structuredLog));\n }\n}\n","import type { DisconnectReason, Namespace, Server, Socket } from \"socket.io\";\nimport { ZodMessageSender } from \"./zodMessageHandler\";\nimport {\n ZodMessageCatalogToSocketIoEvents,\n ZodSocketMessageCatalogSchema,\n ZodSocketMessageHandler,\n ZodSocketMessageHandlers,\n} from \"./zodSocket\";\nimport type { DefaultEventsMap, EventsMap } from \"socket.io/dist/typed-events\";\nimport { z } from \"zod\";\nimport { SimpleStructuredLogger, StructuredLogger } from \"./utils/structuredLogger\";\n\ninterface ExtendedError extends Error {\n data?: any;\n}\n\nexport type ZodNamespaceSocket<\n TClientMessages extends ZodSocketMessageCatalogSchema,\n TServerMessages extends ZodSocketMessageCatalogSchema,\n TServerSideEvents extends EventsMap = DefaultEventsMap,\n TSocketData extends z.ZodObject<any, any, any> = any,\n> = Socket<\n ZodMessageCatalogToSocketIoEvents<TClientMessages>,\n ZodMessageCatalogToSocketIoEvents<TServerMessages>,\n TServerSideEvents,\n z.infer<TSocketData>\n>;\n\ninterface ZodNamespaceOptions<\n TClientMessages extends ZodSocketMessageCatalogSchema,\n TServerMessages extends ZodSocketMessageCatalogSchema,\n TServerSideEvents extends EventsMap = DefaultEventsMap,\n TSocketData extends z.ZodObject<any, any, any> = any,\n> {\n io: Server;\n name: string;\n clientMessages: TClientMessages;\n serverMessages: TServerMessages;\n socketData?: TSocketData;\n handlers?: ZodSocketMessageHandlers<TClientMessages>;\n authToken?: string;\n logger?: StructuredLogger;\n preAuth?: (\n socket: ZodNamespaceSocket<TClientMessages, TServerMessages, TServerSideEvents, TSocketData>,\n next: (err?: ExtendedError) => void,\n logger: StructuredLogger\n ) => Promise<void>;\n postAuth?: (\n socket: ZodNamespaceSocket<TClientMessages, TServerMessages, TServerSideEvents, TSocketData>,\n next: (err?: ExtendedError) => void,\n logger: StructuredLogger\n ) => Promise<void>;\n onConnection?: (\n socket: ZodNamespaceSocket<TClientMessages, TServerMessages, TServerSideEvents, TSocketData>,\n handler: ZodSocketMessageHandler<TClientMessages>,\n sender: ZodMessageSender<TServerMessages>,\n logger: StructuredLogger\n ) => Promise<void>;\n onDisconnect?: (\n socket: ZodNamespaceSocket<TClientMessages, TServerMessages, TServerSideEvents, TSocketData>,\n reason: DisconnectReason,\n description: any,\n logger: StructuredLogger\n ) => Promise<void>;\n onError?: (\n socket: ZodNamespaceSocket<TClientMessages, TServerMessages, TServerSideEvents, TSocketData>,\n err: Error,\n logger: StructuredLogger\n ) => Promise<void>;\n}\n\nexport class ZodNamespace<\n TClientMessages extends ZodSocketMessageCatalogSchema,\n TServerMessages extends ZodSocketMessageCatalogSchema,\n TSocketData extends z.ZodObject<any, any, any> = any,\n TServerSideEvents extends EventsMap = DefaultEventsMap,\n> {\n #logger: StructuredLogger;\n #handler: ZodSocketMessageHandler<TClientMessages>;\n sender: ZodMessageSender<TServerMessages>;\n\n io: Server;\n namespace: Namespace<\n ZodMessageCatalogToSocketIoEvents<TClientMessages>,\n ZodMessageCatalogToSocketIoEvents<TServerMessages>,\n TServerSideEvents,\n z.infer<TSocketData>\n >;\n\n constructor(\n opts: ZodNamespaceOptions<TClientMessages, TServerMessages, TServerSideEvents, TSocketData>\n ) {\n this.#logger = opts.logger ?? new SimpleStructuredLogger(opts.name);\n\n this.#handler = new ZodSocketMessageHandler({\n schema: opts.clientMessages,\n handlers: opts.handlers,\n });\n\n this.io = opts.io;\n\n this.namespace = this.io.of(opts.name);\n\n // FIXME: There's a bug here, this sender should not accept Socket schemas with callbacks\n this.sender = new ZodMessageSender({\n schema: opts.serverMessages,\n sender: async (message) => {\n return new Promise((resolve, reject) => {\n try {\n // @ts-expect-error\n this.namespace.emit(message.type, message.payload);\n resolve();\n } catch (err) {\n reject(err);\n }\n });\n },\n });\n\n if (opts.preAuth) {\n this.namespace.use(async (socket, next) => {\n const logger = this.#logger.child({ socketId: socket.id, socketStage: \"preAuth\" });\n\n if (typeof opts.preAuth === \"function\") {\n await opts.preAuth(socket, next, logger);\n }\n });\n }\n\n if (opts.authToken) {\n this.namespace.use((socket, next) => {\n const logger = this.#logger.child({ socketId: socket.id, socketStage: \"auth\" });\n\n const { auth } = socket.handshake;\n\n if (!(\"token\" in auth)) {\n logger.error(\"no token\");\n return socket.disconnect(true);\n }\n\n if (auth.token !== opts.authToken) {\n logger.error(\"invalid token\");\n return socket.disconnect(true);\n }\n\n logger.info(\"success\");\n\n next();\n });\n }\n\n if (opts.postAuth) {\n this.namespace.use(async (socket, next) => {\n const logger = this.#logger.child({ socketId: socket.id, socketStage: \"auth\" });\n\n if (typeof opts.postAuth === \"function\") {\n await opts.postAuth(socket, next, logger);\n }\n });\n }\n\n this.namespace.on(\"connection\", async (socket) => {\n const logger = this.#logger.child({ socketId: socket.id, socketStage: \"connection\" });\n logger.info(\"connected\");\n\n this.#handler.registerHandlers(socket, logger);\n\n socket.on(\"disconnect\", async (reason, description) => {\n logger.info(\"disconnect\", { reason, description });\n\n if (opts.onDisconnect) {\n await opts.onDisconnect(socket, reason, description, logger);\n }\n });\n\n socket.on(\"error\", async (error) => {\n logger.error(\"error\", { error });\n\n if (opts.onError) {\n await opts.onError(socket, error, logger);\n }\n });\n\n if (opts.onConnection) {\n await opts.onConnection(socket, this.#handler, this.sender, logger);\n }\n });\n }\n\n fetchSockets() {\n return this.namespace.fetchSockets();\n }\n}\n"]}
|
package/dist/v3/zodSocket.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Socket } from 'socket.io-client';
|
|
1
|
+
import { Socket, ManagerOptions, SocketOptions } from 'socket.io-client';
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
import { ZodMessageValueSchema, EventEmitterLike } from './zodMessageHandler.mjs';
|
|
4
4
|
import { StructuredLogger } from './utils/structuredLogger.mjs';
|
|
@@ -27,6 +27,7 @@ type ZodSocketMessageHandlers<TCatalogSchema extends ZodSocketMessageCatalogSche
|
|
|
27
27
|
type ZodSocketMessageHandlerOptions<TMessageCatalog extends ZodSocketMessageCatalogSchema> = {
|
|
28
28
|
schema: TMessageCatalog;
|
|
29
29
|
handlers?: ZodSocketMessageHandlers<TMessageCatalog>;
|
|
30
|
+
logger?: StructuredLogger;
|
|
30
31
|
};
|
|
31
32
|
type MessageFromSocketSchema<K extends keyof TMessageCatalog, TMessageCatalog extends ZodSocketMessageCatalogSchema> = {
|
|
32
33
|
type: K;
|
|
@@ -39,12 +40,13 @@ declare class ZodSocketMessageHandler<TRPCCatalog extends ZodSocketMessageCatalo
|
|
|
39
40
|
#private;
|
|
40
41
|
constructor(options: ZodSocketMessageHandlerOptions<TRPCCatalog>);
|
|
41
42
|
handleMessage(message: unknown): Promise<(SocketMessageHasCallback<TRPCCatalog, keyof TRPCCatalog> extends true ? z.input<GetSocketCallbackSchema<TRPCCatalog, keyof TRPCCatalog>> : void) | undefined>;
|
|
42
|
-
parseMessage
|
|
43
|
+
private parseMessage;
|
|
43
44
|
registerHandlers(emitter: EventEmitterLike, logger?: StructuredLogger): void;
|
|
44
45
|
}
|
|
45
46
|
type ZodSocketMessageSenderOptions<TMessageCatalog extends ZodSocketMessageCatalogSchema> = {
|
|
46
47
|
schema: TMessageCatalog;
|
|
47
48
|
socket: ZodSocket<any, TMessageCatalog>;
|
|
49
|
+
logger?: StructuredLogger;
|
|
48
50
|
};
|
|
49
51
|
type GetSocketMessagesWithCallback<TMessageCatalog extends ZodSocketMessageCatalogSchema> = {
|
|
50
52
|
[K in keyof TMessageCatalog]: SocketMessageHasCallback<TMessageCatalog, K> extends true ? K : never;
|
|
@@ -58,7 +60,9 @@ declare class ZodSocketMessageSender<TMessageCatalog extends ZodSocketMessageCat
|
|
|
58
60
|
send<K extends GetSocketMessagesWithoutCallback<TMessageCatalog>>(type: K, payload: z.input<GetSocketMessageSchema<TMessageCatalog, K>>): void;
|
|
59
61
|
sendWithAck<K extends GetSocketMessagesWithCallback<TMessageCatalog>>(type: K, payload: z.input<GetSocketMessageSchema<TMessageCatalog, K>>): Promise<z.infer<GetSocketCallbackSchema<TMessageCatalog, K>>>;
|
|
60
62
|
}
|
|
61
|
-
type ZodSocket<TListenEvents extends ZodSocketMessageCatalogSchema, TEmitEvents extends ZodSocketMessageCatalogSchema> = Socket<ZodMessageCatalogToSocketIoEvents<TListenEvents>, ZodMessageCatalogToSocketIoEvents<TEmitEvents
|
|
63
|
+
type ZodSocket<TListenEvents extends ZodSocketMessageCatalogSchema, TEmitEvents extends ZodSocketMessageCatalogSchema> = Omit<Socket<ZodMessageCatalogToSocketIoEvents<TListenEvents>, ZodMessageCatalogToSocketIoEvents<TEmitEvents>>, "timeout"> & {
|
|
64
|
+
timeout: (timeout: number) => Socket<ZodMessageCatalogToSocketIoEvents<TListenEvents>, ZodMessageCatalogToSocketIoEvents<TEmitEvents>>;
|
|
65
|
+
};
|
|
62
66
|
interface ZodSocketConnectionOptions<TClientMessages extends ZodSocketMessageCatalogSchema, TServerMessages extends ZodSocketMessageCatalogSchema> {
|
|
63
67
|
host: string;
|
|
64
68
|
port?: number;
|
|
@@ -71,6 +75,7 @@ interface ZodSocketConnectionOptions<TClientMessages extends ZodSocketMessageCat
|
|
|
71
75
|
};
|
|
72
76
|
handlers?: ZodSocketMessageHandlers<TServerMessages>;
|
|
73
77
|
authToken?: string;
|
|
78
|
+
ioOptions?: Partial<ManagerOptions & SocketOptions>;
|
|
74
79
|
onConnection?: (socket: ZodSocket<TServerMessages, TClientMessages>, handler: ZodSocketMessageHandler<TServerMessages>, sender: ZodSocketMessageSender<TClientMessages>, logger: StructuredLogger) => Promise<void>;
|
|
75
80
|
onDisconnect?: (socket: ZodSocket<TServerMessages, TClientMessages>, reason: Socket.DisconnectReason, description: any, logger: StructuredLogger) => Promise<void>;
|
|
76
81
|
onError?: (socket: ZodSocket<TServerMessages, TClientMessages>, err: Error, logger: StructuredLogger) => Promise<void>;
|
package/dist/v3/zodSocket.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Socket } from 'socket.io-client';
|
|
1
|
+
import { Socket, ManagerOptions, SocketOptions } from 'socket.io-client';
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
import { ZodMessageValueSchema, EventEmitterLike } from './zodMessageHandler.js';
|
|
4
4
|
import { StructuredLogger } from './utils/structuredLogger.js';
|
|
@@ -27,6 +27,7 @@ type ZodSocketMessageHandlers<TCatalogSchema extends ZodSocketMessageCatalogSche
|
|
|
27
27
|
type ZodSocketMessageHandlerOptions<TMessageCatalog extends ZodSocketMessageCatalogSchema> = {
|
|
28
28
|
schema: TMessageCatalog;
|
|
29
29
|
handlers?: ZodSocketMessageHandlers<TMessageCatalog>;
|
|
30
|
+
logger?: StructuredLogger;
|
|
30
31
|
};
|
|
31
32
|
type MessageFromSocketSchema<K extends keyof TMessageCatalog, TMessageCatalog extends ZodSocketMessageCatalogSchema> = {
|
|
32
33
|
type: K;
|
|
@@ -39,12 +40,13 @@ declare class ZodSocketMessageHandler<TRPCCatalog extends ZodSocketMessageCatalo
|
|
|
39
40
|
#private;
|
|
40
41
|
constructor(options: ZodSocketMessageHandlerOptions<TRPCCatalog>);
|
|
41
42
|
handleMessage(message: unknown): Promise<(SocketMessageHasCallback<TRPCCatalog, keyof TRPCCatalog> extends true ? z.input<GetSocketCallbackSchema<TRPCCatalog, keyof TRPCCatalog>> : void) | undefined>;
|
|
42
|
-
parseMessage
|
|
43
|
+
private parseMessage;
|
|
43
44
|
registerHandlers(emitter: EventEmitterLike, logger?: StructuredLogger): void;
|
|
44
45
|
}
|
|
45
46
|
type ZodSocketMessageSenderOptions<TMessageCatalog extends ZodSocketMessageCatalogSchema> = {
|
|
46
47
|
schema: TMessageCatalog;
|
|
47
48
|
socket: ZodSocket<any, TMessageCatalog>;
|
|
49
|
+
logger?: StructuredLogger;
|
|
48
50
|
};
|
|
49
51
|
type GetSocketMessagesWithCallback<TMessageCatalog extends ZodSocketMessageCatalogSchema> = {
|
|
50
52
|
[K in keyof TMessageCatalog]: SocketMessageHasCallback<TMessageCatalog, K> extends true ? K : never;
|
|
@@ -58,7 +60,9 @@ declare class ZodSocketMessageSender<TMessageCatalog extends ZodSocketMessageCat
|
|
|
58
60
|
send<K extends GetSocketMessagesWithoutCallback<TMessageCatalog>>(type: K, payload: z.input<GetSocketMessageSchema<TMessageCatalog, K>>): void;
|
|
59
61
|
sendWithAck<K extends GetSocketMessagesWithCallback<TMessageCatalog>>(type: K, payload: z.input<GetSocketMessageSchema<TMessageCatalog, K>>): Promise<z.infer<GetSocketCallbackSchema<TMessageCatalog, K>>>;
|
|
60
62
|
}
|
|
61
|
-
type ZodSocket<TListenEvents extends ZodSocketMessageCatalogSchema, TEmitEvents extends ZodSocketMessageCatalogSchema> = Socket<ZodMessageCatalogToSocketIoEvents<TListenEvents>, ZodMessageCatalogToSocketIoEvents<TEmitEvents
|
|
63
|
+
type ZodSocket<TListenEvents extends ZodSocketMessageCatalogSchema, TEmitEvents extends ZodSocketMessageCatalogSchema> = Omit<Socket<ZodMessageCatalogToSocketIoEvents<TListenEvents>, ZodMessageCatalogToSocketIoEvents<TEmitEvents>>, "timeout"> & {
|
|
64
|
+
timeout: (timeout: number) => Socket<ZodMessageCatalogToSocketIoEvents<TListenEvents>, ZodMessageCatalogToSocketIoEvents<TEmitEvents>>;
|
|
65
|
+
};
|
|
62
66
|
interface ZodSocketConnectionOptions<TClientMessages extends ZodSocketMessageCatalogSchema, TServerMessages extends ZodSocketMessageCatalogSchema> {
|
|
63
67
|
host: string;
|
|
64
68
|
port?: number;
|
|
@@ -71,6 +75,7 @@ interface ZodSocketConnectionOptions<TClientMessages extends ZodSocketMessageCat
|
|
|
71
75
|
};
|
|
72
76
|
handlers?: ZodSocketMessageHandlers<TServerMessages>;
|
|
73
77
|
authToken?: string;
|
|
78
|
+
ioOptions?: Partial<ManagerOptions & SocketOptions>;
|
|
74
79
|
onConnection?: (socket: ZodSocket<TServerMessages, TClientMessages>, handler: ZodSocketMessageHandler<TServerMessages>, sender: ZodSocketMessageSender<TClientMessages>, logger: StructuredLogger) => Promise<void>;
|
|
75
80
|
onDisconnect?: (socket: ZodSocket<TServerMessages, TClientMessages>, reason: Socket.DisconnectReason, description: any, logger: StructuredLogger) => Promise<void>;
|
|
76
81
|
onError?: (socket: ZodSocket<TServerMessages, TClientMessages>, err: Error, logger: StructuredLogger) => Promise<void>;
|