@trigger.dev/core 3.0.0-beta.17 → 3.0.0-beta.19
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/catalog-A-D3UC6S.d.mts +6646 -0
- package/dist/catalog-TAZd4-TP.d.ts +6646 -0
- package/dist/manager-M9GLDnhJ.d.mts +1158 -0
- package/dist/manager-M9GLDnhJ.d.ts +1158 -0
- package/dist/messages-AriaDDm0.d.mts +8696 -0
- package/dist/messages-AriaDDm0.d.ts +8696 -0
- package/dist/v3/dev/index.d.mts +28 -0
- package/dist/v3/dev/index.d.ts +28 -0
- package/dist/v3/dev/index.js +93 -0
- package/dist/v3/dev/index.js.map +1 -0
- package/dist/v3/dev/index.mjs +91 -0
- package/dist/v3/dev/index.mjs.map +1 -0
- package/dist/v3/index.d.mts +299 -17348
- package/dist/v3/index.d.ts +299 -17348
- package/dist/v3/index.js +2091 -3860
- package/dist/v3/index.js.map +1 -1
- package/dist/v3/index.mjs +2093 -3836
- package/dist/v3/index.mjs.map +1 -1
- package/dist/v3/otel/index.js +62 -38
- package/dist/v3/otel/index.js.map +1 -1
- package/dist/v3/otel/index.mjs +62 -38
- package/dist/v3/otel/index.mjs.map +1 -1
- package/dist/v3/prod/index.d.mts +45 -0
- package/dist/v3/prod/index.d.ts +45 -0
- package/dist/v3/prod/index.js +205 -0
- package/dist/v3/prod/index.js.map +1 -0
- package/dist/v3/prod/index.mjs +203 -0
- package/dist/v3/prod/index.mjs.map +1 -0
- package/dist/v3/utils/structuredLogger.d.mts +31 -0
- package/dist/v3/utils/structuredLogger.d.ts +31 -0
- package/dist/v3/utils/structuredLogger.js +88 -0
- package/dist/v3/utils/structuredLogger.js.map +1 -0
- package/dist/v3/utils/structuredLogger.mjs +86 -0
- package/dist/v3/utils/structuredLogger.mjs.map +1 -0
- package/dist/v3/workers/index.d.mts +95 -0
- package/dist/v3/workers/index.d.ts +95 -0
- package/dist/v3/workers/index.js +2663 -0
- package/dist/v3/workers/index.js.map +1 -0
- package/dist/v3/workers/index.mjs +2647 -0
- package/dist/v3/workers/index.mjs.map +1 -0
- package/dist/v3/zodIpc.d.mts +32 -0
- package/dist/v3/zodIpc.d.ts +32 -0
- package/dist/v3/zodIpc.js +268 -0
- package/dist/v3/zodIpc.js.map +1 -0
- package/dist/v3/zodIpc.mjs +266 -0
- package/dist/v3/zodIpc.mjs.map +1 -0
- package/dist/v3/zodMessageHandler.d.mts +69 -0
- package/dist/v3/zodMessageHandler.d.ts +69 -0
- package/dist/v3/zodMessageHandler.js +168 -0
- package/dist/v3/zodMessageHandler.js.map +1 -0
- package/dist/v3/zodMessageHandler.mjs +163 -0
- package/dist/v3/zodMessageHandler.mjs.map +1 -0
- package/dist/v3/zodNamespace.d.mts +3663 -0
- package/dist/v3/zodNamespace.d.ts +3663 -0
- package/dist/v3/zodNamespace.js +356 -0
- package/dist/v3/zodNamespace.js.map +1 -0
- package/dist/v3/zodNamespace.mjs +354 -0
- package/dist/v3/zodNamespace.mjs.map +1 -0
- package/dist/v3/zodSocket.d.mts +88 -0
- package/dist/v3/zodSocket.d.ts +88 -0
- package/dist/v3/zodSocket.js +309 -0
- package/dist/v3/zodSocket.js.map +1 -0
- package/dist/v3/zodSocket.mjs +305 -0
- package/dist/v3/zodSocket.mjs.map +1 -0
- package/package.json +69 -5
|
@@ -0,0 +1,354 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import 'socket.io-client';
|
|
3
|
+
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
6
|
+
var __accessCheck = (obj, member, msg) => {
|
|
7
|
+
if (!member.has(obj))
|
|
8
|
+
throw TypeError("Cannot " + msg);
|
|
9
|
+
};
|
|
10
|
+
var __privateGet = (obj, member, getter) => {
|
|
11
|
+
__accessCheck(obj, member, "read from private field");
|
|
12
|
+
return getter ? getter.call(obj) : member.get(obj);
|
|
13
|
+
};
|
|
14
|
+
var __privateAdd = (obj, member, value) => {
|
|
15
|
+
if (member.has(obj))
|
|
16
|
+
throw TypeError("Cannot add the same private member more than once");
|
|
17
|
+
member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
18
|
+
};
|
|
19
|
+
var __privateSet = (obj, member, value, setter) => {
|
|
20
|
+
__accessCheck(obj, member, "write to private field");
|
|
21
|
+
setter ? setter.call(obj, value) : member.set(obj, value);
|
|
22
|
+
return value;
|
|
23
|
+
};
|
|
24
|
+
var __privateMethod = (obj, member, method) => {
|
|
25
|
+
__accessCheck(obj, member, "access private method");
|
|
26
|
+
return method;
|
|
27
|
+
};
|
|
28
|
+
var _ZodSchemaParsedError = class _ZodSchemaParsedError extends Error {
|
|
29
|
+
constructor(error, payload) {
|
|
30
|
+
super(error.message);
|
|
31
|
+
this.error = error;
|
|
32
|
+
this.payload = payload;
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
__name(_ZodSchemaParsedError, "ZodSchemaParsedError");
|
|
36
|
+
var ZodSchemaParsedError = _ZodSchemaParsedError;
|
|
37
|
+
var ZodMessageSchema = z.object({
|
|
38
|
+
version: z.literal("v1").default("v1"),
|
|
39
|
+
type: z.string(),
|
|
40
|
+
payload: z.unknown()
|
|
41
|
+
});
|
|
42
|
+
var _schema, _sender;
|
|
43
|
+
var _ZodMessageSender = class _ZodMessageSender {
|
|
44
|
+
constructor(options) {
|
|
45
|
+
__privateAdd(this, _schema, void 0);
|
|
46
|
+
__privateAdd(this, _sender, void 0);
|
|
47
|
+
__privateSet(this, _schema, options.schema);
|
|
48
|
+
__privateSet(this, _sender, options.sender);
|
|
49
|
+
}
|
|
50
|
+
async send(type, payload) {
|
|
51
|
+
const schema = __privateGet(this, _schema)[type];
|
|
52
|
+
if (!schema) {
|
|
53
|
+
throw new Error(`Unknown message type: ${type}`);
|
|
54
|
+
}
|
|
55
|
+
const parsedPayload = schema.safeParse(payload);
|
|
56
|
+
if (!parsedPayload.success) {
|
|
57
|
+
throw new ZodSchemaParsedError(parsedPayload.error, payload);
|
|
58
|
+
}
|
|
59
|
+
await __privateGet(this, _sender).call(this, {
|
|
60
|
+
type,
|
|
61
|
+
payload,
|
|
62
|
+
version: "v1"
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
async forwardMessage(message) {
|
|
66
|
+
const parsedMessage = ZodMessageSchema.safeParse(message);
|
|
67
|
+
if (!parsedMessage.success) {
|
|
68
|
+
throw new Error(`Failed to parse message: ${JSON.stringify(parsedMessage.error)}`);
|
|
69
|
+
}
|
|
70
|
+
const schema = __privateGet(this, _schema)[parsedMessage.data.type];
|
|
71
|
+
if (!schema) {
|
|
72
|
+
throw new Error(`Unknown message type: ${parsedMessage.data.type}`);
|
|
73
|
+
}
|
|
74
|
+
const parsedPayload = schema.safeParse(parsedMessage.data.payload);
|
|
75
|
+
if (!parsedPayload.success) {
|
|
76
|
+
throw new Error(`Failed to parse message payload: ${JSON.stringify(parsedPayload.error)}`);
|
|
77
|
+
}
|
|
78
|
+
await __privateGet(this, _sender).call(this, {
|
|
79
|
+
type: parsedMessage.data.type,
|
|
80
|
+
payload: parsedPayload.data,
|
|
81
|
+
version: "v1"
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
_schema = new WeakMap();
|
|
86
|
+
_sender = new WeakMap();
|
|
87
|
+
__name(_ZodMessageSender, "ZodMessageSender");
|
|
88
|
+
var ZodMessageSender = _ZodMessageSender;
|
|
89
|
+
|
|
90
|
+
// src/v3/utils/structuredLogger.ts
|
|
91
|
+
var LogLevel;
|
|
92
|
+
(function(LogLevel2) {
|
|
93
|
+
LogLevel2[LogLevel2["log"] = 0] = "log";
|
|
94
|
+
LogLevel2[LogLevel2["error"] = 1] = "error";
|
|
95
|
+
LogLevel2[LogLevel2["warn"] = 2] = "warn";
|
|
96
|
+
LogLevel2[LogLevel2["info"] = 3] = "info";
|
|
97
|
+
LogLevel2[LogLevel2["debug"] = 4] = "debug";
|
|
98
|
+
})(LogLevel || (LogLevel = {}));
|
|
99
|
+
var _structuredLog, structuredLog_fn;
|
|
100
|
+
var _SimpleStructuredLogger = class _SimpleStructuredLogger {
|
|
101
|
+
constructor(name, level = [
|
|
102
|
+
"1",
|
|
103
|
+
"true"
|
|
104
|
+
].includes(process.env.DEBUG ?? "") ? LogLevel.debug : LogLevel.info, fields) {
|
|
105
|
+
__privateAdd(this, _structuredLog);
|
|
106
|
+
this.name = name;
|
|
107
|
+
this.level = level;
|
|
108
|
+
this.fields = fields;
|
|
109
|
+
}
|
|
110
|
+
child(fields, level) {
|
|
111
|
+
return new _SimpleStructuredLogger(this.name, level, {
|
|
112
|
+
...this.fields,
|
|
113
|
+
...fields
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
log(message, ...args) {
|
|
117
|
+
if (this.level < LogLevel.log)
|
|
118
|
+
return;
|
|
119
|
+
__privateMethod(this, _structuredLog, structuredLog_fn).call(this, console.log, message, "log", ...args);
|
|
120
|
+
}
|
|
121
|
+
error(message, ...args) {
|
|
122
|
+
if (this.level < LogLevel.error)
|
|
123
|
+
return;
|
|
124
|
+
__privateMethod(this, _structuredLog, structuredLog_fn).call(this, console.error, message, "error", ...args);
|
|
125
|
+
}
|
|
126
|
+
warn(message, ...args) {
|
|
127
|
+
if (this.level < LogLevel.warn)
|
|
128
|
+
return;
|
|
129
|
+
__privateMethod(this, _structuredLog, structuredLog_fn).call(this, console.warn, message, "warn", ...args);
|
|
130
|
+
}
|
|
131
|
+
info(message, ...args) {
|
|
132
|
+
if (this.level < LogLevel.info)
|
|
133
|
+
return;
|
|
134
|
+
__privateMethod(this, _structuredLog, structuredLog_fn).call(this, console.info, message, "info", ...args);
|
|
135
|
+
}
|
|
136
|
+
debug(message, ...args) {
|
|
137
|
+
if (this.level < LogLevel.debug)
|
|
138
|
+
return;
|
|
139
|
+
__privateMethod(this, _structuredLog, structuredLog_fn).call(this, console.debug, message, "debug", ...args);
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
_structuredLog = new WeakSet();
|
|
143
|
+
structuredLog_fn = /* @__PURE__ */ __name(function(loggerFunction, message, level, ...args) {
|
|
144
|
+
const structuredLog = {
|
|
145
|
+
...args.length === 1 ? args[0] : args,
|
|
146
|
+
...this.fields,
|
|
147
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
148
|
+
name: this.name,
|
|
149
|
+
message,
|
|
150
|
+
level
|
|
151
|
+
};
|
|
152
|
+
loggerFunction(JSON.stringify(structuredLog));
|
|
153
|
+
}, "#structuredLog");
|
|
154
|
+
__name(_SimpleStructuredLogger, "SimpleStructuredLogger");
|
|
155
|
+
var SimpleStructuredLogger = _SimpleStructuredLogger;
|
|
156
|
+
|
|
157
|
+
// src/v3/zodSocket.ts
|
|
158
|
+
var messageSchema = z.object({
|
|
159
|
+
version: z.literal("v1").default("v1"),
|
|
160
|
+
type: z.string(),
|
|
161
|
+
payload: z.unknown()
|
|
162
|
+
});
|
|
163
|
+
var _schema2, _handlers;
|
|
164
|
+
var _ZodSocketMessageHandler = class _ZodSocketMessageHandler {
|
|
165
|
+
constructor(options) {
|
|
166
|
+
__privateAdd(this, _schema2, void 0);
|
|
167
|
+
__privateAdd(this, _handlers, void 0);
|
|
168
|
+
__privateSet(this, _schema2, options.schema);
|
|
169
|
+
__privateSet(this, _handlers, options.handlers);
|
|
170
|
+
}
|
|
171
|
+
async handleMessage(message) {
|
|
172
|
+
const parsedMessage = this.parseMessage(message);
|
|
173
|
+
if (!__privateGet(this, _handlers)) {
|
|
174
|
+
throw new Error("No handlers provided");
|
|
175
|
+
}
|
|
176
|
+
const handler = __privateGet(this, _handlers)[parsedMessage.type];
|
|
177
|
+
if (!handler) {
|
|
178
|
+
console.error(`No handler for message type: ${String(parsedMessage.type)}`);
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
const ack = await handler(parsedMessage.payload);
|
|
182
|
+
return ack;
|
|
183
|
+
}
|
|
184
|
+
parseMessage(message) {
|
|
185
|
+
const parsedMessage = messageSchema.safeParse(message);
|
|
186
|
+
if (!parsedMessage.success) {
|
|
187
|
+
throw new Error(`Failed to parse message: ${JSON.stringify(parsedMessage.error)}`);
|
|
188
|
+
}
|
|
189
|
+
const schema = __privateGet(this, _schema2)[parsedMessage.data.type]["message"];
|
|
190
|
+
if (!schema) {
|
|
191
|
+
throw new Error(`Unknown message type: ${parsedMessage.data.type}`);
|
|
192
|
+
}
|
|
193
|
+
const parsedPayload = schema.safeParse(parsedMessage.data.payload);
|
|
194
|
+
if (!parsedPayload.success) {
|
|
195
|
+
throw new Error(`Failed to parse message payload: ${JSON.stringify(parsedPayload.error)}`);
|
|
196
|
+
}
|
|
197
|
+
return {
|
|
198
|
+
type: parsedMessage.data.type,
|
|
199
|
+
payload: parsedPayload.data
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
registerHandlers(emitter, logger) {
|
|
203
|
+
const log = logger ?? console;
|
|
204
|
+
if (!__privateGet(this, _handlers)) {
|
|
205
|
+
log.info("No handlers provided");
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
for (const eventName of Object.keys(__privateGet(this, _handlers))) {
|
|
209
|
+
emitter.on(eventName, async (message, callback) => {
|
|
210
|
+
log.info(`handling ${eventName}`, {
|
|
211
|
+
payload: message,
|
|
212
|
+
hasCallback: !!callback
|
|
213
|
+
});
|
|
214
|
+
let ack;
|
|
215
|
+
try {
|
|
216
|
+
if ("payload" in message) {
|
|
217
|
+
ack = await this.handleMessage({
|
|
218
|
+
type: eventName,
|
|
219
|
+
...message
|
|
220
|
+
});
|
|
221
|
+
} else {
|
|
222
|
+
const { version, ...payload } = message;
|
|
223
|
+
ack = await this.handleMessage({
|
|
224
|
+
type: eventName,
|
|
225
|
+
version,
|
|
226
|
+
payload
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
} catch (error) {
|
|
230
|
+
log.error("Error while handling message", {
|
|
231
|
+
error
|
|
232
|
+
});
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
if (callback && typeof callback === "function") {
|
|
236
|
+
callback(ack);
|
|
237
|
+
}
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
};
|
|
242
|
+
_schema2 = new WeakMap();
|
|
243
|
+
_handlers = new WeakMap();
|
|
244
|
+
__name(_ZodSocketMessageHandler, "ZodSocketMessageHandler");
|
|
245
|
+
var ZodSocketMessageHandler = _ZodSocketMessageHandler;
|
|
246
|
+
|
|
247
|
+
// src/v3/zodNamespace.ts
|
|
248
|
+
var _logger, _handler;
|
|
249
|
+
var _ZodNamespace = class _ZodNamespace {
|
|
250
|
+
constructor(opts) {
|
|
251
|
+
__privateAdd(this, _logger, void 0);
|
|
252
|
+
__privateAdd(this, _handler, void 0);
|
|
253
|
+
__privateSet(this, _logger, opts.logger ?? new SimpleStructuredLogger(opts.name));
|
|
254
|
+
__privateSet(this, _handler, new ZodSocketMessageHandler({
|
|
255
|
+
schema: opts.clientMessages,
|
|
256
|
+
handlers: opts.handlers
|
|
257
|
+
}));
|
|
258
|
+
this.io = opts.io;
|
|
259
|
+
this.namespace = this.io.of(opts.name);
|
|
260
|
+
this.sender = new ZodMessageSender({
|
|
261
|
+
schema: opts.serverMessages,
|
|
262
|
+
sender: async (message) => {
|
|
263
|
+
return new Promise((resolve, reject) => {
|
|
264
|
+
try {
|
|
265
|
+
this.namespace.emit(message.type, message.payload);
|
|
266
|
+
resolve();
|
|
267
|
+
} catch (err) {
|
|
268
|
+
reject(err);
|
|
269
|
+
}
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
});
|
|
273
|
+
if (opts.preAuth) {
|
|
274
|
+
this.namespace.use(async (socket, next) => {
|
|
275
|
+
const logger = __privateGet(this, _logger).child({
|
|
276
|
+
socketId: socket.id,
|
|
277
|
+
socketStage: "preAuth"
|
|
278
|
+
});
|
|
279
|
+
if (typeof opts.preAuth === "function") {
|
|
280
|
+
await opts.preAuth(socket, next, logger);
|
|
281
|
+
}
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
if (opts.authToken) {
|
|
285
|
+
this.namespace.use((socket, next) => {
|
|
286
|
+
const logger = __privateGet(this, _logger).child({
|
|
287
|
+
socketId: socket.id,
|
|
288
|
+
socketStage: "auth"
|
|
289
|
+
});
|
|
290
|
+
const { auth } = socket.handshake;
|
|
291
|
+
if (!("token" in auth)) {
|
|
292
|
+
logger.error("no token");
|
|
293
|
+
return socket.disconnect(true);
|
|
294
|
+
}
|
|
295
|
+
if (auth.token !== opts.authToken) {
|
|
296
|
+
logger.error("invalid token");
|
|
297
|
+
return socket.disconnect(true);
|
|
298
|
+
}
|
|
299
|
+
logger.info("success");
|
|
300
|
+
next();
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
if (opts.postAuth) {
|
|
304
|
+
this.namespace.use(async (socket, next) => {
|
|
305
|
+
const logger = __privateGet(this, _logger).child({
|
|
306
|
+
socketId: socket.id,
|
|
307
|
+
socketStage: "auth"
|
|
308
|
+
});
|
|
309
|
+
if (typeof opts.postAuth === "function") {
|
|
310
|
+
await opts.postAuth(socket, next, logger);
|
|
311
|
+
}
|
|
312
|
+
});
|
|
313
|
+
}
|
|
314
|
+
this.namespace.on("connection", async (socket) => {
|
|
315
|
+
const logger = __privateGet(this, _logger).child({
|
|
316
|
+
socketId: socket.id,
|
|
317
|
+
socketStage: "connection"
|
|
318
|
+
});
|
|
319
|
+
logger.info("connected");
|
|
320
|
+
__privateGet(this, _handler).registerHandlers(socket, logger);
|
|
321
|
+
socket.on("disconnect", async (reason, description) => {
|
|
322
|
+
logger.info("disconnect", {
|
|
323
|
+
reason,
|
|
324
|
+
description
|
|
325
|
+
});
|
|
326
|
+
if (opts.onDisconnect) {
|
|
327
|
+
await opts.onDisconnect(socket, reason, description, logger);
|
|
328
|
+
}
|
|
329
|
+
});
|
|
330
|
+
socket.on("error", async (error) => {
|
|
331
|
+
logger.error("error", {
|
|
332
|
+
error
|
|
333
|
+
});
|
|
334
|
+
if (opts.onError) {
|
|
335
|
+
await opts.onError(socket, error, logger);
|
|
336
|
+
}
|
|
337
|
+
});
|
|
338
|
+
if (opts.onConnection) {
|
|
339
|
+
await opts.onConnection(socket, __privateGet(this, _handler), this.sender, logger);
|
|
340
|
+
}
|
|
341
|
+
});
|
|
342
|
+
}
|
|
343
|
+
fetchSockets() {
|
|
344
|
+
return this.namespace.fetchSockets();
|
|
345
|
+
}
|
|
346
|
+
};
|
|
347
|
+
_logger = new WeakMap();
|
|
348
|
+
_handler = new WeakMap();
|
|
349
|
+
__name(_ZodNamespace, "ZodNamespace");
|
|
350
|
+
var ZodNamespace = _ZodNamespace;
|
|
351
|
+
|
|
352
|
+
export { ZodNamespace };
|
|
353
|
+
//# sourceMappingURL=out.js.map
|
|
354
|
+
//# sourceMappingURL=zodNamespace.mjs.map
|
|
@@ -0,0 +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","LogLevel","SimpleStructuredLogger","name","level","includes","process","env","DEBUG","debug","info","fields","child","log","args","console","warn","loggerFunction","structuredLog","length","timestamp","Date","messageSchema","_schema","ZodSocketMessageHandler","handlers","handleMessage","parseMessage","handler","String","ack","registerHandlers","emitter","logger","eventName","Object","keys","on","callback","hasCallback","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 { z } from \"zod\";\nimport { EventEmitterLike, ZodMessageValueSchema } from \"./zodMessageHandler\";\nimport { LogLevel, SimpleStructuredLogger, StructuredLogger } from \"./utils/structuredLogger\";\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.literal(\"v1\").default(\"v1\"),\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 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.#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\", { error });\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"]}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { Socket } from 'socket.io-client';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { ZodMessageValueSchema, EventEmitterLike } from './zodMessageHandler.mjs';
|
|
4
|
+
import { StructuredLogger } from './utils/structuredLogger.mjs';
|
|
5
|
+
|
|
6
|
+
interface ZodSocketMessageCatalogSchema {
|
|
7
|
+
[key: string]: {
|
|
8
|
+
message: ZodMessageValueSchema<any>;
|
|
9
|
+
} | {
|
|
10
|
+
message: ZodMessageValueSchema<any>;
|
|
11
|
+
callback?: ZodMessageValueSchema<any>;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
type ZodMessageCatalogToSocketIoEvents<TCatalog extends ZodSocketMessageCatalogSchema> = {
|
|
15
|
+
[K in keyof TCatalog]: SocketMessageHasCallback<TCatalog, K> extends true ? (message: z.infer<GetSocketMessageSchema<TCatalog, K>>, callback: (ack: z.infer<GetSocketCallbackSchema<TCatalog, K>>) => void) => void : (message: z.infer<GetSocketMessageSchema<TCatalog, K>>) => void;
|
|
16
|
+
};
|
|
17
|
+
type GetSocketMessageSchema<TRPCCatalog extends ZodSocketMessageCatalogSchema, TMessageType extends keyof TRPCCatalog> = TRPCCatalog[TMessageType]["message"];
|
|
18
|
+
type InferSocketMessageSchema<TRPCCatalog extends ZodSocketMessageCatalogSchema, TMessageType extends keyof TRPCCatalog> = z.infer<GetSocketMessageSchema<TRPCCatalog, TMessageType>>;
|
|
19
|
+
type GetSocketCallbackSchema<TRPCCatalog extends ZodSocketMessageCatalogSchema, TMessageType extends keyof TRPCCatalog> = TRPCCatalog[TMessageType] extends {
|
|
20
|
+
callback: any;
|
|
21
|
+
} ? TRPCCatalog[TMessageType]["callback"] : never;
|
|
22
|
+
type InferSocketCallbackSchema<TRPCCatalog extends ZodSocketMessageCatalogSchema, TMessageType extends keyof TRPCCatalog> = z.infer<GetSocketCallbackSchema<TRPCCatalog, TMessageType>>;
|
|
23
|
+
type SocketMessageHasCallback<TRPCCatalog extends ZodSocketMessageCatalogSchema, TMessageType extends keyof TRPCCatalog> = GetSocketCallbackSchema<TRPCCatalog, TMessageType> extends never ? false : true;
|
|
24
|
+
type ZodSocketMessageHandlers<TCatalogSchema extends ZodSocketMessageCatalogSchema> = Partial<{
|
|
25
|
+
[K in keyof TCatalogSchema]: (payload: z.infer<GetSocketMessageSchema<TCatalogSchema, K>>) => Promise<SocketMessageHasCallback<TCatalogSchema, K> extends true ? z.input<GetSocketCallbackSchema<TCatalogSchema, K>> : void>;
|
|
26
|
+
}>;
|
|
27
|
+
type ZodSocketMessageHandlerOptions<TMessageCatalog extends ZodSocketMessageCatalogSchema> = {
|
|
28
|
+
schema: TMessageCatalog;
|
|
29
|
+
handlers?: ZodSocketMessageHandlers<TMessageCatalog>;
|
|
30
|
+
};
|
|
31
|
+
type MessageFromSocketSchema<K extends keyof TMessageCatalog, TMessageCatalog extends ZodSocketMessageCatalogSchema> = {
|
|
32
|
+
type: K;
|
|
33
|
+
payload: z.input<GetSocketMessageSchema<TMessageCatalog, K>>;
|
|
34
|
+
};
|
|
35
|
+
type MessagesFromSocketCatalog<TMessageCatalog extends ZodSocketMessageCatalogSchema> = {
|
|
36
|
+
[K in keyof TMessageCatalog]: MessageFromSocketSchema<K, TMessageCatalog>;
|
|
37
|
+
}[keyof TMessageCatalog];
|
|
38
|
+
declare class ZodSocketMessageHandler<TRPCCatalog extends ZodSocketMessageCatalogSchema> {
|
|
39
|
+
#private;
|
|
40
|
+
constructor(options: ZodSocketMessageHandlerOptions<TRPCCatalog>);
|
|
41
|
+
handleMessage(message: unknown): Promise<(SocketMessageHasCallback<TRPCCatalog, keyof TRPCCatalog> extends true ? z.input<GetSocketCallbackSchema<TRPCCatalog, keyof TRPCCatalog>> : void) | undefined>;
|
|
42
|
+
parseMessage(message: unknown): MessagesFromSocketCatalog<TRPCCatalog>;
|
|
43
|
+
registerHandlers(emitter: EventEmitterLike, logger?: StructuredLogger): void;
|
|
44
|
+
}
|
|
45
|
+
type ZodSocketMessageSenderOptions<TMessageCatalog extends ZodSocketMessageCatalogSchema> = {
|
|
46
|
+
schema: TMessageCatalog;
|
|
47
|
+
socket: ZodSocket<any, TMessageCatalog>;
|
|
48
|
+
};
|
|
49
|
+
type GetSocketMessagesWithCallback<TMessageCatalog extends ZodSocketMessageCatalogSchema> = {
|
|
50
|
+
[K in keyof TMessageCatalog]: SocketMessageHasCallback<TMessageCatalog, K> extends true ? K : never;
|
|
51
|
+
}[keyof TMessageCatalog];
|
|
52
|
+
type GetSocketMessagesWithoutCallback<TMessageCatalog extends ZodSocketMessageCatalogSchema> = {
|
|
53
|
+
[K in keyof TMessageCatalog]: SocketMessageHasCallback<TMessageCatalog, K> extends true ? never : K;
|
|
54
|
+
}[keyof TMessageCatalog];
|
|
55
|
+
declare class ZodSocketMessageSender<TMessageCatalog extends ZodSocketMessageCatalogSchema> {
|
|
56
|
+
#private;
|
|
57
|
+
constructor(options: ZodSocketMessageSenderOptions<TMessageCatalog>);
|
|
58
|
+
send<K extends GetSocketMessagesWithoutCallback<TMessageCatalog>>(type: K, payload: z.input<GetSocketMessageSchema<TMessageCatalog, K>>): void;
|
|
59
|
+
sendWithAck<K extends GetSocketMessagesWithCallback<TMessageCatalog>>(type: K, payload: z.input<GetSocketMessageSchema<TMessageCatalog, K>>): Promise<z.infer<GetSocketCallbackSchema<TMessageCatalog, K>>>;
|
|
60
|
+
}
|
|
61
|
+
type ZodSocket<TListenEvents extends ZodSocketMessageCatalogSchema, TEmitEvents extends ZodSocketMessageCatalogSchema> = Socket<ZodMessageCatalogToSocketIoEvents<TListenEvents>, ZodMessageCatalogToSocketIoEvents<TEmitEvents>>;
|
|
62
|
+
interface ZodSocketConnectionOptions<TClientMessages extends ZodSocketMessageCatalogSchema, TServerMessages extends ZodSocketMessageCatalogSchema> {
|
|
63
|
+
host: string;
|
|
64
|
+
port?: number;
|
|
65
|
+
secure?: boolean;
|
|
66
|
+
namespace: string;
|
|
67
|
+
clientMessages: TClientMessages;
|
|
68
|
+
serverMessages: TServerMessages;
|
|
69
|
+
extraHeaders?: {
|
|
70
|
+
[header: string]: string;
|
|
71
|
+
};
|
|
72
|
+
handlers?: ZodSocketMessageHandlers<TServerMessages>;
|
|
73
|
+
authToken?: string;
|
|
74
|
+
onConnection?: (socket: ZodSocket<TServerMessages, TClientMessages>, handler: ZodSocketMessageHandler<TServerMessages>, sender: ZodSocketMessageSender<TClientMessages>, logger: StructuredLogger) => Promise<void>;
|
|
75
|
+
onDisconnect?: (socket: ZodSocket<TServerMessages, TClientMessages>, reason: Socket.DisconnectReason, description: any, logger: StructuredLogger) => Promise<void>;
|
|
76
|
+
onError?: (socket: ZodSocket<TServerMessages, TClientMessages>, err: Error, logger: StructuredLogger) => Promise<void>;
|
|
77
|
+
}
|
|
78
|
+
declare class ZodSocketConnection<TClientMessages extends ZodSocketMessageCatalogSchema, TServerMessages extends ZodSocketMessageCatalogSchema> {
|
|
79
|
+
#private;
|
|
80
|
+
socket: ZodSocket<TServerMessages, TClientMessages>;
|
|
81
|
+
constructor(opts: ZodSocketConnectionOptions<TClientMessages, TServerMessages>);
|
|
82
|
+
close(): void;
|
|
83
|
+
connect(): void;
|
|
84
|
+
get send(): <K extends GetSocketMessagesWithoutCallback<TClientMessages>>(type: K, payload: z.input<GetSocketMessageSchema<TClientMessages, K>>) => void;
|
|
85
|
+
get sendWithAck(): <K extends GetSocketMessagesWithCallback<TClientMessages>>(type: K, payload: z.input<GetSocketMessageSchema<TClientMessages, K>>) => Promise<z.TypeOf<GetSocketCallbackSchema<TClientMessages, K>>>;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export { type GetSocketCallbackSchema, type GetSocketMessageSchema, type GetSocketMessagesWithCallback, type GetSocketMessagesWithoutCallback, type InferSocketCallbackSchema, type InferSocketMessageSchema, type MessagesFromSocketCatalog, type SocketMessageHasCallback, type ZodMessageCatalogToSocketIoEvents, type ZodSocket, ZodSocketConnection, type ZodSocketMessageCatalogSchema, ZodSocketMessageHandler, type ZodSocketMessageHandlerOptions, type ZodSocketMessageHandlers, ZodSocketMessageSender, type ZodSocketMessageSenderOptions };
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { Socket } from 'socket.io-client';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { ZodMessageValueSchema, EventEmitterLike } from './zodMessageHandler.js';
|
|
4
|
+
import { StructuredLogger } from './utils/structuredLogger.js';
|
|
5
|
+
|
|
6
|
+
interface ZodSocketMessageCatalogSchema {
|
|
7
|
+
[key: string]: {
|
|
8
|
+
message: ZodMessageValueSchema<any>;
|
|
9
|
+
} | {
|
|
10
|
+
message: ZodMessageValueSchema<any>;
|
|
11
|
+
callback?: ZodMessageValueSchema<any>;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
type ZodMessageCatalogToSocketIoEvents<TCatalog extends ZodSocketMessageCatalogSchema> = {
|
|
15
|
+
[K in keyof TCatalog]: SocketMessageHasCallback<TCatalog, K> extends true ? (message: z.infer<GetSocketMessageSchema<TCatalog, K>>, callback: (ack: z.infer<GetSocketCallbackSchema<TCatalog, K>>) => void) => void : (message: z.infer<GetSocketMessageSchema<TCatalog, K>>) => void;
|
|
16
|
+
};
|
|
17
|
+
type GetSocketMessageSchema<TRPCCatalog extends ZodSocketMessageCatalogSchema, TMessageType extends keyof TRPCCatalog> = TRPCCatalog[TMessageType]["message"];
|
|
18
|
+
type InferSocketMessageSchema<TRPCCatalog extends ZodSocketMessageCatalogSchema, TMessageType extends keyof TRPCCatalog> = z.infer<GetSocketMessageSchema<TRPCCatalog, TMessageType>>;
|
|
19
|
+
type GetSocketCallbackSchema<TRPCCatalog extends ZodSocketMessageCatalogSchema, TMessageType extends keyof TRPCCatalog> = TRPCCatalog[TMessageType] extends {
|
|
20
|
+
callback: any;
|
|
21
|
+
} ? TRPCCatalog[TMessageType]["callback"] : never;
|
|
22
|
+
type InferSocketCallbackSchema<TRPCCatalog extends ZodSocketMessageCatalogSchema, TMessageType extends keyof TRPCCatalog> = z.infer<GetSocketCallbackSchema<TRPCCatalog, TMessageType>>;
|
|
23
|
+
type SocketMessageHasCallback<TRPCCatalog extends ZodSocketMessageCatalogSchema, TMessageType extends keyof TRPCCatalog> = GetSocketCallbackSchema<TRPCCatalog, TMessageType> extends never ? false : true;
|
|
24
|
+
type ZodSocketMessageHandlers<TCatalogSchema extends ZodSocketMessageCatalogSchema> = Partial<{
|
|
25
|
+
[K in keyof TCatalogSchema]: (payload: z.infer<GetSocketMessageSchema<TCatalogSchema, K>>) => Promise<SocketMessageHasCallback<TCatalogSchema, K> extends true ? z.input<GetSocketCallbackSchema<TCatalogSchema, K>> : void>;
|
|
26
|
+
}>;
|
|
27
|
+
type ZodSocketMessageHandlerOptions<TMessageCatalog extends ZodSocketMessageCatalogSchema> = {
|
|
28
|
+
schema: TMessageCatalog;
|
|
29
|
+
handlers?: ZodSocketMessageHandlers<TMessageCatalog>;
|
|
30
|
+
};
|
|
31
|
+
type MessageFromSocketSchema<K extends keyof TMessageCatalog, TMessageCatalog extends ZodSocketMessageCatalogSchema> = {
|
|
32
|
+
type: K;
|
|
33
|
+
payload: z.input<GetSocketMessageSchema<TMessageCatalog, K>>;
|
|
34
|
+
};
|
|
35
|
+
type MessagesFromSocketCatalog<TMessageCatalog extends ZodSocketMessageCatalogSchema> = {
|
|
36
|
+
[K in keyof TMessageCatalog]: MessageFromSocketSchema<K, TMessageCatalog>;
|
|
37
|
+
}[keyof TMessageCatalog];
|
|
38
|
+
declare class ZodSocketMessageHandler<TRPCCatalog extends ZodSocketMessageCatalogSchema> {
|
|
39
|
+
#private;
|
|
40
|
+
constructor(options: ZodSocketMessageHandlerOptions<TRPCCatalog>);
|
|
41
|
+
handleMessage(message: unknown): Promise<(SocketMessageHasCallback<TRPCCatalog, keyof TRPCCatalog> extends true ? z.input<GetSocketCallbackSchema<TRPCCatalog, keyof TRPCCatalog>> : void) | undefined>;
|
|
42
|
+
parseMessage(message: unknown): MessagesFromSocketCatalog<TRPCCatalog>;
|
|
43
|
+
registerHandlers(emitter: EventEmitterLike, logger?: StructuredLogger): void;
|
|
44
|
+
}
|
|
45
|
+
type ZodSocketMessageSenderOptions<TMessageCatalog extends ZodSocketMessageCatalogSchema> = {
|
|
46
|
+
schema: TMessageCatalog;
|
|
47
|
+
socket: ZodSocket<any, TMessageCatalog>;
|
|
48
|
+
};
|
|
49
|
+
type GetSocketMessagesWithCallback<TMessageCatalog extends ZodSocketMessageCatalogSchema> = {
|
|
50
|
+
[K in keyof TMessageCatalog]: SocketMessageHasCallback<TMessageCatalog, K> extends true ? K : never;
|
|
51
|
+
}[keyof TMessageCatalog];
|
|
52
|
+
type GetSocketMessagesWithoutCallback<TMessageCatalog extends ZodSocketMessageCatalogSchema> = {
|
|
53
|
+
[K in keyof TMessageCatalog]: SocketMessageHasCallback<TMessageCatalog, K> extends true ? never : K;
|
|
54
|
+
}[keyof TMessageCatalog];
|
|
55
|
+
declare class ZodSocketMessageSender<TMessageCatalog extends ZodSocketMessageCatalogSchema> {
|
|
56
|
+
#private;
|
|
57
|
+
constructor(options: ZodSocketMessageSenderOptions<TMessageCatalog>);
|
|
58
|
+
send<K extends GetSocketMessagesWithoutCallback<TMessageCatalog>>(type: K, payload: z.input<GetSocketMessageSchema<TMessageCatalog, K>>): void;
|
|
59
|
+
sendWithAck<K extends GetSocketMessagesWithCallback<TMessageCatalog>>(type: K, payload: z.input<GetSocketMessageSchema<TMessageCatalog, K>>): Promise<z.infer<GetSocketCallbackSchema<TMessageCatalog, K>>>;
|
|
60
|
+
}
|
|
61
|
+
type ZodSocket<TListenEvents extends ZodSocketMessageCatalogSchema, TEmitEvents extends ZodSocketMessageCatalogSchema> = Socket<ZodMessageCatalogToSocketIoEvents<TListenEvents>, ZodMessageCatalogToSocketIoEvents<TEmitEvents>>;
|
|
62
|
+
interface ZodSocketConnectionOptions<TClientMessages extends ZodSocketMessageCatalogSchema, TServerMessages extends ZodSocketMessageCatalogSchema> {
|
|
63
|
+
host: string;
|
|
64
|
+
port?: number;
|
|
65
|
+
secure?: boolean;
|
|
66
|
+
namespace: string;
|
|
67
|
+
clientMessages: TClientMessages;
|
|
68
|
+
serverMessages: TServerMessages;
|
|
69
|
+
extraHeaders?: {
|
|
70
|
+
[header: string]: string;
|
|
71
|
+
};
|
|
72
|
+
handlers?: ZodSocketMessageHandlers<TServerMessages>;
|
|
73
|
+
authToken?: string;
|
|
74
|
+
onConnection?: (socket: ZodSocket<TServerMessages, TClientMessages>, handler: ZodSocketMessageHandler<TServerMessages>, sender: ZodSocketMessageSender<TClientMessages>, logger: StructuredLogger) => Promise<void>;
|
|
75
|
+
onDisconnect?: (socket: ZodSocket<TServerMessages, TClientMessages>, reason: Socket.DisconnectReason, description: any, logger: StructuredLogger) => Promise<void>;
|
|
76
|
+
onError?: (socket: ZodSocket<TServerMessages, TClientMessages>, err: Error, logger: StructuredLogger) => Promise<void>;
|
|
77
|
+
}
|
|
78
|
+
declare class ZodSocketConnection<TClientMessages extends ZodSocketMessageCatalogSchema, TServerMessages extends ZodSocketMessageCatalogSchema> {
|
|
79
|
+
#private;
|
|
80
|
+
socket: ZodSocket<TServerMessages, TClientMessages>;
|
|
81
|
+
constructor(opts: ZodSocketConnectionOptions<TClientMessages, TServerMessages>);
|
|
82
|
+
close(): void;
|
|
83
|
+
connect(): void;
|
|
84
|
+
get send(): <K extends GetSocketMessagesWithoutCallback<TClientMessages>>(type: K, payload: z.input<GetSocketMessageSchema<TClientMessages, K>>) => void;
|
|
85
|
+
get sendWithAck(): <K extends GetSocketMessagesWithCallback<TClientMessages>>(type: K, payload: z.input<GetSocketMessageSchema<TClientMessages, K>>) => Promise<z.TypeOf<GetSocketCallbackSchema<TClientMessages, K>>>;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export { type GetSocketCallbackSchema, type GetSocketMessageSchema, type GetSocketMessagesWithCallback, type GetSocketMessagesWithoutCallback, type InferSocketCallbackSchema, type InferSocketMessageSchema, type MessagesFromSocketCatalog, type SocketMessageHasCallback, type ZodMessageCatalogToSocketIoEvents, type ZodSocket, ZodSocketConnection, type ZodSocketMessageCatalogSchema, ZodSocketMessageHandler, type ZodSocketMessageHandlerOptions, type ZodSocketMessageHandlers, ZodSocketMessageSender, type ZodSocketMessageSenderOptions };
|