@supabase/realtime-js 2.16.0-next.2 → 2.71.2-canary.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/package.json +13 -16
- package/src/RealtimeChannel.ts +25 -84
- package/src/RealtimeClient.ts +17 -65
- package/src/RealtimePresence.ts +13 -40
- package/src/lib/push.ts +3 -12
- package/src/lib/serializer.ts +1 -3
- package/src/lib/timer.ts +11 -5
- package/src/lib/version.ts +1 -1
- package/src/lib/websocket-factory.ts +7 -23
- package/LICENSE.md +0 -22
- package/dist/main/RealtimeChannel.d.ts +0 -235
- package/dist/main/RealtimeChannel.d.ts.map +0 -1
- package/dist/main/RealtimeChannel.js +0 -581
- package/dist/main/RealtimeChannel.js.map +0 -1
- package/dist/main/RealtimeClient.d.ts +0 -196
- package/dist/main/RealtimeClient.d.ts.map +0 -1
- package/dist/main/RealtimeClient.js +0 -737
- package/dist/main/RealtimeClient.js.map +0 -1
- package/dist/main/RealtimePresence.d.ts +0 -68
- package/dist/main/RealtimePresence.d.ts.map +0 -1
- package/dist/main/RealtimePresence.js +0 -229
- package/dist/main/RealtimePresence.js.map +0 -1
- package/dist/main/index.d.ts +0 -6
- package/dist/main/index.d.ts.map +0 -1
- package/dist/main/index.js +0 -53
- package/dist/main/index.js.map +0 -1
- package/dist/main/lib/constants.d.ts +0 -37
- package/dist/main/lib/constants.d.ts.map +0 -1
- package/dist/main/lib/constants.js +0 -46
- package/dist/main/lib/constants.js.map +0 -1
- package/dist/main/lib/push.d.ts +0 -48
- package/dist/main/lib/push.d.ts.map +0 -1
- package/dist/main/lib/push.js +0 -104
- package/dist/main/lib/push.js.map +0 -1
- package/dist/main/lib/serializer.d.ts +0 -7
- package/dist/main/lib/serializer.d.ts.map +0 -1
- package/dist/main/lib/serializer.js +0 -36
- package/dist/main/lib/serializer.js.map +0 -1
- package/dist/main/lib/timer.d.ts +0 -22
- package/dist/main/lib/timer.d.ts.map +0 -1
- package/dist/main/lib/timer.js +0 -39
- package/dist/main/lib/timer.js.map +0 -1
- package/dist/main/lib/transformers.d.ts +0 -109
- package/dist/main/lib/transformers.d.ts.map +0 -1
- package/dist/main/lib/transformers.js +0 -229
- package/dist/main/lib/transformers.js.map +0 -1
- package/dist/main/lib/version.d.ts +0 -2
- package/dist/main/lib/version.d.ts.map +0 -1
- package/dist/main/lib/version.js +0 -5
- package/dist/main/lib/version.js.map +0 -1
- package/dist/main/lib/websocket-factory.d.ts +0 -35
- package/dist/main/lib/websocket-factory.d.ts.map +0 -1
- package/dist/main/lib/websocket-factory.js +0 -95
- package/dist/main/lib/websocket-factory.js.map +0 -1
- package/dist/module/RealtimeChannel.d.ts +0 -235
- package/dist/module/RealtimeChannel.d.ts.map +0 -1
- package/dist/module/RealtimeChannel.js +0 -541
- package/dist/module/RealtimeChannel.js.map +0 -1
- package/dist/module/RealtimeClient.d.ts +0 -196
- package/dist/module/RealtimeClient.d.ts.map +0 -1
- package/dist/module/RealtimeClient.js +0 -699
- package/dist/module/RealtimeClient.js.map +0 -1
- package/dist/module/RealtimePresence.d.ts +0 -68
- package/dist/module/RealtimePresence.d.ts.map +0 -1
- package/dist/module/RealtimePresence.js +0 -225
- package/dist/module/RealtimePresence.js.map +0 -1
- package/dist/module/index.d.ts +0 -6
- package/dist/module/index.d.ts.map +0 -1
- package/dist/module/index.js +0 -6
- package/dist/module/index.js.map +0 -1
- package/dist/module/lib/constants.d.ts +0 -37
- package/dist/module/lib/constants.d.ts.map +0 -1
- package/dist/module/lib/constants.js +0 -43
- package/dist/module/lib/constants.js.map +0 -1
- package/dist/module/lib/push.d.ts +0 -48
- package/dist/module/lib/push.d.ts.map +0 -1
- package/dist/module/lib/push.js +0 -101
- package/dist/module/lib/push.js.map +0 -1
- package/dist/module/lib/serializer.d.ts +0 -7
- package/dist/module/lib/serializer.d.ts.map +0 -1
- package/dist/module/lib/serializer.js +0 -33
- package/dist/module/lib/serializer.js.map +0 -1
- package/dist/module/lib/timer.d.ts +0 -22
- package/dist/module/lib/timer.d.ts.map +0 -1
- package/dist/module/lib/timer.js +0 -36
- package/dist/module/lib/timer.js.map +0 -1
- package/dist/module/lib/transformers.d.ts +0 -109
- package/dist/module/lib/transformers.d.ts.map +0 -1
- package/dist/module/lib/transformers.js +0 -217
- package/dist/module/lib/transformers.js.map +0 -1
- package/dist/module/lib/version.d.ts +0 -2
- package/dist/module/lib/version.d.ts.map +0 -1
- package/dist/module/lib/version.js +0 -2
- package/dist/module/lib/version.js.map +0 -1
- package/dist/module/lib/websocket-factory.d.ts +0 -35
- package/dist/module/lib/websocket-factory.d.ts.map +0 -1
- package/dist/module/lib/websocket-factory.js +0 -91
- package/dist/module/lib/websocket-factory.js.map +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@supabase/realtime-js",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.71.2-canary.0",
|
|
4
4
|
"description": "Listen to realtime updates to your PostgreSQL database",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"realtime",
|
|
@@ -11,8 +11,8 @@
|
|
|
11
11
|
"firebase",
|
|
12
12
|
"supabase"
|
|
13
13
|
],
|
|
14
|
-
"homepage": "https://github.com/supabase/realtime-js",
|
|
15
|
-
"bugs": "https://github.com/supabase/
|
|
14
|
+
"homepage": "https://github.com/supabase/supabase-js-libs/tree/main/packages/core/realtime-js",
|
|
15
|
+
"bugs": "https://github.com/supabase/supabase-js-libs/issues",
|
|
16
16
|
"files": [
|
|
17
17
|
"dist",
|
|
18
18
|
"src"
|
|
@@ -20,13 +20,17 @@
|
|
|
20
20
|
"main": "dist/main/index.js",
|
|
21
21
|
"module": "dist/module/index.js",
|
|
22
22
|
"types": "dist/module/index.d.ts",
|
|
23
|
-
"repository":
|
|
23
|
+
"repository": {
|
|
24
|
+
"type": "git",
|
|
25
|
+
"url": "https://github.com/supabase/supabase-js-libs.git",
|
|
26
|
+
"directory": "packages/core/realtime-js"
|
|
27
|
+
},
|
|
24
28
|
"author": "Supabase",
|
|
25
29
|
"license": "MIT",
|
|
26
30
|
"scripts": {
|
|
27
31
|
"clean": "rimraf dist docs/v2",
|
|
28
32
|
"format": "prettier --write \"{src,test}/**/*.ts\"",
|
|
29
|
-
"build": "run
|
|
33
|
+
"build": "npm run clean && npm run format && npm run build:main && npm run build:module",
|
|
30
34
|
"build:main": "tsc -p tsconfig.json",
|
|
31
35
|
"build:module": "tsc -p tsconfig.module.json",
|
|
32
36
|
"test": "vitest run",
|
|
@@ -36,30 +40,23 @@
|
|
|
36
40
|
"docs": "typedoc src/index.ts --out docs/v2",
|
|
37
41
|
"docs:json": "typedoc --json docs/v2/spec.json --excludeExternals src/index.ts",
|
|
38
42
|
"check-exports": "attw --pack .",
|
|
39
|
-
"ci": "run
|
|
43
|
+
"ci": "npm run test && npm run coverage",
|
|
44
|
+
"test:ci": "npm run test && npm run coverage"
|
|
40
45
|
},
|
|
41
46
|
"dependencies": {
|
|
42
|
-
"@supabase/node-fetch": "^2.6.13",
|
|
43
47
|
"@types/phoenix": "^1.6.6",
|
|
44
48
|
"ws": "^8.18.2",
|
|
45
|
-
"@types/ws": "^8.18.1"
|
|
49
|
+
"@types/ws": "^8.18.1",
|
|
50
|
+
"@supabase/node-fetch": "2.6.15"
|
|
46
51
|
},
|
|
47
52
|
"devDependencies": {
|
|
48
53
|
"@arethetypeswrong/cli": "^0.16.4",
|
|
49
54
|
"@vitest/coverage-v8": "^3.1.4",
|
|
50
|
-
"eslint": "^9.27.0",
|
|
51
55
|
"esm": "^3.2.25",
|
|
52
56
|
"jsdom": "^16.7.0",
|
|
53
57
|
"jsdom-global": "3.0.0",
|
|
54
|
-
"jsonwebtoken": "^9.0.2",
|
|
55
58
|
"mock-socket": "^9.3.1",
|
|
56
|
-
"npm-run-all": "^4.1.5",
|
|
57
59
|
"nyc": "^15.1.0",
|
|
58
|
-
"prettier": "^2.8.8",
|
|
59
|
-
"semantic-release-plugin-update-version-in-files": "^1.1.0",
|
|
60
|
-
"typedoc": "^0.27.9",
|
|
61
|
-
"typescript": "^5.8.3",
|
|
62
|
-
"vitest": "^3.1.4",
|
|
63
60
|
"web-worker": "1.2.0"
|
|
64
61
|
}
|
|
65
62
|
}
|
package/src/RealtimeChannel.ts
CHANGED
|
@@ -1,14 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
CHANNEL_EVENTS,
|
|
3
|
-
CHANNEL_STATES,
|
|
4
|
-
MAX_PUSH_BUFFER_SIZE,
|
|
5
|
-
} from './lib/constants'
|
|
1
|
+
import { CHANNEL_EVENTS, CHANNEL_STATES, MAX_PUSH_BUFFER_SIZE } from './lib/constants'
|
|
6
2
|
import Push from './lib/push'
|
|
7
3
|
import type RealtimeClient from './RealtimeClient'
|
|
8
4
|
import Timer from './lib/timer'
|
|
9
|
-
import RealtimePresence, {
|
|
10
|
-
REALTIME_PRESENCE_LISTEN_EVENTS,
|
|
11
|
-
} from './RealtimePresence'
|
|
5
|
+
import RealtimePresence, { REALTIME_PRESENCE_LISTEN_EVENTS } from './RealtimePresence'
|
|
12
6
|
import type {
|
|
13
7
|
RealtimePresenceJoinPayload,
|
|
14
8
|
RealtimePresenceLeavePayload,
|
|
@@ -68,9 +62,7 @@ export type RealtimePostgresChangesPayload<T extends { [key: string]: any }> =
|
|
|
68
62
|
| RealtimePostgresUpdatePayload<T>
|
|
69
63
|
| RealtimePostgresDeletePayload<T>
|
|
70
64
|
|
|
71
|
-
export type RealtimePostgresChangesFilter<
|
|
72
|
-
T extends `${REALTIME_POSTGRES_CHANGES_LISTEN_EVENT}`
|
|
73
|
-
> = {
|
|
65
|
+
export type RealtimePostgresChangesFilter<T extends `${REALTIME_POSTGRES_CHANGES_LISTEN_EVENT}`> = {
|
|
74
66
|
/**
|
|
75
67
|
* The type of database change to listen to.
|
|
76
68
|
*/
|
|
@@ -164,16 +156,8 @@ export default class RealtimeChannel {
|
|
|
164
156
|
...params.config,
|
|
165
157
|
}
|
|
166
158
|
this.timeout = this.socket.timeout
|
|
167
|
-
this.joinPush = new Push(
|
|
168
|
-
|
|
169
|
-
CHANNEL_EVENTS.join,
|
|
170
|
-
this.params,
|
|
171
|
-
this.timeout
|
|
172
|
-
)
|
|
173
|
-
this.rejoinTimer = new Timer(
|
|
174
|
-
() => this._rejoinUntilConnected(),
|
|
175
|
-
this.socket.reconnectAfterMs
|
|
176
|
-
)
|
|
159
|
+
this.joinPush = new Push(this, CHANNEL_EVENTS.join, this.params, this.timeout)
|
|
160
|
+
this.rejoinTimer = new Timer(() => this._rejoinUntilConnected(), this.socket.reconnectAfterMs)
|
|
177
161
|
this.joinPush.receive('ok', () => {
|
|
178
162
|
this.state = CHANNEL_STATES.joined
|
|
179
163
|
this.rejoinTimer.reset()
|
|
@@ -234,13 +218,11 @@ export default class RealtimeChannel {
|
|
|
234
218
|
config: { broadcast, presence, private: isPrivate },
|
|
235
219
|
} = this.params
|
|
236
220
|
|
|
237
|
-
const postgres_changes =
|
|
238
|
-
this.bindings.postgres_changes?.map((r) => r.filter) ?? []
|
|
221
|
+
const postgres_changes = this.bindings.postgres_changes?.map((r) => r.filter) ?? []
|
|
239
222
|
|
|
240
223
|
const presence_enabled =
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
this.params.config.presence?.enabled === true
|
|
224
|
+
!!this.bindings[REALTIME_LISTEN_TYPES.PRESENCE] &&
|
|
225
|
+
this.bindings[REALTIME_LISTEN_TYPES.PRESENCE].length > 0
|
|
244
226
|
const accessTokenPayload: { access_token?: string } = {}
|
|
245
227
|
const config = {
|
|
246
228
|
broadcast,
|
|
@@ -253,9 +235,7 @@ export default class RealtimeChannel {
|
|
|
253
235
|
accessTokenPayload.access_token = this.socket.accessTokenValue
|
|
254
236
|
}
|
|
255
237
|
|
|
256
|
-
this._onError((e: Error) =>
|
|
257
|
-
callback?.(REALTIME_SUBSCRIBE_STATES.CHANNEL_ERROR, e)
|
|
258
|
-
)
|
|
238
|
+
this._onError((e: Error) => callback?.(REALTIME_SUBSCRIBE_STATES.CHANNEL_ERROR, e))
|
|
259
239
|
|
|
260
240
|
this._onClose(() => callback?.(REALTIME_SUBSCRIBE_STATES.CLOSED))
|
|
261
241
|
|
|
@@ -280,8 +260,7 @@ export default class RealtimeChannel {
|
|
|
280
260
|
const {
|
|
281
261
|
filter: { event, schema, table, filter },
|
|
282
262
|
} = clientPostgresBinding
|
|
283
|
-
const serverPostgresFilter =
|
|
284
|
-
postgres_changes && postgres_changes[i]
|
|
263
|
+
const serverPostgresFilter = postgres_changes && postgres_changes[i]
|
|
285
264
|
|
|
286
265
|
if (
|
|
287
266
|
serverPostgresFilter &&
|
|
@@ -300,9 +279,7 @@ export default class RealtimeChannel {
|
|
|
300
279
|
|
|
301
280
|
callback?.(
|
|
302
281
|
REALTIME_SUBSCRIBE_STATES.CHANNEL_ERROR,
|
|
303
|
-
new Error(
|
|
304
|
-
'mismatch between server and client bindings for postgres changes'
|
|
305
|
-
)
|
|
282
|
+
new Error('mismatch between server and client bindings for postgres changes')
|
|
306
283
|
)
|
|
307
284
|
return
|
|
308
285
|
}
|
|
@@ -318,9 +295,7 @@ export default class RealtimeChannel {
|
|
|
318
295
|
this.state = CHANNEL_STATES.errored
|
|
319
296
|
callback?.(
|
|
320
297
|
REALTIME_SUBSCRIBE_STATES.CHANNEL_ERROR,
|
|
321
|
-
new Error(
|
|
322
|
-
JSON.stringify(Object.values(error).join(', ') || 'error')
|
|
323
|
-
)
|
|
298
|
+
new Error(JSON.stringify(Object.values(error).join(', ') || 'error'))
|
|
324
299
|
)
|
|
325
300
|
return
|
|
326
301
|
})
|
|
@@ -332,9 +307,7 @@ export default class RealtimeChannel {
|
|
|
332
307
|
return this
|
|
333
308
|
}
|
|
334
309
|
|
|
335
|
-
presenceState<
|
|
336
|
-
T extends { [key: string]: any } = {}
|
|
337
|
-
>(): RealtimePresenceState<T> {
|
|
310
|
+
presenceState<T extends { [key: string]: any } = {}>(): RealtimePresenceState<T> {
|
|
338
311
|
return this.presence.state as RealtimePresenceState<T>
|
|
339
312
|
}
|
|
340
313
|
|
|
@@ -352,9 +325,7 @@ export default class RealtimeChannel {
|
|
|
352
325
|
)
|
|
353
326
|
}
|
|
354
327
|
|
|
355
|
-
async untrack(
|
|
356
|
-
opts: { [key: string]: any } = {}
|
|
357
|
-
): Promise<RealtimeChannelSendResponse> {
|
|
328
|
+
async untrack(opts: { [key: string]: any } = {}): Promise<RealtimeChannelSendResponse> {
|
|
358
329
|
return await this.send(
|
|
359
330
|
{
|
|
360
331
|
type: 'presence',
|
|
@@ -436,10 +407,7 @@ export default class RealtimeChannel {
|
|
|
436
407
|
filter: { event: string; [key: string]: string },
|
|
437
408
|
callback: (payload: any) => void
|
|
438
409
|
): RealtimeChannel {
|
|
439
|
-
if (
|
|
440
|
-
this.state === CHANNEL_STATES.joined &&
|
|
441
|
-
type === REALTIME_LISTEN_TYPES.PRESENCE
|
|
442
|
-
) {
|
|
410
|
+
if (this.state === CHANNEL_STATES.joined && type === REALTIME_LISTEN_TYPES.PRESENCE) {
|
|
443
411
|
this.socket.log(
|
|
444
412
|
'channel',
|
|
445
413
|
`resubscribe to ${this.topic} due to change in presence callbacks on joined channel`
|
|
@@ -584,11 +552,7 @@ export default class RealtimeChannel {
|
|
|
584
552
|
|
|
585
553
|
/** @internal */
|
|
586
554
|
|
|
587
|
-
async _fetchWithTimeout(
|
|
588
|
-
url: string,
|
|
589
|
-
options: { [key: string]: any },
|
|
590
|
-
timeout: number
|
|
591
|
-
) {
|
|
555
|
+
async _fetchWithTimeout(url: string, options: { [key: string]: any }, timeout: number) {
|
|
592
556
|
const controller = new AbortController()
|
|
593
557
|
const id = setTimeout(() => controller.abort(), timeout)
|
|
594
558
|
|
|
@@ -603,11 +567,7 @@ export default class RealtimeChannel {
|
|
|
603
567
|
}
|
|
604
568
|
|
|
605
569
|
/** @internal */
|
|
606
|
-
_push(
|
|
607
|
-
event: string,
|
|
608
|
-
payload: { [key: string]: any },
|
|
609
|
-
timeout = this.timeout
|
|
610
|
-
) {
|
|
570
|
+
_push(event: string, payload: { [key: string]: any }, timeout = this.timeout) {
|
|
611
571
|
if (!this.joinedOnce) {
|
|
612
572
|
throw `tried to push '${event}' to '${this.topic}' before joining. Use channel.subscribe() before pushing events`
|
|
613
573
|
}
|
|
@@ -678,18 +638,13 @@ export default class RealtimeChannel {
|
|
|
678
638
|
if (['insert', 'update', 'delete'].includes(typeLower)) {
|
|
679
639
|
this.bindings.postgres_changes
|
|
680
640
|
?.filter((bind) => {
|
|
681
|
-
return (
|
|
682
|
-
bind.filter?.event === '*' ||
|
|
683
|
-
bind.filter?.event?.toLocaleLowerCase() === typeLower
|
|
684
|
-
)
|
|
641
|
+
return bind.filter?.event === '*' || bind.filter?.event?.toLocaleLowerCase() === typeLower
|
|
685
642
|
})
|
|
686
643
|
.map((bind) => bind.callback(handledPayload, ref))
|
|
687
644
|
} else {
|
|
688
645
|
this.bindings[typeLower]
|
|
689
646
|
?.filter((bind) => {
|
|
690
|
-
if (
|
|
691
|
-
['broadcast', 'presence', 'postgres_changes'].includes(typeLower)
|
|
692
|
-
) {
|
|
647
|
+
if (['broadcast', 'presence', 'postgres_changes'].includes(typeLower)) {
|
|
693
648
|
if ('id' in bind) {
|
|
694
649
|
const bindId = bind.id
|
|
695
650
|
const bindEvent = bind.filter?.event
|
|
@@ -697,15 +652,11 @@ export default class RealtimeChannel {
|
|
|
697
652
|
bindId &&
|
|
698
653
|
payload.ids?.includes(bindId) &&
|
|
699
654
|
(bindEvent === '*' ||
|
|
700
|
-
bindEvent?.toLocaleLowerCase() ===
|
|
701
|
-
payload.data?.type.toLocaleLowerCase())
|
|
655
|
+
bindEvent?.toLocaleLowerCase() === payload.data?.type.toLocaleLowerCase())
|
|
702
656
|
)
|
|
703
657
|
} else {
|
|
704
658
|
const bindEvent = bind?.filter?.event?.toLocaleLowerCase()
|
|
705
|
-
return (
|
|
706
|
-
bindEvent === '*' ||
|
|
707
|
-
bindEvent === payload?.event?.toLocaleLowerCase()
|
|
708
|
-
)
|
|
659
|
+
return bindEvent === '*' || bindEvent === payload?.event?.toLocaleLowerCase()
|
|
709
660
|
}
|
|
710
661
|
} else {
|
|
711
662
|
return bind.type.toLocaleLowerCase() === typeLower
|
|
@@ -714,8 +665,7 @@ export default class RealtimeChannel {
|
|
|
714
665
|
.map((bind) => {
|
|
715
666
|
if (typeof handledPayload === 'object' && 'ids' in handledPayload) {
|
|
716
667
|
const postgresChanges = handledPayload.data
|
|
717
|
-
const { schema, table, commit_timestamp, type, errors } =
|
|
718
|
-
postgresChanges
|
|
668
|
+
const { schema, table, commit_timestamp, type, errors } = postgresChanges
|
|
719
669
|
const enrichedPayload = {
|
|
720
670
|
schema: schema,
|
|
721
671
|
table: table,
|
|
@@ -794,10 +744,7 @@ export default class RealtimeChannel {
|
|
|
794
744
|
}
|
|
795
745
|
|
|
796
746
|
/** @internal */
|
|
797
|
-
private static isEqual(
|
|
798
|
-
obj1: { [key: string]: string },
|
|
799
|
-
obj2: { [key: string]: string }
|
|
800
|
-
) {
|
|
747
|
+
private static isEqual(obj1: { [key: string]: string }, obj2: { [key: string]: string }) {
|
|
801
748
|
if (Object.keys(obj1).length !== Object.keys(obj2).length) {
|
|
802
749
|
return false
|
|
803
750
|
}
|
|
@@ -864,17 +811,11 @@ export default class RealtimeChannel {
|
|
|
864
811
|
}
|
|
865
812
|
|
|
866
813
|
if (payload.type === 'INSERT' || payload.type === 'UPDATE') {
|
|
867
|
-
records.new = Transformers.convertChangeData(
|
|
868
|
-
payload.columns,
|
|
869
|
-
payload.record
|
|
870
|
-
)
|
|
814
|
+
records.new = Transformers.convertChangeData(payload.columns, payload.record)
|
|
871
815
|
}
|
|
872
816
|
|
|
873
817
|
if (payload.type === 'UPDATE' || payload.type === 'DELETE') {
|
|
874
|
-
records.old = Transformers.convertChangeData(
|
|
875
|
-
payload.columns,
|
|
876
|
-
payload.old_record
|
|
877
|
-
)
|
|
818
|
+
records.old = Transformers.convertChangeData(payload.columns, payload.old_record)
|
|
878
819
|
}
|
|
879
820
|
|
|
880
821
|
return records
|
package/src/RealtimeClient.ts
CHANGED
|
@@ -37,20 +37,11 @@ export type RealtimeMessage = {
|
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
export type RealtimeRemoveChannelResponse = 'ok' | 'timed out' | 'error'
|
|
40
|
-
export type HeartbeatStatus =
|
|
41
|
-
| 'sent'
|
|
42
|
-
| 'ok'
|
|
43
|
-
| 'error'
|
|
44
|
-
| 'timeout'
|
|
45
|
-
| 'disconnected'
|
|
40
|
+
export type HeartbeatStatus = 'sent' | 'ok' | 'error' | 'timeout' | 'disconnected'
|
|
46
41
|
|
|
47
42
|
const noop = () => {}
|
|
48
43
|
|
|
49
|
-
type RealtimeClientState =
|
|
50
|
-
| 'connecting'
|
|
51
|
-
| 'connected'
|
|
52
|
-
| 'disconnecting'
|
|
53
|
-
| 'disconnected'
|
|
44
|
+
type RealtimeClientState = 'connecting' | 'connected' | 'disconnecting' | 'disconnected'
|
|
54
45
|
|
|
55
46
|
// Connection-related constants
|
|
56
47
|
const CONNECTION_TIMEOUTS = {
|
|
@@ -63,10 +54,7 @@ const RECONNECT_INTERVALS = [1000, 2000, 5000, 10000] as const
|
|
|
63
54
|
const DEFAULT_RECONNECT_FALLBACK = 10000
|
|
64
55
|
|
|
65
56
|
export interface WebSocketLikeConstructor {
|
|
66
|
-
new (
|
|
67
|
-
address: string | URL,
|
|
68
|
-
subprotocols?: string | string[] | undefined
|
|
69
|
-
): WebSocketLike
|
|
57
|
+
new (address: string | URL, subprotocols?: string | string[] | undefined): WebSocketLike
|
|
70
58
|
// Allow additional properties that may exist on WebSocket constructors
|
|
71
59
|
[key: string]: any
|
|
72
60
|
}
|
|
@@ -236,10 +224,7 @@ export default class RealtimeClient {
|
|
|
236
224
|
* @returns string The URL of the websocket.
|
|
237
225
|
*/
|
|
238
226
|
endpointURL(): string {
|
|
239
|
-
return this._appendParams(
|
|
240
|
-
this.endPoint,
|
|
241
|
-
Object.assign({}, this.params, { vsn: VSN })
|
|
242
|
-
)
|
|
227
|
+
return this._appendParams(this.endPoint, Object.assign({}, this.params, { vsn: VSN }))
|
|
243
228
|
}
|
|
244
229
|
|
|
245
230
|
/**
|
|
@@ -290,9 +275,7 @@ export default class RealtimeClient {
|
|
|
290
275
|
* Unsubscribes and removes a single channel
|
|
291
276
|
* @param channel A RealtimeChannel instance
|
|
292
277
|
*/
|
|
293
|
-
async removeChannel(
|
|
294
|
-
channel: RealtimeChannel
|
|
295
|
-
): Promise<RealtimeRemoveChannelResponse> {
|
|
278
|
+
async removeChannel(channel: RealtimeChannel): Promise<RealtimeRemoveChannelResponse> {
|
|
296
279
|
const status = await channel.unsubscribe()
|
|
297
280
|
|
|
298
281
|
if (this.channels.length === 0) {
|
|
@@ -306,9 +289,7 @@ export default class RealtimeClient {
|
|
|
306
289
|
* Unsubscribes and removes all channels
|
|
307
290
|
*/
|
|
308
291
|
async removeAllChannels(): Promise<RealtimeRemoveChannelResponse[]> {
|
|
309
|
-
const values_1 = await Promise.all(
|
|
310
|
-
this.channels.map((channel) => channel.unsubscribe())
|
|
311
|
-
)
|
|
292
|
+
const values_1 = await Promise.all(this.channels.map((channel) => channel.unsubscribe()))
|
|
312
293
|
this.channels = []
|
|
313
294
|
this.disconnect()
|
|
314
295
|
return values_1
|
|
@@ -360,14 +341,9 @@ export default class RealtimeClient {
|
|
|
360
341
|
return this._connectionState === 'disconnecting'
|
|
361
342
|
}
|
|
362
343
|
|
|
363
|
-
channel(
|
|
364
|
-
topic: string,
|
|
365
|
-
params: RealtimeChannelOptions = { config: {} }
|
|
366
|
-
): RealtimeChannel {
|
|
344
|
+
channel(topic: string, params: RealtimeChannelOptions = { config: {} }): RealtimeChannel {
|
|
367
345
|
const realtimeTopic = `realtime:${topic}`
|
|
368
|
-
const exists = this.getChannels().find(
|
|
369
|
-
(c: RealtimeChannel) => c.topic === realtimeTopic
|
|
370
|
-
)
|
|
346
|
+
const exists = this.getChannels().find((c: RealtimeChannel) => c.topic === realtimeTopic)
|
|
371
347
|
|
|
372
348
|
if (!exists) {
|
|
373
349
|
const chan = new RealtimeChannel(`realtime:${topic}`, params, this)
|
|
@@ -428,10 +404,7 @@ export default class RealtimeClient {
|
|
|
428
404
|
// Handle heartbeat timeout and force reconnection if needed
|
|
429
405
|
if (this.pendingHeartbeatRef) {
|
|
430
406
|
this.pendingHeartbeatRef = null
|
|
431
|
-
this.log(
|
|
432
|
-
'transport',
|
|
433
|
-
'heartbeat timeout. Attempting to re-establish connection'
|
|
434
|
-
)
|
|
407
|
+
this.log('transport', 'heartbeat timeout. Attempting to re-establish connection')
|
|
435
408
|
this.heartbeatCallback('timeout')
|
|
436
409
|
|
|
437
410
|
// Force reconnection after heartbeat timeout
|
|
@@ -557,18 +530,12 @@ export default class RealtimeClient {
|
|
|
557
530
|
const { topic, event, payload, ref } = msg
|
|
558
531
|
const refString = ref ? `(${ref})` : ''
|
|
559
532
|
const status = payload.status || ''
|
|
560
|
-
this.log(
|
|
561
|
-
'receive',
|
|
562
|
-
`${status} ${topic} ${event} ${refString}`.trim(),
|
|
563
|
-
payload
|
|
564
|
-
)
|
|
533
|
+
this.log('receive', `${status} ${topic} ${event} ${refString}`.trim(), payload)
|
|
565
534
|
|
|
566
535
|
// Route message to appropriate channels
|
|
567
536
|
this.channels
|
|
568
537
|
.filter((channel: RealtimeChannel) => channel._isMember(topic))
|
|
569
|
-
.forEach((channel: RealtimeChannel) =>
|
|
570
|
-
channel._trigger(event, payload, ref)
|
|
571
|
-
)
|
|
538
|
+
.forEach((channel: RealtimeChannel) => channel._trigger(event, payload, ref))
|
|
572
539
|
|
|
573
540
|
this._triggerStateCallbacks('message', msg)
|
|
574
541
|
})
|
|
@@ -650,10 +617,7 @@ export default class RealtimeClient {
|
|
|
650
617
|
/** @internal */
|
|
651
618
|
private _startHeartbeat() {
|
|
652
619
|
this.heartbeatTimer && clearInterval(this.heartbeatTimer)
|
|
653
|
-
this.heartbeatTimer = setInterval(
|
|
654
|
-
() => this.sendHeartbeat(),
|
|
655
|
-
this.heartbeatIntervalMs
|
|
656
|
-
)
|
|
620
|
+
this.heartbeatTimer = setInterval(() => this.sendHeartbeat(), this.heartbeatIntervalMs)
|
|
657
621
|
}
|
|
658
622
|
|
|
659
623
|
/** @internal */
|
|
@@ -704,16 +668,11 @@ export default class RealtimeClient {
|
|
|
704
668
|
|
|
705
669
|
/** @internal */
|
|
706
670
|
private _triggerChanError() {
|
|
707
|
-
this.channels.forEach((channel: RealtimeChannel) =>
|
|
708
|
-
channel._trigger(CHANNEL_EVENTS.error)
|
|
709
|
-
)
|
|
671
|
+
this.channels.forEach((channel: RealtimeChannel) => channel._trigger(CHANNEL_EVENTS.error))
|
|
710
672
|
}
|
|
711
673
|
|
|
712
674
|
/** @internal */
|
|
713
|
-
private _appendParams(
|
|
714
|
-
url: string,
|
|
715
|
-
params: { [key: string]: string }
|
|
716
|
-
): string {
|
|
675
|
+
private _appendParams(url: string, params: { [key: string]: string }): string {
|
|
717
676
|
if (Object.keys(params).length === 0) {
|
|
718
677
|
return url
|
|
719
678
|
}
|
|
@@ -737,10 +696,7 @@ export default class RealtimeClient {
|
|
|
737
696
|
* Set connection state with proper state management
|
|
738
697
|
* @internal
|
|
739
698
|
*/
|
|
740
|
-
private _setConnectionState(
|
|
741
|
-
state: RealtimeClientState,
|
|
742
|
-
manual = false
|
|
743
|
-
): void {
|
|
699
|
+
private _setConnectionState(state: RealtimeClientState, manual = false): void {
|
|
744
700
|
this._connectionState = state
|
|
745
701
|
|
|
746
702
|
if (state === 'connecting') {
|
|
@@ -809,10 +765,7 @@ export default class RealtimeClient {
|
|
|
809
765
|
* Trigger state change callbacks with proper error handling
|
|
810
766
|
* @internal
|
|
811
767
|
*/
|
|
812
|
-
private _triggerStateCallbacks(
|
|
813
|
-
event: keyof typeof this.stateChangeCallbacks,
|
|
814
|
-
data?: any
|
|
815
|
-
): void {
|
|
768
|
+
private _triggerStateCallbacks(event: keyof typeof this.stateChangeCallbacks, data?: any): void {
|
|
816
769
|
try {
|
|
817
770
|
this.stateChangeCallbacks[event].forEach((callback) => {
|
|
818
771
|
try {
|
|
@@ -875,8 +828,7 @@ export default class RealtimeClient {
|
|
|
875
828
|
return callback(JSON.stringify(payload))
|
|
876
829
|
})
|
|
877
830
|
|
|
878
|
-
this.decode =
|
|
879
|
-
options?.decode ?? this.serializer.decode.bind(this.serializer)
|
|
831
|
+
this.decode = options?.decode ?? this.serializer.decode.bind(this.serializer)
|
|
880
832
|
|
|
881
833
|
// Handle worker setup
|
|
882
834
|
if (this.worker) {
|
package/src/RealtimePresence.ts
CHANGED
|
@@ -3,11 +3,7 @@
|
|
|
3
3
|
License: https://github.com/phoenixframework/phoenix/blob/d344ec0a732ab4ee204215b31de69cf4be72e3bf/LICENSE.md
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import type {
|
|
7
|
-
PresenceOpts,
|
|
8
|
-
PresenceOnJoinCallback,
|
|
9
|
-
PresenceOnLeaveCallback,
|
|
10
|
-
} from 'phoenix'
|
|
6
|
+
import type { PresenceOpts, PresenceOnJoinCallback, PresenceOnLeaveCallback } from 'phoenix'
|
|
11
7
|
import type RealtimeChannel from './RealtimeChannel'
|
|
12
8
|
|
|
13
9
|
type Presence<T extends { [key: string]: any } = {}> = {
|
|
@@ -82,7 +78,10 @@ export default class RealtimePresence {
|
|
|
82
78
|
* @param opts - The options,
|
|
83
79
|
* for example `{events: {state: 'state', diff: 'diff'}}`
|
|
84
80
|
*/
|
|
85
|
-
constructor(
|
|
81
|
+
constructor(
|
|
82
|
+
public channel: RealtimeChannel,
|
|
83
|
+
opts?: PresenceOpts
|
|
84
|
+
) {
|
|
86
85
|
const events = opts?.events || {
|
|
87
86
|
state: 'presence_state',
|
|
88
87
|
diff: 'presence_diff',
|
|
@@ -93,20 +92,10 @@ export default class RealtimePresence {
|
|
|
93
92
|
|
|
94
93
|
this.joinRef = this.channel._joinRef()
|
|
95
94
|
|
|
96
|
-
this.state = RealtimePresence.syncState(
|
|
97
|
-
this.state,
|
|
98
|
-
newState,
|
|
99
|
-
onJoin,
|
|
100
|
-
onLeave
|
|
101
|
-
)
|
|
95
|
+
this.state = RealtimePresence.syncState(this.state, newState, onJoin, onLeave)
|
|
102
96
|
|
|
103
97
|
this.pendingDiffs.forEach((diff) => {
|
|
104
|
-
this.state = RealtimePresence.syncDiff(
|
|
105
|
-
this.state,
|
|
106
|
-
diff,
|
|
107
|
-
onJoin,
|
|
108
|
-
onLeave
|
|
109
|
-
)
|
|
98
|
+
this.state = RealtimePresence.syncDiff(this.state, diff, onJoin, onLeave)
|
|
110
99
|
})
|
|
111
100
|
|
|
112
101
|
this.pendingDiffs = []
|
|
@@ -120,12 +109,7 @@ export default class RealtimePresence {
|
|
|
120
109
|
if (this.inPendingSyncState()) {
|
|
121
110
|
this.pendingDiffs.push(diff)
|
|
122
111
|
} else {
|
|
123
|
-
this.state = RealtimePresence.syncDiff(
|
|
124
|
-
this.state,
|
|
125
|
-
diff,
|
|
126
|
-
onJoin,
|
|
127
|
-
onLeave
|
|
128
|
-
)
|
|
112
|
+
this.state = RealtimePresence.syncDiff(this.state, diff, onJoin, onLeave)
|
|
129
113
|
|
|
130
114
|
onSync()
|
|
131
115
|
}
|
|
@@ -185,12 +169,8 @@ export default class RealtimePresence {
|
|
|
185
169
|
const currentPresences: Presence[] = state[key]
|
|
186
170
|
|
|
187
171
|
if (currentPresences) {
|
|
188
|
-
const newPresenceRefs = newPresences.map(
|
|
189
|
-
|
|
190
|
-
)
|
|
191
|
-
const curPresenceRefs = currentPresences.map(
|
|
192
|
-
(m: Presence) => m.presence_ref
|
|
193
|
-
)
|
|
172
|
+
const newPresenceRefs = newPresences.map((m: Presence) => m.presence_ref)
|
|
173
|
+
const curPresenceRefs = currentPresences.map((m: Presence) => m.presence_ref)
|
|
194
174
|
const joinedPresences: Presence[] = newPresences.filter(
|
|
195
175
|
(m: Presence) => curPresenceRefs.indexOf(m.presence_ref) < 0
|
|
196
176
|
)
|
|
@@ -247,9 +227,7 @@ export default class RealtimePresence {
|
|
|
247
227
|
state[key] = this.cloneDeep(newPresences)
|
|
248
228
|
|
|
249
229
|
if (currentPresences.length > 0) {
|
|
250
|
-
const joinedPresenceRefs = state[key].map(
|
|
251
|
-
(m: Presence) => m.presence_ref
|
|
252
|
-
)
|
|
230
|
+
const joinedPresenceRefs = state[key].map((m: Presence) => m.presence_ref)
|
|
253
231
|
const curPresences: Presence[] = currentPresences.filter(
|
|
254
232
|
(m: Presence) => joinedPresenceRefs.indexOf(m.presence_ref) < 0
|
|
255
233
|
)
|
|
@@ -265,9 +243,7 @@ export default class RealtimePresence {
|
|
|
265
243
|
|
|
266
244
|
if (!currentPresences) return
|
|
267
245
|
|
|
268
|
-
const presenceRefsToRemove = leftPresences.map(
|
|
269
|
-
(m: Presence) => m.presence_ref
|
|
270
|
-
)
|
|
246
|
+
const presenceRefsToRemove = leftPresences.map((m: Presence) => m.presence_ref)
|
|
271
247
|
currentPresences = currentPresences.filter(
|
|
272
248
|
(m: Presence) => presenceRefsToRemove.indexOf(m.presence_ref) < 0
|
|
273
249
|
)
|
|
@@ -283,10 +259,7 @@ export default class RealtimePresence {
|
|
|
283
259
|
}
|
|
284
260
|
|
|
285
261
|
/** @internal */
|
|
286
|
-
private static map<T = any>(
|
|
287
|
-
obj: RealtimePresenceState,
|
|
288
|
-
func: PresenceChooser<T>
|
|
289
|
-
): T[] {
|
|
262
|
+
private static map<T = any>(obj: RealtimePresenceState, func: PresenceChooser<T>): T[] {
|
|
290
263
|
return Object.getOwnPropertyNames(obj).map((key) => func(key, obj[key]))
|
|
291
264
|
}
|
|
292
265
|
|
package/src/lib/push.ts
CHANGED
|
@@ -90,8 +90,7 @@ export default class Push {
|
|
|
90
90
|
}
|
|
91
91
|
|
|
92
92
|
trigger(status: string, response: any) {
|
|
93
|
-
if (this.refEvent)
|
|
94
|
-
this.channel._trigger(this.refEvent, { status, response })
|
|
93
|
+
if (this.refEvent) this.channel._trigger(this.refEvent, { status, response })
|
|
95
94
|
}
|
|
96
95
|
|
|
97
96
|
destroy() {
|
|
@@ -112,16 +111,8 @@ export default class Push {
|
|
|
112
111
|
this.timeoutTimer = undefined
|
|
113
112
|
}
|
|
114
113
|
|
|
115
|
-
private _matchReceive({
|
|
116
|
-
status
|
|
117
|
-
response,
|
|
118
|
-
}: {
|
|
119
|
-
status: string
|
|
120
|
-
response: Function
|
|
121
|
-
}) {
|
|
122
|
-
this.recHooks
|
|
123
|
-
.filter((h) => h.status === status)
|
|
124
|
-
.forEach((h) => h.callback(response))
|
|
114
|
+
private _matchReceive({ status, response }: { status: string; response: Function }) {
|
|
115
|
+
this.recHooks.filter((h) => h.status === status).forEach((h) => h.callback(response))
|
|
125
116
|
}
|
|
126
117
|
|
|
127
118
|
private _hasReceived(status: string) {
|
package/src/lib/serializer.ts
CHANGED
|
@@ -40,9 +40,7 @@ export default class Serializer {
|
|
|
40
40
|
offset = offset + topicSize
|
|
41
41
|
const event = decoder.decode(buffer.slice(offset, offset + eventSize))
|
|
42
42
|
offset = offset + eventSize
|
|
43
|
-
const data = JSON.parse(
|
|
44
|
-
decoder.decode(buffer.slice(offset, buffer.byteLength))
|
|
45
|
-
)
|
|
43
|
+
const data = JSON.parse(decoder.decode(buffer.slice(offset, buffer.byteLength)))
|
|
46
44
|
|
|
47
45
|
return { ref: null, topic: topic, event: event, payload: data }
|
|
48
46
|
}
|
package/src/lib/timer.ts
CHANGED
|
@@ -14,7 +14,10 @@ export default class Timer {
|
|
|
14
14
|
timer: number | undefined = undefined
|
|
15
15
|
tries: number = 0
|
|
16
16
|
|
|
17
|
-
constructor(
|
|
17
|
+
constructor(
|
|
18
|
+
public callback: Function,
|
|
19
|
+
public timerCalc: Function
|
|
20
|
+
) {
|
|
18
21
|
this.callback = callback
|
|
19
22
|
this.timerCalc = timerCalc
|
|
20
23
|
}
|
|
@@ -29,9 +32,12 @@ export default class Timer {
|
|
|
29
32
|
scheduleTimeout() {
|
|
30
33
|
clearTimeout(this.timer)
|
|
31
34
|
|
|
32
|
-
this.timer = <any>setTimeout(
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
35
|
+
this.timer = <any>setTimeout(
|
|
36
|
+
() => {
|
|
37
|
+
this.tries = this.tries + 1
|
|
38
|
+
this.callback()
|
|
39
|
+
},
|
|
40
|
+
this.timerCalc(this.tries + 1)
|
|
41
|
+
)
|
|
36
42
|
}
|
|
37
43
|
}
|
package/src/lib/version.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const version = '
|
|
1
|
+
export const version = '0.0.0-automated'
|