@gleamkit/socket.io 4.8.6
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/LICENSE +22 -0
- package/Readme.md +273 -0
- package/client-dist/socket.io.esm.min.js +7 -0
- package/client-dist/socket.io.esm.min.js.map +1 -0
- package/client-dist/socket.io.js +4955 -0
- package/client-dist/socket.io.js.map +1 -0
- package/client-dist/socket.io.min.js +7 -0
- package/client-dist/socket.io.min.js.map +1 -0
- package/client-dist/socket.io.msgpack.min.js +7 -0
- package/client-dist/socket.io.msgpack.min.js.map +1 -0
- package/dist/broadcast-operator.d.ts +283 -0
- package/dist/broadcast-operator.js +436 -0
- package/dist/client.d.ts +120 -0
- package/dist/client.js +274 -0
- package/dist/index.d.ts +598 -0
- package/dist/index.js +818 -0
- package/dist/namespace.d.ts +432 -0
- package/dist/namespace.js +584 -0
- package/dist/parent-namespace.d.ts +30 -0
- package/dist/parent-namespace.js +88 -0
- package/dist/socket-types.d.ts +56 -0
- package/dist/socket-types.js +11 -0
- package/dist/socket.d.ts +613 -0
- package/dist/socket.js +977 -0
- package/dist/typed-events.d.ts +203 -0
- package/dist/typed-events.js +81 -0
- package/dist/uws.d.ts +3 -0
- package/dist/uws.js +136 -0
- package/package.json +88 -0
- package/wrapper.mjs +3 -0
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
import { EventEmitter } from "events";
|
|
2
|
+
/**
|
|
3
|
+
* An events map is an interface that maps event names to their value, which
|
|
4
|
+
* represents the type of the `on` listener.
|
|
5
|
+
*/
|
|
6
|
+
export interface EventsMap {
|
|
7
|
+
[event: string]: any;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* The default events map, used if no EventsMap is given. Using this EventsMap
|
|
11
|
+
* is equivalent to accepting all event names, and any data.
|
|
12
|
+
*/
|
|
13
|
+
export interface DefaultEventsMap {
|
|
14
|
+
[event: string]: (...args: any[]) => void;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Returns a union type containing all the keys of an event map.
|
|
18
|
+
*/
|
|
19
|
+
export type EventNames<Map extends EventsMap> = keyof Map & (string | symbol);
|
|
20
|
+
/**
|
|
21
|
+
* Returns a union type containing all the keys of an event map that have an acknowledgement callback.
|
|
22
|
+
*
|
|
23
|
+
* That also have *some* data coming in.
|
|
24
|
+
*/
|
|
25
|
+
export type EventNamesWithAck<Map extends EventsMap, K extends EventNames<Map> = EventNames<Map>> = IfAny<Last<Parameters<Map[K]>> | Map[K], K, K extends (Last<Parameters<Map[K]>> extends (...args: any[]) => any ? FirstNonErrorArg<Last<Parameters<Map[K]>>> extends void ? never : K : never) ? K : never>;
|
|
26
|
+
/**
|
|
27
|
+
* Returns a union type containing all the keys of an event map that have an acknowledgement callback.
|
|
28
|
+
*
|
|
29
|
+
* That also have *some* data coming in.
|
|
30
|
+
*/
|
|
31
|
+
export type EventNamesWithoutAck<Map extends EventsMap, K extends EventNames<Map> = EventNames<Map>> = IfAny<Last<Parameters<Map[K]>> | Map[K], K, K extends (Parameters<Map[K]> extends never[] ? K : never) ? K : K extends (Last<Parameters<Map[K]>> extends (...args: any[]) => any ? never : K) ? K : never>;
|
|
32
|
+
export type RemoveAcknowledgements<E extends EventsMap> = {
|
|
33
|
+
[K in EventNamesWithoutAck<E>]: E[K];
|
|
34
|
+
};
|
|
35
|
+
export type EventNamesWithError<Map extends EventsMap, K extends EventNamesWithAck<Map> = EventNamesWithAck<Map>> = IfAny<Last<Parameters<Map[K]>> | Map[K], K, K extends (LooseParameters<Last<Parameters<Map[K]>>>[0] extends Error ? K : never) ? K : never>;
|
|
36
|
+
/** The tuple type representing the parameters of an event listener */
|
|
37
|
+
export type EventParams<Map extends EventsMap, Ev extends EventNames<Map>> = Parameters<Map[Ev]>;
|
|
38
|
+
/**
|
|
39
|
+
* The event names that are either in ReservedEvents or in UserEvents
|
|
40
|
+
*/
|
|
41
|
+
export type ReservedOrUserEventNames<ReservedEventsMap extends EventsMap, UserEvents extends EventsMap> = EventNames<ReservedEventsMap> | EventNames<UserEvents>;
|
|
42
|
+
/**
|
|
43
|
+
* Type of a listener of a user event or a reserved event. If `Ev` is in
|
|
44
|
+
* `ReservedEvents`, the reserved event listener is returned.
|
|
45
|
+
*/
|
|
46
|
+
export type ReservedOrUserListener<ReservedEvents extends EventsMap, UserEvents extends EventsMap, Ev extends ReservedOrUserEventNames<ReservedEvents, UserEvents>> = FallbackToUntypedListener<Ev extends EventNames<ReservedEvents> ? ReservedEvents[Ev] : Ev extends EventNames<UserEvents> ? UserEvents[Ev] : never>;
|
|
47
|
+
/**
|
|
48
|
+
* Returns an untyped listener type if `T` is `never`; otherwise, returns `T`.
|
|
49
|
+
*
|
|
50
|
+
* This is a hack to mitigate https://github.com/socketio/socket.io/issues/3833.
|
|
51
|
+
* Needed because of https://github.com/microsoft/TypeScript/issues/41778
|
|
52
|
+
*/
|
|
53
|
+
type FallbackToUntypedListener<T> = [T] extends [never] ? (...args: any[]) => void | Promise<void> : T;
|
|
54
|
+
/**
|
|
55
|
+
* Interface for classes that aren't `EventEmitter`s, but still expose a
|
|
56
|
+
* strictly typed `emit` method.
|
|
57
|
+
*/
|
|
58
|
+
export interface TypedEventBroadcaster<EmitEvents extends EventsMap> {
|
|
59
|
+
emit<Ev extends EventNames<EmitEvents>>(ev: Ev, ...args: EventParams<EmitEvents, Ev>): boolean;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Strictly typed version of an `EventEmitter`. A `TypedEventEmitter` takes type
|
|
63
|
+
* parameters for mappings of event names to event data types, and strictly
|
|
64
|
+
* types method calls to the `EventEmitter` according to these event maps.
|
|
65
|
+
*
|
|
66
|
+
* @typeParam ListenEvents - `EventsMap` of user-defined events that can be
|
|
67
|
+
* listened to with `on` or `once`
|
|
68
|
+
* @typeParam EmitEvents - `EventsMap` of user-defined events that can be
|
|
69
|
+
* emitted with `emit`
|
|
70
|
+
* @typeParam ReservedEvents - `EventsMap` of reserved events, that can be
|
|
71
|
+
* emitted by socket.io with `emitReserved`, and can be listened to with
|
|
72
|
+
* `listen`.
|
|
73
|
+
*/
|
|
74
|
+
export declare abstract class StrictEventEmitter<ListenEvents extends EventsMap, EmitEvents extends EventsMap, ReservedEvents extends EventsMap = {}> extends EventEmitter implements TypedEventBroadcaster<EmitEvents> {
|
|
75
|
+
/**
|
|
76
|
+
* Adds the `listener` function as an event listener for `ev`.
|
|
77
|
+
*
|
|
78
|
+
* @param ev Name of the event
|
|
79
|
+
* @param listener Callback function
|
|
80
|
+
*/
|
|
81
|
+
on<Ev extends ReservedOrUserEventNames<ReservedEvents, ListenEvents>>(ev: Ev, listener: ReservedOrUserListener<ReservedEvents, ListenEvents, Ev>): this;
|
|
82
|
+
/**
|
|
83
|
+
* Adds a one-time `listener` function as an event listener for `ev`.
|
|
84
|
+
*
|
|
85
|
+
* @param ev Name of the event
|
|
86
|
+
* @param listener Callback function
|
|
87
|
+
*/
|
|
88
|
+
once<Ev extends ReservedOrUserEventNames<ReservedEvents, ListenEvents>>(ev: Ev, listener: ReservedOrUserListener<ReservedEvents, ListenEvents, Ev>): this;
|
|
89
|
+
/**
|
|
90
|
+
* Emits an event.
|
|
91
|
+
*
|
|
92
|
+
* @param ev Name of the event
|
|
93
|
+
* @param args Values to send to listeners of this event
|
|
94
|
+
*/
|
|
95
|
+
emit<Ev extends EventNames<EmitEvents>>(ev: Ev, ...args: EventParams<EmitEvents, Ev>): boolean;
|
|
96
|
+
/**
|
|
97
|
+
* Emits a reserved event.
|
|
98
|
+
*
|
|
99
|
+
* This method is `protected`, so that only a class extending
|
|
100
|
+
* `StrictEventEmitter` can emit its own reserved events.
|
|
101
|
+
*
|
|
102
|
+
* @param ev Reserved event name
|
|
103
|
+
* @param args Arguments to emit along with the event
|
|
104
|
+
*/
|
|
105
|
+
protected emitReserved<Ev extends EventNames<ReservedEvents>>(ev: Ev, ...args: EventParams<ReservedEvents, Ev>): boolean;
|
|
106
|
+
/**
|
|
107
|
+
* Emits an event.
|
|
108
|
+
*
|
|
109
|
+
* This method is `protected`, so that only a class extending
|
|
110
|
+
* `StrictEventEmitter` can get around the strict typing. This is useful for
|
|
111
|
+
* calling `emit.apply`, which can be called as `emitUntyped.apply`.
|
|
112
|
+
*
|
|
113
|
+
* @param ev Event name
|
|
114
|
+
* @param args Arguments to emit along with the event
|
|
115
|
+
*/
|
|
116
|
+
protected emitUntyped(ev: string, ...args: any[]): boolean;
|
|
117
|
+
/**
|
|
118
|
+
* Returns the listeners listening to an event.
|
|
119
|
+
*
|
|
120
|
+
* @param event Event name
|
|
121
|
+
* @returns Array of listeners subscribed to `event`
|
|
122
|
+
*/
|
|
123
|
+
listeners<Ev extends ReservedOrUserEventNames<ReservedEvents, ListenEvents>>(event: Ev): ReservedOrUserListener<ReservedEvents, ListenEvents, Ev>[];
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Returns a boolean for whether the given type is `any`.
|
|
127
|
+
*
|
|
128
|
+
* @link https://stackoverflow.com/a/49928360/1490091
|
|
129
|
+
*
|
|
130
|
+
* Useful in type utilities, such as disallowing `any`s to be passed to a function.
|
|
131
|
+
*
|
|
132
|
+
* @author sindresorhus
|
|
133
|
+
* @link https://github.com/sindresorhus/type-fest
|
|
134
|
+
*/
|
|
135
|
+
type IsAny<T> = 0 extends 1 & T ? true : false;
|
|
136
|
+
/**
|
|
137
|
+
* An if-else-like type that resolves depending on whether the given type is `any`.
|
|
138
|
+
*
|
|
139
|
+
* @see {@link IsAny}
|
|
140
|
+
*
|
|
141
|
+
* @author sindresorhus
|
|
142
|
+
* @link https://github.com/sindresorhus/type-fest
|
|
143
|
+
*/
|
|
144
|
+
type IfAny<T, TypeIfAny = true, TypeIfNotAny = false> = IsAny<T> extends true ? TypeIfAny : TypeIfNotAny;
|
|
145
|
+
/**
|
|
146
|
+
* Extracts the type of the last element of an array.
|
|
147
|
+
*
|
|
148
|
+
* Use-case: Defining the return type of functions that extract the last element of an array, for example [`lodash.last`](https://lodash.com/docs/4.17.15#last).
|
|
149
|
+
*
|
|
150
|
+
* @author sindresorhus
|
|
151
|
+
* @link https://github.com/sindresorhus/type-fest
|
|
152
|
+
*/
|
|
153
|
+
export type Last<ValueType extends readonly unknown[]> = ValueType extends readonly [infer ElementType] ? ElementType : ValueType extends readonly [infer _, ...infer Tail] ? Last<Tail> : ValueType extends ReadonlyArray<infer ElementType> ? ElementType : never;
|
|
154
|
+
export type FirstNonErrorTuple<T extends unknown[]> = T[0] extends Error ? T[1] : T[0];
|
|
155
|
+
export type AllButLast<T extends any[]> = T extends [...infer H, infer L] ? H : any[];
|
|
156
|
+
/**
|
|
157
|
+
* Like `Parameters<T>`, but doesn't require `T` to be a function ahead of time.
|
|
158
|
+
*/
|
|
159
|
+
type LooseParameters<T> = T extends (...args: infer P) => any ? P : never;
|
|
160
|
+
export type FirstNonErrorArg<T> = T extends (...args: infer Params) => any ? FirstNonErrorTuple<Params> : any;
|
|
161
|
+
type PrependTimeoutError<T extends any[]> = {
|
|
162
|
+
[K in keyof T]: T[K] extends (...args: infer Params) => infer Result ? Params[0] extends Error ? T[K] : (err: Error, ...args: Params) => Result : T[K];
|
|
163
|
+
};
|
|
164
|
+
export type MultiplyArray<T extends unknown[]> = {
|
|
165
|
+
[K in keyof T]: T[K][];
|
|
166
|
+
};
|
|
167
|
+
type InferFirstAndPreserveLabel<T extends any[]> = T extends [any, ...infer R] ? T extends [...infer H, ...R] ? H : never : never;
|
|
168
|
+
/**
|
|
169
|
+
* Utility type to decorate the acknowledgement callbacks multiple values
|
|
170
|
+
* on the first non error element while removing any elements after
|
|
171
|
+
*/
|
|
172
|
+
type ExpectMultipleResponses<T extends any[]> = {
|
|
173
|
+
[K in keyof T]: T[K] extends (...args: infer Params) => infer Result ? Params extends [Error] ? (err: Error) => Result : Params extends [Error, ...infer Rest] ? (err: Error, ...args: InferFirstAndPreserveLabel<MultiplyArray<Rest>>) => Result : Params extends [] ? () => Result : (...args: InferFirstAndPreserveLabel<MultiplyArray<Params>>) => Result : T[K];
|
|
174
|
+
};
|
|
175
|
+
/**
|
|
176
|
+
* Utility type to decorate the acknowledgement callbacks with a timeout error.
|
|
177
|
+
*
|
|
178
|
+
* This is needed because the timeout() flag breaks the symmetry between the sender and the receiver:
|
|
179
|
+
*
|
|
180
|
+
* @example
|
|
181
|
+
* interface Events {
|
|
182
|
+
* "my-event": (val: string) => void;
|
|
183
|
+
* }
|
|
184
|
+
*
|
|
185
|
+
* socket.on("my-event", (cb) => {
|
|
186
|
+
* cb("123"); // one single argument here
|
|
187
|
+
* });
|
|
188
|
+
*
|
|
189
|
+
* socket.timeout(1000).emit("my-event", (err, val) => {
|
|
190
|
+
* // two arguments there (the "err" argument is not properly typed)
|
|
191
|
+
* });
|
|
192
|
+
*
|
|
193
|
+
*/
|
|
194
|
+
export type DecorateAcknowledgements<E> = {
|
|
195
|
+
[K in keyof E]: E[K] extends (...args: infer Params) => infer Result ? (...args: PrependTimeoutError<Params>) => Result : E[K];
|
|
196
|
+
};
|
|
197
|
+
export type DecorateAcknowledgementsWithTimeoutAndMultipleResponses<E> = {
|
|
198
|
+
[K in keyof E]: E[K] extends (...args: infer Params) => infer Result ? (...args: ExpectMultipleResponses<PrependTimeoutError<Params>>) => Result : E[K];
|
|
199
|
+
};
|
|
200
|
+
export type DecorateAcknowledgementsWithMultipleResponses<E> = {
|
|
201
|
+
[K in keyof E]: E[K] extends (...args: infer Params) => infer Result ? (...args: ExpectMultipleResponses<Params>) => Result : E[K];
|
|
202
|
+
};
|
|
203
|
+
export {};
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.StrictEventEmitter = void 0;
|
|
4
|
+
const events_1 = require("events");
|
|
5
|
+
/**
|
|
6
|
+
* Strictly typed version of an `EventEmitter`. A `TypedEventEmitter` takes type
|
|
7
|
+
* parameters for mappings of event names to event data types, and strictly
|
|
8
|
+
* types method calls to the `EventEmitter` according to these event maps.
|
|
9
|
+
*
|
|
10
|
+
* @typeParam ListenEvents - `EventsMap` of user-defined events that can be
|
|
11
|
+
* listened to with `on` or `once`
|
|
12
|
+
* @typeParam EmitEvents - `EventsMap` of user-defined events that can be
|
|
13
|
+
* emitted with `emit`
|
|
14
|
+
* @typeParam ReservedEvents - `EventsMap` of reserved events, that can be
|
|
15
|
+
* emitted by socket.io with `emitReserved`, and can be listened to with
|
|
16
|
+
* `listen`.
|
|
17
|
+
*/
|
|
18
|
+
class StrictEventEmitter extends events_1.EventEmitter {
|
|
19
|
+
/**
|
|
20
|
+
* Adds the `listener` function as an event listener for `ev`.
|
|
21
|
+
*
|
|
22
|
+
* @param ev Name of the event
|
|
23
|
+
* @param listener Callback function
|
|
24
|
+
*/
|
|
25
|
+
on(ev, listener) {
|
|
26
|
+
return super.on(ev, listener);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Adds a one-time `listener` function as an event listener for `ev`.
|
|
30
|
+
*
|
|
31
|
+
* @param ev Name of the event
|
|
32
|
+
* @param listener Callback function
|
|
33
|
+
*/
|
|
34
|
+
once(ev, listener) {
|
|
35
|
+
return super.once(ev, listener);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Emits an event.
|
|
39
|
+
*
|
|
40
|
+
* @param ev Name of the event
|
|
41
|
+
* @param args Values to send to listeners of this event
|
|
42
|
+
*/
|
|
43
|
+
emit(ev, ...args) {
|
|
44
|
+
return super.emit(ev, ...args);
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Emits a reserved event.
|
|
48
|
+
*
|
|
49
|
+
* This method is `protected`, so that only a class extending
|
|
50
|
+
* `StrictEventEmitter` can emit its own reserved events.
|
|
51
|
+
*
|
|
52
|
+
* @param ev Reserved event name
|
|
53
|
+
* @param args Arguments to emit along with the event
|
|
54
|
+
*/
|
|
55
|
+
emitReserved(ev, ...args) {
|
|
56
|
+
return super.emit(ev, ...args);
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Emits an event.
|
|
60
|
+
*
|
|
61
|
+
* This method is `protected`, so that only a class extending
|
|
62
|
+
* `StrictEventEmitter` can get around the strict typing. This is useful for
|
|
63
|
+
* calling `emit.apply`, which can be called as `emitUntyped.apply`.
|
|
64
|
+
*
|
|
65
|
+
* @param ev Event name
|
|
66
|
+
* @param args Arguments to emit along with the event
|
|
67
|
+
*/
|
|
68
|
+
emitUntyped(ev, ...args) {
|
|
69
|
+
return super.emit(ev, ...args);
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Returns the listeners listening to an event.
|
|
73
|
+
*
|
|
74
|
+
* @param event Event name
|
|
75
|
+
* @returns Array of listeners subscribed to `event`
|
|
76
|
+
*/
|
|
77
|
+
listeners(event) {
|
|
78
|
+
return super.listeners(event);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
exports.StrictEventEmitter = StrictEventEmitter;
|
package/dist/uws.d.ts
ADDED
package/dist/uws.js
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.patchAdapter = patchAdapter;
|
|
7
|
+
exports.restoreAdapter = restoreAdapter;
|
|
8
|
+
exports.serveFile = serveFile;
|
|
9
|
+
const socket_io_adapter_1 = require("socket.io-adapter");
|
|
10
|
+
const fs_1 = require("fs");
|
|
11
|
+
const debug_1 = __importDefault(require("debug"));
|
|
12
|
+
const debug = (0, debug_1.default)("socket.io:adapter-uws");
|
|
13
|
+
const SEPARATOR = "\x1f"; // see https://en.wikipedia.org/wiki/Delimiter#ASCII_delimited_text
|
|
14
|
+
const { addAll, del, broadcast } = socket_io_adapter_1.Adapter.prototype;
|
|
15
|
+
function patchAdapter(app /* : TemplatedApp */) {
|
|
16
|
+
socket_io_adapter_1.Adapter.prototype.addAll = function (id, rooms) {
|
|
17
|
+
const isNew = !this.sids.has(id);
|
|
18
|
+
addAll.call(this, id, rooms);
|
|
19
|
+
const socket = this.nsp.sockets.get(id) || this.nsp._preConnectSockets.get(id);
|
|
20
|
+
if (!socket) {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
if (socket.conn.transport.name === "websocket") {
|
|
24
|
+
subscribe(this.nsp.name, socket, isNew, rooms);
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
if (isNew) {
|
|
28
|
+
socket.conn.on("upgrade", () => {
|
|
29
|
+
const rooms = this.sids.get(id);
|
|
30
|
+
if (rooms) {
|
|
31
|
+
subscribe(this.nsp.name, socket, isNew, rooms);
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
socket_io_adapter_1.Adapter.prototype.del = function (id, room) {
|
|
37
|
+
del.call(this, id, room);
|
|
38
|
+
const socket = this.nsp.sockets.get(id) || this.nsp._preConnectSockets.get(id);
|
|
39
|
+
if (socket && socket.conn.transport.name === "websocket") {
|
|
40
|
+
// @ts-ignore
|
|
41
|
+
const sessionId = socket.conn.id;
|
|
42
|
+
// @ts-ignore
|
|
43
|
+
const websocket = socket.conn.transport.socket;
|
|
44
|
+
const topic = `${this.nsp.name}${SEPARATOR}${room}`;
|
|
45
|
+
debug("unsubscribe connection %s from topic %s", sessionId, topic);
|
|
46
|
+
websocket.unsubscribe(topic);
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
socket_io_adapter_1.Adapter.prototype.broadcast = function (packet, opts) {
|
|
50
|
+
const useFastPublish = opts.rooms.size <= 1 && opts.except.size === 0;
|
|
51
|
+
if (!useFastPublish) {
|
|
52
|
+
broadcast.call(this, packet, opts);
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
const flags = opts.flags || {};
|
|
56
|
+
const basePacketOpts = {
|
|
57
|
+
preEncoded: true,
|
|
58
|
+
volatile: flags.volatile,
|
|
59
|
+
compress: flags.compress,
|
|
60
|
+
};
|
|
61
|
+
packet.nsp = this.nsp.name;
|
|
62
|
+
const encodedPackets = this.encoder.encode(packet);
|
|
63
|
+
const topic = opts.rooms.size === 0
|
|
64
|
+
? this.nsp.name
|
|
65
|
+
: `${this.nsp.name}${SEPARATOR}${opts.rooms.keys().next().value}`;
|
|
66
|
+
debug("fast publish to %s", topic);
|
|
67
|
+
// fast publish for clients connected with WebSocket
|
|
68
|
+
encodedPackets.forEach((encodedPacket) => {
|
|
69
|
+
const isBinary = typeof encodedPacket !== "string";
|
|
70
|
+
// "4" being the message type in the Engine.IO protocol, see https://github.com/socketio/engine.io-protocol
|
|
71
|
+
app.publish(topic, isBinary ? encodedPacket : "4" + encodedPacket, isBinary);
|
|
72
|
+
});
|
|
73
|
+
this.apply(opts, (socket) => {
|
|
74
|
+
if (socket.conn.transport.name !== "websocket") {
|
|
75
|
+
// classic publish for clients connected with HTTP long-polling
|
|
76
|
+
socket.client.writeToEngine(encodedPackets, basePacketOpts);
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
function subscribe(namespaceName, socket, isNew, rooms) {
|
|
82
|
+
// @ts-ignore
|
|
83
|
+
const sessionId = socket.conn.id;
|
|
84
|
+
// @ts-ignore
|
|
85
|
+
const websocket = socket.conn.transport.socket;
|
|
86
|
+
if (isNew) {
|
|
87
|
+
debug("subscribe connection %s to topic %s", sessionId, namespaceName);
|
|
88
|
+
websocket.subscribe(namespaceName);
|
|
89
|
+
}
|
|
90
|
+
rooms.forEach((room) => {
|
|
91
|
+
const topic = `${namespaceName}${SEPARATOR}${room}`; // '#' can be used as wildcard
|
|
92
|
+
debug("subscribe connection %s to topic %s", sessionId, topic);
|
|
93
|
+
websocket.subscribe(topic);
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
function restoreAdapter() {
|
|
97
|
+
socket_io_adapter_1.Adapter.prototype.addAll = addAll;
|
|
98
|
+
socket_io_adapter_1.Adapter.prototype.del = del;
|
|
99
|
+
socket_io_adapter_1.Adapter.prototype.broadcast = broadcast;
|
|
100
|
+
}
|
|
101
|
+
const toArrayBuffer = (buffer) => {
|
|
102
|
+
const { buffer: arrayBuffer, byteOffset, byteLength } = buffer;
|
|
103
|
+
return arrayBuffer.slice(byteOffset, byteOffset + byteLength);
|
|
104
|
+
};
|
|
105
|
+
// imported from https://github.com/kolodziejczak-sz/uwebsocket-serve
|
|
106
|
+
function serveFile(res /* : HttpResponse */, filepath) {
|
|
107
|
+
const { size } = (0, fs_1.statSync)(filepath);
|
|
108
|
+
const readStream = (0, fs_1.createReadStream)(filepath);
|
|
109
|
+
const destroyReadStream = () => !readStream.destroyed && readStream.destroy();
|
|
110
|
+
const onError = (error) => {
|
|
111
|
+
destroyReadStream();
|
|
112
|
+
throw error;
|
|
113
|
+
};
|
|
114
|
+
const onDataChunk = (chunk) => {
|
|
115
|
+
const arrayBufferChunk = toArrayBuffer(chunk);
|
|
116
|
+
res.cork(() => {
|
|
117
|
+
const lastOffset = res.getWriteOffset();
|
|
118
|
+
const [ok, done] = res.tryEnd(arrayBufferChunk, size);
|
|
119
|
+
if (!done && !ok) {
|
|
120
|
+
readStream.pause();
|
|
121
|
+
res.onWritable((offset) => {
|
|
122
|
+
const [ok, done] = res.tryEnd(arrayBufferChunk.slice(offset - lastOffset), size);
|
|
123
|
+
if (!done && ok) {
|
|
124
|
+
readStream.resume();
|
|
125
|
+
}
|
|
126
|
+
return ok;
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
};
|
|
131
|
+
res.onAborted(destroyReadStream);
|
|
132
|
+
readStream
|
|
133
|
+
.on("data", onDataChunk)
|
|
134
|
+
.on("error", onError)
|
|
135
|
+
.on("end", destroyReadStream);
|
|
136
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@gleamkit/socket.io",
|
|
3
|
+
"version": "4.8.6",
|
|
4
|
+
"description": "node.js realtime framework server",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"realtime",
|
|
7
|
+
"framework",
|
|
8
|
+
"websocket",
|
|
9
|
+
"tcp",
|
|
10
|
+
"events",
|
|
11
|
+
"socket",
|
|
12
|
+
"io"
|
|
13
|
+
],
|
|
14
|
+
"files": [
|
|
15
|
+
"dist/",
|
|
16
|
+
"client-dist/",
|
|
17
|
+
"wrapper.mjs",
|
|
18
|
+
"!**/*.tsbuildinfo"
|
|
19
|
+
],
|
|
20
|
+
"directories": {
|
|
21
|
+
"doc": "docs/",
|
|
22
|
+
"example": "example/",
|
|
23
|
+
"lib": "lib/",
|
|
24
|
+
"test": "test/"
|
|
25
|
+
},
|
|
26
|
+
"type": "commonjs",
|
|
27
|
+
"main": "./dist/index.js",
|
|
28
|
+
"exports": {
|
|
29
|
+
".": {
|
|
30
|
+
"types": "./dist/index.d.ts",
|
|
31
|
+
"import": "./wrapper.mjs",
|
|
32
|
+
"require": "./dist/index.js"
|
|
33
|
+
},
|
|
34
|
+
"./package.json": "./package.json"
|
|
35
|
+
},
|
|
36
|
+
"types": "./dist/index.d.ts",
|
|
37
|
+
"license": "MIT",
|
|
38
|
+
"homepage": "https://github.com/socketio/socket.io/tree/main/packages/socket.io#readme",
|
|
39
|
+
"repository": {
|
|
40
|
+
"type": "git",
|
|
41
|
+
"url": "git+https://github.com/socketio/socket.io.git"
|
|
42
|
+
},
|
|
43
|
+
"bugs": {
|
|
44
|
+
"url": "https://github.com/socketio/socket.io/issues"
|
|
45
|
+
},
|
|
46
|
+
"scripts": {
|
|
47
|
+
"compile": "rimraf ./dist && tsc",
|
|
48
|
+
"test": "npm run format:check && npm run compile && npm run test:types && npm run test:unit",
|
|
49
|
+
"test:types": "tsd",
|
|
50
|
+
"test:unit": "nyc mocha --import=tsx --reporter spec --slow 200 --bail --timeout 10000 test/index.ts",
|
|
51
|
+
"format:check": "prettier --check \"lib/**/*.ts\" \"test/**/*.ts\"",
|
|
52
|
+
"format:fix": "prettier --write \"lib/**/*.ts\" \"test/**/*.ts\"",
|
|
53
|
+
"prepack": "echo 'skip compile — dist already present'"
|
|
54
|
+
},
|
|
55
|
+
"dependencies": {
|
|
56
|
+
"accepts": "~1.3.4",
|
|
57
|
+
"base64id": "~2.0.0",
|
|
58
|
+
"cors": "~2.8.5",
|
|
59
|
+
"debug": "~4.4.1",
|
|
60
|
+
"engine.io": "npm:@gleamkit/engine.io@6.6.3",
|
|
61
|
+
"socket.io-adapter": "~2.5.2",
|
|
62
|
+
"socket.io-parser": "~4.2.4"
|
|
63
|
+
},
|
|
64
|
+
"contributors": [
|
|
65
|
+
{
|
|
66
|
+
"name": "Guillermo Rauch",
|
|
67
|
+
"email": "rauchg@gmail.com"
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
"name": "Arnout Kazemier",
|
|
71
|
+
"email": "info@3rd-eden.com"
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
"name": "Vladimir Dronnikov",
|
|
75
|
+
"email": "dronnikov@gmail.com"
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
"name": "Einar Otto Stangvik",
|
|
79
|
+
"email": "einaros@gmail.com"
|
|
80
|
+
}
|
|
81
|
+
],
|
|
82
|
+
"engines": {
|
|
83
|
+
"node": ">=10.2.0"
|
|
84
|
+
},
|
|
85
|
+
"tsd": {
|
|
86
|
+
"directory": "test"
|
|
87
|
+
}
|
|
88
|
+
}
|
package/wrapper.mjs
ADDED