larasopp 1.1.3 → 1.2.2
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/README.md +17 -4
- package/lib/Core.d.ts +16 -8
- package/lib/Core.js +53 -23
- package/lib/Listener.d.ts +11 -0
- package/lib/Listener.js +40 -0
- package/lib/Subscribe.d.ts +3 -3
- package/lib/Subscribe.js +1 -1
- package/lib/index.d.ts +8 -9
- package/lib/index.js +30 -31
- package/package.json +1 -1
- package/src/Core.ts +57 -33
- package/src/Listener.ts +31 -0
- package/src/index.ts +39 -40
- package/src/Subscribe.ts +0 -96
package/README.md
CHANGED
|
@@ -10,6 +10,7 @@ composer require larasopp/larasopp
|
|
|
10
10
|
```
|
|
11
11
|
|
|
12
12
|
### Connect app to websocket
|
|
13
|
+
|
|
13
14
|
```js
|
|
14
15
|
...
|
|
15
16
|
import Larasopp from "Larasopp";
|
|
@@ -21,17 +22,22 @@ const larasopp = new Larasopp({
|
|
|
21
22
|
|
|
22
23
|
larasopp.connect();
|
|
23
24
|
|
|
24
|
-
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### Update user token
|
|
25
28
|
|
|
29
|
+
```js
|
|
30
|
+
larasopp.setToken('new token');
|
|
26
31
|
```
|
|
27
32
|
|
|
28
|
-
### Subscribe on channel and
|
|
33
|
+
### Subscribe on channel and listen event
|
|
34
|
+
|
|
29
35
|
```js
|
|
30
|
-
const listener = larasopp.subscribe('chat').
|
|
36
|
+
const listener = larasopp.subscribe('chat').listen('message',(data) => {
|
|
31
37
|
console.log(data.text); // Hello World
|
|
32
38
|
});
|
|
33
39
|
|
|
34
|
-
// Unsubscribe
|
|
40
|
+
// Unsubscribe event
|
|
35
41
|
listener.remove();
|
|
36
42
|
```
|
|
37
43
|
|
|
@@ -43,7 +49,14 @@ larasopp.trigger('chat','message',{
|
|
|
43
49
|
},'public');
|
|
44
50
|
```
|
|
45
51
|
|
|
52
|
+
### Unsubscribe channel
|
|
53
|
+
|
|
54
|
+
```js
|
|
55
|
+
larasopp.unsubscribe('chat');
|
|
56
|
+
```
|
|
57
|
+
|
|
46
58
|
### Disconnect
|
|
59
|
+
|
|
47
60
|
```js
|
|
48
61
|
larasopp.disconnect();
|
|
49
62
|
```
|
package/lib/Core.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { Events } from "easy-event-emitter";
|
|
1
|
+
import { type Events } from "easy-event-emitter";
|
|
2
|
+
import type Listener from "./Listener";
|
|
2
3
|
export declare const SocketEvents: readonly ["open", "close", "error"];
|
|
3
4
|
export type TSocketEvents = typeof SocketEvents[number];
|
|
4
5
|
export declare const ListenerEvents: readonly ["subscribe", "unsubscribe"];
|
|
@@ -7,7 +8,7 @@ export type TListenerCallback = (data: {
|
|
|
7
8
|
channel: string;
|
|
8
9
|
}) => void;
|
|
9
10
|
export type TPermissions = 'public' | 'protected' | 'private';
|
|
10
|
-
export type
|
|
11
|
+
export type TListen = {
|
|
11
12
|
remove: () => void;
|
|
12
13
|
};
|
|
13
14
|
export type TMessage<T> = {
|
|
@@ -15,6 +16,7 @@ export type TMessage<T> = {
|
|
|
15
16
|
unsubscribe?: string;
|
|
16
17
|
channel?: string;
|
|
17
18
|
event?: string;
|
|
19
|
+
token?: string;
|
|
18
20
|
message?: T;
|
|
19
21
|
type?: TPermissions;
|
|
20
22
|
};
|
|
@@ -23,10 +25,14 @@ export interface IConfig {
|
|
|
23
25
|
token?: string;
|
|
24
26
|
tls?: boolean;
|
|
25
27
|
}
|
|
28
|
+
export type TChannels = {
|
|
29
|
+
[channel: string]: Listener[];
|
|
30
|
+
};
|
|
26
31
|
declare abstract class Core {
|
|
27
|
-
|
|
32
|
+
readonly events: Events;
|
|
28
33
|
private ws?;
|
|
29
34
|
protected _status: boolean;
|
|
35
|
+
private _socketId?;
|
|
30
36
|
private config;
|
|
31
37
|
constructor(config: IConfig);
|
|
32
38
|
setConfig(config: IConfig): void;
|
|
@@ -41,13 +47,15 @@ declare abstract class Core {
|
|
|
41
47
|
* @returns {void}
|
|
42
48
|
*/
|
|
43
49
|
disconnect(): void;
|
|
44
|
-
protected
|
|
45
|
-
private
|
|
46
|
-
private
|
|
47
|
-
private
|
|
48
|
-
private
|
|
50
|
+
protected isJson(str: string): boolean;
|
|
51
|
+
private handleOpen;
|
|
52
|
+
private handleClose;
|
|
53
|
+
private handleError;
|
|
54
|
+
private handleMessage;
|
|
49
55
|
private emitListener;
|
|
56
|
+
get socketId(): string | undefined;
|
|
50
57
|
get status(): boolean;
|
|
58
|
+
private _send;
|
|
51
59
|
protected send<T>(message: TMessage<T>): void;
|
|
52
60
|
}
|
|
53
61
|
export default Core;
|
package/lib/Core.js
CHANGED
|
@@ -27,6 +27,12 @@ class Core {
|
|
|
27
27
|
writable: true,
|
|
28
28
|
value: void 0
|
|
29
29
|
});
|
|
30
|
+
Object.defineProperty(this, "_socketId", {
|
|
31
|
+
enumerable: true,
|
|
32
|
+
configurable: true,
|
|
33
|
+
writable: true,
|
|
34
|
+
value: void 0
|
|
35
|
+
});
|
|
30
36
|
Object.defineProperty(this, "config", {
|
|
31
37
|
enumerable: true,
|
|
32
38
|
configurable: true,
|
|
@@ -36,20 +42,19 @@ class Core {
|
|
|
36
42
|
this.events = new easy_event_emitter_1.default;
|
|
37
43
|
this.config = Object.assign({ tls: false }, config);
|
|
38
44
|
this._status = false;
|
|
39
|
-
this.
|
|
40
|
-
this.
|
|
41
|
-
this.
|
|
42
|
-
this.
|
|
43
|
-
this.onOpen = this.onOpen.bind(this);
|
|
44
|
-
this.onClose = this.onClose.bind(this);
|
|
45
|
-
this.onError = this.onError.bind(this);
|
|
46
|
-
this.onMessage = this.onMessage.bind(this);
|
|
45
|
+
this.handleOpen = this.handleOpen.bind(this);
|
|
46
|
+
this.handleClose = this.handleClose.bind(this);
|
|
47
|
+
this.handleError = this.handleError.bind(this);
|
|
48
|
+
this.handleMessage = this.handleMessage.bind(this);
|
|
47
49
|
}
|
|
48
50
|
setConfig(config) {
|
|
49
51
|
this.config = Object.assign({ tls: false }, config);
|
|
50
52
|
}
|
|
51
53
|
setToken(token) {
|
|
52
54
|
this.config = Object.assign(Object.assign({}, this.config), { token });
|
|
55
|
+
this.send({
|
|
56
|
+
token
|
|
57
|
+
});
|
|
53
58
|
}
|
|
54
59
|
/**
|
|
55
60
|
* Connect to websocket
|
|
@@ -61,17 +66,21 @@ class Core {
|
|
|
61
66
|
return this;
|
|
62
67
|
}
|
|
63
68
|
try {
|
|
64
|
-
|
|
69
|
+
const host = [(this.config.tls ? 'wss' : 'ws') + '://'];
|
|
70
|
+
host.push(this.config.host);
|
|
71
|
+
if (this.config.token)
|
|
72
|
+
host.push('/token=' + this.config.token);
|
|
73
|
+
this.ws = new WebSocket(host.join(''));
|
|
74
|
+
this.ws.onopen = this.handleOpen;
|
|
75
|
+
this.ws.onclose = this.handleClose;
|
|
76
|
+
this.ws.onerror = this.handleError;
|
|
77
|
+
this.ws.onmessage = this.handleMessage;
|
|
65
78
|
}
|
|
66
79
|
catch (e) {
|
|
67
80
|
console.warn(e);
|
|
68
|
-
this.
|
|
69
|
-
this.
|
|
81
|
+
this.handleError(new Event('Socket exception'));
|
|
82
|
+
this.handleClose(new CloseEvent(String(e)));
|
|
70
83
|
}
|
|
71
|
-
this.ws.onopen = this.onOpen;
|
|
72
|
-
this.ws.onclose = this.onClose;
|
|
73
|
-
this.ws.onerror = this.onError;
|
|
74
|
-
this.ws.onmessage = this.onMessage;
|
|
75
84
|
return this;
|
|
76
85
|
}
|
|
77
86
|
/**
|
|
@@ -84,8 +93,9 @@ class Core {
|
|
|
84
93
|
(_a = this.ws) === null || _a === void 0 ? void 0 : _a.close();
|
|
85
94
|
this._status = false;
|
|
86
95
|
}
|
|
96
|
+
this.ws = undefined;
|
|
87
97
|
}
|
|
88
|
-
|
|
98
|
+
isJson(str) {
|
|
89
99
|
try {
|
|
90
100
|
JSON.parse(str);
|
|
91
101
|
}
|
|
@@ -94,20 +104,24 @@ class Core {
|
|
|
94
104
|
}
|
|
95
105
|
return true;
|
|
96
106
|
}
|
|
97
|
-
|
|
107
|
+
handleOpen(e) {
|
|
98
108
|
this._status = true;
|
|
99
109
|
this.events.emit("open", e);
|
|
100
110
|
}
|
|
101
|
-
|
|
111
|
+
handleClose(e) {
|
|
102
112
|
this._status = false;
|
|
103
113
|
this.events.emit("close", e);
|
|
104
114
|
}
|
|
105
|
-
|
|
115
|
+
handleError(e) {
|
|
106
116
|
this.events.emit("error", e);
|
|
107
117
|
}
|
|
108
|
-
|
|
109
|
-
if (this.
|
|
118
|
+
handleMessage(e) {
|
|
119
|
+
if (this.isJson(e.data)) {
|
|
110
120
|
const json = JSON.parse(e.data);
|
|
121
|
+
if (json.socket_id) {
|
|
122
|
+
this._socketId = json.socket_id;
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
111
125
|
this.emitListener(json.channel, json.message);
|
|
112
126
|
this.events.emit(json.channel + ':' + json.event, json.message);
|
|
113
127
|
}
|
|
@@ -119,13 +133,29 @@ class Core {
|
|
|
119
133
|
});
|
|
120
134
|
}
|
|
121
135
|
}
|
|
136
|
+
get socketId() {
|
|
137
|
+
return this._socketId;
|
|
138
|
+
}
|
|
122
139
|
get status() {
|
|
140
|
+
if (!this._status)
|
|
141
|
+
this.connect();
|
|
123
142
|
return this._status;
|
|
124
143
|
}
|
|
125
|
-
|
|
126
|
-
if (!this.
|
|
144
|
+
_send(message) {
|
|
145
|
+
if (!this.ws)
|
|
127
146
|
return;
|
|
128
147
|
this.ws.send(JSON.stringify(message));
|
|
129
148
|
}
|
|
149
|
+
send(message) {
|
|
150
|
+
if (this.status) {
|
|
151
|
+
this._send(message);
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
const event = this.events.addListener('open', () => {
|
|
155
|
+
this._send(message);
|
|
156
|
+
event.remove();
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
}
|
|
130
160
|
}
|
|
131
161
|
exports.default = Core;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type Event } from "easy-event-emitter";
|
|
2
|
+
import type Larasopp from ".";
|
|
3
|
+
declare class Listener {
|
|
4
|
+
private readonly context;
|
|
5
|
+
private channel;
|
|
6
|
+
private listeners?;
|
|
7
|
+
constructor(channel: string, constext: Larasopp);
|
|
8
|
+
listen(event: string, callback: (data: any) => void): Event;
|
|
9
|
+
remove(): void;
|
|
10
|
+
}
|
|
11
|
+
export default Listener;
|
package/lib/Listener.js
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
class Listener {
|
|
4
|
+
constructor(channel, constext) {
|
|
5
|
+
Object.defineProperty(this, "context", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
configurable: true,
|
|
8
|
+
writable: true,
|
|
9
|
+
value: void 0
|
|
10
|
+
});
|
|
11
|
+
Object.defineProperty(this, "channel", {
|
|
12
|
+
enumerable: true,
|
|
13
|
+
configurable: true,
|
|
14
|
+
writable: true,
|
|
15
|
+
value: void 0
|
|
16
|
+
});
|
|
17
|
+
Object.defineProperty(this, "listeners", {
|
|
18
|
+
enumerable: true,
|
|
19
|
+
configurable: true,
|
|
20
|
+
writable: true,
|
|
21
|
+
value: void 0
|
|
22
|
+
});
|
|
23
|
+
this.channel = channel;
|
|
24
|
+
this.context = constext;
|
|
25
|
+
}
|
|
26
|
+
listen(event, callback) {
|
|
27
|
+
if (!this.listeners) {
|
|
28
|
+
this.listeners = [];
|
|
29
|
+
}
|
|
30
|
+
const listener = this.context.events.addListener(this.channel + ':' + event, callback);
|
|
31
|
+
this.listeners.push(listener);
|
|
32
|
+
return listener;
|
|
33
|
+
}
|
|
34
|
+
remove() {
|
|
35
|
+
if (!this.listeners)
|
|
36
|
+
return;
|
|
37
|
+
this.listeners.forEach((listener) => listener.remove());
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
exports.default = Listener;
|
package/lib/Subscribe.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { TMessage, TListenerEvents, TListenerCallback,
|
|
2
|
-
import { Event, Events } from "easy-event-emitter";
|
|
1
|
+
import { TMessage, TListenerEvents, TListenerCallback, TListen } from "./Core";
|
|
2
|
+
import type { Event, Events } from "easy-event-emitter";
|
|
3
3
|
interface ISubscribe {
|
|
4
4
|
events: Events;
|
|
5
5
|
hasChannel: (channel: string) => boolean;
|
|
@@ -21,7 +21,7 @@ declare class Subscribe {
|
|
|
21
21
|
constructor({ events, hasChannel, pushChannel, removeChannel, status, channel, send }: ISubscribe);
|
|
22
22
|
get channel(): string;
|
|
23
23
|
private init;
|
|
24
|
-
|
|
24
|
+
listen<T>(event: string, callback: (data: T) => void): TListen;
|
|
25
25
|
private clearEvents;
|
|
26
26
|
remove(): void;
|
|
27
27
|
addListener(event: TListenerEvents, callback: TListenerCallback): Event | undefined;
|
package/lib/Subscribe.js
CHANGED
package/lib/index.d.ts
CHANGED
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
import { Event } from "easy-event-emitter";
|
|
2
|
-
import Core, { IConfig, TPermissions, TSocketEvents, TListenerCallback,
|
|
3
|
-
import
|
|
2
|
+
import Core, { type IConfig, type TPermissions, type TSocketEvents, type TListenerCallback, type TListen } from "./Core";
|
|
3
|
+
import Listener from "./Listener";
|
|
4
4
|
declare class Larasopp extends Core {
|
|
5
|
-
private
|
|
5
|
+
private readonly channels;
|
|
6
6
|
constructor(config: IConfig);
|
|
7
|
-
|
|
7
|
+
private listenResumeSubscribes;
|
|
8
|
+
subscribe(channel: string): Listener;
|
|
9
|
+
unsubscribe(channel: string): void;
|
|
8
10
|
trigger<T>(channel: string, event: string, message: T, permission?: TPermissions, waitSubscribe?: boolean): void;
|
|
9
|
-
private
|
|
10
|
-
private removeChannel;
|
|
11
|
-
private get channels();
|
|
12
|
-
hasChannel(channel: string): boolean;
|
|
11
|
+
private pushListener;
|
|
13
12
|
addListener(event: TSocketEvents, callback: TListenerCallback): Event | undefined;
|
|
14
13
|
}
|
|
15
|
-
export type {
|
|
14
|
+
export type { TListen };
|
|
16
15
|
export default Larasopp;
|
package/lib/index.js
CHANGED
|
@@ -27,32 +27,38 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
27
27
|
};
|
|
28
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
29
|
const Core_1 = __importStar(require("./Core"));
|
|
30
|
-
const
|
|
30
|
+
const Listener_1 = __importDefault(require("./Listener"));
|
|
31
31
|
class Larasopp extends Core_1.default {
|
|
32
32
|
constructor(config) {
|
|
33
33
|
super(config);
|
|
34
|
-
Object.defineProperty(this, "
|
|
34
|
+
Object.defineProperty(this, "channels", {
|
|
35
35
|
enumerable: true,
|
|
36
36
|
configurable: true,
|
|
37
37
|
writable: true,
|
|
38
38
|
value: void 0
|
|
39
39
|
});
|
|
40
|
-
this.
|
|
41
|
-
this.
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
this.
|
|
45
|
-
|
|
40
|
+
this.channels = {};
|
|
41
|
+
this.listenResumeSubscribes();
|
|
42
|
+
}
|
|
43
|
+
listenResumeSubscribes() {
|
|
44
|
+
this.addListener('open', () => {
|
|
45
|
+
Object.keys(this.channels).forEach((channel) => this.send({
|
|
46
|
+
subscribe: channel
|
|
47
|
+
}));
|
|
48
|
+
});
|
|
46
49
|
}
|
|
47
50
|
subscribe(channel) {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
51
|
+
const listener = new Listener_1.default(channel, this);
|
|
52
|
+
this.pushListener(channel, listener);
|
|
53
|
+
return listener;
|
|
54
|
+
}
|
|
55
|
+
unsubscribe(channel) {
|
|
56
|
+
if (!this.channels[channel])
|
|
57
|
+
return;
|
|
58
|
+
this.channels[channel].forEach((listener) => listener.remove());
|
|
59
|
+
delete this.channels[channel];
|
|
60
|
+
this.send({
|
|
61
|
+
unsubscribe: channel
|
|
56
62
|
});
|
|
57
63
|
}
|
|
58
64
|
trigger(channel, event, message, permission = 'public', waitSubscribe = false) {
|
|
@@ -68,21 +74,14 @@ class Larasopp extends Core_1.default {
|
|
|
68
74
|
this.events.addListener(event + ':' + channel, send);
|
|
69
75
|
send();
|
|
70
76
|
}
|
|
71
|
-
|
|
72
|
-
if (this.
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
this._channels.splice(index, 1);
|
|
80
|
-
}
|
|
81
|
-
get channels() {
|
|
82
|
-
return this._channels;
|
|
83
|
-
}
|
|
84
|
-
hasChannel(channel) {
|
|
85
|
-
return this.channels.indexOf(channel) >= 0;
|
|
77
|
+
pushListener(channel, listener) {
|
|
78
|
+
if (!this.channels[channel]) {
|
|
79
|
+
this.channels[channel] = [];
|
|
80
|
+
}
|
|
81
|
+
this.send({
|
|
82
|
+
subscribe: channel
|
|
83
|
+
});
|
|
84
|
+
this.channels[channel].push(listener);
|
|
86
85
|
}
|
|
87
86
|
addListener(event, callback) {
|
|
88
87
|
if (!Core_1.SocketEvents.includes(event))
|
package/package.json
CHANGED
package/src/Core.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import EventEmitter,{
|
|
2
|
-
Events
|
|
2
|
+
type Events
|
|
3
3
|
} from "easy-event-emitter";
|
|
4
|
+
import type Listener from "./Listener";
|
|
4
5
|
|
|
5
6
|
export const SocketEvents = ['open', 'close', 'error'] as const;
|
|
6
7
|
export type TSocketEvents = typeof SocketEvents[number];
|
|
@@ -12,7 +13,7 @@ export type TListenerCallback = (data:{channel: string}) => void;
|
|
|
12
13
|
|
|
13
14
|
export type TPermissions = 'public' | 'protected' | 'private';
|
|
14
15
|
|
|
15
|
-
export type
|
|
16
|
+
export type TListen = {
|
|
16
17
|
remove: () => void;
|
|
17
18
|
}
|
|
18
19
|
|
|
@@ -21,6 +22,7 @@ export type TMessage<T> = {
|
|
|
21
22
|
unsubscribe?: string;
|
|
22
23
|
channel?: string;
|
|
23
24
|
event?: string;
|
|
25
|
+
token?: string;
|
|
24
26
|
message?: T;
|
|
25
27
|
type?: TPermissions;
|
|
26
28
|
}
|
|
@@ -31,10 +33,15 @@ export interface IConfig {
|
|
|
31
33
|
tls?: boolean;
|
|
32
34
|
}
|
|
33
35
|
|
|
36
|
+
export type TChannels = {
|
|
37
|
+
[channel: string]: Listener[];
|
|
38
|
+
};
|
|
39
|
+
|
|
34
40
|
abstract class Core {
|
|
35
|
-
|
|
41
|
+
public readonly events: Events;
|
|
36
42
|
private ws?: WebSocket;
|
|
37
43
|
protected _status: boolean;
|
|
44
|
+
private _socketId?: string;
|
|
38
45
|
private config: IConfig;
|
|
39
46
|
|
|
40
47
|
constructor(config: IConfig) {
|
|
@@ -46,14 +53,10 @@ abstract class Core {
|
|
|
46
53
|
};
|
|
47
54
|
this._status = false;
|
|
48
55
|
|
|
49
|
-
this.
|
|
50
|
-
this.
|
|
51
|
-
this.
|
|
52
|
-
this.
|
|
53
|
-
this.onOpen = this.onOpen.bind(this);
|
|
54
|
-
this.onClose = this.onClose.bind(this);
|
|
55
|
-
this.onError = this.onError.bind(this);
|
|
56
|
-
this.onMessage = this.onMessage.bind(this);
|
|
56
|
+
this.handleOpen = this.handleOpen.bind(this);
|
|
57
|
+
this.handleClose = this.handleClose.bind(this);
|
|
58
|
+
this.handleError = this.handleError.bind(this);
|
|
59
|
+
this.handleMessage = this.handleMessage.bind(this);
|
|
57
60
|
}
|
|
58
61
|
|
|
59
62
|
public setConfig(config: IConfig): void {
|
|
@@ -68,6 +71,9 @@ abstract class Core {
|
|
|
68
71
|
...this.config,
|
|
69
72
|
token
|
|
70
73
|
};
|
|
74
|
+
this.send({
|
|
75
|
+
token
|
|
76
|
+
});
|
|
71
77
|
}
|
|
72
78
|
|
|
73
79
|
/**
|
|
@@ -75,24 +81,21 @@ abstract class Core {
|
|
|
75
81
|
* @returns {this}
|
|
76
82
|
*/
|
|
77
83
|
public connect(): this {
|
|
78
|
-
|
|
79
|
-
if (!navigator.onLine) {
|
|
80
|
-
setTimeout(this.connect.bind(this), 5000);
|
|
81
|
-
return this;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
84
|
try {
|
|
85
|
-
|
|
85
|
+
const host = [(this.config.tls ? 'wss' : 'ws') + '://'];
|
|
86
|
+
host.push(this.config.host);
|
|
87
|
+
if (this.config.token) host.push('/token=' + this.config.token);
|
|
88
|
+
|
|
89
|
+
this.ws = new WebSocket(host.join(''));
|
|
90
|
+
this.ws.onopen = this.handleOpen;
|
|
91
|
+
this.ws.onclose = this.handleClose;
|
|
92
|
+
this.ws.onerror = this.handleError;
|
|
93
|
+
this.ws.onmessage = this.handleMessage;
|
|
86
94
|
}catch(e) {
|
|
87
95
|
console.warn(e);
|
|
88
|
-
this.
|
|
89
|
-
this.
|
|
96
|
+
this.handleError(new Event('Socket exception'));
|
|
97
|
+
this.handleClose(new CloseEvent(String(e)));
|
|
90
98
|
}
|
|
91
|
-
|
|
92
|
-
this.ws!.onopen = this.onOpen;
|
|
93
|
-
this.ws!.onclose = this.onClose;
|
|
94
|
-
this.ws!.onerror = this.onError;
|
|
95
|
-
this.ws!.onmessage = this.onMessage;
|
|
96
99
|
|
|
97
100
|
return this;
|
|
98
101
|
}
|
|
@@ -106,9 +109,10 @@ abstract class Core {
|
|
|
106
109
|
this.ws?.close();
|
|
107
110
|
this._status = false;
|
|
108
111
|
}
|
|
112
|
+
this.ws = undefined;
|
|
109
113
|
}
|
|
110
114
|
|
|
111
|
-
protected
|
|
115
|
+
protected isJson(str: string) {
|
|
112
116
|
try {
|
|
113
117
|
JSON.parse(str);
|
|
114
118
|
} catch (e) {
|
|
@@ -117,23 +121,27 @@ abstract class Core {
|
|
|
117
121
|
return true;
|
|
118
122
|
}
|
|
119
123
|
|
|
120
|
-
private
|
|
124
|
+
private handleOpen(e: Event): void {
|
|
121
125
|
this._status = true;
|
|
122
126
|
this.events.emit("open", e);
|
|
123
127
|
}
|
|
124
128
|
|
|
125
|
-
private
|
|
129
|
+
private handleClose(e: CloseEvent): void {
|
|
126
130
|
this._status = false;
|
|
127
131
|
this.events.emit("close", e);
|
|
128
132
|
}
|
|
129
133
|
|
|
130
|
-
private
|
|
134
|
+
private handleError(e: Event): void {
|
|
131
135
|
this.events.emit("error", e);
|
|
132
136
|
}
|
|
133
137
|
|
|
134
|
-
private
|
|
135
|
-
if (this.
|
|
138
|
+
private handleMessage(e: MessageEvent): void {
|
|
139
|
+
if (this.isJson(e.data)) {
|
|
136
140
|
const json = JSON.parse(e.data);
|
|
141
|
+
if (json.socket_id) {
|
|
142
|
+
this._socketId = json.socket_id;
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
137
145
|
this.emitListener(json.channel, json.message);
|
|
138
146
|
this.events.emit(json.channel + ':' + json.event, json.message);
|
|
139
147
|
}
|
|
@@ -147,13 +155,29 @@ abstract class Core {
|
|
|
147
155
|
}
|
|
148
156
|
}
|
|
149
157
|
|
|
158
|
+
public get socketId() {
|
|
159
|
+
return this._socketId;
|
|
160
|
+
}
|
|
161
|
+
|
|
150
162
|
public get status(): boolean {
|
|
163
|
+
if (!this._status) this.connect();
|
|
151
164
|
return this._status;
|
|
152
165
|
}
|
|
153
166
|
|
|
167
|
+
private _send<T>(message: TMessage<T>) {
|
|
168
|
+
if (!this.ws) return;
|
|
169
|
+
this.ws.send(JSON.stringify(message));
|
|
170
|
+
}
|
|
171
|
+
|
|
154
172
|
protected send<T>(message: TMessage<T>) {
|
|
155
|
-
if (
|
|
156
|
-
|
|
173
|
+
if (this.status) {
|
|
174
|
+
this._send(message);
|
|
175
|
+
}else{
|
|
176
|
+
const event = this.events.addListener('open',() => {
|
|
177
|
+
this._send(message);
|
|
178
|
+
event.remove();
|
|
179
|
+
});
|
|
180
|
+
}
|
|
157
181
|
}
|
|
158
182
|
}
|
|
159
183
|
|
package/src/Listener.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import {
|
|
2
|
+
type Event
|
|
3
|
+
} from "easy-event-emitter";
|
|
4
|
+
import type Larasopp from ".";
|
|
5
|
+
|
|
6
|
+
class Listener {
|
|
7
|
+
private readonly context: Larasopp;
|
|
8
|
+
private channel: string;
|
|
9
|
+
private listeners?: Event[];
|
|
10
|
+
|
|
11
|
+
constructor(channel: string, constext: Larasopp) {
|
|
12
|
+
this.channel = channel;
|
|
13
|
+
this.context = constext;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
public listen(event: string, callback: (data: any) => void) {
|
|
17
|
+
if (!this.listeners) {
|
|
18
|
+
this.listeners = [];
|
|
19
|
+
}
|
|
20
|
+
const listener = this.context.events.addListener(this.channel + ':' + event, callback);
|
|
21
|
+
this.listeners.push(listener);
|
|
22
|
+
return listener;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
public remove() {
|
|
26
|
+
if (!this.listeners) return;
|
|
27
|
+
this.listeners.forEach((listener) => listener.remove());
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export default Listener;
|
package/src/index.ts
CHANGED
|
@@ -2,39 +2,47 @@ import {
|
|
|
2
2
|
Event
|
|
3
3
|
} from "easy-event-emitter";
|
|
4
4
|
import Core,{
|
|
5
|
-
IConfig,
|
|
6
|
-
TPermissions,
|
|
5
|
+
type IConfig,
|
|
6
|
+
type TPermissions,
|
|
7
7
|
SocketEvents,
|
|
8
|
-
TSocketEvents,
|
|
9
|
-
TListenerCallback,
|
|
10
|
-
|
|
8
|
+
type TSocketEvents,
|
|
9
|
+
type TListenerCallback,
|
|
10
|
+
type TListen,
|
|
11
|
+
type TChannels
|
|
11
12
|
} from "./Core";
|
|
12
|
-
import
|
|
13
|
+
import Listener from "./Listener";
|
|
13
14
|
|
|
14
15
|
class Larasopp extends Core {
|
|
15
|
-
private
|
|
16
|
+
private readonly channels: TChannels;
|
|
16
17
|
|
|
17
18
|
constructor(config: IConfig) {
|
|
18
19
|
super(config);
|
|
19
20
|
|
|
20
|
-
this.
|
|
21
|
+
this.channels = {};
|
|
21
22
|
|
|
22
|
-
this.
|
|
23
|
-
this.trigger = this.trigger.bind(this);
|
|
24
|
-
this.hasChannel = this.hasChannel.bind(this);
|
|
25
|
-
this.pushChannel = this.pushChannel.bind(this);
|
|
26
|
-
this.removeChannel = this.removeChannel.bind(this);
|
|
23
|
+
this.listenResumeSubscribes();
|
|
27
24
|
}
|
|
28
25
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
26
|
+
private listenResumeSubscribes() {
|
|
27
|
+
this.addListener('open', () => {
|
|
28
|
+
Object.keys(this.channels).forEach((channel) => this.send({
|
|
29
|
+
subscribe: channel
|
|
30
|
+
}));
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
public subscribe(channel: string) {
|
|
35
|
+
const listener = new Listener(channel, this);
|
|
36
|
+
this.pushListener(channel, listener);
|
|
37
|
+
return listener;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
public unsubscribe(channel: string) {
|
|
41
|
+
if (!this.channels[channel]) return;
|
|
42
|
+
this.channels[channel].forEach((listener) => listener.remove());
|
|
43
|
+
delete this.channels[channel];
|
|
44
|
+
this.send({
|
|
45
|
+
unsubscribe: channel
|
|
38
46
|
});
|
|
39
47
|
}
|
|
40
48
|
|
|
@@ -52,22 +60,14 @@ class Larasopp extends Core {
|
|
|
52
60
|
send();
|
|
53
61
|
}
|
|
54
62
|
|
|
55
|
-
private
|
|
56
|
-
if (this.
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
private get channels(): string[] {
|
|
66
|
-
return this._channels;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
public hasChannel(channel: string): boolean {
|
|
70
|
-
return this.channels.indexOf(channel) >= 0;
|
|
63
|
+
private pushListener(channel: string, listener: Listener): void {
|
|
64
|
+
if (!this.channels[channel]) {
|
|
65
|
+
this.channels[channel] = [];
|
|
66
|
+
}
|
|
67
|
+
this.send({
|
|
68
|
+
subscribe: channel
|
|
69
|
+
});
|
|
70
|
+
this.channels[channel].push(listener);
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
public addListener(event: TSocketEvents, callback: TListenerCallback): Event | undefined {
|
|
@@ -77,8 +77,7 @@ class Larasopp extends Core {
|
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
export type {
|
|
80
|
-
|
|
81
|
-
TBind
|
|
80
|
+
TListen
|
|
82
81
|
};
|
|
83
82
|
|
|
84
83
|
export default Larasopp;
|
package/src/Subscribe.ts
DELETED
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
TMessage,
|
|
3
|
-
ListenerEvents,
|
|
4
|
-
TListenerEvents,
|
|
5
|
-
TListenerCallback,
|
|
6
|
-
TBind
|
|
7
|
-
} from "./Core";
|
|
8
|
-
import {
|
|
9
|
-
Event,
|
|
10
|
-
Events
|
|
11
|
-
} from "easy-event-emitter";
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
interface ISubscribe {
|
|
15
|
-
events: Events;
|
|
16
|
-
hasChannel: (channel: string) => boolean;
|
|
17
|
-
pushChannel: (channel: string) => void;
|
|
18
|
-
removeChannel: (channel: string) => void;
|
|
19
|
-
send: <T>(message: TMessage<T>) => void;
|
|
20
|
-
channel: string;
|
|
21
|
-
status: boolean;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
class Subscribe {
|
|
25
|
-
private events: Events;
|
|
26
|
-
private currentEvents: Event[];
|
|
27
|
-
private hasChannel: (channel: string) => boolean;
|
|
28
|
-
private pushChannel: (channel: string) => void;
|
|
29
|
-
private removeChannel: (channel: string) => void;
|
|
30
|
-
private status: boolean;
|
|
31
|
-
private _channel: string;
|
|
32
|
-
private send: <T>(message: TMessage<T>) => void;
|
|
33
|
-
|
|
34
|
-
constructor({events, hasChannel, pushChannel, removeChannel, status, channel, send}: ISubscribe) {
|
|
35
|
-
this.events = events;
|
|
36
|
-
this.currentEvents = [];
|
|
37
|
-
this.hasChannel = hasChannel;
|
|
38
|
-
this.pushChannel = pushChannel;
|
|
39
|
-
this.removeChannel = removeChannel;
|
|
40
|
-
this.status = status;
|
|
41
|
-
this._channel = channel;
|
|
42
|
-
this.send = send;
|
|
43
|
-
|
|
44
|
-
this.init();
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
public get channel(): string {
|
|
48
|
-
return this._channel;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
private init(): void {
|
|
52
|
-
this.pushChannel(this.channel);
|
|
53
|
-
|
|
54
|
-
if (this.status) {
|
|
55
|
-
this.send({
|
|
56
|
-
subscribe: this.channel
|
|
57
|
-
});
|
|
58
|
-
}else{
|
|
59
|
-
const event = this.events.addListener('open',() => {
|
|
60
|
-
this.send({
|
|
61
|
-
subscribe: this.channel
|
|
62
|
-
});
|
|
63
|
-
event.remove();
|
|
64
|
-
});
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
public bind<T>(event: string, callback: (data: T) => void): TBind {
|
|
69
|
-
const Event = this.events.addListener(this.channel + ':' + event, callback);
|
|
70
|
-
this.currentEvents.push(Event);
|
|
71
|
-
return {
|
|
72
|
-
remove: () => {
|
|
73
|
-
Event.remove();
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
private clearEvents(): void {
|
|
79
|
-
this.currentEvents.forEach((event) => event.remove());
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
public remove(): void {
|
|
83
|
-
this.clearEvents();
|
|
84
|
-
this.removeChannel(this.channel);
|
|
85
|
-
if (this.hasChannel(this.channel)) return;
|
|
86
|
-
this.send({
|
|
87
|
-
unsubscribe: this.channel
|
|
88
|
-
});
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
public addListener(event: TListenerEvents, callback: TListenerCallback): Event | undefined {
|
|
92
|
-
return this.events.addListener(event + ':' + this.channel, callback);
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
export default Subscribe;
|