Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 | 2x 2x 2x 18x 18x 18x 18x 2x 35x 35x 35x 35x 35x 35x 35x 19x 3x 35x 35x 17x 17x 17x 16x 16x 15x 15x 16x 16x 16x 16x 2x 2x 2x 5x 5x 5x 35x 35x 35x 35x 34x 7x 9x 8x 1x 1x 9x 9x 9x 9x | import {utf8Size} from '@jsonjoy.com/util/lib/strings/utf8';
import {WebSocketState} from '../constants';
import type {Subscription} from 'rxjs';
import {toUint8Array} from '@jsonjoy.com/buffers/lib/toUint8Array';
import type {WebSocketMockServerConnection} from './WebSocketMockServerConnection';
export class CloseEvent {
public readonly type = 'close';
constructor(
public readonly code: number,
public readonly reason: string,
public readonly wasClean: boolean,
) {}
}
export interface WebSocketMockParams {
connection?: WebSocketMockServerConnection;
}
export class WebSocketMock
implements
Pick<
WebSocket,
'binaryType' | 'readyState' | 'bufferedAmount' | 'onopen' | 'onclose' | 'onerror' | 'onmessage' | 'close' | 'send'
>
{
public static create(params: Partial<WebSocketMockParams>, url: string = 'http://127.0.0.1') {
const ws = new WebSocketMock(params, url);
return [ws, ws.controller];
}
public onclose: ((event: any) => void) | null = null;
public onerror: ((event: Event) => void) | null = null;
public onmessage: ((event: Event) => void) | null = null;
public onopen: ((event: Event) => void) | null = null;
public binaryType: 'arraybuffer' | 'blob' = 'blob';
public _readyState: WebSocketState = WebSocketState.CONNECTING;
public _bufferedAmount = 0;
public get bufferedAmount(): number {
return this._bufferedAmount;
}
public get readyState(): number {
return this._readyState;
}
public _connectionSub: Subscription | null = null;
public readonly controller = {
readyState: WebSocketState.CLOSED,
bufferedAmount: 0,
open: (): void => {
this._readyState = WebSocketState.OPEN;
const event = {type: 'open'} as Event;
this.onopen?.(event);
},
close: (code: number, reason: string, wasClean: boolean): void => {
this._connectionSub?.unsubscribe();
if (this.params.connection) {
this.params.connection.outgoing$.complete();
this.params.connection.incoming$.complete();
}
Iif (this._readyState === WebSocketState.CLOSED) throw new Error('Mock WebSocket already closed.');
this._readyState = WebSocketState.CLOSED;
const event = new CloseEvent(code, reason, wasClean);
this.onclose?.(event);
},
error: (message: string): void => {
const event = {type: 'error'} as Event;
this.onerror?.(event);
this.controller.close(1000, message, false);
},
message: (message: string | ArrayBuffer | ArrayBufferView): void => {
Iif (!this.onmessage) return;
const event = {type: 'message', data: message} as any;
this.onmessage(event);
},
};
constructor(
public readonly params: Partial<WebSocketMockParams>,
public readonly url: string = 'http://127.0.0.1',
) {
const {connection} = params;
if (connection) {
this._connectionSub = connection.outgoing$.subscribe((data) => {
this.controller.message(data);
});
}
}
public close(code?: number, reason?: string): void {
this.controller.close(code ?? 0, reason ?? '', true);
}
public send(data: string | ArrayBufferLike | Blob | ArrayBufferView): void {
if (typeof data === 'string') {
this._bufferedAmount += utf8Size(data);
} else if (ArrayBuffer.isView(data)) {
this._bufferedAmount += data.byteLength;
} else Eif (data && typeof data === 'object') {
if ((data as any).byteLength !== undefined) {
this._bufferedAmount += Number((data as any).byteLength);
} else if ((data as unknown as Blob).size !== undefined) {
this._bufferedAmount += Number((data as unknown as Blob).size);
}
}
Eif (this.params.connection) {
Iif (data instanceof Blob) {
data.bytes().then((buf) => {
this.params.connection?.incoming$.next(new Uint8Array(buf));
});
} else {
const buf = toUint8Array(data);
this.params.connection.incoming$.next(buf);
}
}
}
}
|