@adonisjs/transmit-client 0.1.6 → 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.
@@ -0,0 +1,165 @@
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 { SubscriptionStatus } from './subscription_status.js'
11
+ import { HttpClient } from './http_client.js'
12
+ import { Hook } from './hook.js'
13
+ import { TransmitStatus } from './transmit_status.js'
14
+
15
+ interface SubscriptionOptions {
16
+ channel: string
17
+ httpClient: HttpClient
18
+ getEventSourceStatus: () => TransmitStatus
19
+ hooks?: Hook
20
+ }
21
+
22
+ export class Subscription {
23
+ /**
24
+ * HTTP client instance.
25
+ */
26
+ #httpClient: HttpClient
27
+
28
+ /**
29
+ * Hook instance.
30
+ */
31
+ #hooks: Hook | undefined
32
+
33
+ /**
34
+ * Channel name.
35
+ */
36
+ #channel: string
37
+
38
+ /**
39
+ * Event source status getter.
40
+ */
41
+ #getEventSourceStatus: () => TransmitStatus
42
+
43
+ /**
44
+ * Registered message handlers.
45
+ */
46
+ #handlers = new Set<(message: any) => void>()
47
+
48
+ /**
49
+ * Current status of the subscription.
50
+ */
51
+ #status: SubscriptionStatus = SubscriptionStatus.Pending
52
+
53
+ /**
54
+ * Returns if the subscription is created or not.
55
+ */
56
+ get isCreated() {
57
+ return this.#status === SubscriptionStatus.Created
58
+ }
59
+
60
+ /**
61
+ * Returns if the subscription is deleted or not.
62
+ */
63
+ get isDeleted() {
64
+ return this.#status === SubscriptionStatus.Deleted
65
+ }
66
+
67
+ /**
68
+ * Returns the number of registered handlers.
69
+ */
70
+ get handlerCount() {
71
+ return this.#handlers.size
72
+ }
73
+
74
+ constructor(options: SubscriptionOptions) {
75
+ this.#channel = options.channel
76
+ this.#httpClient = options.httpClient
77
+ this.#hooks = options.hooks
78
+ this.#getEventSourceStatus = options.getEventSourceStatus
79
+ }
80
+
81
+ /**
82
+ * Run all registered handlers for the subscription.
83
+ */
84
+ $runHandler(message: unknown) {
85
+ for (const handler of this.#handlers) {
86
+ handler(message)
87
+ }
88
+ }
89
+
90
+ async create() {
91
+ if (this.isCreated) {
92
+ return
93
+ }
94
+
95
+ if (this.#getEventSourceStatus() !== TransmitStatus.Connected) {
96
+ return new Promise((resolve) => {
97
+ setTimeout(() => {
98
+ resolve(this.create())
99
+ }, 100)
100
+ })
101
+ }
102
+
103
+ const request = this.#httpClient.createRequest('/__transmit/subscribe', {
104
+ channel: this.#channel,
105
+ })
106
+
107
+ this.#hooks?.beforeSubscribe(request)
108
+
109
+ try {
110
+ const response = await this.#httpClient.send(request)
111
+
112
+ //? Dump the response text
113
+ void response.text()
114
+
115
+ if (!response.ok) {
116
+ this.#hooks?.onSubscribeFailed(response)
117
+ return
118
+ }
119
+
120
+ this.#status = SubscriptionStatus.Created
121
+ this.#hooks?.onSubscription(this.#channel)
122
+ } catch (error) {}
123
+ }
124
+
125
+ async delete() {
126
+ if (this.isDeleted || !this.isCreated) {
127
+ return
128
+ }
129
+
130
+ const request = this.#httpClient.createRequest('/__transmit/unsubscribe', {
131
+ channel: this.#channel,
132
+ })
133
+
134
+ this.#hooks?.beforeUnsubscribe(request)
135
+
136
+ try {
137
+ const response = await this.#httpClient.send(request)
138
+
139
+ //? Dump the response text
140
+ void response.text()
141
+
142
+ if (!response.ok) {
143
+ return
144
+ }
145
+
146
+ this.#status = SubscriptionStatus.Deleted
147
+ this.#hooks?.onUnsubscription(this.#channel)
148
+ } catch (error) {}
149
+ }
150
+
151
+ onMessage<T>(handler: (message: T) => void) {
152
+ this.#handlers.add(handler)
153
+
154
+ return () => {
155
+ this.#handlers.delete(handler)
156
+ }
157
+ }
158
+
159
+ onMessageOnce<T>(handler: (message: T) => void) {
160
+ const deleteHandler = this.onMessage<T>((message) => {
161
+ handler(message)
162
+ deleteHandler()
163
+ })
164
+ }
165
+ }
@@ -0,0 +1,16 @@
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 SubscriptionStatus = {
11
+ Pending: 0,
12
+ Created: 1,
13
+ Deleted: 2,
14
+ } as const
15
+
16
+ export type SubscriptionStatus = (typeof SubscriptionStatus)[keyof typeof SubscriptionStatus]
package/src/transmit.ts CHANGED
@@ -1,6 +1,23 @@
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 { Subscription } from './subscription.js'
11
+ import { HttpClient } from './http_client.js'
12
+ import { TransmitStatus } from './transmit_status.js'
13
+ import { Hook } from './hook.js'
14
+ import { HookEvent } from './hook_event.js'
15
+
1
16
  interface TransmitOptions {
2
17
  baseUrl: string
3
- eventSourceConstructor?: typeof EventSource
18
+ uidGenerator?: () => string
19
+ eventSourceFactory?: (url: string | URL, options: { withCredentials: boolean }) => EventSource
20
+ eventTargetFactory?: () => EventTarget | null
4
21
  beforeSubscribe?: (request: RequestInit) => void
5
22
  beforeUnsubscribe?: (request: RequestInit) => void
6
23
  maxReconnectAttempts?: number
@@ -9,24 +26,13 @@ interface TransmitOptions {
9
26
  onSubscribeFailed?: (response: Response) => void
10
27
  onSubscription?: (channel: string) => void
11
28
  onUnsubscription?: (channel: string) => void
12
- removeSubscriptionOnZeroListener?: boolean
13
29
  }
14
30
 
15
- export const TransmitStatus = {
16
- Initializing: 'initializing',
17
- Connecting: 'connecting',
18
- Connected: 'connected',
19
- Disconnected: 'disconnected',
20
- Reconnecting: 'reconnecting',
21
- } as const
22
-
23
- type TTransmitStatus = (typeof TransmitStatus)[keyof typeof TransmitStatus]
24
-
25
- export class Transmit extends EventTarget {
31
+ export class Transmit {
26
32
  /**
27
33
  * Unique identifier for this client.
28
34
  */
29
- #uid: string = crypto.randomUUID()
35
+ #uid: string
30
36
 
31
37
  /**
32
38
  * Options for this client.
@@ -34,19 +40,34 @@ export class Transmit extends EventTarget {
34
40
  #options: TransmitOptions
35
41
 
36
42
  /**
37
- * Registered listeners.
43
+ * Registered subscriptions.
44
+ */
45
+ #subscriptions = new Map<string, Subscription>()
46
+
47
+ /**
48
+ * HTTP client instance.
38
49
  */
39
- #listeners: Map<string, Set<(message: any) => void>> = new Map()
50
+ #httpClient: HttpClient
51
+
52
+ /**
53
+ * Hook instance.
54
+ */
55
+ #hooks: Hook
40
56
 
41
57
  /**
42
58
  * Current status of the client.
43
59
  */
44
- #status: TTransmitStatus = TransmitStatus.Initializing
60
+ #status: TransmitStatus = TransmitStatus.Initializing
45
61
 
46
62
  /**
47
63
  * EventSource instance.
48
64
  */
49
- #eventSource!: EventSource
65
+ #eventSource: EventSource | undefined
66
+
67
+ /**
68
+ * EventTarget instance.
69
+ */
70
+ #eventTarget: EventTarget | null
50
71
 
51
72
  /**
52
73
  * Number of reconnect attempts.
@@ -54,40 +75,72 @@ export class Transmit extends EventTarget {
54
75
  #reconnectAttempts: number = 0
55
76
 
56
77
  /**
57
- * Locks for channel subscriptions.
78
+ * Returns the unique identifier of the client.
58
79
  */
59
- #channelSubscriptionLock: Set<string> = new Set()
60
-
61
80
  get uid() {
62
81
  return this.#uid
63
82
  }
64
83
 
65
- get listOfSubscriptions() {
66
- return Array.from(this.#listeners.keys())
67
- }
68
-
69
84
  constructor(options: TransmitOptions) {
70
- super()
85
+ if (typeof options.uidGenerator === 'undefined') {
86
+ options.uidGenerator = () => crypto.randomUUID()
87
+ }
88
+
89
+ if (typeof options.eventSourceFactory === 'undefined') {
90
+ options.eventSourceFactory = (...args) => new EventSource(...args)
91
+ }
71
92
 
72
- if (typeof options.eventSourceConstructor === 'undefined') {
73
- options.eventSourceConstructor = EventSource
93
+ if (typeof options.eventTargetFactory === 'undefined') {
94
+ options.eventTargetFactory = () => new EventTarget()
74
95
  }
75
96
 
76
97
  if (typeof options.maxReconnectAttempts === 'undefined') {
77
98
  options.maxReconnectAttempts = 5
78
99
  }
79
100
 
80
- if (typeof options.removeSubscriptionOnZeroListener === 'undefined') {
81
- options.removeSubscriptionOnZeroListener = false
101
+ this.#uid = options.uidGenerator()
102
+ this.#eventTarget = options.eventTargetFactory()
103
+ this.#hooks = new Hook()
104
+ this.#httpClient = new HttpClient({
105
+ baseUrl: options.baseUrl,
106
+ uid: this.#uid,
107
+ })
108
+
109
+ if (options.beforeSubscribe) {
110
+ this.#hooks.register(HookEvent.BeforeSubscribe, options.beforeSubscribe)
111
+ }
112
+
113
+ if (options.beforeUnsubscribe) {
114
+ this.#hooks.register(HookEvent.BeforeUnsubscribe, options.beforeUnsubscribe)
115
+ }
116
+
117
+ if (options.onReconnectAttempt) {
118
+ this.#hooks.register(HookEvent.OnReconnectAttempt, options.onReconnectAttempt)
119
+ }
120
+
121
+ if (options.onReconnectFailed) {
122
+ this.#hooks.register(HookEvent.OnReconnectFailed, options.onReconnectFailed)
123
+ }
124
+
125
+ if (options.onSubscribeFailed) {
126
+ this.#hooks.register(HookEvent.OnSubscribeFailed, options.onSubscribeFailed)
127
+ }
128
+
129
+ if (options.onSubscription) {
130
+ this.#hooks.register(HookEvent.OnSubscription, options.onSubscription)
131
+ }
132
+
133
+ if (options.onUnsubscription) {
134
+ this.#hooks.register(HookEvent.OnUnsubscription, options.onUnsubscription)
82
135
  }
83
136
 
84
137
  this.#options = options
85
138
  this.#connect()
86
139
  }
87
140
 
88
- #changeStatus(status: TTransmitStatus) {
141
+ #changeStatus(status: TransmitStatus) {
89
142
  this.#status = status
90
- this.dispatchEvent(new CustomEvent(status))
143
+ this.#eventTarget?.dispatchEvent(new CustomEvent(status))
91
144
  }
92
145
 
93
146
  #connect() {
@@ -96,40 +149,38 @@ export class Transmit extends EventTarget {
96
149
  const url = new URL(`${this.#options.baseUrl}/__transmit/events`)
97
150
  url.searchParams.append('uid', this.#uid)
98
151
 
99
- this.#eventSource = new this.#options.eventSourceConstructor(url.toString(), {
152
+ this.#eventSource = this.#options.eventSourceFactory!(url, {
100
153
  withCredentials: true,
101
154
  })
155
+
102
156
  this.#eventSource.addEventListener('message', this.#onMessage.bind(this))
103
157
  this.#eventSource.addEventListener('error', this.#onError.bind(this))
104
158
  this.#eventSource.addEventListener('open', () => {
105
159
  this.#changeStatus(TransmitStatus.Connected)
106
160
  this.#reconnectAttempts = 0
107
161
 
108
- for (const channel of this.#listeners.keys()) {
109
- void this.#subscribe(channel)
162
+ for (const subscription of this.#subscriptions.values()) {
163
+ void subscription.create()
110
164
  }
111
165
  })
112
166
  }
113
167
 
114
168
  #onMessage(event: MessageEvent) {
115
169
  const data = JSON.parse(event.data)
116
- const listeners = this.#listeners.get(data.channel)
170
+ const subscription = this.#subscriptions.get(data.channel)
117
171
 
118
- if (typeof listeners === 'undefined') {
172
+ if (typeof subscription === 'undefined') {
119
173
  return
120
174
  }
121
175
 
122
- for (const listener of listeners) {
123
- listener(data.payload)
176
+ try {
177
+ subscription.$runHandler(data.payload)
178
+ } catch (error) {
179
+ // TODO: Rescue
180
+ console.log(error)
124
181
  }
125
182
  }
126
183
 
127
- #retrieveXsrfToken() {
128
- const match = document.cookie.match(new RegExp('(^|;\\s*)(XSRF-TOKEN)=([^;]*)'))
129
-
130
- return match ? decodeURIComponent(match[3]) : null
131
- }
132
-
133
184
  #onError() {
134
185
  if (this.#status !== TransmitStatus.Reconnecting) {
135
186
  this.#changeStatus(TransmitStatus.Disconnected)
@@ -137,19 +188,15 @@ export class Transmit extends EventTarget {
137
188
 
138
189
  this.#changeStatus(TransmitStatus.Reconnecting)
139
190
 
140
- if (this.#options.onReconnectAttempt) {
141
- this.#options.onReconnectAttempt(this.#reconnectAttempts + 1)
142
- }
191
+ this.#hooks.onReconnectAttempt(this.#reconnectAttempts + 1)
143
192
 
144
193
  if (
145
194
  this.#options.maxReconnectAttempts &&
146
195
  this.#reconnectAttempts >= this.#options.maxReconnectAttempts
147
196
  ) {
148
- this.#eventSource.close()
197
+ this.#eventSource!.close()
149
198
 
150
- if (this.#options.onReconnectFailed) {
151
- this.#options.onReconnectFailed()
152
- }
199
+ this.#hooks.onReconnectFailed()
153
200
 
154
201
  return
155
202
  }
@@ -157,124 +204,29 @@ export class Transmit extends EventTarget {
157
204
  this.#reconnectAttempts++
158
205
  }
159
206
 
160
- async #subscribe(channel: string, callback?: any) {
161
- if (this.#status !== TransmitStatus.Connected) {
162
- return new Promise((resolve) => {
163
- setTimeout(() => {
164
- resolve(this.#subscribe(channel, callback))
165
- }, 100)
166
- })
167
- }
168
-
169
- const listeners = this.#listeners.get(channel)
170
-
171
- if (typeof listeners !== 'undefined' && typeof callback !== 'undefined') {
172
- this.#options.onSubscription?.(channel)
173
- listeners.add(callback)
174
- return
175
- }
176
-
177
- if (this.#channelSubscriptionLock.has(channel)) {
178
- return new Promise((resolve) => {
179
- setTimeout(() => {
180
- resolve(this.#subscribe(channel, callback))
181
- }, 100)
182
- })
183
- }
184
-
185
- this.#channelSubscriptionLock.add(channel)
186
-
187
- const request = new Request(`${this.#options.baseUrl}/__transmit/subscribe`, {
188
- method: 'POST',
189
- headers: {
190
- 'Content-Type': 'application/json',
191
- 'X-XSRF-TOKEN': this.#retrieveXsrfToken() ?? '',
192
- },
193
- body: JSON.stringify({ uid: this.#uid, channel }),
194
- credentials: 'include',
207
+ subscription(channel: string) {
208
+ const subscription = new Subscription({
209
+ channel,
210
+ httpClient: this.#httpClient,
211
+ hooks: this.#hooks,
212
+ getEventSourceStatus: () => this.#status,
195
213
  })
196
214
 
197
- this.#options.beforeSubscribe?.(request)
198
-
199
- try {
200
- const response = await fetch(request)
201
-
202
- if (!response.ok) {
203
- this.#options.onSubscribeFailed?.(response)
204
- this.#channelSubscriptionLock.delete(channel)
205
- return
206
- }
207
-
208
- if (typeof callback !== 'undefined') {
209
- const listeners = this.#listeners.get(channel)
210
-
211
- if (typeof listeners === 'undefined') {
212
- this.#listeners.set(channel, new Set([callback]))
213
- } else {
214
- listeners.add(callback)
215
- }
216
-
217
- this.#options.onSubscription?.(channel)
218
- }
219
- } finally {
220
- this.#channelSubscriptionLock.delete(channel)
215
+ if (this.#subscriptions.has(channel)) {
216
+ return this.#subscriptions.get(channel)!
221
217
  }
222
- }
223
-
224
- async #unsubscribe(channel: string) {
225
- const request = new Request(`${this.#options.baseUrl}/__transmit/unsubscribe`, {
226
- method: 'POST',
227
- headers: {
228
- 'Content-Type': 'application/json',
229
- 'X-XSRF-TOKEN': this.#retrieveXsrfToken() ?? '',
230
- },
231
- body: JSON.stringify({ uid: this.#uid, channel }),
232
- credentials: 'include',
233
- })
234
-
235
- this.#options.beforeUnsubscribe?.(request)
236
-
237
- const response = await fetch(request)
238
-
239
- if (!response.ok) {
240
- return
241
- }
242
- }
243
218
 
244
- on(event: Exclude<TTransmitStatus, 'connecting'>, callback: (event: CustomEvent) => void) {
245
- this.addEventListener(event, callback)
246
- }
247
-
248
- listenOn<T = unknown>(channel: string, callback: (message: T) => void) {
249
- void this.#subscribe(channel, callback)
250
-
251
- return (unsubscribeOnTheServer?: boolean) => {
252
- const listeners = this.#listeners.get(channel)
253
-
254
- if (typeof listeners === 'undefined') {
255
- return
256
- }
219
+ this.#subscriptions.set(channel, subscription)
257
220
 
258
- listeners.delete(callback)
259
- this.#options.onUnsubscription?.(channel)
260
-
261
- if (
262
- (unsubscribeOnTheServer ?? this.#options.removeSubscriptionOnZeroListener) &&
263
- listeners.size === 0
264
- ) {
265
- void this.#unsubscribe(channel)
266
- }
267
- }
221
+ return subscription
268
222
  }
269
223
 
270
- listenOnce<T = unknown>(channel: string, callback: (message: T) => void) {
271
- const unsubscribe = this.listenOn<T>(channel, (message) => {
272
- callback(message)
273
- unsubscribe()
274
- })
224
+ on(event: Exclude<TransmitStatus, 'connecting'>, callback: (event: CustomEvent) => void) {
225
+ // @ts-ignore
226
+ this.#eventTarget?.addEventListener(event, callback)
275
227
  }
276
228
 
277
229
  close() {
278
- this.#eventSource.close()
230
+ this.#eventSource?.close()
279
231
  }
280
232
  }
@@ -0,0 +1,18 @@
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 TransmitStatus = {
11
+ Initializing: 'initializing',
12
+ Connecting: 'connecting',
13
+ Connected: 'connected',
14
+ Disconnected: 'disconnected',
15
+ Reconnecting: 'reconnecting',
16
+ } as const
17
+
18
+ export type TransmitStatus = (typeof TransmitStatus)[keyof typeof TransmitStatus]
@@ -1,2 +0,0 @@
1
- function e(){try{var t=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){}))}catch(t){}return(e=function(){return!!t})()}function t(e){var t=function(e,t){if("object"!=typeof e||!e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var r=n.call(e,"string");if("object"!=typeof r)return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(e)}(e);return"symbol"==typeof t?t:String(t)}function n(e){return n=Object.setPrototypeOf?Object.getPrototypeOf.bind():function(e){return e.__proto__||Object.getPrototypeOf(e)},n(e)}function r(e,t){return r=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,t){return e.__proto__=t,e},r(e,t)}function o(t){var i="function"==typeof Map?new Map:void 0;return o=function(t){if(null===t||!function(e){try{return-1!==Function.toString.call(e).indexOf("[native code]")}catch(t){return"function"==typeof e}}(t))return t;if("function"!=typeof t)throw new TypeError("Super expression must either be null or a function");if(void 0!==i){if(i.has(t))return i.get(t);i.set(t,o)}function o(){return function(t,n,o){if(e())return Reflect.construct.apply(null,arguments);var i=[null];i.push.apply(i,n);var c=new(t.bind.apply(t,i));return o&&r(c,o.prototype),c}(t,arguments,n(this).constructor)}return o.prototype=Object.create(t.prototype,{constructor:{value:o,enumerable:!1,writable:!0,configurable:!0}}),r(o,t)},o(t)}function i(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function c(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}function u(e,t){var n="undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(n)return(n=n.call(e)).next.bind(n);if(Array.isArray(e)||(n=function(e,t){if(e){if("string"==typeof e)return c(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?c(e,t):void 0}}(e))||t&&e&&"number"==typeof e.length){n&&(e=n);var r=0;return function(){return r>=e.length?{done:!0}:{done:!1,value:e[r++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var a=0;function s(e){return"__private_"+a+++"_"+e}function l(e,t){if(!Object.prototype.hasOwnProperty.call(e,t))throw new TypeError("attempted to use private field on non-instance");return e}var f=function(e){try{var t,n,r,o=this,i=new Request(l(o,b)[b].baseUrl+"/__transmit/unsubscribe",{method:"POST",headers:{"Content-Type":"application/json","X-XSRF-TOKEN":null!=(t=l(o,j)[j]())?t:""},body:JSON.stringify({uid:l(o,v)[v],channel:e}),credentials:"include"});return null==(n=(r=l(o,b)[b]).beforeUnsubscribe)||n.call(r,i),Promise.resolve(fetch(i)).then(function(e){})}catch(e){return Promise.reject(e)}},p=function(e,t){try{var n,r,o,i=this;if(l(i,y)[y]!==d.Connected)return Promise.resolve(new Promise(function(n){setTimeout(function(){n(l(i,E)[E](e,t))},100)}));var c,u,a=l(i,h)[h].get(e);if(void 0!==a&&void 0!==t)return null==(c=(u=l(i,b)[b]).onSubscription)||c.call(u,e),a.add(t),Promise.resolve();if(l(i,g)[g].has(e))return Promise.resolve(new Promise(function(n){setTimeout(function(){n(l(i,E)[E](e,t))},100)}));l(i,g)[g].add(e);var s=new Request(l(i,b)[b].baseUrl+"/__transmit/subscribe",{method:"POST",headers:{"Content-Type":"application/json","X-XSRF-TOKEN":null!=(n=l(i,j)[j]())?n:""},body:JSON.stringify({uid:l(i,v)[v],channel:e}),credentials:"include"});return null==(r=(o=l(i,b)[b]).beforeSubscribe)||r.call(o,s),Promise.resolve(function(n,r){try{var o=Promise.resolve(fetch(s)).then(function(n){var r,o;if(!n.ok)return null==(r=(o=l(i,b)[b]).onSubscribeFailed)||r.call(o,n),void l(i,g)[g].delete(e);if(void 0!==t){var c,u,a=l(i,h)[h].get(e);void 0===a?l(i,h)[h].set(e,new Set([t])):a.add(t),null==(c=(u=l(i,b)[b]).onSubscription)||c.call(u,e)}})}catch(e){return r(!0,e)}return o&&o.then?o.then(r.bind(null,!1),r.bind(null,!0)):r(!1,o)}(0,function(t,n){if(l(i,g)[g].delete(e),t)throw n;return n}))}catch(e){return Promise.reject(e)}},d={Initializing:"initializing",Connecting:"connecting",Connected:"connected",Disconnected:"disconnected",Reconnecting:"reconnecting"},v=/*#__PURE__*/s("uid"),b=/*#__PURE__*/s("options"),h=/*#__PURE__*/s("listeners"),y=/*#__PURE__*/s("status"),m=/*#__PURE__*/s("eventSource"),O=/*#__PURE__*/s("reconnectAttempts"),g=/*#__PURE__*/s("channelSubscriptionLock"),w=/*#__PURE__*/s("changeStatus"),P=/*#__PURE__*/s("connect"),S=/*#__PURE__*/s("onMessage"),j=/*#__PURE__*/s("retrieveXsrfToken"),R=/*#__PURE__*/s("onError"),E=/*#__PURE__*/s("subscribe"),_=/*#__PURE__*/s("unsubscribe"),T=/*#__PURE__*/function(e){var n,o;function c(t){var n;return n=e.call(this)||this,Object.defineProperty(i(n),_,{value:f}),Object.defineProperty(i(n),E,{value:p}),Object.defineProperty(i(n),R,{value:k}),Object.defineProperty(i(n),j,{value:U}),Object.defineProperty(i(n),S,{value:x}),Object.defineProperty(i(n),P,{value:C}),Object.defineProperty(i(n),w,{value:A}),Object.defineProperty(i(n),v,{writable:!0,value:crypto.randomUUID()}),Object.defineProperty(i(n),b,{writable:!0,value:void 0}),Object.defineProperty(i(n),h,{writable:!0,value:new Map}),Object.defineProperty(i(n),y,{writable:!0,value:d.Initializing}),Object.defineProperty(i(n),m,{writable:!0,value:void 0}),Object.defineProperty(i(n),O,{writable:!0,value:0}),Object.defineProperty(i(n),g,{writable:!0,value:new Set}),void 0===t.eventSourceConstructor&&(t.eventSourceConstructor=EventSource),void 0===t.maxReconnectAttempts&&(t.maxReconnectAttempts=5),void 0===t.removeSubscriptionOnZeroListener&&(t.removeSubscriptionOnZeroListener=!1),l(i(n),b)[b]=t,l(i(n),P)[P](),n}o=e,(n=c).prototype=Object.create(o.prototype),n.prototype.constructor=n,r(n,o);var u,a,s=c.prototype;return s.on=function(e,t){this.addEventListener(e,t)},s.listenOn=function(e,t){var n=this;return l(this,E)[E](e,t),function(r){var o,i,c=l(n,h)[h].get(e);void 0!==c&&(c.delete(t),null==(o=(i=l(n,b)[b]).onUnsubscription)||o.call(i,e),(null!=r?r:l(n,b)[b].removeSubscriptionOnZeroListener)&&0===c.size&&l(n,_)[_](e))}},s.listenOnce=function(e,t){var n=this.listenOn(e,function(e){t(e),n()})},s.close=function(){l(this,m)[m].close()},u=c,(a=[{key:"uid",get:function(){return l(this,v)[v]}},{key:"listOfSubscriptions",get:function(){return Array.from(l(this,h)[h].keys())}}])&&function(e,n){for(var r=0;r<n.length;r++){var o=n[r];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(e,t(o.key),o)}}(u.prototype,a),Object.defineProperty(u,"prototype",{writable:!1}),c}(/*#__PURE__*/o(EventTarget));function A(e){l(this,y)[y]=e,this.dispatchEvent(new CustomEvent(e))}function C(){var e=this;l(this,w)[w](d.Connecting);var t=new URL(l(this,b)[b].baseUrl+"/__transmit/events");t.searchParams.append("uid",l(this,v)[v]),l(this,m)[m]=new(l(this,b)[b].eventSourceConstructor)(t.toString(),{withCredentials:!0}),l(this,m)[m].addEventListener("message",l(this,S)[S].bind(this)),l(this,m)[m].addEventListener("error",l(this,R)[R].bind(this)),l(this,m)[m].addEventListener("open",function(){l(e,w)[w](d.Connected),l(e,O)[O]=0;for(var t,n=u(l(e,h)[h].keys());!(t=n()).done;){var r=t.value;l(e,E)[E](r)}})}function x(e){var t=JSON.parse(e.data),n=l(this,h)[h].get(t.channel);if(void 0!==n)for(var r,o=u(n);!(r=o()).done;)(0,r.value)(t.payload)}function U(){var e=document.cookie.match(new RegExp("(^|;\\s*)(XSRF-TOKEN)=([^;]*)"));return e?decodeURIComponent(e[3]):null}function k(){if(l(this,y)[y]!==d.Reconnecting&&l(this,w)[w](d.Disconnected),l(this,w)[w](d.Reconnecting),l(this,b)[b].onReconnectAttempt&&l(this,b)[b].onReconnectAttempt(l(this,O)[O]+1),l(this,b)[b].maxReconnectAttempts&&l(this,O)[O]>=l(this,b)[b].maxReconnectAttempts)return l(this,m)[m].close(),void(l(this,b)[b].onReconnectFailed&&l(this,b)[b].onReconnectFailed());l(this,O)[O]++}exports.Transmit=T,exports.TransmitStatus=d;
2
- //# sourceMappingURL=transmit.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"transmit.cjs","sources":["../src/transmit.ts"],"sourcesContent":["interface TransmitOptions {\n baseUrl: string\n eventSourceConstructor?: typeof EventSource\n beforeSubscribe?: (request: RequestInit) => void\n beforeUnsubscribe?: (request: RequestInit) => void\n maxReconnectAttempts?: number\n onReconnectAttempt?: (attempt: number) => void\n onReconnectFailed?: () => void\n onSubscribeFailed?: (response: Response) => void\n onSubscription?: (channel: string) => void\n onUnsubscription?: (channel: string) => void\n removeSubscriptionOnZeroListener?: boolean\n}\n\nexport const TransmitStatus = {\n Initializing: 'initializing',\n Connecting: 'connecting',\n Connected: 'connected',\n Disconnected: 'disconnected',\n Reconnecting: 'reconnecting',\n} as const\n\ntype TTransmitStatus = (typeof TransmitStatus)[keyof typeof TransmitStatus]\n\nexport class Transmit extends EventTarget {\n /**\n * Unique identifier for this client.\n */\n #uid: string = crypto.randomUUID()\n\n /**\n * Options for this client.\n */\n #options: TransmitOptions\n\n /**\n * Registered listeners.\n */\n #listeners: Map<string, Set<(message: any) => void>> = new Map()\n\n /**\n * Current status of the client.\n */\n #status: TTransmitStatus = TransmitStatus.Initializing\n\n /**\n * EventSource instance.\n */\n #eventSource!: EventSource\n\n /**\n * Number of reconnect attempts.\n */\n #reconnectAttempts: number = 0\n\n /**\n * Locks for channel subscriptions.\n */\n #channelSubscriptionLock: Set<string> = new Set()\n\n get uid() {\n return this.#uid\n }\n\n get listOfSubscriptions() {\n return Array.from(this.#listeners.keys())\n }\n\n constructor(options: TransmitOptions) {\n super()\n\n if (typeof options.eventSourceConstructor === 'undefined') {\n options.eventSourceConstructor = EventSource\n }\n\n if (typeof options.maxReconnectAttempts === 'undefined') {\n options.maxReconnectAttempts = 5\n }\n\n if (typeof options.removeSubscriptionOnZeroListener === 'undefined') {\n options.removeSubscriptionOnZeroListener = false\n }\n\n this.#options = options\n this.#connect()\n }\n\n #changeStatus(status: TTransmitStatus) {\n this.#status = status\n this.dispatchEvent(new CustomEvent(status))\n }\n\n #connect() {\n this.#changeStatus(TransmitStatus.Connecting)\n\n const url = new URL(`${this.#options.baseUrl}/__transmit/events`)\n url.searchParams.append('uid', this.#uid)\n\n this.#eventSource = new this.#options.eventSourceConstructor(url.toString(), {\n withCredentials: true,\n })\n this.#eventSource.addEventListener('message', this.#onMessage.bind(this))\n this.#eventSource.addEventListener('error', this.#onError.bind(this))\n this.#eventSource.addEventListener('open', () => {\n this.#changeStatus(TransmitStatus.Connected)\n this.#reconnectAttempts = 0\n\n for (const channel of this.#listeners.keys()) {\n void this.#subscribe(channel)\n }\n })\n }\n\n #onMessage(event: MessageEvent) {\n const data = JSON.parse(event.data)\n const listeners = this.#listeners.get(data.channel)\n\n if (typeof listeners === 'undefined') {\n return\n }\n\n for (const listener of listeners) {\n listener(data.payload)\n }\n }\n\n #retrieveXsrfToken() {\n const match = document.cookie.match(new RegExp('(^|;\\\\s*)(XSRF-TOKEN)=([^;]*)'))\n\n return match ? decodeURIComponent(match[3]) : null\n }\n\n #onError() {\n if (this.#status !== TransmitStatus.Reconnecting) {\n this.#changeStatus(TransmitStatus.Disconnected)\n }\n\n this.#changeStatus(TransmitStatus.Reconnecting)\n\n if (this.#options.onReconnectAttempt) {\n this.#options.onReconnectAttempt(this.#reconnectAttempts + 1)\n }\n\n if (\n this.#options.maxReconnectAttempts &&\n this.#reconnectAttempts >= this.#options.maxReconnectAttempts\n ) {\n this.#eventSource.close()\n\n if (this.#options.onReconnectFailed) {\n this.#options.onReconnectFailed()\n }\n\n return\n }\n\n this.#reconnectAttempts++\n }\n\n async #subscribe(channel: string, callback?: any) {\n if (this.#status !== TransmitStatus.Connected) {\n return new Promise((resolve) => {\n setTimeout(() => {\n resolve(this.#subscribe(channel, callback))\n }, 100)\n })\n }\n\n const listeners = this.#listeners.get(channel)\n\n if (typeof listeners !== 'undefined' && typeof callback !== 'undefined') {\n this.#options.onSubscription?.(channel)\n listeners.add(callback)\n return\n }\n\n if (this.#channelSubscriptionLock.has(channel)) {\n return new Promise((resolve) => {\n setTimeout(() => {\n resolve(this.#subscribe(channel, callback))\n }, 100)\n })\n }\n\n this.#channelSubscriptionLock.add(channel)\n\n const request = new Request(`${this.#options.baseUrl}/__transmit/subscribe`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'X-XSRF-TOKEN': this.#retrieveXsrfToken() ?? '',\n },\n body: JSON.stringify({ uid: this.#uid, channel }),\n credentials: 'include',\n })\n\n this.#options.beforeSubscribe?.(request)\n\n try {\n const response = await fetch(request)\n\n if (!response.ok) {\n this.#options.onSubscribeFailed?.(response)\n this.#channelSubscriptionLock.delete(channel)\n return\n }\n\n if (typeof callback !== 'undefined') {\n const listeners = this.#listeners.get(channel)\n\n if (typeof listeners === 'undefined') {\n this.#listeners.set(channel, new Set([callback]))\n } else {\n listeners.add(callback)\n }\n\n this.#options.onSubscription?.(channel)\n }\n } finally {\n this.#channelSubscriptionLock.delete(channel)\n }\n }\n\n async #unsubscribe(channel: string) {\n const request = new Request(`${this.#options.baseUrl}/__transmit/unsubscribe`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'X-XSRF-TOKEN': this.#retrieveXsrfToken() ?? '',\n },\n body: JSON.stringify({ uid: this.#uid, channel }),\n credentials: 'include',\n })\n\n this.#options.beforeUnsubscribe?.(request)\n\n const response = await fetch(request)\n\n if (!response.ok) {\n return\n }\n }\n\n on(event: Exclude<TTransmitStatus, 'connecting'>, callback: (event: CustomEvent) => void) {\n this.addEventListener(event, callback)\n }\n\n listenOn<T = unknown>(channel: string, callback: (message: T) => void) {\n void this.#subscribe(channel, callback)\n\n return (unsubscribeOnTheServer?: boolean) => {\n const listeners = this.#listeners.get(channel)\n\n if (typeof listeners === 'undefined') {\n return\n }\n\n listeners.delete(callback)\n this.#options.onUnsubscription?.(channel)\n\n if (\n (unsubscribeOnTheServer ?? this.#options.removeSubscriptionOnZeroListener) &&\n listeners.size === 0\n ) {\n void this.#unsubscribe(channel)\n }\n }\n }\n\n listenOnce<T = unknown>(channel: string, callback: (message: T) => void) {\n const unsubscribe = this.listenOn<T>(channel, (message) => {\n callback(message)\n unsubscribe()\n })\n }\n\n close() {\n this.#eventSource.close()\n }\n}\n"],"names":["channel","_classPrivateFieldLoo12","_classPrivateFieldLoo13","_classPrivateFieldLoo14","_this5","this","request","Request","_classPrivateFieldLooseBase","_options","baseUrl","method","headers","_retrieveXsrfToken","body","JSON","stringify","uid","_uid","credentials","beforeUnsubscribe","call","Promise","resolve","fetch","then","response","e","reject","_subscribe2","callback","_classPrivateFieldLoo5","_classPrivateFieldLoo6","_classPrivateFieldLoo7","_this4","_status","TransmitStatus","Connected","setTimeout","_subscribe","_classPrivateFieldLoo3","_classPrivateFieldLoo4","listeners","_listeners","get","onSubscription","add","_channelSubscriptionLock","has","beforeSubscribe","_classPrivateFieldLoo8","_classPrivateFieldLoo9","ok","onSubscribeFailed","_classPrivateFieldLoo10","_classPrivateFieldLoo11","set","Set","_finallyRethrows","_wasThrown","_result","Initializing","Connecting","Disconnected","Reconnecting","_classPrivateFieldLooseKey","_eventSource","_reconnectAttempts","_changeStatus","_connect","_onMessage","_onError","_unsubscribe","Transmit","_EventTarget","options","_this","Object","defineProperty","_assertThisInitialized","value","_unsubscribe2","_onError2","_retrieveXsrfToken2","_onMessage2","_connect2","_changeStatus2","writable","crypto","randomUUID","Map","eventSourceConstructor","EventSource","maxReconnectAttempts","removeSubscriptionOnZeroListener","_proto","prototype","on","event","addEventListener","listenOn","_this2","unsubscribeOnTheServer","_classPrivateFieldLoo","_classPrivateFieldLoo2","onUnsubscription","size","listenOnce","unsubscribe","message","close","key","Array","from","keys","_wrapNativeSuper","EventTarget","status","dispatchEvent","CustomEvent","_this3","url","URL","searchParams","append","toString","withCredentials","bind","_step","_iterator","_createForOfIteratorHelperLoose","done","data","parse","_step2","_iterator2","listener","payload","match","document","cookie","RegExp","decodeURIComponent","onReconnectAttempt","onReconnectFailed"],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- var e=0;function t(t){return"__private_"+e+++"_"+t}function n(e,t){if(!Object.prototype.hasOwnProperty.call(e,t))throw new TypeError("attempted to use private field on non-instance");return e}const i={Initializing:"initializing",Connecting:"connecting",Connected:"connected",Disconnected:"disconnected",Reconnecting:"reconnecting"};var s=/*#__PURE__*/t("uid"),o=/*#__PURE__*/t("options"),r=/*#__PURE__*/t("listeners"),c=/*#__PURE__*/t("status"),a=/*#__PURE__*/t("eventSource"),h=/*#__PURE__*/t("reconnectAttempts"),l=/*#__PURE__*/t("channelSubscriptionLock"),u=/*#__PURE__*/t("changeStatus"),d=/*#__PURE__*/t("connect"),p=/*#__PURE__*/t("onMessage"),v=/*#__PURE__*/t("retrieveXsrfToken"),b=/*#__PURE__*/t("onError"),f=/*#__PURE__*/t("subscribe"),m=/*#__PURE__*/t("unsubscribe");class y extends EventTarget{get uid(){return n(this,s)[s]}get listOfSubscriptions(){return Array.from(n(this,r)[r].keys())}constructor(e){super(),Object.defineProperty(this,m,{value:j}),Object.defineProperty(this,f,{value:R}),Object.defineProperty(this,b,{value:P}),Object.defineProperty(this,v,{value:w}),Object.defineProperty(this,p,{value:g}),Object.defineProperty(this,d,{value:S}),Object.defineProperty(this,u,{value:O}),Object.defineProperty(this,s,{writable:!0,value:crypto.randomUUID()}),Object.defineProperty(this,o,{writable:!0,value:void 0}),Object.defineProperty(this,r,{writable:!0,value:new Map}),Object.defineProperty(this,c,{writable:!0,value:i.Initializing}),Object.defineProperty(this,a,{writable:!0,value:void 0}),Object.defineProperty(this,h,{writable:!0,value:0}),Object.defineProperty(this,l,{writable:!0,value:new Set}),void 0===e.eventSourceConstructor&&(e.eventSourceConstructor=EventSource),void 0===e.maxReconnectAttempts&&(e.maxReconnectAttempts=5),void 0===e.removeSubscriptionOnZeroListener&&(e.removeSubscriptionOnZeroListener=!1),n(this,o)[o]=e,n(this,d)[d]()}on(e,t){this.addEventListener(e,t)}listenOn(e,t){return n(this,f)[f](e,t),i=>{var s,c;const a=n(this,r)[r].get(e);void 0!==a&&(a.delete(t),null==(s=(c=n(this,o)[o]).onUnsubscription)||s.call(c,e),(null!=i?i:n(this,o)[o].removeSubscriptionOnZeroListener)&&0===a.size&&n(this,m)[m](e))}}listenOnce(e,t){const n=this.listenOn(e,e=>{t(e),n()})}close(){n(this,a)[a].close()}}function O(e){n(this,c)[c]=e,this.dispatchEvent(new CustomEvent(e))}function S(){n(this,u)[u](i.Connecting);const e=new URL(`${n(this,o)[o].baseUrl}/__transmit/events`);e.searchParams.append("uid",n(this,s)[s]),n(this,a)[a]=new(n(this,o)[o].eventSourceConstructor)(e.toString(),{withCredentials:!0}),n(this,a)[a].addEventListener("message",n(this,p)[p].bind(this)),n(this,a)[a].addEventListener("error",n(this,b)[b].bind(this)),n(this,a)[a].addEventListener("open",()=>{n(this,u)[u](i.Connected),n(this,h)[h]=0;for(const e of n(this,r)[r].keys())n(this,f)[f](e)})}function g(e){const t=JSON.parse(e.data),i=n(this,r)[r].get(t.channel);if(void 0!==i)for(const e of i)e(t.payload)}function w(){const e=document.cookie.match(new RegExp("(^|;\\s*)(XSRF-TOKEN)=([^;]*)"));return e?decodeURIComponent(e[3]):null}function P(){if(n(this,c)[c]!==i.Reconnecting&&n(this,u)[u](i.Disconnected),n(this,u)[u](i.Reconnecting),n(this,o)[o].onReconnectAttempt&&n(this,o)[o].onReconnectAttempt(n(this,h)[h]+1),n(this,o)[o].maxReconnectAttempts&&n(this,h)[h]>=n(this,o)[o].maxReconnectAttempts)return n(this,a)[a].close(),void(n(this,o)[o].onReconnectFailed&&n(this,o)[o].onReconnectFailed());n(this,h)[h]++}async function R(e,t){var a,h,u;if(n(this,c)[c]!==i.Connected)return new Promise(i=>{setTimeout(()=>{i(n(this,f)[f](e,t))},100)});const d=n(this,r)[r].get(e);var p,b;if(void 0!==d&&void 0!==t)return null==(p=(b=n(this,o)[o]).onSubscription)||p.call(b,e),void d.add(t);if(n(this,l)[l].has(e))return new Promise(i=>{setTimeout(()=>{i(n(this,f)[f](e,t))},100)});n(this,l)[l].add(e);const m=new Request(`${n(this,o)[o].baseUrl}/__transmit/subscribe`,{method:"POST",headers:{"Content-Type":"application/json","X-XSRF-TOKEN":null!=(a=n(this,v)[v]())?a:""},body:JSON.stringify({uid:n(this,s)[s],channel:e}),credentials:"include"});null==(h=(u=n(this,o)[o]).beforeSubscribe)||h.call(u,m);try{const i=await fetch(m);var y,O;if(!i.ok)return null==(y=(O=n(this,o)[o]).onSubscribeFailed)||y.call(O,i),void n(this,l)[l].delete(e);if(void 0!==t){var S,g;const i=n(this,r)[r].get(e);void 0===i?n(this,r)[r].set(e,new Set([t])):i.add(t),null==(S=(g=n(this,o)[o]).onSubscription)||S.call(g,e)}}finally{n(this,l)[l].delete(e)}}async function j(e){var t,i,r;const c=new Request(`${n(this,o)[o].baseUrl}/__transmit/unsubscribe`,{method:"POST",headers:{"Content-Type":"application/json","X-XSRF-TOKEN":null!=(t=n(this,v)[v]())?t:""},body:JSON.stringify({uid:n(this,s)[s],channel:e}),credentials:"include"});null==(i=(r=n(this,o)[o]).beforeUnsubscribe)||i.call(r,c),await fetch(c)}export{y as Transmit,i as TransmitStatus};
2
- //# sourceMappingURL=transmit.modern.js.map