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 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
- export default larasopp;
25
+ ```
26
+
27
+ ### Update user token
25
28
 
29
+ ```js
30
+ larasopp.setToken('new token');
26
31
  ```
27
32
 
28
- ### Subscribe on channel and bind event
33
+ ### Subscribe on channel and listen event
34
+
29
35
  ```js
30
- const listener = larasopp.subscribe('chat').bind('message',(data) => {
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 TBind = {
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
- protected events: Events;
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 isJsonString(str: string): boolean;
45
- private onOpen;
46
- private onClose;
47
- private onError;
48
- private onMessage;
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.send = this.send.bind(this);
40
- this.setConfig = this.setConfig.bind(this);
41
- this.setToken = this.setToken.bind(this);
42
- this.connect = this.connect.bind(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
- this.ws = new WebSocket((this.config.tls ? 'wss' : 'ws') + '://' + this.config.host + '/token=' + this.config.token);
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.onError('Socket exception');
69
- this.onClose(e);
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
- isJsonString(str) {
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
- onOpen(e) {
107
+ handleOpen(e) {
98
108
  this._status = true;
99
109
  this.events.emit("open", e);
100
110
  }
101
- onClose(e) {
111
+ handleClose(e) {
102
112
  this._status = false;
103
113
  this.events.emit("close", e);
104
114
  }
105
- onError(e) {
115
+ handleError(e) {
106
116
  this.events.emit("error", e);
107
117
  }
108
- onMessage(e) {
109
- if (this.isJsonString(e.data)) {
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
- send(message) {
126
- if (!this.status)
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;
@@ -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;
@@ -1,5 +1,5 @@
1
- import { TMessage, TListenerEvents, TListenerCallback, TBind } from "./Core";
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
- bind<T>(event: string, callback: (data: T) => void): TBind;
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
@@ -79,7 +79,7 @@ class Subscribe {
79
79
  });
80
80
  }
81
81
  }
82
- bind(event, callback) {
82
+ listen(event, callback) {
83
83
  const Event = this.events.addListener(this.channel + ':' + event, callback);
84
84
  this.currentEvents.push(Event);
85
85
  return {
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, TBind } from "./Core";
3
- import Subscribe from "./Subscribe";
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 _channels;
5
+ private readonly channels;
6
6
  constructor(config: IConfig);
7
- subscribe(channel: string): Subscribe;
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 pushChannel;
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 { Subscribe, TBind };
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 Subscribe_1 = __importDefault(require("./Subscribe"));
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, "_channels", {
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._channels = [];
41
- this.subscribe = this.subscribe.bind(this);
42
- this.trigger = this.trigger.bind(this);
43
- this.hasChannel = this.hasChannel.bind(this);
44
- this.pushChannel = this.pushChannel.bind(this);
45
- this.removeChannel = this.removeChannel.bind(this);
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
- return new Subscribe_1.default({
49
- events: this.events,
50
- hasChannel: this.hasChannel,
51
- pushChannel: this.pushChannel,
52
- removeChannel: this.removeChannel,
53
- status: this.status,
54
- send: this.send,
55
- channel
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
- pushChannel(channel) {
72
- if (this._channels.indexOf(channel) >= 0)
73
- return;
74
- this._channels.push(channel);
75
- }
76
- removeChannel(channel) {
77
- const index = this._channels.indexOf(channel);
78
- if (index >= 0)
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "larasopp",
3
- "version": "1.1.3",
3
+ "version": "1.2.2",
4
4
  "description": "Websocket client for laravel",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
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 TBind = {
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
- protected events: Events;
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.send = this.send.bind(this);
50
- this.setConfig = this.setConfig.bind(this);
51
- this.setToken = this.setToken.bind(this);
52
- this.connect = this.connect.bind(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
- this.ws = new WebSocket((this.config.tls ? 'wss' : 'ws') + '://' + this.config.host + '/token=' + this.config.token);
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.onError('Socket exception');
89
- this.onClose(e);
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 isJsonString(str: string) {
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 onOpen(e: any): void {
124
+ private handleOpen(e: Event): void {
121
125
  this._status = true;
122
126
  this.events.emit("open", e);
123
127
  }
124
128
 
125
- private onClose(e: any): void {
129
+ private handleClose(e: CloseEvent): void {
126
130
  this._status = false;
127
131
  this.events.emit("close", e);
128
132
  }
129
133
 
130
- private onError(e: any): void {
134
+ private handleError(e: Event): void {
131
135
  this.events.emit("error", e);
132
136
  }
133
137
 
134
- private onMessage(e: any): void {
135
- if (this.isJsonString(e.data)) {
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 (!this.status) return;
156
- this.ws!.send(JSON.stringify(message));
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
 
@@ -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
- TBind
8
+ type TSocketEvents,
9
+ type TListenerCallback,
10
+ type TListen,
11
+ type TChannels
11
12
  } from "./Core";
12
- import Subscribe from "./Subscribe";
13
+ import Listener from "./Listener";
13
14
 
14
15
  class Larasopp extends Core {
15
- private _channels: string[];
16
+ private readonly channels: TChannels;
16
17
 
17
18
  constructor(config: IConfig) {
18
19
  super(config);
19
20
 
20
- this._channels = [];
21
+ this.channels = {};
21
22
 
22
- this.subscribe = this.subscribe.bind(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
- public subscribe(channel: string): Subscribe {
30
- return new Subscribe({
31
- events: this.events,
32
- hasChannel: this.hasChannel,
33
- pushChannel: this.pushChannel,
34
- removeChannel: this.removeChannel,
35
- status: this.status,
36
- send: this.send,
37
- channel
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 pushChannel(channel: string): void {
56
- if (this._channels.indexOf(channel) >= 0) return;
57
- this._channels.push(channel);
58
- }
59
-
60
- private removeChannel(channel: string): void {
61
- const index = this._channels.indexOf(channel);
62
- if (index >= 0) this._channels.splice(index, 1);
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
- Subscribe,
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;