@adonisjs/transmit-client 0.1.5 → 0.2.0
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/LICENSE.md +9 -9
- package/README.md +45 -51
- package/build/transmit.d.ts +87 -16
- package/build/transmit.js +434 -0
- package/package.json +36 -20
- package/src/hook.ts +66 -0
- package/src/hook_event.ts +20 -0
- package/src/http_client.ts +46 -0
- package/src/subscription.ts +165 -0
- package/src/subscription_status.ts +16 -0
- package/src/transmit.ts +113 -153
- package/src/transmit_status.ts +18 -0
- package/build/transmit.cjs +0 -2
- package/build/transmit.cjs.map +0 -1
- package/build/transmit.modern.js +0 -2
- package/build/transmit.modern.js.map +0 -1
- package/build/transmit.module.js +0 -2
- package/build/transmit.module.js.map +0 -1
- package/build/transmit.umd.js +0 -2
- package/build/transmit.umd.js.map +0 -1
|
@@ -0,0 +1,434 @@
|
|
|
1
|
+
var __accessCheck = (obj, member, msg) => {
|
|
2
|
+
if (!member.has(obj))
|
|
3
|
+
throw TypeError("Cannot " + msg);
|
|
4
|
+
};
|
|
5
|
+
var __privateGet = (obj, member, getter) => {
|
|
6
|
+
__accessCheck(obj, member, "read from private field");
|
|
7
|
+
return getter ? getter.call(obj) : member.get(obj);
|
|
8
|
+
};
|
|
9
|
+
var __privateAdd = (obj, member, value) => {
|
|
10
|
+
if (member.has(obj))
|
|
11
|
+
throw TypeError("Cannot add the same private member more than once");
|
|
12
|
+
member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
13
|
+
};
|
|
14
|
+
var __privateSet = (obj, member, value, setter) => {
|
|
15
|
+
__accessCheck(obj, member, "write to private field");
|
|
16
|
+
setter ? setter.call(obj, value) : member.set(obj, value);
|
|
17
|
+
return value;
|
|
18
|
+
};
|
|
19
|
+
var __privateWrapper = (obj, member, setter, getter) => ({
|
|
20
|
+
set _(value) {
|
|
21
|
+
__privateSet(obj, member, value, setter);
|
|
22
|
+
},
|
|
23
|
+
get _() {
|
|
24
|
+
return __privateGet(obj, member, getter);
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
var __privateMethod = (obj, member, method) => {
|
|
28
|
+
__accessCheck(obj, member, "access private method");
|
|
29
|
+
return method;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
// src/subscription_status.ts
|
|
33
|
+
var SubscriptionStatus = {
|
|
34
|
+
Pending: 0,
|
|
35
|
+
Created: 1,
|
|
36
|
+
Deleted: 2
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
// src/transmit_status.ts
|
|
40
|
+
var TransmitStatus = {
|
|
41
|
+
Initializing: "initializing",
|
|
42
|
+
Connecting: "connecting",
|
|
43
|
+
Connected: "connected",
|
|
44
|
+
Disconnected: "disconnected",
|
|
45
|
+
Reconnecting: "reconnecting"
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
// src/subscription.ts
|
|
49
|
+
var _httpClient, _hooks, _channel, _getEventSourceStatus, _handlers, _status;
|
|
50
|
+
var Subscription = class {
|
|
51
|
+
constructor(options) {
|
|
52
|
+
/**
|
|
53
|
+
* HTTP client instance.
|
|
54
|
+
*/
|
|
55
|
+
__privateAdd(this, _httpClient, void 0);
|
|
56
|
+
/**
|
|
57
|
+
* Hook instance.
|
|
58
|
+
*/
|
|
59
|
+
__privateAdd(this, _hooks, void 0);
|
|
60
|
+
/**
|
|
61
|
+
* Channel name.
|
|
62
|
+
*/
|
|
63
|
+
__privateAdd(this, _channel, void 0);
|
|
64
|
+
/**
|
|
65
|
+
* Event source status getter.
|
|
66
|
+
*/
|
|
67
|
+
__privateAdd(this, _getEventSourceStatus, void 0);
|
|
68
|
+
/**
|
|
69
|
+
* Registered message handlers.
|
|
70
|
+
*/
|
|
71
|
+
__privateAdd(this, _handlers, /* @__PURE__ */ new Set());
|
|
72
|
+
/**
|
|
73
|
+
* Current status of the subscription.
|
|
74
|
+
*/
|
|
75
|
+
__privateAdd(this, _status, SubscriptionStatus.Pending);
|
|
76
|
+
__privateSet(this, _channel, options.channel);
|
|
77
|
+
__privateSet(this, _httpClient, options.httpClient);
|
|
78
|
+
__privateSet(this, _hooks, options.hooks);
|
|
79
|
+
__privateSet(this, _getEventSourceStatus, options.getEventSourceStatus);
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Returns if the subscription is created or not.
|
|
83
|
+
*/
|
|
84
|
+
get isCreated() {
|
|
85
|
+
return __privateGet(this, _status) === SubscriptionStatus.Created;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Returns if the subscription is deleted or not.
|
|
89
|
+
*/
|
|
90
|
+
get isDeleted() {
|
|
91
|
+
return __privateGet(this, _status) === SubscriptionStatus.Deleted;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Returns the number of registered handlers.
|
|
95
|
+
*/
|
|
96
|
+
get handlerCount() {
|
|
97
|
+
return __privateGet(this, _handlers).size;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Run all registered handlers for the subscription.
|
|
101
|
+
*/
|
|
102
|
+
$runHandler(message) {
|
|
103
|
+
for (const handler of __privateGet(this, _handlers)) {
|
|
104
|
+
handler(message);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
async create() {
|
|
108
|
+
if (this.isCreated) {
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
if (__privateGet(this, _getEventSourceStatus).call(this) !== TransmitStatus.Connected) {
|
|
112
|
+
return new Promise((resolve) => {
|
|
113
|
+
setTimeout(() => {
|
|
114
|
+
resolve(this.create());
|
|
115
|
+
}, 100);
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
const request = __privateGet(this, _httpClient).createRequest("/__transmit/subscribe", {
|
|
119
|
+
channel: __privateGet(this, _channel)
|
|
120
|
+
});
|
|
121
|
+
__privateGet(this, _hooks)?.beforeSubscribe(request);
|
|
122
|
+
try {
|
|
123
|
+
const response = await __privateGet(this, _httpClient).send(request);
|
|
124
|
+
void response.text();
|
|
125
|
+
if (!response.ok) {
|
|
126
|
+
__privateGet(this, _hooks)?.onSubscribeFailed(response);
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
__privateSet(this, _status, SubscriptionStatus.Created);
|
|
130
|
+
__privateGet(this, _hooks)?.onSubscription(__privateGet(this, _channel));
|
|
131
|
+
} catch (error) {
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
async delete() {
|
|
135
|
+
if (this.isDeleted || !this.isCreated) {
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
const request = __privateGet(this, _httpClient).createRequest("/__transmit/unsubscribe", {
|
|
139
|
+
channel: __privateGet(this, _channel)
|
|
140
|
+
});
|
|
141
|
+
__privateGet(this, _hooks)?.beforeUnsubscribe(request);
|
|
142
|
+
try {
|
|
143
|
+
const response = await __privateGet(this, _httpClient).send(request);
|
|
144
|
+
void response.text();
|
|
145
|
+
if (!response.ok) {
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
__privateSet(this, _status, SubscriptionStatus.Deleted);
|
|
149
|
+
__privateGet(this, _hooks)?.onUnsubscription(__privateGet(this, _channel));
|
|
150
|
+
} catch (error) {
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
onMessage(handler) {
|
|
154
|
+
__privateGet(this, _handlers).add(handler);
|
|
155
|
+
return () => {
|
|
156
|
+
__privateGet(this, _handlers).delete(handler);
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
onMessageOnce(handler) {
|
|
160
|
+
const deleteHandler = this.onMessage((message) => {
|
|
161
|
+
handler(message);
|
|
162
|
+
deleteHandler();
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
_httpClient = new WeakMap();
|
|
167
|
+
_hooks = new WeakMap();
|
|
168
|
+
_channel = new WeakMap();
|
|
169
|
+
_getEventSourceStatus = new WeakMap();
|
|
170
|
+
_handlers = new WeakMap();
|
|
171
|
+
_status = new WeakMap();
|
|
172
|
+
|
|
173
|
+
// src/http_client.ts
|
|
174
|
+
var _options, _retrieveXsrfToken, retrieveXsrfToken_fn;
|
|
175
|
+
var HttpClient = class {
|
|
176
|
+
constructor(options) {
|
|
177
|
+
__privateAdd(this, _retrieveXsrfToken);
|
|
178
|
+
__privateAdd(this, _options, void 0);
|
|
179
|
+
__privateSet(this, _options, options);
|
|
180
|
+
}
|
|
181
|
+
send(request) {
|
|
182
|
+
return fetch(request);
|
|
183
|
+
}
|
|
184
|
+
createRequest(path, body) {
|
|
185
|
+
return new Request(`${__privateGet(this, _options).baseUrl}${path}`, {
|
|
186
|
+
method: "POST",
|
|
187
|
+
headers: {
|
|
188
|
+
"Content-Type": "application/json",
|
|
189
|
+
"X-XSRF-TOKEN": __privateMethod(this, _retrieveXsrfToken, retrieveXsrfToken_fn).call(this) ?? ""
|
|
190
|
+
},
|
|
191
|
+
body: JSON.stringify({ uid: __privateGet(this, _options).uid, ...body }),
|
|
192
|
+
credentials: "include"
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
};
|
|
196
|
+
_options = new WeakMap();
|
|
197
|
+
_retrieveXsrfToken = new WeakSet();
|
|
198
|
+
retrieveXsrfToken_fn = function() {
|
|
199
|
+
if (typeof document === "undefined")
|
|
200
|
+
return null;
|
|
201
|
+
const match = document.cookie.match(new RegExp("(^|;\\s*)(XSRF-TOKEN)=([^;]*)"));
|
|
202
|
+
return match ? decodeURIComponent(match[3]) : null;
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
// src/hook_event.ts
|
|
206
|
+
var HookEvent = {
|
|
207
|
+
BeforeSubscribe: "beforeSubscribe",
|
|
208
|
+
BeforeUnsubscribe: "beforeUnsubscribe",
|
|
209
|
+
OnReconnectAttempt: "onReconnectAttempt",
|
|
210
|
+
OnReconnectFailed: "onReconnectFailed",
|
|
211
|
+
OnSubscribeFailed: "onSubscribeFailed",
|
|
212
|
+
OnSubscription: "onSubscription",
|
|
213
|
+
OnUnsubscription: "onUnsubscription"
|
|
214
|
+
};
|
|
215
|
+
|
|
216
|
+
// src/hook.ts
|
|
217
|
+
var _handlers2;
|
|
218
|
+
var Hook = class {
|
|
219
|
+
constructor() {
|
|
220
|
+
__privateAdd(this, _handlers2, /* @__PURE__ */ new Map());
|
|
221
|
+
}
|
|
222
|
+
register(event, handler) {
|
|
223
|
+
if (!__privateGet(this, _handlers2).has(event)) {
|
|
224
|
+
__privateGet(this, _handlers2).set(event, /* @__PURE__ */ new Set());
|
|
225
|
+
}
|
|
226
|
+
__privateGet(this, _handlers2).get(event)?.add(handler);
|
|
227
|
+
return this;
|
|
228
|
+
}
|
|
229
|
+
beforeSubscribe(request) {
|
|
230
|
+
__privateGet(this, _handlers2).get(HookEvent.BeforeSubscribe)?.forEach((handler) => handler(request));
|
|
231
|
+
return this;
|
|
232
|
+
}
|
|
233
|
+
beforeUnsubscribe(request) {
|
|
234
|
+
__privateGet(this, _handlers2).get(HookEvent.BeforeUnsubscribe)?.forEach((handler) => handler(request));
|
|
235
|
+
return this;
|
|
236
|
+
}
|
|
237
|
+
onReconnectAttempt(attempt) {
|
|
238
|
+
__privateGet(this, _handlers2).get(HookEvent.OnReconnectAttempt)?.forEach((handler) => handler(attempt));
|
|
239
|
+
return this;
|
|
240
|
+
}
|
|
241
|
+
onReconnectFailed() {
|
|
242
|
+
__privateGet(this, _handlers2).get(HookEvent.OnReconnectFailed)?.forEach((handler) => handler());
|
|
243
|
+
return this;
|
|
244
|
+
}
|
|
245
|
+
onSubscribeFailed(response) {
|
|
246
|
+
__privateGet(this, _handlers2).get(HookEvent.OnSubscribeFailed)?.forEach((handler) => handler(response));
|
|
247
|
+
return this;
|
|
248
|
+
}
|
|
249
|
+
onSubscription(channel) {
|
|
250
|
+
__privateGet(this, _handlers2).get(HookEvent.OnSubscription)?.forEach((handler) => handler(channel));
|
|
251
|
+
return this;
|
|
252
|
+
}
|
|
253
|
+
onUnsubscription(channel) {
|
|
254
|
+
__privateGet(this, _handlers2).get(HookEvent.OnUnsubscription)?.forEach((handler) => handler(channel));
|
|
255
|
+
return this;
|
|
256
|
+
}
|
|
257
|
+
};
|
|
258
|
+
_handlers2 = new WeakMap();
|
|
259
|
+
|
|
260
|
+
// src/transmit.ts
|
|
261
|
+
var _uid, _options2, _subscriptions, _httpClient2, _hooks2, _status2, _eventSource, _eventTarget, _reconnectAttempts, _changeStatus, changeStatus_fn, _connect, connect_fn, _onMessage, onMessage_fn, _onError, onError_fn;
|
|
262
|
+
var Transmit = class {
|
|
263
|
+
constructor(options) {
|
|
264
|
+
__privateAdd(this, _changeStatus);
|
|
265
|
+
__privateAdd(this, _connect);
|
|
266
|
+
__privateAdd(this, _onMessage);
|
|
267
|
+
__privateAdd(this, _onError);
|
|
268
|
+
/**
|
|
269
|
+
* Unique identifier for this client.
|
|
270
|
+
*/
|
|
271
|
+
__privateAdd(this, _uid, void 0);
|
|
272
|
+
/**
|
|
273
|
+
* Options for this client.
|
|
274
|
+
*/
|
|
275
|
+
__privateAdd(this, _options2, void 0);
|
|
276
|
+
/**
|
|
277
|
+
* Registered subscriptions.
|
|
278
|
+
*/
|
|
279
|
+
__privateAdd(this, _subscriptions, /* @__PURE__ */ new Map());
|
|
280
|
+
/**
|
|
281
|
+
* HTTP client instance.
|
|
282
|
+
*/
|
|
283
|
+
__privateAdd(this, _httpClient2, void 0);
|
|
284
|
+
/**
|
|
285
|
+
* Hook instance.
|
|
286
|
+
*/
|
|
287
|
+
__privateAdd(this, _hooks2, void 0);
|
|
288
|
+
/**
|
|
289
|
+
* Current status of the client.
|
|
290
|
+
*/
|
|
291
|
+
__privateAdd(this, _status2, TransmitStatus.Initializing);
|
|
292
|
+
/**
|
|
293
|
+
* EventSource instance.
|
|
294
|
+
*/
|
|
295
|
+
__privateAdd(this, _eventSource, void 0);
|
|
296
|
+
/**
|
|
297
|
+
* EventTarget instance.
|
|
298
|
+
*/
|
|
299
|
+
__privateAdd(this, _eventTarget, void 0);
|
|
300
|
+
/**
|
|
301
|
+
* Number of reconnect attempts.
|
|
302
|
+
*/
|
|
303
|
+
__privateAdd(this, _reconnectAttempts, 0);
|
|
304
|
+
if (typeof options.uidGenerator === "undefined") {
|
|
305
|
+
options.uidGenerator = () => crypto.randomUUID();
|
|
306
|
+
}
|
|
307
|
+
if (typeof options.eventSourceFactory === "undefined") {
|
|
308
|
+
options.eventSourceFactory = (...args) => new EventSource(...args);
|
|
309
|
+
}
|
|
310
|
+
if (typeof options.eventTargetFactory === "undefined") {
|
|
311
|
+
options.eventTargetFactory = () => new EventTarget();
|
|
312
|
+
}
|
|
313
|
+
if (typeof options.maxReconnectAttempts === "undefined") {
|
|
314
|
+
options.maxReconnectAttempts = 5;
|
|
315
|
+
}
|
|
316
|
+
__privateSet(this, _uid, options.uidGenerator());
|
|
317
|
+
__privateSet(this, _eventTarget, options.eventTargetFactory());
|
|
318
|
+
__privateSet(this, _hooks2, new Hook());
|
|
319
|
+
__privateSet(this, _httpClient2, new HttpClient({
|
|
320
|
+
baseUrl: options.baseUrl,
|
|
321
|
+
uid: __privateGet(this, _uid)
|
|
322
|
+
}));
|
|
323
|
+
if (options.beforeSubscribe) {
|
|
324
|
+
__privateGet(this, _hooks2).register(HookEvent.BeforeSubscribe, options.beforeSubscribe);
|
|
325
|
+
}
|
|
326
|
+
if (options.beforeUnsubscribe) {
|
|
327
|
+
__privateGet(this, _hooks2).register(HookEvent.BeforeUnsubscribe, options.beforeUnsubscribe);
|
|
328
|
+
}
|
|
329
|
+
if (options.onReconnectAttempt) {
|
|
330
|
+
__privateGet(this, _hooks2).register(HookEvent.OnReconnectAttempt, options.onReconnectAttempt);
|
|
331
|
+
}
|
|
332
|
+
if (options.onReconnectFailed) {
|
|
333
|
+
__privateGet(this, _hooks2).register(HookEvent.OnReconnectFailed, options.onReconnectFailed);
|
|
334
|
+
}
|
|
335
|
+
if (options.onSubscribeFailed) {
|
|
336
|
+
__privateGet(this, _hooks2).register(HookEvent.OnSubscribeFailed, options.onSubscribeFailed);
|
|
337
|
+
}
|
|
338
|
+
if (options.onSubscription) {
|
|
339
|
+
__privateGet(this, _hooks2).register(HookEvent.OnSubscription, options.onSubscription);
|
|
340
|
+
}
|
|
341
|
+
if (options.onUnsubscription) {
|
|
342
|
+
__privateGet(this, _hooks2).register(HookEvent.OnUnsubscription, options.onUnsubscription);
|
|
343
|
+
}
|
|
344
|
+
__privateSet(this, _options2, options);
|
|
345
|
+
__privateMethod(this, _connect, connect_fn).call(this);
|
|
346
|
+
}
|
|
347
|
+
/**
|
|
348
|
+
* Returns the unique identifier of the client.
|
|
349
|
+
*/
|
|
350
|
+
get uid() {
|
|
351
|
+
return __privateGet(this, _uid);
|
|
352
|
+
}
|
|
353
|
+
subscription(channel) {
|
|
354
|
+
const subscription = new Subscription({
|
|
355
|
+
channel,
|
|
356
|
+
httpClient: __privateGet(this, _httpClient2),
|
|
357
|
+
hooks: __privateGet(this, _hooks2),
|
|
358
|
+
getEventSourceStatus: () => __privateGet(this, _status2)
|
|
359
|
+
});
|
|
360
|
+
if (__privateGet(this, _subscriptions).has(channel)) {
|
|
361
|
+
return __privateGet(this, _subscriptions).get(channel);
|
|
362
|
+
}
|
|
363
|
+
__privateGet(this, _subscriptions).set(channel, subscription);
|
|
364
|
+
return subscription;
|
|
365
|
+
}
|
|
366
|
+
on(event, callback) {
|
|
367
|
+
__privateGet(this, _eventTarget)?.addEventListener(event, callback);
|
|
368
|
+
}
|
|
369
|
+
close() {
|
|
370
|
+
__privateGet(this, _eventSource)?.close();
|
|
371
|
+
}
|
|
372
|
+
};
|
|
373
|
+
_uid = new WeakMap();
|
|
374
|
+
_options2 = new WeakMap();
|
|
375
|
+
_subscriptions = new WeakMap();
|
|
376
|
+
_httpClient2 = new WeakMap();
|
|
377
|
+
_hooks2 = new WeakMap();
|
|
378
|
+
_status2 = new WeakMap();
|
|
379
|
+
_eventSource = new WeakMap();
|
|
380
|
+
_eventTarget = new WeakMap();
|
|
381
|
+
_reconnectAttempts = new WeakMap();
|
|
382
|
+
_changeStatus = new WeakSet();
|
|
383
|
+
changeStatus_fn = function(status) {
|
|
384
|
+
__privateSet(this, _status2, status);
|
|
385
|
+
__privateGet(this, _eventTarget)?.dispatchEvent(new CustomEvent(status));
|
|
386
|
+
};
|
|
387
|
+
_connect = new WeakSet();
|
|
388
|
+
connect_fn = function() {
|
|
389
|
+
__privateMethod(this, _changeStatus, changeStatus_fn).call(this, TransmitStatus.Connecting);
|
|
390
|
+
const url = new URL(`${__privateGet(this, _options2).baseUrl}/__transmit/events`);
|
|
391
|
+
url.searchParams.append("uid", __privateGet(this, _uid));
|
|
392
|
+
__privateSet(this, _eventSource, __privateGet(this, _options2).eventSourceFactory(url, {
|
|
393
|
+
withCredentials: true
|
|
394
|
+
}));
|
|
395
|
+
__privateGet(this, _eventSource).addEventListener("message", __privateMethod(this, _onMessage, onMessage_fn).bind(this));
|
|
396
|
+
__privateGet(this, _eventSource).addEventListener("error", __privateMethod(this, _onError, onError_fn).bind(this));
|
|
397
|
+
__privateGet(this, _eventSource).addEventListener("open", () => {
|
|
398
|
+
__privateMethod(this, _changeStatus, changeStatus_fn).call(this, TransmitStatus.Connected);
|
|
399
|
+
__privateSet(this, _reconnectAttempts, 0);
|
|
400
|
+
for (const subscription of __privateGet(this, _subscriptions).values()) {
|
|
401
|
+
void subscription.create();
|
|
402
|
+
}
|
|
403
|
+
});
|
|
404
|
+
};
|
|
405
|
+
_onMessage = new WeakSet();
|
|
406
|
+
onMessage_fn = function(event) {
|
|
407
|
+
const data = JSON.parse(event.data);
|
|
408
|
+
const subscription = __privateGet(this, _subscriptions).get(data.channel);
|
|
409
|
+
if (typeof subscription === "undefined") {
|
|
410
|
+
return;
|
|
411
|
+
}
|
|
412
|
+
try {
|
|
413
|
+
subscription.$runHandler(data.payload);
|
|
414
|
+
} catch (error) {
|
|
415
|
+
console.log(error);
|
|
416
|
+
}
|
|
417
|
+
};
|
|
418
|
+
_onError = new WeakSet();
|
|
419
|
+
onError_fn = function() {
|
|
420
|
+
if (__privateGet(this, _status2) !== TransmitStatus.Reconnecting) {
|
|
421
|
+
__privateMethod(this, _changeStatus, changeStatus_fn).call(this, TransmitStatus.Disconnected);
|
|
422
|
+
}
|
|
423
|
+
__privateMethod(this, _changeStatus, changeStatus_fn).call(this, TransmitStatus.Reconnecting);
|
|
424
|
+
__privateGet(this, _hooks2).onReconnectAttempt(__privateGet(this, _reconnectAttempts) + 1);
|
|
425
|
+
if (__privateGet(this, _options2).maxReconnectAttempts && __privateGet(this, _reconnectAttempts) >= __privateGet(this, _options2).maxReconnectAttempts) {
|
|
426
|
+
__privateGet(this, _eventSource).close();
|
|
427
|
+
__privateGet(this, _hooks2).onReconnectFailed();
|
|
428
|
+
return;
|
|
429
|
+
}
|
|
430
|
+
__privateWrapper(this, _reconnectAttempts)._++;
|
|
431
|
+
};
|
|
432
|
+
export {
|
|
433
|
+
Transmit
|
|
434
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adonisjs/transmit-client",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "A client for the native Server-Sent-Event module of AdonisJS.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"client",
|
|
@@ -15,34 +15,33 @@
|
|
|
15
15
|
"author": "Romain Lanz <romain.lanz@pm.me>",
|
|
16
16
|
"type": "module",
|
|
17
17
|
"source": "src/transmit.ts",
|
|
18
|
-
"exports": {
|
|
19
|
-
"types": "./build/transmit.d.ts",
|
|
20
|
-
"require": "./build/transmit.cjs",
|
|
21
|
-
"default": "./build/transmit.modern.js"
|
|
22
|
-
},
|
|
23
18
|
"main": "./build/transmit.js",
|
|
24
|
-
"
|
|
25
|
-
"unpkg": "./build/transmit.umd.js",
|
|
19
|
+
"types": "./build/transmit.d.ts",
|
|
26
20
|
"scripts": {
|
|
27
21
|
"clean": "del-cli build",
|
|
28
22
|
"typecheck": "tsc --noEmit",
|
|
29
23
|
"lint": "eslint . --ext=.ts",
|
|
30
24
|
"format": "prettier --write .",
|
|
31
|
-
"
|
|
32
|
-
"
|
|
33
|
-
"dev": "microbundle watch",
|
|
34
|
-
"release": "np",
|
|
25
|
+
"build": "tsup",
|
|
26
|
+
"release": "npx release-it",
|
|
35
27
|
"version": "npm run build",
|
|
36
|
-
"prepublishOnly": "npm run build"
|
|
28
|
+
"prepublishOnly": "npm run build",
|
|
29
|
+
"test": "c8 node --loader ts-node/esm --enable-source-maps bin/test.ts"
|
|
37
30
|
},
|
|
38
31
|
"devDependencies": {
|
|
39
32
|
"@adonisjs/eslint-config": "^1.1.7",
|
|
40
33
|
"@adonisjs/prettier-config": "^1.1.7",
|
|
34
|
+
"@adonisjs/tsconfig": "^1.3.0",
|
|
35
|
+
"@japa/assert": "^2.0.0-2",
|
|
36
|
+
"@japa/runner": "^3.0.0-9",
|
|
37
|
+
"@swc/core": "^1.4.11",
|
|
38
|
+
"c8": "^9.1.0",
|
|
41
39
|
"del-cli": "^5.0.0",
|
|
42
40
|
"eslint": "^8.44.0",
|
|
43
|
-
"microbundle": "^0.15.1",
|
|
44
|
-
"np": "^8.0.4",
|
|
45
41
|
"prettier": "^3.0.0",
|
|
42
|
+
"release-it": "^17.1.1",
|
|
43
|
+
"ts-node": "^10.9.2",
|
|
44
|
+
"tsup": "^8.0.2",
|
|
46
45
|
"typescript": "^5.1.6"
|
|
47
46
|
},
|
|
48
47
|
"files": [
|
|
@@ -60,10 +59,27 @@
|
|
|
60
59
|
"access": "public",
|
|
61
60
|
"tag": "latest"
|
|
62
61
|
},
|
|
63
|
-
"
|
|
64
|
-
"
|
|
65
|
-
"
|
|
66
|
-
"
|
|
67
|
-
"
|
|
62
|
+
"tsup": {
|
|
63
|
+
"dts": true,
|
|
64
|
+
"clean": true,
|
|
65
|
+
"format": "esm",
|
|
66
|
+
"sourceMap": true,
|
|
67
|
+
"target": "es2020",
|
|
68
|
+
"outDir": "build",
|
|
69
|
+
"entry": [
|
|
70
|
+
"src/transmit.ts"
|
|
71
|
+
]
|
|
72
|
+
},
|
|
73
|
+
"release-it": {
|
|
74
|
+
"git": {
|
|
75
|
+
"commitMessage": "chore(release): ${version}",
|
|
76
|
+
"tagAnnotation": "v${version}",
|
|
77
|
+
"tagName": "v${version}"
|
|
78
|
+
},
|
|
79
|
+
"github": {
|
|
80
|
+
"release": true,
|
|
81
|
+
"releaseName": "v${version}",
|
|
82
|
+
"web": true
|
|
83
|
+
}
|
|
68
84
|
}
|
|
69
85
|
}
|
package/src/hook.ts
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* @adonisjs/transmit-client
|
|
3
|
+
*
|
|
4
|
+
* (c) AdonisJS
|
|
5
|
+
*
|
|
6
|
+
* For the full copyright and license information, please view the LICENSE
|
|
7
|
+
* file that was distributed with this source code.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { HookEvent } from './hook_event.js'
|
|
11
|
+
|
|
12
|
+
export class Hook {
|
|
13
|
+
#handlers = new Map<HookEvent, Set<(...args: any[]) => void>>()
|
|
14
|
+
|
|
15
|
+
register(event: HookEvent, handler: (...args: any[]) => void) {
|
|
16
|
+
if (!this.#handlers.has(event)) {
|
|
17
|
+
this.#handlers.set(event, new Set())
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
this.#handlers.get(event)?.add(handler)
|
|
21
|
+
|
|
22
|
+
return this
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
beforeSubscribe(request: Request) {
|
|
26
|
+
this.#handlers.get(HookEvent.BeforeSubscribe)?.forEach((handler) => handler(request))
|
|
27
|
+
|
|
28
|
+
return this
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
beforeUnsubscribe(request: Request) {
|
|
32
|
+
this.#handlers.get(HookEvent.BeforeUnsubscribe)?.forEach((handler) => handler(request))
|
|
33
|
+
|
|
34
|
+
return this
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
onReconnectAttempt(attempt: number) {
|
|
38
|
+
this.#handlers.get(HookEvent.OnReconnectAttempt)?.forEach((handler) => handler(attempt))
|
|
39
|
+
|
|
40
|
+
return this
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
onReconnectFailed() {
|
|
44
|
+
this.#handlers.get(HookEvent.OnReconnectFailed)?.forEach((handler) => handler())
|
|
45
|
+
|
|
46
|
+
return this
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
onSubscribeFailed(response: Response) {
|
|
50
|
+
this.#handlers.get(HookEvent.OnSubscribeFailed)?.forEach((handler) => handler(response))
|
|
51
|
+
|
|
52
|
+
return this
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
onSubscription(channel: string) {
|
|
56
|
+
this.#handlers.get(HookEvent.OnSubscription)?.forEach((handler) => handler(channel))
|
|
57
|
+
|
|
58
|
+
return this
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
onUnsubscription(channel: string) {
|
|
62
|
+
this.#handlers.get(HookEvent.OnUnsubscription)?.forEach((handler) => handler(channel))
|
|
63
|
+
|
|
64
|
+
return this
|
|
65
|
+
}
|
|
66
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* @adonisjs/transmit-client
|
|
3
|
+
*
|
|
4
|
+
* (c) AdonisJS
|
|
5
|
+
*
|
|
6
|
+
* For the full copyright and license information, please view the LICENSE
|
|
7
|
+
* file that was distributed with this source code.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
export const HookEvent = {
|
|
11
|
+
BeforeSubscribe: 'beforeSubscribe',
|
|
12
|
+
BeforeUnsubscribe: 'beforeUnsubscribe',
|
|
13
|
+
OnReconnectAttempt: 'onReconnectAttempt',
|
|
14
|
+
OnReconnectFailed: 'onReconnectFailed',
|
|
15
|
+
OnSubscribeFailed: 'onSubscribeFailed',
|
|
16
|
+
OnSubscription: 'onSubscription',
|
|
17
|
+
OnUnsubscription: 'onUnsubscription',
|
|
18
|
+
} as const
|
|
19
|
+
|
|
20
|
+
export type HookEvent = (typeof HookEvent)[keyof typeof HookEvent]
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* @adonisjs/transmit-client
|
|
3
|
+
*
|
|
4
|
+
* (c) AdonisJS
|
|
5
|
+
*
|
|
6
|
+
* For the full copyright and license information, please view the LICENSE
|
|
7
|
+
* file that was distributed with this source code.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
interface HttpClientOptions {
|
|
11
|
+
baseUrl: string
|
|
12
|
+
uid: string
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export class HttpClient {
|
|
16
|
+
#options: HttpClientOptions
|
|
17
|
+
|
|
18
|
+
constructor(options: HttpClientOptions) {
|
|
19
|
+
this.#options = options
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
send(request: Request) {
|
|
23
|
+
return fetch(request)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
createRequest(path: string, body: Record<string, unknown>) {
|
|
27
|
+
return new Request(`${this.#options.baseUrl}${path}`, {
|
|
28
|
+
method: 'POST',
|
|
29
|
+
headers: {
|
|
30
|
+
'Content-Type': 'application/json',
|
|
31
|
+
'X-XSRF-TOKEN': this.#retrieveXsrfToken() ?? '',
|
|
32
|
+
},
|
|
33
|
+
body: JSON.stringify({ uid: this.#options.uid, ...body }),
|
|
34
|
+
credentials: 'include',
|
|
35
|
+
})
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
#retrieveXsrfToken() {
|
|
39
|
+
//? This is a browser-only feature
|
|
40
|
+
if (typeof document === 'undefined') return null
|
|
41
|
+
|
|
42
|
+
const match = document.cookie.match(new RegExp('(^|;\\s*)(XSRF-TOKEN)=([^;]*)'))
|
|
43
|
+
|
|
44
|
+
return match ? decodeURIComponent(match[3]) : null
|
|
45
|
+
}
|
|
46
|
+
}
|