Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export { SocketIoModule, SOCKET_CONFIG_TOKEN, provideSocketIo } from './src/socket-io.module';
export { SocketIoConfig } from './src/config/socket-io.config';
export { WrappedSocket as Socket } from './src/socket-io.service';
export type { AllButLast, First, FirstArg, Last } from './src/socket-io.service';
export type { AllButLast, DecorateAcknowledgements, First, FirstArg, Last } from './src/socket-io.service';
export type { DefaultEventsMap, EventNames, EventParams, EventsMap, ReservedOrUserEventNames, ReservedOrUserListener } from '@socket.io/component-emitter';
46 changes: 30 additions & 16 deletions src/socket-io.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,16 @@ export type IoSocket<
EmitEvents extends EventsMap = ListenEvents,
> = Socket<ListenEvents, EmitEvents>;
// socket.io-client internal types for emitWithAck
type PrependTimeoutError<T extends any[]> = {
[K in keyof T]: T[K] extends (...args: infer Params) => infer Result
? (err: Error, ...args: Params) => Result
: T[K];
};
export type DecorateAcknowledgements<E> = {
[K in keyof E]: E[K] extends (...args: infer Params) => infer Result
? (...args: PrependTimeoutError<Params>) => Result
: E[K];
};
export type First<T extends any[]> = T extends [infer F, ...infer L] ? F : any;
export type Last<T extends any[]> = T extends [...infer H, infer L] ? L : any;
export type AllButLast<T extends any[]> = T extends [...infer H, infer L] ? H : any[];
Expand All @@ -42,22 +52,24 @@ interface SocketReservedEvents {
) => void;
}

type IgnoredWrapperEvents = 'receiveBuffer' | 'sendBuffer';
type IgnoredWrapperEvents = 'receiveBuffer' | 'sendBuffer' | 'timeout';

type WrappedSocketIface<Wrapper> = {
[K in Exclude<keyof IoSocket, IgnoredWrapperEvents>]: IoSocket[K] extends (
...args: any[]
) => IoSocket
? (...args: Parameters<IoSocket[K]>) => Wrapper // chainable methods on().off().emit()...
: IoSocket[K] extends IoSocket
? Wrapper // ie: volatile is a getter
: IoSocket[K];
};
type WrappedSocketIface<Wrapper> = Wrapper extends WrappedSocket<infer ListenEvents, infer EmitEvents>
? {
[K in Exclude<keyof IoSocket<ListenEvents, EmitEvents>, IgnoredWrapperEvents>]: IoSocket<ListenEvents, EmitEvents>[K] extends (
...args: any[]
) => IoSocket<ListenEvents, EmitEvents>
? (...args: Parameters<IoSocket<ListenEvents, EmitEvents>[K]>) => Wrapper // chainable methods on().off().emit()...
: IoSocket<ListenEvents, EmitEvents>[K] extends IoSocket<ListenEvents, EmitEvents>
? Wrapper // ie: volatile is a getter
: IoSocket<ListenEvents, EmitEvents>[K];
}
: never;

export class WrappedSocket<
ListenEvents extends EventsMap = DefaultEventsMap,
EmitEvents extends EventsMap = ListenEvents,
> implements WrappedSocketIface<WrappedSocket> {
> implements WrappedSocketIface<WrappedSocket<ListenEvents, EmitEvents>> {
private readonly subscribersCounter: Partial<Record<ReservedOrUserEventNames<SocketReservedEvents, ListenEvents>, number>> = {};
private readonly eventObservables$: Partial<Record<ReservedOrUserEventNames<SocketReservedEvents, ListenEvents>, Observable<any>>> = {};
private readonly namespaces: Record<string, WrappedSocket> = {};
Expand Down Expand Up @@ -96,12 +108,12 @@ export class WrappedSocket<
}

/** alias to connect */
get open(): WrappedSocket['connect'] {
get open(): WrappedSocket<ListenEvents, EmitEvents>['connect'] {
return this.connect;
}

/** alias to disconnect */
get close(): WrappedSocket['disconnect'] {
get close(): WrappedSocket<ListenEvents, EmitEvents>['disconnect'] {
return this.disconnect;
}

Expand Down Expand Up @@ -171,8 +183,8 @@ export class WrappedSocket<
return this;
}

send(..._args: any[]): this {
this.ioSocket.send.apply(this.ioSocket, arguments);
send(...args: any[]): this {
this.ioSocket.send(...args);
return this;
}

Expand Down Expand Up @@ -297,7 +309,9 @@ export class WrappedSocket<
return this;
}

timeout(value: number): this {
timeout(
value: number
): WrappedSocket<ListenEvents, DecorateAcknowledgements<EmitEvents>> {
this.ioSocket.timeout(value);
return this;
}
Expand Down
3 changes: 1 addition & 2 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@
"declaration": true,
"stripInternal": true,
"experimentalDecorators": true,
"strictNullChecks": true,
"noImplicitAny": true,
"strict": true,
"module": "es2015",
"moduleResolution": "node",
"paths": {
Expand Down