@adonisjs/transmit-client 0.1.6 → 0.2.1

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,169 @@
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
+ return this.forceCreate()
96
+ }
97
+
98
+ async forceCreate() {
99
+ if (this.#getEventSourceStatus() !== TransmitStatus.Connected) {
100
+ return new Promise((resolve) => {
101
+ setTimeout(() => {
102
+ resolve(this.create())
103
+ }, 100)
104
+ })
105
+ }
106
+
107
+ const request = this.#httpClient.createRequest('/__transmit/subscribe', {
108
+ channel: this.#channel,
109
+ })
110
+
111
+ this.#hooks?.beforeSubscribe(request)
112
+
113
+ try {
114
+ const response = await this.#httpClient.send(request)
115
+
116
+ //? Dump the response text
117
+ void response.text()
118
+
119
+ if (!response.ok) {
120
+ this.#hooks?.onSubscribeFailed(response)
121
+ return
122
+ }
123
+
124
+ this.#status = SubscriptionStatus.Created
125
+ this.#hooks?.onSubscription(this.#channel)
126
+ } catch (error) {}
127
+ }
128
+
129
+ async delete() {
130
+ if (this.isDeleted || !this.isCreated) {
131
+ return
132
+ }
133
+
134
+ const request = this.#httpClient.createRequest('/__transmit/unsubscribe', {
135
+ channel: this.#channel,
136
+ })
137
+
138
+ this.#hooks?.beforeUnsubscribe(request)
139
+
140
+ try {
141
+ const response = await this.#httpClient.send(request)
142
+
143
+ //? Dump the response text
144
+ void response.text()
145
+
146
+ if (!response.ok) {
147
+ return
148
+ }
149
+
150
+ this.#status = SubscriptionStatus.Deleted
151
+ this.#hooks?.onUnsubscription(this.#channel)
152
+ } catch (error) {}
153
+ }
154
+
155
+ onMessage<T>(handler: (message: T) => void) {
156
+ this.#handlers.add(handler)
157
+
158
+ return () => {
159
+ this.#handlers.delete(handler)
160
+ }
161
+ }
162
+
163
+ onMessageOnce<T>(handler: (message: T) => void) {
164
+ const deleteHandler = this.onMessage<T>((message) => {
165
+ handler(message)
166
+ deleteHandler()
167
+ })
168
+ }
169
+ }
@@ -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,24 @@
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
21
+ httpClientFactory?: (baseUrl: string, uid: string) => HttpClient
4
22
  beforeSubscribe?: (request: RequestInit) => void
5
23
  beforeUnsubscribe?: (request: RequestInit) => void
6
24
  maxReconnectAttempts?: number
@@ -9,24 +27,13 @@ interface TransmitOptions {
9
27
  onSubscribeFailed?: (response: Response) => void
10
28
  onSubscription?: (channel: string) => void
11
29
  onUnsubscription?: (channel: string) => void
12
- removeSubscriptionOnZeroListener?: boolean
13
30
  }
14
31
 
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 {
32
+ export class Transmit {
26
33
  /**
27
34
  * Unique identifier for this client.
28
35
  */
29
- #uid: string = crypto.randomUUID()
36
+ #uid: string
30
37
 
31
38
  /**
32
39
  * Options for this client.
@@ -34,19 +41,34 @@ export class Transmit extends EventTarget {
34
41
  #options: TransmitOptions
35
42
 
36
43
  /**
37
- * Registered listeners.
44
+ * Registered subscriptions.
45
+ */
46
+ #subscriptions = new Map<string, Subscription>()
47
+
48
+ /**
49
+ * HTTP client instance.
38
50
  */
39
- #listeners: Map<string, Set<(message: any) => void>> = new Map()
51
+ #httpClient: HttpClient
52
+
53
+ /**
54
+ * Hook instance.
55
+ */
56
+ #hooks: Hook
40
57
 
41
58
  /**
42
59
  * Current status of the client.
43
60
  */
44
- #status: TTransmitStatus = TransmitStatus.Initializing
61
+ #status: TransmitStatus = TransmitStatus.Initializing
45
62
 
46
63
  /**
47
64
  * EventSource instance.
48
65
  */
49
- #eventSource!: EventSource
66
+ #eventSource: EventSource | undefined
67
+
68
+ /**
69
+ * EventTarget instance.
70
+ */
71
+ #eventTarget: EventTarget | null
50
72
 
51
73
  /**
52
74
  * Number of reconnect attempts.
@@ -54,40 +76,73 @@ export class Transmit extends EventTarget {
54
76
  #reconnectAttempts: number = 0
55
77
 
56
78
  /**
57
- * Locks for channel subscriptions.
79
+ * Returns the unique identifier of the client.
58
80
  */
59
- #channelSubscriptionLock: Set<string> = new Set()
60
-
61
81
  get uid() {
62
82
  return this.#uid
63
83
  }
64
84
 
65
- get listOfSubscriptions() {
66
- return Array.from(this.#listeners.keys())
67
- }
68
-
69
85
  constructor(options: TransmitOptions) {
70
- super()
86
+ if (typeof options.uidGenerator === 'undefined') {
87
+ options.uidGenerator = () => crypto.randomUUID()
88
+ }
89
+
90
+ if (typeof options.eventSourceFactory === 'undefined') {
91
+ options.eventSourceFactory = (...args) => new EventSource(...args)
92
+ }
93
+
94
+ if (typeof options.eventTargetFactory === 'undefined') {
95
+ options.eventTargetFactory = () => new EventTarget()
96
+ }
71
97
 
72
- if (typeof options.eventSourceConstructor === 'undefined') {
73
- options.eventSourceConstructor = EventSource
98
+ if (typeof options.httpClientFactory === 'undefined') {
99
+ options.httpClientFactory = (baseUrl, uid) => new HttpClient({ baseUrl, uid })
74
100
  }
75
101
 
76
102
  if (typeof options.maxReconnectAttempts === 'undefined') {
77
103
  options.maxReconnectAttempts = 5
78
104
  }
79
105
 
80
- if (typeof options.removeSubscriptionOnZeroListener === 'undefined') {
81
- options.removeSubscriptionOnZeroListener = false
106
+ this.#uid = options.uidGenerator()
107
+ this.#eventTarget = options.eventTargetFactory()
108
+ this.#hooks = new Hook()
109
+ this.#httpClient = options.httpClientFactory(options.baseUrl, this.#uid)
110
+
111
+ if (options.beforeSubscribe) {
112
+ this.#hooks.register(HookEvent.BeforeSubscribe, options.beforeSubscribe)
113
+ }
114
+
115
+ if (options.beforeUnsubscribe) {
116
+ this.#hooks.register(HookEvent.BeforeUnsubscribe, options.beforeUnsubscribe)
117
+ }
118
+
119
+ if (options.onReconnectAttempt) {
120
+ this.#hooks.register(HookEvent.OnReconnectAttempt, options.onReconnectAttempt)
121
+ }
122
+
123
+ if (options.onReconnectFailed) {
124
+ this.#hooks.register(HookEvent.OnReconnectFailed, options.onReconnectFailed)
125
+ }
126
+
127
+ if (options.onSubscribeFailed) {
128
+ this.#hooks.register(HookEvent.OnSubscribeFailed, options.onSubscribeFailed)
129
+ }
130
+
131
+ if (options.onSubscription) {
132
+ this.#hooks.register(HookEvent.OnSubscription, options.onSubscription)
133
+ }
134
+
135
+ if (options.onUnsubscription) {
136
+ this.#hooks.register(HookEvent.OnUnsubscription, options.onUnsubscription)
82
137
  }
83
138
 
84
139
  this.#options = options
85
140
  this.#connect()
86
141
  }
87
142
 
88
- #changeStatus(status: TTransmitStatus) {
143
+ #changeStatus(status: TransmitStatus) {
89
144
  this.#status = status
90
- this.dispatchEvent(new CustomEvent(status))
145
+ this.#eventTarget?.dispatchEvent(new CustomEvent(status))
91
146
  }
92
147
 
93
148
  #connect() {
@@ -96,40 +151,40 @@ export class Transmit extends EventTarget {
96
151
  const url = new URL(`${this.#options.baseUrl}/__transmit/events`)
97
152
  url.searchParams.append('uid', this.#uid)
98
153
 
99
- this.#eventSource = new this.#options.eventSourceConstructor(url.toString(), {
154
+ this.#eventSource = this.#options.eventSourceFactory!(url, {
100
155
  withCredentials: true,
101
156
  })
157
+
102
158
  this.#eventSource.addEventListener('message', this.#onMessage.bind(this))
103
159
  this.#eventSource.addEventListener('error', this.#onError.bind(this))
104
160
  this.#eventSource.addEventListener('open', () => {
105
161
  this.#changeStatus(TransmitStatus.Connected)
106
162
  this.#reconnectAttempts = 0
107
163
 
108
- for (const channel of this.#listeners.keys()) {
109
- void this.#subscribe(channel)
164
+ for (const subscription of this.#subscriptions.values()) {
165
+ if (subscription.isCreated) {
166
+ void subscription.forceCreate()
167
+ }
110
168
  }
111
169
  })
112
170
  }
113
171
 
114
172
  #onMessage(event: MessageEvent) {
115
173
  const data = JSON.parse(event.data)
116
- const listeners = this.#listeners.get(data.channel)
174
+ const subscription = this.#subscriptions.get(data.channel)
117
175
 
118
- if (typeof listeners === 'undefined') {
176
+ if (typeof subscription === 'undefined') {
119
177
  return
120
178
  }
121
179
 
122
- for (const listener of listeners) {
123
- listener(data.payload)
180
+ try {
181
+ subscription.$runHandler(data.payload)
182
+ } catch (error) {
183
+ // TODO: Rescue
184
+ console.log(error)
124
185
  }
125
186
  }
126
187
 
127
- #retrieveXsrfToken() {
128
- const match = document.cookie.match(new RegExp('(^|;\\s*)(XSRF-TOKEN)=([^;]*)'))
129
-
130
- return match ? decodeURIComponent(match[3]) : null
131
- }
132
-
133
188
  #onError() {
134
189
  if (this.#status !== TransmitStatus.Reconnecting) {
135
190
  this.#changeStatus(TransmitStatus.Disconnected)
@@ -137,19 +192,15 @@ export class Transmit extends EventTarget {
137
192
 
138
193
  this.#changeStatus(TransmitStatus.Reconnecting)
139
194
 
140
- if (this.#options.onReconnectAttempt) {
141
- this.#options.onReconnectAttempt(this.#reconnectAttempts + 1)
142
- }
195
+ this.#hooks.onReconnectAttempt(this.#reconnectAttempts + 1)
143
196
 
144
197
  if (
145
198
  this.#options.maxReconnectAttempts &&
146
199
  this.#reconnectAttempts >= this.#options.maxReconnectAttempts
147
200
  ) {
148
- this.#eventSource.close()
201
+ this.#eventSource!.close()
149
202
 
150
- if (this.#options.onReconnectFailed) {
151
- this.#options.onReconnectFailed()
152
- }
203
+ this.#hooks.onReconnectFailed()
153
204
 
154
205
  return
155
206
  }
@@ -157,124 +208,29 @@ export class Transmit extends EventTarget {
157
208
  this.#reconnectAttempts++
158
209
  }
159
210
 
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',
195
- })
196
-
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)
221
- }
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',
211
+ subscription(channel: string) {
212
+ const subscription = new Subscription({
213
+ channel,
214
+ httpClient: this.#httpClient,
215
+ hooks: this.#hooks,
216
+ getEventSourceStatus: () => this.#status,
233
217
  })
234
218
 
235
- this.#options.beforeUnsubscribe?.(request)
236
-
237
- const response = await fetch(request)
238
-
239
- if (!response.ok) {
240
- return
219
+ if (this.#subscriptions.has(channel)) {
220
+ return this.#subscriptions.get(channel)!
241
221
  }
242
- }
243
222
 
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
- }
223
+ this.#subscriptions.set(channel, subscription)
257
224
 
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
- }
225
+ return subscription
268
226
  }
269
227
 
270
- listenOnce<T = unknown>(channel: string, callback: (message: T) => void) {
271
- const unsubscribe = this.listenOn<T>(channel, (message) => {
272
- callback(message)
273
- unsubscribe()
274
- })
228
+ on(event: Exclude<TransmitStatus, 'connecting'>, callback: (event: CustomEvent) => void) {
229
+ // @ts-ignore
230
+ this.#eventTarget?.addEventListener(event, callback)
275
231
  }
276
232
 
277
233
  close() {
278
- this.#eventSource.close()
234
+ this.#eventSource?.close()
279
235
  }
280
236
  }
@@ -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