itty-sockets 0.2.2 → 0.3.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 +145 -52
- package/connect.d.ts +33 -6
- package/connect.js +1 -1
- package/connect.mjs +1 -1
- package/connect.snippet.js +1 -1
- package/index.js +1 -1
- package/index.mjs +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -12,18 +12,31 @@
|
|
|
12
12
|
[](https://github.com/kwhitley/itty-sockets/issues)
|
|
13
13
|
[](https://discord.gg/53vyrZAu9u)
|
|
14
14
|
|
|
15
|
-
### [Documentation](https://
|
|
15
|
+
### [Documentation](https://ittysockets.io) | [Discord](https://discord.gg/53vyrZAu9u)
|
|
16
16
|
|
|
17
17
|
---
|
|
18
18
|
|
|
19
|
-
Tiny realtime messaging client in under
|
|
19
|
+
Tiny realtime messaging client in under 500 bytes. **No backend needed.**
|
|
20
20
|
|
|
21
|
-
##
|
|
21
|
+
## What does this solve?
|
|
22
|
+
|
|
23
|
+
Itty Sockets simplifies sending/receiving realtime data.
|
|
24
|
+
|
|
25
|
+
By pairing an ultra-tiny client (this) with the public **[ittysockets.io](https://ittysockets.io)** backend, you
|
|
26
|
+
can focus on sending/receiving messages, instead of building a transport layer.
|
|
27
|
+
|
|
28
|
+
The idea is simple:
|
|
29
|
+
|
|
30
|
+
1. One or more parties connect to a channel (by name).
|
|
31
|
+
2. They send/receive messages (this can be anything) in the channel.
|
|
32
|
+
3. That's it!
|
|
33
|
+
|
|
34
|
+
# Example
|
|
22
35
|
```ts
|
|
23
|
-
import { connect } from 'itty-sockets'
|
|
36
|
+
import { connect } from 'itty-sockets'
|
|
24
37
|
|
|
25
|
-
// connect to a channel
|
|
26
|
-
const foo = connect('my-secret-room-name'
|
|
38
|
+
// connect to a channel
|
|
39
|
+
const foo = connect('my-secret-room-name')
|
|
27
40
|
|
|
28
41
|
foo
|
|
29
42
|
// we can listen for messages
|
|
@@ -35,73 +48,112 @@ foo
|
|
|
35
48
|
.send({ foo: 'bar' }) // { foo: "bar" }
|
|
36
49
|
```
|
|
37
50
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
- Simple and powerful API for sending and receiving messages & data.
|
|
41
|
-
- No backend service needed. Ours is fast and private.
|
|
42
|
-
- Full TypeScript support, including custom types for messages.
|
|
43
|
-
- Prevents WebSocket race conditions. Automatically connects when needed to send/listen.
|
|
44
|
-
- Chainable. Every method returns the channel again.
|
|
45
|
-
- Ultra-tiny. It's an itty library, after all.
|
|
51
|
+
### Important Considerations
|
|
46
52
|
|
|
47
|
-
|
|
53
|
+
1. **There is no history/replay/storage.** It's a live stream only.
|
|
54
|
+
2. **We don't authenticate.** [ittysockets.io](https://ittysockets.io) leverages security through obfuscation (a near-infinite number of channel names). Choose a more unique channel for more privacy. Need more? Consider encrypting/decrypting your payloads before transmission (this is easy).
|
|
55
|
+
3. **There are no guarantees of delivery.** While [ittysockets.io](https://ittysockets.io) is *extremely* stable, it's a free public service that is provided without any guarantees of delivery or uptime. Manage risk accordingly.
|
|
48
56
|
|
|
49
|
-
|
|
50
|
-
It's powered by [ittysockets.io](https://ittysockets.io), a free, fast, and private public service. The idea is simple:
|
|
51
|
-
|
|
52
|
-
1. Connect to a channel by name (creates a new channel if it doesn't exist).
|
|
53
|
-
2. Send/receive messages in the channel.
|
|
54
|
-
3. That's it!
|
|
55
|
-
|
|
56
|
-
This is an easy way to transmit messages between clients, but comes with limitations and considerations:
|
|
57
|
-
|
|
58
|
-
1. **There is no history/replay.** It's a live stream.
|
|
59
|
-
2. **We don't authenticate.** Itty Sockets leverages security merely through obfuscation (a near-infinite number of channel names). Use a secure channel name and/or encode your payloads if concerned about eavesdropping. Add your own authentication layer, if needed.
|
|
60
|
-
3. **There are no guarantees of delivery.** Itty Sockets is not a traditional messaging system. It's a public service that is provided without any guarantees of delivery, order, or persistence. Use it for real-time communication, not for mission-critical data.
|
|
61
|
-
|
|
62
|
-
### Privacy Concerns
|
|
63
|
-
**We do not store any messages or data**
|
|
64
|
-
There is intentionally no message logging or tracking of any kind. It's easier for us that way, and safer for you.
|
|
57
|
+
<br />
|
|
65
58
|
|
|
66
|
-
|
|
59
|
+
# Getting Started
|
|
67
60
|
|
|
68
|
-
|
|
61
|
+
### 1. Import the [tiny client](https://npmjs.com/package/itty-sockets).
|
|
62
|
+
```ts
|
|
63
|
+
import { connect } from 'itty-sockets'
|
|
64
|
+
```
|
|
69
65
|
|
|
66
|
+
...or simply paste this into your environment/console:
|
|
70
67
|
<!-- BEGIN SNIPPET -->
|
|
71
68
|
```ts
|
|
72
|
-
let connect=(e,
|
|
69
|
+
let connect=(e,o={})=>{let s,t=[],n=0,r={},a=()=>(s||(s=new WebSocket(`wss://ittysockets.io/r/${e}?${new URLSearchParams(o)}`),s.onopen=()=>{for(;t.length;)s?.send(t.shift());for(let e of r.open??[])e();n&&s?.close()},s.onmessage=(e,o=JSON.parse(e.data))=>{for(let e of r[o.type??"message"]??[])e({...o,date:new Date(o.date)})},s.onclose=()=>{n=0,s=null;for(let e of r.close??[])e()}),l);const l=new Proxy(a,{get:(e,o)=>({open:a,close:()=>(1==s?.readyState?s.close():n=1,l),send:(e,o)=>(e=JSON.stringify(e),e=o?`@@${o}@@${e}`:e,1==s?.readyState?(s.send(e),l):(t.push(e),a())),push:(e,o)=>(n=1,l.send(e,o)),on:(e,o)=>((r[e]??=[]).push(o),a()),remove:(e,o,s=r[e],t=s?.indexOf(o)??-1)=>(~t&&s?.splice(t,1),a())}[o])});return l};
|
|
73
70
|
```
|
|
74
71
|
<!-- END SNIPPET -->
|
|
75
72
|
|
|
76
|
-
|
|
73
|
+
<br />
|
|
74
|
+
|
|
75
|
+
### 2. Create a Channel
|
|
76
|
+
To start, simply connect to a channel based on a unique name (this can be anything).
|
|
77
|
+
|
|
77
78
|
```ts
|
|
78
|
-
|
|
79
|
-
|
|
79
|
+
import { connect } from 'itty-sockets'
|
|
80
|
+
|
|
81
|
+
// basic connection
|
|
82
|
+
const channel = connect('my-channels/my-super-secret-channel')
|
|
83
|
+
|
|
84
|
+
// with options
|
|
85
|
+
const channel = connect('my-channels/my-super-secret-channel', {
|
|
86
|
+
as: 'Kevin',
|
|
87
|
+
announce: true,
|
|
88
|
+
echo: true
|
|
89
|
+
})
|
|
80
90
|
```
|
|
81
91
|
|
|
82
|
-
|
|
92
|
+
#### Connection Options
|
|
83
93
|
|
|
84
|
-
|
|
|
94
|
+
| option | default value | description |
|
|
85
95
|
| --- | --- | --- |
|
|
86
|
-
|
|
|
87
|
-
|
|
|
88
|
-
|
|
|
89
|
-
|
|
|
90
|
-
| **.push(message)** | Sends a message and closes the connection | `channel.push({ type: 'goodbye' })` |
|
|
91
|
-
| **.on('message', listener)** | Adds a message listener (multiple allowed) | `channel.on('message', event => console.log(event))` |
|
|
92
|
-
| **.on('open', listener)** | Executes a listener on channel open (one allowed) | `channel.on('open', () => console.log('channel opened'))` |
|
|
93
|
-
| **.on('close', listener)** | Executes a listener on channel close (one allowed) | `channel.on('close', () => console.log('channel closed'))` |
|
|
96
|
+
| `{ alias: 'any-string' }` | `undefined` | An optional display name to be included in your messages. |
|
|
97
|
+
| `{ as: 'any-string' }` | `undefined` | An optional display name to be included in your message (same as alias). |
|
|
98
|
+
| `{ announce: true }` | `false` | Shares your uid/alias when joining/leaving. | `false` |
|
|
99
|
+
| `{ echo: true }` | `false` | Echos messages back to original sender (good for testing). |
|
|
94
100
|
|
|
101
|
+
<br />
|
|
95
102
|
|
|
96
|
-
###
|
|
103
|
+
### 3. Use the channel.
|
|
104
|
+
With the channel connected, simply call methods on it. Every method is chainable, returning the connection again (for more chaining).
|
|
97
105
|
|
|
98
|
-
|
|
|
106
|
+
| method | description | example |
|
|
107
|
+
| --- | --- | --- |
|
|
108
|
+
| **`.open()`** | Opens/re-opens the connection (manually, usually not needed). |
|
|
109
|
+
| **`.close()`** | Closes the connection. | `channel.close()` |
|
|
110
|
+
| **`.send(message: any)`** | Sends a message to the channel. This can be anything serializable with JSON.stringify. | `channel.send({ type: 'chat', text: 'hello' })` |
|
|
111
|
+
| **`.push(message: any)`** | Sends a message and immediately closes the connection. | `channel.push('Hello World!')` |
|
|
112
|
+
| **`.on(eventName: string, listener)`** | Add an event listener. | `channel.on('close', () => console.log('channel closed'))` |
|
|
113
|
+
| **`.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)` |
|
|
114
|
+
|
|
115
|
+
#### Example
|
|
116
|
+
|
|
117
|
+
```ts
|
|
118
|
+
|
|
119
|
+
// connect
|
|
120
|
+
const channel = connect('my-secret-channel')
|
|
121
|
+
|
|
122
|
+
// add event listeners or send messages
|
|
123
|
+
|
|
124
|
+
channel
|
|
125
|
+
.on('message', ({ alias, uid, message, date }) =>
|
|
126
|
+
console.log(`${alias ?? uid} says: ${message} @ ${date.toLocaleTimeString()}`)
|
|
127
|
+
)
|
|
128
|
+
.on('join', ({ users }) =>
|
|
129
|
+
console.log(`A user has joined. There are now ${users} in the channel.`)
|
|
130
|
+
)
|
|
131
|
+
.on('leave', ({ users }) =>
|
|
132
|
+
console.log(`A user has left. There are now ${users} in the channel.`)
|
|
133
|
+
)
|
|
134
|
+
.send('Hello World!') // this will queue up and send the message once connected
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
<br />
|
|
138
|
+
|
|
139
|
+
# Events
|
|
140
|
+
Each event can have multiple listeners registered on it. These are stable, even if the underlying WebSocket is broken/re-established.
|
|
141
|
+
| event name | description | payload | example |
|
|
99
142
|
| --- | --- | --- | --- |
|
|
100
|
-
|
|
|
101
|
-
|
|
|
143
|
+
| `message` | Triggered when receiving a message event. | [MessageEvent](#messageevent) | `channel.on<MessageType = any>('message', listener)` |
|
|
144
|
+
| `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.')` |
|
|
145
|
+
| `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.')` |
|
|
146
|
+
| `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)` |
|
|
147
|
+
| `open` | Triggered when the connection is established. | none | `channel.on('open', () => console.log('connected to channel.')` |
|
|
148
|
+
| `close` | Triggered when the connection is closed. | none | `channel.on('close', () => console.log('disconnected from channel.')` |
|
|
102
149
|
|
|
103
150
|
|
|
104
|
-
|
|
151
|
+
<br />
|
|
152
|
+
|
|
153
|
+
## EventTypes
|
|
154
|
+
All event types *other* than `message` are identified with a `type` attribute. For the sake of smaller payloads, `type` is omitted on normal messages.
|
|
155
|
+
|
|
156
|
+
#### MessageEvent
|
|
105
157
|
```ts
|
|
106
158
|
type MessageEvent = {
|
|
107
159
|
id: string // unique message ID
|
|
@@ -112,5 +164,46 @@ type MessageEvent = {
|
|
|
112
164
|
}
|
|
113
165
|
```
|
|
114
166
|
|
|
167
|
+
#### JoinEvent <a id="joinevent" />
|
|
168
|
+
```ts
|
|
169
|
+
type JoinEvent = {
|
|
170
|
+
type: 'join' // type of event
|
|
171
|
+
uid?: string // uid of joiner if { announce: true }
|
|
172
|
+
alias: string? // alias of joiner if { announce: true }
|
|
173
|
+
date: Date // date of event
|
|
174
|
+
users: number // new number of users in the channel
|
|
175
|
+
}
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
#### LeaveEvent
|
|
179
|
+
```ts
|
|
180
|
+
type LeaveEvent = {
|
|
181
|
+
type: 'leave' // type of event
|
|
182
|
+
uid?: string // uid of leaver if { announce: true }
|
|
183
|
+
alias: string? // alias of leaver if { announce: true }
|
|
184
|
+
date: Date // date of event
|
|
185
|
+
users: number // new number of users in the channel
|
|
186
|
+
}
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
#### ErrorEvent
|
|
190
|
+
```ts
|
|
191
|
+
type MessageEvent = {
|
|
192
|
+
type: 'error' // error event identifier
|
|
193
|
+
date: Date // JavaScript Date object
|
|
194
|
+
message: any // the message payload
|
|
195
|
+
}
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
<br />
|
|
199
|
+
|
|
200
|
+
# Privacy
|
|
201
|
+
[ittysockets.io](https://ittysockets.io) is a free, public-use, but _private_ service.
|
|
202
|
+
|
|
203
|
+
It was designed by me (a developer), to help myself and other developers achieve cool things. As such:
|
|
204
|
+
|
|
205
|
+
1. Your messages are never transmitted to anything other than the sockets on the channel you're connected to. No third-party service, no loggers, no storage (local or otherwise), not even a collection in memory. This protects your privacy/data, but keeps my costs to virtually zero, allowing me to share this service with the world... hopefully indefinitely.
|
|
206
|
+
|
|
207
|
+
2. I ask that you please use the channels responsibly. We're all sharing this space!
|
|
115
208
|
|
|
116
209
|
|
package/connect.d.ts
CHANGED
|
@@ -1,10 +1,30 @@
|
|
|
1
|
-
export type
|
|
2
|
-
|
|
1
|
+
export type IttySocketEvent = 'open' | 'close' | 'message' | 'join' | 'leave';
|
|
2
|
+
type Date = {
|
|
3
3
|
date: Date;
|
|
4
|
+
};
|
|
5
|
+
type UserDetails = {
|
|
6
|
+
uid: string;
|
|
7
|
+
alias?: string;
|
|
8
|
+
};
|
|
9
|
+
type OptionalUserDetails = {
|
|
4
10
|
uid?: string;
|
|
5
11
|
alias?: string;
|
|
6
|
-
message: MessageType;
|
|
7
12
|
};
|
|
13
|
+
export type MessageEvent<MessageType = any> = {
|
|
14
|
+
message: MessageType;
|
|
15
|
+
} & Date & UserDetails;
|
|
16
|
+
export type JoinEvent = {
|
|
17
|
+
type: 'join';
|
|
18
|
+
users: number;
|
|
19
|
+
} & Date & OptionalUserDetails;
|
|
20
|
+
export type LeaveEvent = {
|
|
21
|
+
type: 'leave';
|
|
22
|
+
users: number;
|
|
23
|
+
} & Date & OptionalUserDetails;
|
|
24
|
+
export type ErrorEvent = {
|
|
25
|
+
type: 'error';
|
|
26
|
+
message: string;
|
|
27
|
+
} & Date;
|
|
8
28
|
export type SendMessage = <MessageFormat = any>(message: MessageFormat, recipient?: string) => IttySocket;
|
|
9
29
|
export type IttySocket = {
|
|
10
30
|
open: () => IttySocket;
|
|
@@ -12,11 +32,18 @@ export type IttySocket = {
|
|
|
12
32
|
connected: boolean;
|
|
13
33
|
send: SendMessage;
|
|
14
34
|
push: SendMessage;
|
|
15
|
-
on
|
|
35
|
+
on<MessageFormat = any>(type: 'message', listener: (event: MessageEvent<MessageFormat>) => any): IttySocket;
|
|
36
|
+
on(type: 'join', listener: (event: JoinEvent) => any): IttySocket;
|
|
37
|
+
on(type: 'leave', listener: (event: LeaveEvent) => any): IttySocket;
|
|
38
|
+
on(type: 'error', listener: (event: ErrorEvent) => any): IttySocket;
|
|
39
|
+
on(type: Exclude<IttySocketEvent, 'message'>, listener: () => any): IttySocket;
|
|
40
|
+
remove(type: IttySocketEvent, listener: () => any): IttySocket;
|
|
16
41
|
};
|
|
17
42
|
export type IttySocketOptions = {
|
|
18
43
|
as?: string;
|
|
19
44
|
alias?: string;
|
|
20
|
-
echo?:
|
|
45
|
+
echo?: true;
|
|
46
|
+
announce?: true;
|
|
21
47
|
};
|
|
22
|
-
export declare const connect: (
|
|
48
|
+
export declare const connect: (channelId: string, options?: IttySocketOptions) => IttySocket;
|
|
49
|
+
export {};
|
package/connect.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";exports.connect=(e,s={})=>{let t
|
|
1
|
+
"use strict";exports.connect=(e,s={})=>{let o,t=[],n=0,r={},a=()=>(o||(o=new WebSocket(`wss://ittysockets.io/r/${e}?${new URLSearchParams(s)}`),o.onopen=()=>{for(;t.length;)o?.send(t.shift());for(let e of r.open??[])e();n&&o?.close()},o.onmessage=(e,s=JSON.parse(e.data))=>{for(let e of r[s.type??"message"]??[])e({...s,date:new Date(s.date)})},o.onclose=()=>{n=0,o=null;for(let e of r.close??[])e()}),c);const c=new Proxy(a,{get:(e,s)=>({open:a,close:()=>(1==o?.readyState?o.close():n=1,c),send:(e,s)=>(e=JSON.stringify(e),e=s?`@@${s}@@${e}`:e,1==o?.readyState?(o.send(e),c):(t.push(e),a())),push:(e,s)=>(n=1,c.send(e,s)),on:(e,s)=>((r[e]??=[]).push(s),a()),remove:(e,s,o=r[e],t=o?.indexOf(s)??-1)=>(~t&&o?.splice(t,1),a())}[s])});return c};
|
package/connect.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
const e=(e,
|
|
1
|
+
const e=(e,o={})=>{let s,t=[],n=0,r={},a=()=>(s||(s=new WebSocket(`wss://ittysockets.io/r/${e}?${new URLSearchParams(o)}`),s.onopen=()=>{for(;t.length;)s?.send(t.shift());for(let e of r.open??[])e();n&&s?.close()},s.onmessage=(e,o=JSON.parse(e.data))=>{for(let e of r[o.type??"message"]??[])e({...o,date:new Date(o.date)})},s.onclose=()=>{n=0,s=null;for(let e of r.close??[])e()}),l);const l=new Proxy(a,{get:(e,o)=>({open:a,close:()=>(1==s?.readyState?s.close():n=1,l),send:(e,o)=>(e=JSON.stringify(e),e=o?`@@${o}@@${e}`:e,1==s?.readyState?(s.send(e),l):(t.push(e),a())),push:(e,o)=>(n=1,l.send(e,o)),on:(e,o)=>((r[e]??=[]).push(o),a()),remove:(e,o,s=r[e],t=s?.indexOf(o)??-1)=>(~t&&s?.splice(t,1),a())}[o])});return l};export{e as connect};
|
package/connect.snippet.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
let connect=(e,
|
|
1
|
+
let connect=(e,o={})=>{let s,t=[],n=0,r={},a=()=>(s||(s=new WebSocket(`wss://ittysockets.io/r/${e}?${new URLSearchParams(o)}`),s.onopen=()=>{for(;t.length;)s?.send(t.shift());for(let e of r.open??[])e();n&&s?.close()},s.onmessage=(e,o=JSON.parse(e.data))=>{for(let e of r[o.type??"message"]??[])e({...o,date:new Date(o.date)})},s.onclose=()=>{n=0,s=null;for(let e of r.close??[])e()}),l);const l=new Proxy(a,{get:(e,o)=>({open:a,close:()=>(1==s?.readyState?s.close():n=1,l),send:(e,o)=>(e=JSON.stringify(e),e=o?`@@${o}@@${e}`:e,1==s?.readyState?(s.send(e),l):(t.push(e),a())),push:(e,o)=>(n=1,l.send(e,o)),on:(e,o)=>((r[e]??=[]).push(o),a()),remove:(e,o,s=r[e],t=s?.indexOf(o)??-1)=>(~t&&s?.splice(t,1),a())}[o])});return l};
|
package/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";exports.connect=(e,s={})=>{let t
|
|
1
|
+
"use strict";exports.connect=(e,s={})=>{let o,t=[],n=0,r={},a=()=>(o||(o=new WebSocket(`wss://ittysockets.io/r/${e}?${new URLSearchParams(s)}`),o.onopen=()=>{for(;t.length;)o?.send(t.shift());for(let e of r.open??[])e();n&&o?.close()},o.onmessage=(e,s=JSON.parse(e.data))=>{for(let e of r[s.type??"message"]??[])e({...s,date:new Date(s.date)})},o.onclose=()=>{n=0,o=null;for(let e of r.close??[])e()}),c);const c=new Proxy(a,{get:(e,s)=>({open:a,close:()=>(1==o?.readyState?o.close():n=1,c),send:(e,s)=>(e=JSON.stringify(e),e=s?`@@${s}@@${e}`:e,1==o?.readyState?(o.send(e),c):(t.push(e),a())),push:(e,s)=>(n=1,c.send(e,s)),on:(e,s)=>((r[e]??=[]).push(s),a()),remove:(e,s,o=r[e],t=o?.indexOf(s)??-1)=>(~t&&o?.splice(t,1),a())}[s])});return c};
|
package/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
const e=(e,
|
|
1
|
+
const e=(e,o={})=>{let s,t=[],n=0,r={},a=()=>(s||(s=new WebSocket(`wss://ittysockets.io/r/${e}?${new URLSearchParams(o)}`),s.onopen=()=>{for(;t.length;)s?.send(t.shift());for(let e of r.open??[])e();n&&s?.close()},s.onmessage=(e,o=JSON.parse(e.data))=>{for(let e of r[o.type??"message"]??[])e({...o,date:new Date(o.date)})},s.onclose=()=>{n=0,s=null;for(let e of r.close??[])e()}),l);const l=new Proxy(a,{get:(e,o)=>({open:a,close:()=>(1==s?.readyState?s.close():n=1,l),send:(e,o)=>(e=JSON.stringify(e),e=o?`@@${o}@@${e}`:e,1==s?.readyState?(s.send(e),l):(t.push(e),a())),push:(e,o)=>(n=1,l.send(e,o)),on:(e,o)=>((r[e]??=[]).push(o),a()),remove:(e,o,s=r[e],t=s?.indexOf(o)??-1)=>(~t&&s?.splice(t,1),a())}[o])});return l};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.3.0",
|
|
4
4
|
"description": "Tiny realtime messaging client in under 450 bytes. No backend needed.",
|
|
5
5
|
"main": "./sockets.js",
|
|
6
6
|
"module": "./sockets.mjs",
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"prerelease": "bun run verify",
|
|
13
13
|
"prerelease:next": "bun run verify",
|
|
14
14
|
"prebuild": "rimraf dist && mkdir dist",
|
|
15
|
-
"build": "rollup -c &&
|
|
15
|
+
"build": "rollup -c && bun readme-inject.mjs",
|
|
16
16
|
"release": "release --tag --push --patch --src=dist",
|
|
17
17
|
"release:next": "release --tag --push --type=next --src=dist"
|
|
18
18
|
},
|