itty-sockets 0.5.4 → 0.6.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/README.md +88 -157
- package/connect.d.ts +30 -23
- package/connect.js +1 -0
- package/connect.mjs +1 -1
- package/package.json +2 -2
- package/connect.cjs +0 -1
package/README.md
CHANGED
|
@@ -6,212 +6,143 @@
|
|
|
6
6
|
</a>
|
|
7
7
|
</p>
|
|
8
8
|
|
|
9
|
+
[](https://github.com/kwhitley/itty-sockets)
|
|
9
10
|
[](https://npmjs.com/package/itty-sockets)
|
|
10
11
|
[](https://deno.bundlejs.com/?q=itty-sockets)
|
|
12
|
+
[](https://github.com/kwhitley/itty-sockets/actions/workflows/verify.yml)
|
|
11
13
|
[](https://coveralls.io/github/kwhitley/itty-sockets)
|
|
12
14
|
[](https://github.com/kwhitley/itty-sockets/issues)
|
|
13
15
|
[](https://discord.gg/53vyrZAu9u)
|
|
14
16
|
|
|
15
|
-
### [Documentation](https://
|
|
17
|
+
### [Documentation](https://itty.dev/itty-sockets) | [Discord](https://discord.gg/53vyrZAu9u)
|
|
16
18
|
|
|
17
19
|
---
|
|
18
20
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
21
|
+
### The last WebSocket client you'll need : 512 bytes, all-in.
|
|
22
|
+
|
|
23
|
+
## Features ✨
|
|
24
|
+
1. **DX perks** - JSON-in/out, queued messages, easy-reconnect, chainable everything.
|
|
25
|
+
1. **Works with any JSON-based WebSocket server**
|
|
26
|
+
1. **Powerful Routing**
|
|
27
|
+
- Listen for all messages
|
|
28
|
+
```ts
|
|
29
|
+
.on('message', data => console.log(data))
|
|
30
|
+
```
|
|
31
|
+
- Only specific types
|
|
32
|
+
```ts
|
|
33
|
+
// matches any data with { type: 'chat' }
|
|
34
|
+
.on('chat', ({ text }) => console.log(text))
|
|
35
|
+
```
|
|
36
|
+
- or fully custom filters
|
|
37
|
+
```ts
|
|
38
|
+
// matches only messages where data.value > 20
|
|
39
|
+
.on(
|
|
40
|
+
({ value }) => value > 20), // filter function
|
|
41
|
+
({ value }) => console.log(value),
|
|
42
|
+
)
|
|
43
|
+
```
|
|
44
|
+
1. **Type-safe message handling**
|
|
45
|
+
1. **Tiny footprint** - 512 bytes, all-in.
|
|
46
|
+
1. **Optional usage with free/public/zero-config [itty.ws](https://itty.ws) service**
|
|
47
|
+
|
|
48
|
+
## Basic Example
|
|
22
49
|
```ts
|
|
23
|
-
|
|
24
|
-
connect('unique-channel-name')
|
|
25
|
-
// listen for all messages
|
|
26
|
-
.on('message', e => console.log(e.message))
|
|
27
|
-
|
|
28
|
-
// or just our custom messages
|
|
29
|
-
.on('my-chat-message', ({ user, text }) => console.log(user, 'says:', text))
|
|
30
|
-
```
|
|
50
|
+
import { connect } from 'itty-sockets'
|
|
31
51
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
const channel = connect('unique-channel-name')
|
|
35
|
-
.send({ foo: 'bar' })
|
|
36
|
-
.send({ type: 'my-chat-message', user: 'Halsey', text: 'Meow!' })
|
|
52
|
+
// connect to the channel
|
|
53
|
+
const channel = connect('wss://example.com')
|
|
37
54
|
|
|
55
|
+
channel
|
|
56
|
+
// log all messages
|
|
57
|
+
.on('message', e => console.log(e.message))
|
|
38
58
|
|
|
39
|
-
|
|
59
|
+
// send some messages
|
|
60
|
+
.send('hey!')
|
|
61
|
+
.send({ foo: 'bar' })
|
|
40
62
|
```
|
|
41
63
|
|
|
64
|
+
## Optional use with `itty.ws` public, privacy-first server
|
|
65
|
+
`itty-sockets` has been designed to work with the public [itty.ws](https://itty.ws) service for even easier integrations. With this path, it's possible to add realtime features without hosting a backend server at all. We recommend using this for testing, prototyping, or simple projects. As your needs expand, you can always replace [itty.ws](https://itty.ws) with your own server(s) - nothing in the client changes.
|
|
42
66
|
|
|
43
|
-
|
|
67
|
+
Using [itty.ws](https://itty.ws) channels provides a few features to the client (fully typed by passing the `UseItty` generic to `connect`):
|
|
44
68
|
|
|
45
|
-
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
- chainable syntax (it's just handy)
|
|
69
|
+
1. `connect<UseItty>('my-channel')` - connect to a channel and go
|
|
70
|
+
1. adds `uid`, `alias`, and `date` to all messages
|
|
71
|
+
1. adds `join` and `leave` events to announce user changes
|
|
72
|
+
1. allows private messaging (by uid)
|
|
50
73
|
|
|
51
|
-
|
|
52
|
-
const ws = connect('wss://somewhere.else')
|
|
53
|
-
.on('message', console.log) // log all messages
|
|
54
|
-
.send({ foo: 'bar' }) // send immediately, no waiting
|
|
74
|
+
## Installation
|
|
55
75
|
|
|
56
|
-
|
|
57
|
-
|
|
76
|
+
**Option 1: Import**
|
|
77
|
+
```bash
|
|
78
|
+
npm install itty-sockets
|
|
58
79
|
```
|
|
59
80
|
|
|
60
|
-
<br />
|
|
61
|
-
|
|
62
|
-
# Getting Started
|
|
63
|
-
|
|
64
|
-
### 1. Import the [tiny client](https://npmjs.com/package/itty-sockets).
|
|
65
81
|
```ts
|
|
66
82
|
import { connect } from 'itty-sockets'
|
|
67
83
|
```
|
|
68
84
|
|
|
69
|
-
|
|
85
|
+
**Option 2: Just copy this snippet:**
|
|
70
86
|
<!-- BEGIN SNIPPET -->
|
|
71
87
|
```ts
|
|
72
|
-
let connect=(e,s={})=>{let
|
|
88
|
+
let connect=(e,s={})=>{let p,a=0,n=[],t=[],o={},l=()=>(p||(p=new WebSocket((/^wss?:/.test(e)?e:"wss://itty.ws/c/"+e)+"?"+new URLSearchParams(s)),p.onmessage=(e,s=JSON.parse(e.data),p=s?.message,a={...null==p?.[0]&&p,...s})=>{o[s?.type??p?.type]?.map(e=>e(a)),s?.type||o.message?.map(e=>e(a)),t.map(([e,s])=>e(a)&&s(a))},p.onopen=()=>(n.splice(0).map(e=>p?.send(e)),o.open?.map(e=>e()),a&&p?.close()),p.onclose=()=>(a=0,p=null,o.close?.map(e=>e()))),m),m=new Proxy(l,{get:(e,s)=>({open:l,close:()=>(1==p?.readyState?p.close():a=1,m),push:(e,s)=>(a=1,m.send(e,s)),send:(e,s)=>(e=JSON.stringify(e),e=s?""+s+""+e:e,1==p?.readyState?(p.send(e),m):(n.push(e),l())),on:(e,s)=>(s&&(e?.[0]?(o[e]??=[]).push(s):t.push([e,s])),l()),remove:(e,s,p=o[e],a=p?.indexOf(s)??-1)=>(~a&&p?.splice(a,1),l())}[s])});return m};
|
|
73
89
|
```
|
|
74
90
|
<!-- END SNIPPET -->
|
|
91
|
+
*Note: This will lose TypeScript support.*
|
|
75
92
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
### 2. Connect to a Channel (or external server)
|
|
79
|
-
To start, simply connect to a channel based on a unique name (this can be anything).
|
|
80
|
-
|
|
81
|
-
> **NOTE:** Pass a valid `ws://` or `wss://` URL as the channel identifier to bypass the public [ittysockets.io](https://ittysockets.io) service and use your own.
|
|
82
|
-
|
|
93
|
+
## Example 2 - Receiving basic messages
|
|
94
|
+
Assume the following simple client
|
|
83
95
|
```ts
|
|
84
96
|
import { connect } from 'itty-sockets'
|
|
85
97
|
|
|
86
|
-
|
|
87
|
-
const channel = connect('my-super-secret-channel')
|
|
88
|
-
|
|
89
|
-
// with options
|
|
90
|
-
const channel = connect('my-super-secret-channel', {
|
|
91
|
-
alias: 'Kevin', // optional non-unique identifier, visible in messages
|
|
92
|
-
announce: true, // shares your uid/alias with the channel on joining
|
|
93
|
-
echo: true // echos your own messages back to you (for testing)
|
|
94
|
-
})
|
|
95
|
-
|
|
96
|
-
// or any external JSON WebSocket server
|
|
97
|
-
const channel = connect('wss://somewhere.else.entirely')
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
#### Connection Options
|
|
101
|
-
|
|
102
|
-
| option | default value | description |
|
|
103
|
-
| --- | --- | --- |
|
|
104
|
-
| `{ alias: 'any-string' }` | `undefined` | An optional display name to be included in your messages. |
|
|
105
|
-
| `{ as: 'any-string' }` | `undefined` | An optional display name to be included in your message (same as alias). |
|
|
106
|
-
| `{ announce: true }` | `false` | Shares your uid/alias when joining/leaving. |
|
|
107
|
-
| `{ echo: true }` | `false` | Echos messages back to original sender (good for testing). |
|
|
108
|
-
|
|
109
|
-
<br />
|
|
110
|
-
|
|
111
|
-
### 3. Use the channel.
|
|
112
|
-
With the channel connected, simply call methods on it. Every method is chainable, returning the connection again (for more chaining).
|
|
113
|
-
|
|
114
|
-
| method | description | example |
|
|
115
|
-
| --- | --- | --- |
|
|
116
|
-
| **`.open()`** | Opens/re-opens the connection (manually, usually not needed). |
|
|
117
|
-
| **`.close()`** | Closes the connection. | `channel.close()` |
|
|
118
|
-
| **`.send(message: any)`** | Sends a message to the channel. This can be anything serializable with JSON.stringify. | `channel.send({ type: 'chat', text: 'hello' })` |
|
|
119
|
-
| **`.push(message: any)`** | Sends a message and immediately closes the connection. | `channel.push('Hello World!')` |
|
|
120
|
-
| **`.on(eventName: string, listener)`** | Add an event listener. | `channel.on('close', () => console.log('channel closed'))` |
|
|
121
|
-
| **`.remove(eventName: string, listener)`** | Remove an event listener. The 2nd argument must be the same listener function registered in the `on` method. | `channel.remove('open', myListenerFunction)` |
|
|
98
|
+
connect('wss://example.com')
|
|
122
99
|
|
|
123
|
-
|
|
100
|
+
// listen for every message
|
|
101
|
+
.on('message', console.log)
|
|
124
102
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
const channel = connect('my-secret-channel')
|
|
129
|
-
|
|
130
|
-
// add event listeners or send messages
|
|
131
|
-
|
|
132
|
-
channel
|
|
133
|
-
.on('message', ({ alias, uid, message, date }) =>
|
|
134
|
-
console.log(`${alias ?? uid} says: ${message} @ ${date.toLocaleTimeString()}`)
|
|
135
|
-
)
|
|
136
|
-
.on('join', ({ users }) =>
|
|
137
|
-
console.log(`A user has joined. There are now ${users} in the channel.`)
|
|
138
|
-
)
|
|
139
|
-
.on('leave', ({ users }) =>
|
|
140
|
-
console.log(`A user has left. There are now ${users} in the channel.`)
|
|
103
|
+
// and just { type: 'chat' }
|
|
104
|
+
.on('chat',
|
|
105
|
+
({ user, text }) => console.log(`${user} says: ${text}`)
|
|
141
106
|
)
|
|
142
|
-
.send('Hello World!') // this will queue up and send the message once connected
|
|
143
|
-
```
|
|
144
|
-
|
|
145
|
-
<br />
|
|
146
|
-
|
|
147
|
-
# Events
|
|
148
|
-
Each event can have multiple listeners registered on it. These are stable, even if the underlying WebSocket is broken/re-established.
|
|
149
|
-
| event name | description | payload | example |
|
|
150
|
-
| --- | --- | --- | --- |
|
|
151
|
-
| `message` | Triggered when receiving a message event. | [MessageEvent](#messageevent) | `channel.on<MessageType = any>('message', listener)` |
|
|
152
|
-
| `join` | Triggered when a user (including self) joins the channel. This alerts all users that someone has joined, and informs them of the total number of users in the channel. If the joining party connected with { announce: true }, their user details will be shared with the channel. | [JoinEvent](#joineevent) | `channel.on('join', e => console.log('There are now', e.users, 'users in the channel.')` |
|
|
153
|
-
| `leave` | Triggered when a user leaves the channel. This alerts all users that someone has left, and informs them of the total number of users in the channel. If the leaving party connected with { announce: true }, their user details will be shared with the channel. | [LeaveEvent](#leaveeevent) | `channel.on('leave', e => console.log('There are now', e.users, 'users in the channel.')` |
|
|
154
|
-
| `error` | Triggered when the server sends an error to the user. This is rare. | [ErrorEvent](#error) | `channel.on('error', e => console.error('IttySockets Error:', e.message)` |
|
|
155
|
-
| `open` | Triggered when the connection is established. | none | `channel.on('open', () => console.log('connected to channel.')` |
|
|
156
|
-
| `close` | Triggered when the connection is closed. | none | `channel.on('close', () => console.log('disconnected from channel.')` |
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
<br />
|
|
160
|
-
|
|
161
|
-
## EventTypes
|
|
162
|
-
All event types *other* than `message` are identified with a `type` attribute. For the sake of smaller payloads, `type` is omitted on normal messages.
|
|
163
|
-
|
|
164
|
-
#### MessageEvent
|
|
165
|
-
```ts
|
|
166
|
-
type MessageEvent = {
|
|
167
|
-
id: string // unique message ID
|
|
168
|
-
uid: string // unique user ID
|
|
169
|
-
alias: string? // optional display name
|
|
170
|
-
date: Date // JavaScript Date object
|
|
171
|
-
message: any // the message payload
|
|
172
|
-
}
|
|
173
107
|
```
|
|
174
108
|
|
|
175
|
-
|
|
176
|
-
```
|
|
177
|
-
|
|
178
|
-
type:
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
date: Date // date of event
|
|
182
|
-
users: number // new number of users in the channel
|
|
109
|
+
Now let's assume the following 2 messages are sent:
|
|
110
|
+
```json
|
|
111
|
+
{
|
|
112
|
+
"type": "chat",
|
|
113
|
+
"user": "Kevin",
|
|
114
|
+
"text": "Hey!"
|
|
183
115
|
}
|
|
184
116
|
```
|
|
185
117
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
uid?: string // uid of leaver if { announce: true }
|
|
191
|
-
alias: string? // alias of leaver if { announce: true }
|
|
192
|
-
date: Date // date of event
|
|
193
|
-
users: number // new number of users in the channel
|
|
118
|
+
```json
|
|
119
|
+
{
|
|
120
|
+
"date": 1754659171196,
|
|
121
|
+
"items": [1, 2, 3],
|
|
194
122
|
}
|
|
195
123
|
```
|
|
196
124
|
|
|
197
|
-
|
|
198
|
-
```ts
|
|
199
|
-
type MessageEvent = {
|
|
200
|
-
type: 'error' // error event identifier
|
|
201
|
-
date: Date // JavaScript Date object
|
|
202
|
-
message: any // the message payload
|
|
203
|
-
}
|
|
125
|
+
This will output the following to the console:
|
|
204
126
|
```
|
|
127
|
+
{ type: "chat", user: "Kevin", text: "Hey!" }
|
|
205
128
|
|
|
206
|
-
|
|
129
|
+
{ date: 1754659171196, items: [1, 2, 3] }
|
|
207
130
|
|
|
208
|
-
|
|
209
|
-
|
|
131
|
+
"Kevin says: Hey!"
|
|
132
|
+
```
|
|
210
133
|
|
|
211
|
-
|
|
134
|
+
## Example 3 - Reconnection
|
|
135
|
+
Using `itty-sockets`, you can safely fire `.open()` on the connection at any time, even if already connected. All listeners will continue to work perfectly once reconnected.
|
|
212
136
|
|
|
213
|
-
|
|
137
|
+
```ts
|
|
138
|
+
const channel = connect('wss://example.com')
|
|
139
|
+
.on('message', console.log)
|
|
140
|
+
.on('open', () => console.log('connected'))
|
|
141
|
+
.on('close', () => console.log('disconnected'))
|
|
214
142
|
|
|
215
|
-
|
|
143
|
+
// we'll just reconnect every second - this is safe!
|
|
144
|
+
setInterval(channel.open, 1000)
|
|
145
|
+
```
|
|
216
146
|
|
|
147
|
+
## See the [full documentation](https://itty.dev/itty-sockets) to continue your journey!
|
|
217
148
|
|
package/connect.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
type IttySocketEvent<BaseFormat> = BaseFormat extends UseItty ? 'open' | 'close' | 'message' | 'join' | 'leave' : 'open' | 'close' | 'message';
|
|
2
2
|
type Date = {
|
|
3
3
|
date: Date;
|
|
4
4
|
};
|
|
@@ -10,9 +10,9 @@ type OptionalUserDetails = {
|
|
|
10
10
|
uid?: string;
|
|
11
11
|
alias?: string;
|
|
12
12
|
};
|
|
13
|
-
export type
|
|
13
|
+
export type UseItty<MessageType = any> = {
|
|
14
14
|
message: MessageType;
|
|
15
|
-
} &
|
|
15
|
+
} & UserDetails & Date;
|
|
16
16
|
export type JoinEvent = {
|
|
17
17
|
type: 'join';
|
|
18
18
|
users: number;
|
|
@@ -25,30 +25,37 @@ export type ErrorEvent = {
|
|
|
25
25
|
type: 'error';
|
|
26
26
|
message: string;
|
|
27
27
|
} & Date;
|
|
28
|
-
export type SendMessage = <MessageFormat = any>(message: MessageFormat, recipient?: string) => IttySocket;
|
|
29
|
-
export type IttySocket = {
|
|
30
|
-
open: () => IttySocket;
|
|
31
|
-
close: () => IttySocket;
|
|
32
|
-
connected: boolean;
|
|
33
|
-
send: SendMessage;
|
|
34
|
-
push: SendMessage;
|
|
35
|
-
on(type: 'join', listener: (event: JoinEvent) => any): IttySocket;
|
|
36
|
-
on(type: 'leave', listener: (event: LeaveEvent) => any): IttySocket;
|
|
37
|
-
on(type: 'error', listener: (event: ErrorEvent) => any): IttySocket;
|
|
38
|
-
on<MessageFormat = any>(type: 'message', listener: (event: MessageEvent<MessageFormat>) => any): IttySocket;
|
|
39
|
-
on<MessageFormat = any>(type: string, listener: (event: MessageEvent<MessageFormat & {
|
|
40
|
-
type: string;
|
|
41
|
-
}>) => any): IttySocket;
|
|
42
|
-
on<MessageFormat = any>(type: (event?: any) => any, listener: (event: MessageEvent<MessageFormat & {
|
|
43
|
-
type: string;
|
|
44
|
-
}>) => any): IttySocket;
|
|
45
|
-
remove(type: IttySocketEvent, listener: () => any): IttySocket;
|
|
46
|
-
};
|
|
47
28
|
export type IttySocketOptions = {
|
|
48
29
|
as?: string;
|
|
49
30
|
alias?: string;
|
|
50
31
|
echo?: true;
|
|
51
32
|
announce?: true;
|
|
52
33
|
};
|
|
53
|
-
export
|
|
34
|
+
export interface IttySocketConnect {
|
|
35
|
+
<BaseFormat = object>(...args: BaseFormat extends UseItty ? [channelID: string, options?: IttySocketOptions] : [url: string, queryParams?: any]): IttySocket<BaseFormat>;
|
|
36
|
+
}
|
|
37
|
+
type UseIttyEvents<BaseFormat> = {
|
|
38
|
+
on(type: 'join', listener: (event: JoinEvent) => any): IttySocket<BaseFormat>;
|
|
39
|
+
on(type: 'leave', listener: (event: LeaveEvent) => any): IttySocket<BaseFormat>;
|
|
40
|
+
on(type: 'error', listener: (event: ErrorEvent) => any): IttySocket<BaseFormat>;
|
|
41
|
+
};
|
|
42
|
+
type SendMessage<BaseFormat> = BaseFormat extends UseItty ? <MessageFormat = any>(message: MessageFormat, uid?: string) => IttySocket<BaseFormat> : <MessageFormat = any>(message: MessageFormat) => IttySocket<BaseFormat>;
|
|
43
|
+
export type IttySocket<BaseFormat = object> = {
|
|
44
|
+
open: () => IttySocket<BaseFormat>;
|
|
45
|
+
close: () => IttySocket<BaseFormat>;
|
|
46
|
+
send: SendMessage<BaseFormat>;
|
|
47
|
+
push: SendMessage<BaseFormat>;
|
|
48
|
+
remove(type: IttySocketEvent<BaseFormat>, listener: () => any): IttySocket<BaseFormat>;
|
|
49
|
+
remove(type: string, listener: () => any): IttySocket<BaseFormat>;
|
|
50
|
+
on(type: 'open', listener: () => any): IttySocket<BaseFormat>;
|
|
51
|
+
on(type: 'close', listener: () => any): IttySocket<BaseFormat>;
|
|
52
|
+
on<MessageFormat = BaseFormat>(type: 'message', listener: (event: BaseFormat & MessageFormat) => any): IttySocket<BaseFormat>;
|
|
53
|
+
on<MessageFormat = BaseFormat>(type: string, listener: (event: BaseFormat & MessageFormat & {
|
|
54
|
+
type: string;
|
|
55
|
+
}) => any): IttySocket<BaseFormat>;
|
|
56
|
+
on<MessageFormat = BaseFormat>(type: (event?: any) => any, listener: (event: BaseFormat & MessageFormat & {
|
|
57
|
+
type: string;
|
|
58
|
+
}) => any): IttySocket<BaseFormat>;
|
|
59
|
+
} & (BaseFormat extends UseItty ? UseIttyEvents<BaseFormat> : object);
|
|
60
|
+
export declare let connect: IttySocketConnect;
|
|
54
61
|
export {};
|
package/connect.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";exports.connect=(e,s={})=>{let n,t=0,p=[],a=[],o={},c=()=>(n||(n=new WebSocket((/^wss?:/.test(e)?e:"wss://itty.ws/c/"+e)+"?"+new URLSearchParams(s)),n.onmessage=(e,s=JSON.parse(e.data),n=s?.message,t={...null==n?.[0]&&n,...s})=>{o[s?.type??n?.type]?.map(e=>e(t)),s?.type||o.message?.map(e=>e(t)),a.map(([e,s])=>e(t)&&s(t))},n.onopen=()=>(p.splice(0).map(e=>n?.send(e)),o.open?.map(e=>e()),t&&n?.close()),n.onclose=()=>(t=0,n=null,o.close?.map(e=>e()))),l),l=new Proxy(c,{get:(e,s)=>({open:c,close:()=>(1==n?.readyState?n.close():t=1,l),push:(e,s)=>(t=1,l.send(e,s)),send:(e,s)=>(e=JSON.stringify(e),e=s?""+s+""+e:e,1==n?.readyState?(n.send(e),l):(p.push(e),c())),on:(e,s)=>(s&&(e?.[0]?(o[e]??=[]).push(s):a.push([e,s])),c()),remove:(e,s,n=o[e],t=n?.indexOf(s)??-1)=>(~t&&n?.splice(t,1),c())}[s])});return l};
|
package/connect.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
let e=(e,s={})=>{let
|
|
1
|
+
let e=(e,s={})=>{let p,a=0,n=[],t=[],o={},l=()=>(p||(p=new WebSocket((/^wss?:/.test(e)?e:"wss://itty.ws/c/"+e)+"?"+new URLSearchParams(s)),p.onmessage=(e,s=JSON.parse(e.data),p=s?.message,a={...null==p?.[0]&&p,...s})=>{o[s?.type??p?.type]?.map(e=>e(a)),s?.type||o.message?.map(e=>e(a)),t.map(([e,s])=>e(a)&&s(a))},p.onopen=()=>(n.splice(0).map(e=>p?.send(e)),o.open?.map(e=>e()),a&&p?.close()),p.onclose=()=>(a=0,p=null,o.close?.map(e=>e()))),m),m=new Proxy(l,{get:(e,s)=>({open:l,close:()=>(1==p?.readyState?p.close():a=1,m),push:(e,s)=>(a=1,m.send(e,s)),send:(e,s)=>(e=JSON.stringify(e),e=s?""+s+""+e:e,1==p?.readyState?(p.send(e),m):(n.push(e),l())),on:(e,s)=>(s&&(e?.[0]?(o[e]??=[]).push(s):t.push([e,s])),l()),remove:(e,s,p=o[e],a=p?.indexOf(s)??-1)=>(~a&&p?.splice(a,1),l())}[s])});return m};export{e as connect};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "itty-sockets",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "WebSockets : simplified and minified.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -34,6 +34,6 @@
|
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
36
|
"@types/bun": "^1.2.3",
|
|
37
|
-
"itty-packager": "^1.6.
|
|
37
|
+
"itty-packager": "^1.6.10"
|
|
38
38
|
}
|
|
39
39
|
}
|
package/connect.cjs
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";exports.connect=(e,s={})=>{let t,a=0,n=[],p=[],o={},c=()=>(t||(t=new WebSocket((/^wss?:/.test(e)?e:"wss://ittysockets.io/c/"+e)+"?"+new URLSearchParams(s)),t.onmessage=(e,s=JSON.parse(e.data),t=s?.message,a={...null==t?.[0]&&t,...s,...s.date&&{date:new Date(s.date)}})=>{o[s?.type??t?.type]?.map(e=>e(a)),s?.type||o.message?.map(e=>e(a)),p.map(([e,s])=>e(a)&&s(a))},t.onopen=()=>(n.splice(0).map(e=>t?.send(e)),o.open?.map(e=>e()),a&&t?.close()),t.onclose=()=>(a=0,t=null,o.close?.map(e=>e()))),l),l=new Proxy(c,{get:(e,s)=>({open:c,close:()=>(1==t?.readyState?t.close():a=1,l),push:(e,s)=>(a=1,l.send(e,s)),send:(e,s)=>(e=JSON.stringify(e),e=s?"@@"+s+"@@"+e:e,1==t?.readyState?(t.send(e),l):(n.push(e),c())),on:(e,s)=>(s&&(e?.[0]?(o[e]??=[]).push(s):p.push([e,s])),c()),remove:(e,s,t=o[e],a=t?.indexOf(s)??-1)=>(~a&&t?.splice(a,1),c())}[s])});return l};
|