@supabase/phoenix 0.1.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.
Files changed (49) hide show
  1. package/LICENSE.md +22 -0
  2. package/README.md +122 -0
  3. package/assets/js/phoenix/ajax.js +116 -0
  4. package/assets/js/phoenix/channel.js +331 -0
  5. package/assets/js/phoenix/constants.js +35 -0
  6. package/assets/js/phoenix/index.js +212 -0
  7. package/assets/js/phoenix/longpoll.js +192 -0
  8. package/assets/js/phoenix/presence.js +208 -0
  9. package/assets/js/phoenix/push.js +134 -0
  10. package/assets/js/phoenix/serializer.js +133 -0
  11. package/assets/js/phoenix/socket.js +747 -0
  12. package/assets/js/phoenix/timer.js +48 -0
  13. package/assets/js/phoenix/types.js +184 -0
  14. package/assets/js/phoenix/utils.js +16 -0
  15. package/package.json +58 -0
  16. package/priv/static/favicon.ico +0 -0
  17. package/priv/static/phoenix-orange.png +0 -0
  18. package/priv/static/phoenix.cjs.js +1812 -0
  19. package/priv/static/phoenix.cjs.js.map +7 -0
  20. package/priv/static/phoenix.js +1834 -0
  21. package/priv/static/phoenix.min.js +2 -0
  22. package/priv/static/phoenix.mjs +1789 -0
  23. package/priv/static/phoenix.mjs.map +7 -0
  24. package/priv/static/phoenix.png +0 -0
  25. package/priv/static/types/ajax.d.ts +10 -0
  26. package/priv/static/types/ajax.d.ts.map +1 -0
  27. package/priv/static/types/channel.d.ts +167 -0
  28. package/priv/static/types/channel.d.ts.map +1 -0
  29. package/priv/static/types/constants.d.ts +36 -0
  30. package/priv/static/types/constants.d.ts.map +1 -0
  31. package/priv/static/types/index.d.ts +10 -0
  32. package/priv/static/types/index.d.ts.map +1 -0
  33. package/priv/static/types/longpoll.d.ts +29 -0
  34. package/priv/static/types/longpoll.d.ts.map +1 -0
  35. package/priv/static/types/presence.d.ts +107 -0
  36. package/priv/static/types/presence.d.ts.map +1 -0
  37. package/priv/static/types/push.d.ts +70 -0
  38. package/priv/static/types/push.d.ts.map +1 -0
  39. package/priv/static/types/serializer.d.ts +74 -0
  40. package/priv/static/types/serializer.d.ts.map +1 -0
  41. package/priv/static/types/socket.d.ts +284 -0
  42. package/priv/static/types/socket.d.ts.map +1 -0
  43. package/priv/static/types/timer.d.ts +36 -0
  44. package/priv/static/types/timer.d.ts.map +1 -0
  45. package/priv/static/types/types.d.ts +280 -0
  46. package/priv/static/types/types.d.ts.map +1 -0
  47. package/priv/static/types/utils.d.ts +2 -0
  48. package/priv/static/types/utils.d.ts.map +1 -0
  49. package/tsconfig.json +20 -0
@@ -0,0 +1,48 @@
1
+ /**
2
+ *
3
+ * Creates a timer that accepts a `timerCalc` function to perform
4
+ * calculated timeout retries, such as exponential backoff.
5
+ *
6
+ * @example
7
+ * let reconnectTimer = new Timer(() => this.connect(), function(tries){
8
+ * return [1000, 5000, 10000][tries - 1] || 10000
9
+ * })
10
+ * reconnectTimer.scheduleTimeout() // fires after 1000
11
+ * reconnectTimer.scheduleTimeout() // fires after 5000
12
+ * reconnectTimer.reset()
13
+ * reconnectTimer.scheduleTimeout() // fires after 1000
14
+ *
15
+ */
16
+ export default class Timer {
17
+ /**
18
+ * @param {() => void} callback
19
+ * @param {(tries: number) => number} timerCalc
20
+ */
21
+ constructor(callback, timerCalc){
22
+ /** @type {() => void} */
23
+ this.callback = callback
24
+ /** @type {(tries: number) => number} */
25
+ this.timerCalc = timerCalc
26
+ /** @type {ReturnType<typeof setTimeout> | undefined} */
27
+ this.timer = undefined
28
+ /** @type {number} */
29
+ this.tries = 0
30
+ }
31
+
32
+ reset(){
33
+ this.tries = 0
34
+ clearTimeout(this.timer)
35
+ }
36
+
37
+ /**
38
+ * Cancels any previous scheduleTimeout and schedules callback
39
+ */
40
+ scheduleTimeout(){
41
+ clearTimeout(this.timer)
42
+
43
+ this.timer = setTimeout(() => {
44
+ this.tries = this.tries + 1
45
+ this.callback()
46
+ }, this.timerCalc(this.tries + 1))
47
+ }
48
+ }
@@ -0,0 +1,184 @@
1
+ /**
2
+ * @import LongPoll from "./longpoll"
3
+ */
4
+
5
+ /**
6
+ * MISC
7
+ * @typedef {Record<string, unknown>} Params
8
+ */
9
+
10
+ /**
11
+ * @template T
12
+ * @typedef {T | (() => T)} Closure
13
+ *
14
+ */
15
+
16
+ /**
17
+ * CHANNEL
18
+ * @typedef {(payload: unknown, ref: string | null | undefined, joinRef: string) => void} ChannelBindingCallback
19
+ * @typedef {(reason: unknown) => void} ChannelOnErrorCallback
20
+ * @typedef {({event: string, ref: number, callback: ChannelBindingCallback})} ChannelBinding
21
+ * @typedef {(event: string, payload?: unknown, ref?: ?string, joinRef?: ?string) => unknown} ChannelOnMessage
22
+ * @typedef {(binding: ChannelBinding, payload: unknown, ref?: ?string) => boolean} ChannelFilterBindings
23
+ */
24
+
25
+
26
+ /**
27
+ * CONSTANTS
28
+ * @import {SOCKET_STATES, CHANNEL_STATES, CHANNEL_EVENTS, TRANSPORTS, XHR_STATES} from "./constants"
29
+ * @typedef {"1.0.0" | "2.0.0"} Vsn
30
+ * @typedef {typeof SOCKET_STATES[keyof typeof SOCKET_STATES]} SocketState
31
+ * @typedef {typeof CHANNEL_STATES[keyof typeof CHANNEL_STATES]} ChannelState
32
+ * @typedef {typeof CHANNEL_EVENTS[keyof typeof CHANNEL_EVENTS]} ChannelEvent
33
+ * @typedef {typeof TRANSPORTS[keyof typeof TRANSPORTS]} Transport
34
+ * @typedef {typeof XHR_STATES[keyof typeof XHR_STATES]} XhrState
35
+ */
36
+
37
+ /**
38
+ * PRESENCE
39
+ * @typedef {{state: string, diff: string}} PresenceEvents
40
+ * @typedef {(key: string, currentPresence: PresenceState, newPresence: PresenceState) => void} PresenceOnJoin
41
+ * @typedef {(key: string, currentPresence: PresenceState, leftPresence: PresenceState) => void} PresenceOnLeave
42
+ * @typedef {() => void} PresenceOnSync
43
+ * @typedef {({joins: PresenceState, leaves: PresenceState})} PresenceDiff
44
+ * @typedef {(
45
+ * {
46
+ * metas: {
47
+ * phx_ref?: string
48
+ * phx_ref_prev?: string
49
+ * [key: string]: any
50
+ * }[]
51
+ * }
52
+ *)} PresenceState
53
+ *
54
+ * @typedef {Object} PresenceOptions
55
+ * @property {PresenceEvents} [events]
56
+ */
57
+
58
+ /**
59
+ * SERIALIZER
60
+ * @template T
61
+ * @typedef {({
62
+ * join_ref?: string | null;
63
+ * ref?: string | null;
64
+ * event: string;
65
+ * topic: string;
66
+ * payload: T;
67
+ * })} Message
68
+ */
69
+ /**
70
+ * @template T
71
+ * @typedef {(msg: Message<Record<string, any>>, callback: (result: ArrayBuffer | string) => T) => T} Encode
72
+ */
73
+ /**
74
+ * @template T
75
+ * @typedef {(rawPayload: ArrayBuffer | string, callback: (msg: Message<unknown>) => T) => T} Decode
76
+ */
77
+
78
+ /**
79
+ * SOCKET
80
+ * @typedef {(typeof WebSocket | typeof LongPoll)} SocketTransport
81
+ * @typedef {() => void} SocketOnOpen
82
+ * @typedef {(event: CloseEvent) => void} SocketOnClose
83
+ * @typedef {(error: Event, transportBefore: SocketTransport, establishedBefore: number) => void} SocketOnError
84
+ * @typedef {(rawMessage: Message<unknown>) => void} SocketOnMessage
85
+ * @typedef {({
86
+ * open: [string, SocketOnOpen][]
87
+ * close: [string, SocketOnClose][]
88
+ * error: [string, SocketOnError][]
89
+ * message: [string, SocketOnMessage][]
90
+ * })} SocketStateChangeCallbacks
91
+ * @typedef {'sent' | 'ok' | 'error' | 'timeout' | 'disconnected'} HeartbeatStatus
92
+ * @typedef {(status: HeartbeatStatus, latency?: number) => void} HeartbeatCallback
93
+ *
94
+ *
95
+ *
96
+ * @typedef {Object} SocketOptions
97
+ * @property {SocketTransport} [transport] - The Websocket Transport, for example WebSocket or Phoenix.LongPoll.
98
+ *
99
+ * @property {number} [longPollFallbackMs] - The millisecond time to attempt the primary transport
100
+ * before falling back to the LongPoll transport. Disabled by default.
101
+ *
102
+ * @property {number} [longpollerTimeout] - The millisecond time before LongPoll transport times out. Default 20000.
103
+ *
104
+ * @property {boolean} [debug] - When true, enables debug logging. Default false.
105
+ *
106
+ * @property {Encode<void>} [encode] - The function to encode outgoing messages.
107
+ * Defaults to JSON encoder.
108
+ *
109
+ * @property {Decode<void>} [decode] - The function to decode incoming messages.
110
+ * Defaults to JSON:
111
+ *
112
+ * ```javascript
113
+ * (payload, callback) => callback(JSON.parse(payload))
114
+ * ```
115
+ *
116
+ * @property {number} [timeout] - The default timeout in milliseconds to trigger push timeouts.
117
+ * Defaults `DEFAULT_TIMEOUT`
118
+ *
119
+ * @property {number} [heartbeatIntervalMs] - The millisec interval to send a heartbeat message
120
+ *
121
+ * @property {boolean} [autoSendHeartbeat] - Whether to automatically send heartbeats after
122
+ * connection is established.
123
+ *
124
+ * Defaults to true.
125
+ *
126
+ * @property {HeartbeatCallback} [heartbeatCallback] - The optional function to handle heartbeat status and latency.
127
+ *
128
+ * @property {(tries: number) => number} [reconnectAfterMs] - The optional function that returns the
129
+ * socket reconnect interval, in milliseconds.
130
+ *
131
+ * Defaults to stepped backoff of:
132
+ *
133
+ * ```javascript
134
+ * function(tries){
135
+ * return [10, 50, 100, 150, 200, 250, 500, 1000, 2000][tries - 1] || 5000
136
+ * }
137
+ * ````
138
+ *
139
+ * @property {(tries: number) => number} [rejoinAfterMs] - The optional function that returns the millisec
140
+ * rejoin interval for individual channels.
141
+ *
142
+ * ```javascript
143
+ * function(tries){
144
+ * return [1000, 2000, 5000][tries - 1] || 10000
145
+ * }
146
+ * ````
147
+ *
148
+ * @property {(kind: string, msg: string, data: any) => void} [logger] - The optional function for specialized logging, ie:
149
+ *
150
+ * ```javascript
151
+ * function(kind, msg, data) {
152
+ * console.log(`${kind}: ${msg}`, data)
153
+ * }
154
+ * ```
155
+ *
156
+ * @property {Closure<Params>} [params] - The optional params to pass when connecting
157
+ *
158
+ * @property {string} [authToken] - the optional authentication token to be exposed on the server
159
+ * under the `:auth_token` connect_info key.
160
+ *
161
+ * @property {BinaryType} [binaryType] - The binary type to use for binary WebSocket frames.
162
+ *
163
+ * Defaults to "arraybuffer"
164
+ *
165
+ * @property {Vsn} [vsn] - The serializer's protocol version to send on connect.
166
+ *
167
+ * Defaults to DEFAULT_VSN.
168
+ *
169
+ * @property {Storage} [sessionStorage] - An optional Storage compatible object
170
+ * Phoenix uses sessionStorage for longpoll fallback history. Overriding the store is
171
+ * useful when Phoenix won't have access to `sessionStorage`. For example, This could
172
+ * happen if a site loads a cross-domain channel in an iframe. Example usage:
173
+ *
174
+ * class InMemoryStorage {
175
+ * constructor() { this.storage = {} }
176
+ * getItem(keyName) { return this.storage[keyName] || null }
177
+ * removeItem(keyName) { delete this.storage[keyName] }
178
+ * setItem(keyName, keyValue) { this.storage[keyName] = keyValue }
179
+ * }
180
+ *
181
+ * @property {() => Promise<void>} [beforeReconnect] - Callback ran before socket tries to reconnect.
182
+ *
183
+ */
184
+ export {}
@@ -0,0 +1,16 @@
1
+ /**
2
+ *
3
+ * Wraps value in closure or returns closure
4
+ *
5
+ * @template T
6
+ * @param {T | (() => T)} value
7
+ * @returns {() => T}
8
+ */
9
+ export let closure = (value) => {
10
+ if(typeof value === "function"){
11
+ return /** @type {() => T} */ (value)
12
+ } else {
13
+ let closure = function (){ return value }
14
+ return closure
15
+ }
16
+ }
package/package.json ADDED
@@ -0,0 +1,58 @@
1
+ {
2
+ "name": "@supabase/phoenix",
3
+ "version": "0.1.0",
4
+ "description": "The official JavaScript client for the Phoenix web framework.",
5
+ "license": "MIT",
6
+ "module": "./priv/static/phoenix.mjs",
7
+ "main": "./priv/static/phoenix.cjs.js",
8
+ "types": "./priv/static/types/index.d.ts",
9
+ "unpkg": "./priv/static/phoenix.min.js",
10
+ "jsdelivr": "./priv/static/phoenix.min.js",
11
+ "exports": {
12
+ "import": {
13
+ "types": "./priv/static/types/index.d.ts",
14
+ "default": "./priv/static/phoenix.mjs"
15
+ },
16
+ "require": {
17
+ "types": "./priv/static/types/index.d.ts",
18
+ "default": "./priv/static/phoenix.cjs.js"
19
+ }
20
+ },
21
+ "repository": {
22
+ "type": "git",
23
+ "url": "git://github.com/supabase/phoenix.git"
24
+ },
25
+ "author": "Chris McCord <chris@chrismccord.com> (https://www.phoenixframework.org)",
26
+ "files": [
27
+ "README.md",
28
+ "LICENSE.md",
29
+ "package.json",
30
+ "tsconfig.json",
31
+ "priv/static/*",
32
+ "assets/js/phoenix/*"
33
+ ],
34
+ "devDependencies": {
35
+ "@babel/cli": "7.28.6",
36
+ "@babel/core": "7.29.0",
37
+ "@babel/preset-env": "7.29.0",
38
+ "@eslint/js": "^9.28.0",
39
+ "@stylistic/eslint-plugin": "^5.0.0",
40
+ "documentation": "^14.0.3",
41
+ "eslint": "9.39.2",
42
+ "eslint-plugin-jest": "29.12.1",
43
+ "jest": "^30.0.0",
44
+ "jest-environment-jsdom": "^30.0.0",
45
+ "jsdom": "^27.0.0",
46
+ "mock-socket": "^9.3.1",
47
+ "typescript": "^5.9.3"
48
+ },
49
+ "scripts": {
50
+ "test": "jest",
51
+ "test.coverage": "jest --coverage",
52
+ "test.watch": "jest --watch",
53
+ "build.types": "tsc",
54
+ "docs": "documentation build assets/js/phoenix/index.js -f html -o doc/js",
55
+ "lint": "eslint assets",
56
+ "lint:fix": "eslint --fix assets"
57
+ }
58
+ }
Binary file
Binary file