arifa-client 1.0.13 → 1.1.13
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/dist/arifa-client.esm.js
CHANGED
|
@@ -4,11 +4,12 @@ class ArifaClient {
|
|
|
4
4
|
this.isConnected = false;
|
|
5
5
|
this.reconnectAttempts = 0;
|
|
6
6
|
this.reconnectTimer = null;
|
|
7
|
+
this.reconnectScheduled = false;
|
|
7
8
|
this.internetOnline = true;
|
|
8
9
|
this.internetTimer = null;
|
|
9
10
|
this.recipient = null;
|
|
10
|
-
this.listeners =
|
|
11
|
-
this.connectionListeners =
|
|
11
|
+
this.listeners = new Set();
|
|
12
|
+
this.connectionListeners = new Set();
|
|
12
13
|
this.HEALTH_URL = "https://notifications.arifa.dev/health";
|
|
13
14
|
this.MAX_BACKOFF = 60000;
|
|
14
15
|
this.apiKey = apiKey;
|
|
@@ -36,7 +37,7 @@ class ArifaClient {
|
|
|
36
37
|
const controller = new AbortController();
|
|
37
38
|
const timeout = setTimeout(() => controller.abort(), 3000);
|
|
38
39
|
await fetch(this.HEALTH_URL, {
|
|
39
|
-
method: "
|
|
40
|
+
method: "HEAD",
|
|
40
41
|
cache: "no-store",
|
|
41
42
|
signal: controller.signal,
|
|
42
43
|
});
|
|
@@ -76,15 +77,18 @@ class ArifaClient {
|
|
|
76
77
|
}
|
|
77
78
|
return {
|
|
78
79
|
listen: (callback) => {
|
|
79
|
-
this.listeners.
|
|
80
|
+
this.listeners.add(callback);
|
|
80
81
|
},
|
|
81
|
-
unsubscribe: () => {
|
|
82
|
-
|
|
82
|
+
unsubscribe: (callback) => {
|
|
83
|
+
if (callback)
|
|
84
|
+
this.listeners.delete(callback);
|
|
85
|
+
else
|
|
86
|
+
this.listeners.clear();
|
|
83
87
|
},
|
|
84
88
|
};
|
|
85
89
|
}
|
|
86
90
|
onConnectionChange(callback) {
|
|
87
|
-
this.connectionListeners.
|
|
91
|
+
this.connectionListeners.add(callback);
|
|
88
92
|
}
|
|
89
93
|
emitConnection(state) {
|
|
90
94
|
this.connectionListeners.forEach((cb) => cb(state));
|
|
@@ -95,24 +99,31 @@ class ArifaClient {
|
|
|
95
99
|
return;
|
|
96
100
|
if (!this.internetOnline)
|
|
97
101
|
return;
|
|
98
|
-
if (this.ws &&
|
|
102
|
+
if (this.ws &&
|
|
103
|
+
(this.ws.readyState === WebSocket.OPEN ||
|
|
104
|
+
this.ws.readyState === WebSocket.CONNECTING)) {
|
|
99
105
|
return;
|
|
106
|
+
}
|
|
100
107
|
this.ws = new WebSocket(`${this.wsUrl}/connect?api_key=${this.apiKey}&recipient=${this.recipient}&client=${this.client}`);
|
|
101
108
|
this.ws.onopen = () => {
|
|
102
109
|
this.isConnected = true;
|
|
103
110
|
this.reconnectAttempts = 0;
|
|
111
|
+
this.reconnectScheduled = false;
|
|
112
|
+
if (this.reconnectTimer) {
|
|
113
|
+
clearTimeout(this.reconnectTimer);
|
|
114
|
+
this.reconnectTimer = null;
|
|
115
|
+
}
|
|
104
116
|
this.emitConnection("connected");
|
|
105
117
|
};
|
|
106
118
|
this.ws.onmessage = (event) => {
|
|
107
119
|
const parsed = this.safeParse(event.data);
|
|
108
|
-
if (!parsed)
|
|
109
|
-
return;
|
|
110
120
|
// IMMEDIATE ACK
|
|
111
121
|
this.ws.send(JSON.stringify({
|
|
112
122
|
kind: "ack",
|
|
113
123
|
event_id: parsed.ack.event_id,
|
|
114
124
|
}));
|
|
115
|
-
|
|
125
|
+
if (parsed.event)
|
|
126
|
+
this.listeners.forEach((fn) => fn(parsed.event));
|
|
116
127
|
};
|
|
117
128
|
this.ws.onclose = () => {
|
|
118
129
|
this.isConnected = false;
|
|
@@ -125,13 +136,15 @@ class ArifaClient {
|
|
|
125
136
|
};
|
|
126
137
|
}
|
|
127
138
|
scheduleReconnect() {
|
|
128
|
-
if (!this.internetOnline)
|
|
139
|
+
if (!this.internetOnline || this.reconnectScheduled)
|
|
129
140
|
return;
|
|
141
|
+
this.reconnectScheduled = true;
|
|
130
142
|
const base = Math.min(this.MAX_BACKOFF, 1000 * 2 ** this.reconnectAttempts);
|
|
131
143
|
const jitter = Math.random() * 1000;
|
|
132
144
|
const timeout = base + jitter;
|
|
133
145
|
this.reconnectAttempts++;
|
|
134
146
|
this.reconnectTimer = window.setTimeout(() => {
|
|
147
|
+
this.reconnectScheduled = false;
|
|
135
148
|
this.connect();
|
|
136
149
|
}, timeout);
|
|
137
150
|
}
|
|
@@ -7,11 +7,12 @@ var ArifaClient = (function () {
|
|
|
7
7
|
this.isConnected = false;
|
|
8
8
|
this.reconnectAttempts = 0;
|
|
9
9
|
this.reconnectTimer = null;
|
|
10
|
+
this.reconnectScheduled = false;
|
|
10
11
|
this.internetOnline = true;
|
|
11
12
|
this.internetTimer = null;
|
|
12
13
|
this.recipient = null;
|
|
13
|
-
this.listeners =
|
|
14
|
-
this.connectionListeners =
|
|
14
|
+
this.listeners = new Set();
|
|
15
|
+
this.connectionListeners = new Set();
|
|
15
16
|
this.HEALTH_URL = "https://notifications.arifa.dev/health";
|
|
16
17
|
this.MAX_BACKOFF = 60000;
|
|
17
18
|
this.apiKey = apiKey;
|
|
@@ -39,7 +40,7 @@ var ArifaClient = (function () {
|
|
|
39
40
|
const controller = new AbortController();
|
|
40
41
|
const timeout = setTimeout(() => controller.abort(), 3000);
|
|
41
42
|
await fetch(this.HEALTH_URL, {
|
|
42
|
-
method: "
|
|
43
|
+
method: "HEAD",
|
|
43
44
|
cache: "no-store",
|
|
44
45
|
signal: controller.signal,
|
|
45
46
|
});
|
|
@@ -79,15 +80,18 @@ var ArifaClient = (function () {
|
|
|
79
80
|
}
|
|
80
81
|
return {
|
|
81
82
|
listen: (callback) => {
|
|
82
|
-
this.listeners.
|
|
83
|
+
this.listeners.add(callback);
|
|
83
84
|
},
|
|
84
|
-
unsubscribe: () => {
|
|
85
|
-
|
|
85
|
+
unsubscribe: (callback) => {
|
|
86
|
+
if (callback)
|
|
87
|
+
this.listeners.delete(callback);
|
|
88
|
+
else
|
|
89
|
+
this.listeners.clear();
|
|
86
90
|
},
|
|
87
91
|
};
|
|
88
92
|
}
|
|
89
93
|
onConnectionChange(callback) {
|
|
90
|
-
this.connectionListeners.
|
|
94
|
+
this.connectionListeners.add(callback);
|
|
91
95
|
}
|
|
92
96
|
emitConnection(state) {
|
|
93
97
|
this.connectionListeners.forEach((cb) => cb(state));
|
|
@@ -98,24 +102,31 @@ var ArifaClient = (function () {
|
|
|
98
102
|
return;
|
|
99
103
|
if (!this.internetOnline)
|
|
100
104
|
return;
|
|
101
|
-
if (this.ws &&
|
|
105
|
+
if (this.ws &&
|
|
106
|
+
(this.ws.readyState === WebSocket.OPEN ||
|
|
107
|
+
this.ws.readyState === WebSocket.CONNECTING)) {
|
|
102
108
|
return;
|
|
109
|
+
}
|
|
103
110
|
this.ws = new WebSocket(`${this.wsUrl}/connect?api_key=${this.apiKey}&recipient=${this.recipient}&client=${this.client}`);
|
|
104
111
|
this.ws.onopen = () => {
|
|
105
112
|
this.isConnected = true;
|
|
106
113
|
this.reconnectAttempts = 0;
|
|
114
|
+
this.reconnectScheduled = false;
|
|
115
|
+
if (this.reconnectTimer) {
|
|
116
|
+
clearTimeout(this.reconnectTimer);
|
|
117
|
+
this.reconnectTimer = null;
|
|
118
|
+
}
|
|
107
119
|
this.emitConnection("connected");
|
|
108
120
|
};
|
|
109
121
|
this.ws.onmessage = (event) => {
|
|
110
122
|
const parsed = this.safeParse(event.data);
|
|
111
|
-
if (!parsed)
|
|
112
|
-
return;
|
|
113
123
|
// IMMEDIATE ACK
|
|
114
124
|
this.ws.send(JSON.stringify({
|
|
115
125
|
kind: "ack",
|
|
116
126
|
event_id: parsed.ack.event_id,
|
|
117
127
|
}));
|
|
118
|
-
|
|
128
|
+
if (parsed.event)
|
|
129
|
+
this.listeners.forEach((fn) => fn(parsed.event));
|
|
119
130
|
};
|
|
120
131
|
this.ws.onclose = () => {
|
|
121
132
|
this.isConnected = false;
|
|
@@ -128,13 +139,15 @@ var ArifaClient = (function () {
|
|
|
128
139
|
};
|
|
129
140
|
}
|
|
130
141
|
scheduleReconnect() {
|
|
131
|
-
if (!this.internetOnline)
|
|
142
|
+
if (!this.internetOnline || this.reconnectScheduled)
|
|
132
143
|
return;
|
|
144
|
+
this.reconnectScheduled = true;
|
|
133
145
|
const base = Math.min(this.MAX_BACKOFF, 1000 * 2 ** this.reconnectAttempts);
|
|
134
146
|
const jitter = Math.random() * 1000;
|
|
135
147
|
const timeout = base + jitter;
|
|
136
148
|
this.reconnectAttempts++;
|
|
137
149
|
this.reconnectTimer = window.setTimeout(() => {
|
|
150
|
+
this.reconnectScheduled = false;
|
|
138
151
|
this.connect();
|
|
139
152
|
}, timeout);
|
|
140
153
|
}
|
|
@@ -26,6 +26,7 @@ export declare class ArifaClient {
|
|
|
26
26
|
private isConnected;
|
|
27
27
|
private reconnectAttempts;
|
|
28
28
|
private reconnectTimer;
|
|
29
|
+
private reconnectScheduled;
|
|
29
30
|
private internetOnline;
|
|
30
31
|
private internetTimer;
|
|
31
32
|
private recipient;
|
|
@@ -39,7 +40,7 @@ export declare class ArifaClient {
|
|
|
39
40
|
private startInternetMonitor;
|
|
40
41
|
subscribe(recipient: string): {
|
|
41
42
|
listen: (callback: (event: ArifaEvent) => void) => void;
|
|
42
|
-
unsubscribe: () => void;
|
|
43
|
+
unsubscribe: (callback?: (event: ArifaEvent) => void) => void;
|
|
43
44
|
};
|
|
44
45
|
onConnectionChange(callback: ConnectionCallback): void;
|
|
45
46
|
private emitConnection;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ArifaClient.d.ts","sourceRoot":"","sources":["../../src/ArifaClient.ts"],"names":[],"mappings":"AAAA,KAAK,UAAU,GAAG,GAAG,CAAC;AACtB,KAAK,eAAe,GAAG,WAAW,GAAG,cAAc,CAAC;AAEpD,UAAU,kBAAkB;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,KAAK,GAAG,QAAQ,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,UAAU,aAAa;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC7B,MAAM,CAAC,EAAE,KAAK,GAAG,QAAQ,CAAC;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,UAAU,cAAc;IACtB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,KAAK,kBAAkB,GAAG,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,CAAC;AAE3D,qBAAa,WAAW;IACtB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,MAAM,CAAmB;IACjC,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,WAAW,CAAS;IAE5B,OAAO,CAAC,EAAE,CAA0B;IACpC,OAAO,CAAC,WAAW,CAAS;IAE5B,OAAO,CAAC,iBAAiB,CAAK;IAC9B,OAAO,CAAC,cAAc,CAAuB;
|
|
1
|
+
{"version":3,"file":"ArifaClient.d.ts","sourceRoot":"","sources":["../../src/ArifaClient.ts"],"names":[],"mappings":"AAAA,KAAK,UAAU,GAAG,GAAG,CAAC;AACtB,KAAK,eAAe,GAAG,WAAW,GAAG,cAAc,CAAC;AAEpD,UAAU,kBAAkB;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,KAAK,GAAG,QAAQ,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,UAAU,aAAa;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC7B,MAAM,CAAC,EAAE,KAAK,GAAG,QAAQ,CAAC;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,UAAU,cAAc;IACtB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,KAAK,kBAAkB,GAAG,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,CAAC;AAE3D,qBAAa,WAAW;IACtB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,MAAM,CAAmB;IACjC,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,WAAW,CAAS;IAE5B,OAAO,CAAC,EAAE,CAA0B;IACpC,OAAO,CAAC,WAAW,CAAS;IAE5B,OAAO,CAAC,iBAAiB,CAAK;IAC9B,OAAO,CAAC,cAAc,CAAuB;IAC7C,OAAO,CAAC,kBAAkB,CAAS;IAEnC,OAAO,CAAC,cAAc,CAAQ;IAC9B,OAAO,CAAC,aAAa,CAAuB;IAE5C,OAAO,CAAC,SAAS,CAAuB;IAExC,OAAO,CAAC,SAAS,CAA+C;IAChE,OAAO,CAAC,mBAAmB,CAAsC;IAEjE,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA4C;IACvE,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAU;gBAE1B,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,EAAE,kBAAkB;IAStE,OAAO,CAAC,SAAS;YAaH,aAAa;IAkB3B,OAAO,CAAC,oBAAoB;IA2B5B,SAAS,CAAC,SAAS,EAAE,MAAM;2BAOJ,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI;iCAGrB,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI;;IAOxD,kBAAkB,CAAC,QAAQ,EAAE,kBAAkB;IAI/C,OAAO,CAAC,cAAc;IAMtB,OAAO,CAAC,OAAO;IAsDf,OAAO,CAAC,iBAAiB;IAmBnB,MAAM,CAAC,EACX,SAAS,EACT,OAAO,EACP,MAAM,EACN,MAAM,GACP,EAAE,aAAa,GAAG,OAAO,CAAC,cAAc,CAAC;IA0B1C,UAAU;IAUV,SAAS;CAGV"}
|
package/package.json
CHANGED