itty-sockets 0.8.2 → 0.9.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.
Files changed (3) hide show
  1. package/README.md +52 -96
  2. package/connect.d.ts +9 -2
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -14,125 +14,81 @@
14
14
  [![Issues](https://img.shields.io/github/issues/kwhitley/itty-sockets?style=flat-square)](https://github.com/kwhitley/itty-sockets/issues)
15
15
  [![Discord](https://img.shields.io/discord/832353585802903572?label=Discord&logo=Discord&style=flat-square&logoColor=fff)](https://discord.gg/53vyrZAu9u)
16
16
 
17
- ### [Documentation](https://itty.dev/itty-sockets)  |   [Discord](https://discord.gg/53vyrZAu9u)
17
+ ### [Full Documentation](https://itty.ws/docs)  |   [Discord](https://discord.gg/53vyrZAu9u)
18
18
 
19
19
  ---
20
20
 
21
- ### Say goodbye to WebSocket boilerplate.
21
+ # Zero-Config WebSockets.
22
22
 
23
- Your own wrapper is bigger, I promise.
23
+ No accounts, no API keys, nothing to deploy. Just connect and start sending.
24
24
 
25
- Or [optionally] go a step further and use the integrated [itty.ws](https://itty.ws) connection to send messages (zero-config, zero-tracking, 100% free).
25
+ ### **~466 bytes** • **free forever**
26
26
 
27
- ## Features ✨
28
- 1. **DX perks** - JSON-in/out, queued messages, easy-reconnect, chainable everything
29
- 1. **Works with *any* JSON-based WebSocket server** - it's just a raw WebSocket wrapper, after all
30
- 1. **Powerful routing** - easily handle your own message formats
31
- 1. **Type-safe message handling** - so your app knows what to expect
32
- 1. **No socket server needed** - Use [itty.ws](https://itty.ws) public channels to get started even faster
33
- 1. **Tiny** - under 500 bytes total
34
-
35
- ## Basic Example
36
- ```ts
37
- import { connect } from 'itty-sockets'
38
-
39
- // connect to the channel
40
- const channel = connect('wss://example.com')
41
-
42
- channel
43
- // log all messages
44
- .on('message', e => console.log(e.message))
45
-
46
- // send some messages
47
- .send('hey!')
48
- .send({ foo: 'bar' })
49
- ```
50
-
51
- ## Optional use with `itty.ws` public, privacy-first server
52
- `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.
27
+ <br />
53
28
 
54
- Using [itty.ws](https://itty.ws) channels provides a few features to the client (fully typed by passing the `UseItty` generic to `connect`):
29
+ > After working in realtime for quite a few years, I wanted something absolutely frictionless for prototyping. Spinning up socket servers or authenticating to services like Pusher/Ably involves overhead every time... so I built a service for myself (and everyone else). Then I designed this super-tiny WebSocket client that made even *that* side really easy to work with.
30
+ >
31
+ > Welcome to `itty-sockets`!
32
+ >
33
+ > ~ Kevin W
55
34
 
56
- 1. `connect<UseItty>('my-channel')` - connect to a channel and go
57
- 1. adds `uid`, `alias`, and `date` to all messages
58
- 1. adds `join` and `leave` events to announce user changes
59
- 1. allows private messaging (by uid)
35
+ <br />
60
36
 
61
- ## Installation
37
+ ## Features
38
+ - **Zero Configuration** - No accounts, no API keys, no server. Pick a channel name and you're live.
39
+ - **Zero Cost** - No tiers. No credit card. Built for the community.
40
+ - **Private by Default** - No logging, no tracking, no storage. Messages are relayed and forgotten.
41
+ - **Send Anything** - Strings, objects, arrays — anything JSON-serializable.
42
+ - **Access Control** - [Reserve a namespace](https://ittysockets.com/reservations) to control who can join or send on your channels.
43
+ - **Use Anywhere** - No vendor lock. This client works with *any* WebSocket server. Want to host your own? No problem.
44
+ - **Tiny Client** - Only 466 bytes gzipped.
62
45
 
63
- **Option 1: Import**
64
- ```bash
65
- npm install itty-sockets
66
- ```
46
+ <br />
67
47
 
48
+ ## Quick Start
68
49
  ```ts
69
- import { connect } from 'itty-sockets'
70
- ```
50
+ import { connect } from 'itty-sockets' // ~466 bytes
71
51
 
72
- **Option 2: Just copy this snippet:**
73
- <!-- BEGIN SNIPPET -->
74
- ```ts
75
- let connect=(e,s={})=>{let a,t,n=[],p={},o=()=>(a||(a=new WebSocket((/^wss?:/.test(e)?e:"wss://itty.ws/c/"+e)+"?"+new URLSearchParams(s)),a.onmessage=(e,s=JSON.parse(e.data),a=s?.message,t={...null==a?.[0]&&a,...s})=>[t.type,s.type?0:"message","*"].map(e=>p[e]?.map(e=>e(t))),a.onopen=()=>(n.splice(0).map(e=>a.send(e)),p.open?.map(e=>e(t)),t&&a?.close()),a.onclose=()=>(t=a=null,p.close?.map(e=>e(t)))),l),l={open:o,send:(e,s)=>(e=(s?`${s}`:"")+JSON.stringify(e),1&a?.readyState?a.send(e):n.push(e),o()),on:(e,s)=>((p[e?.[0]?e:"*"]??=[]).push(e?.[0]?s:a=>e?.(a)&&s(a)),o()),remove:(e,s)=>(p[e]=p[e]?.filter(e=>e!=s),l),close:()=>(1&a?.readyState?a.close():t=1,l),push:(e,s)=>(t=1,l.send(e,s))};return l};
52
+ connect('my-channel')
53
+ .on('message', ({ message }) => console.log(message))
54
+ .send('hello world') // strings
55
+ .send([1, 2, 3]) // arrays
56
+ .send({ foo: 'bar' }) // objects
76
57
  ```
77
- <!-- END SNIPPET -->
78
- *Note: This will lose TypeScript support.*
79
58
 
80
- ## Example 2 - Receiving basic messages
81
- Assume the following simple client
59
+ <br />
60
+
61
+ ## Chat Example
82
62
  ```ts
83
63
  import { connect } from 'itty-sockets'
84
64
 
85
- connect('wss://example.com')
86
-
87
- // listen for every message
88
- .on('message', console.log)
89
-
90
- // and just { type: 'chat' }
91
- .on('chat',
92
- ({ user, text }) => console.log(`${user} says: ${text}`)
93
- )
94
- ```
95
-
96
- Now let's assume the following 2 messages are sent:
97
- ```json
98
- // message 1
99
- {
100
- "type": "chat",
101
- "user": "Kevin",
102
- "text": "Hey!"
103
- }
104
- ```
105
-
106
- ```json
107
- // message 2
108
- {
109
- "date": 1754659171196,
110
- "items": [1, 2, 3],
111
- }
112
- ```
65
+ // two users, same channel
66
+ const alice = connect('chat-room', { as: 'Alice' })
67
+ const bob = connect('chat-room', { as: 'Bob' })
113
68
 
114
- This will output the following to the console:
115
- ```js
116
- // message 1
117
- { type: "chat", user: "Kevin", text: "Hey!" }
118
- "Kevin says: Hey!"
69
+ alice.on('message', ({ message, alias }) =>
70
+ console.log(`${alias}: ${message}`)
71
+ )
119
72
 
120
- // message 2
121
- { date: 1754659171196, items: [1, 2, 3] }
73
+ bob.send('hey Alice!')
74
+ // "Bob: hey Alice!"
122
75
  ```
123
76
 
124
- ## Example 3 - Reconnection
125
- 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.
77
+ <br />
126
78
 
127
- ```ts
128
- const channel = connect('wss://example.com')
129
- .on('message', console.log)
130
- .on('open', () => console.log('connected'))
131
- .on('close', () => console.log('disconnected'))
79
+ ## API at a Glance
132
80
 
133
- // we'll just reconnect every second - this is safe!
134
- setInterval(channel.open, 1000)
135
- ```
81
+ | Method | Description |
82
+ |---|---|
83
+ | `connect(channel, options?)` | Connect to a channel (or raw `wss://` URL) |
84
+ | `.on(type, listener)` | Listen for events (`'message'`, `'join'`, `'leave'`, `'open'`, `'close'`, `'error'`, custom types, or `'*'`) |
85
+ | `.on(filterFn, listener)` | Listen with a custom filter function |
86
+ | `.send(message, uid?)` | Send a message (optionally to a specific user) |
87
+ | `.push(message, uid?)` | Send a message and disconnect |
88
+ | `.open()` | (Re)connect — safe to call anytime, listeners are preserved |
89
+ | `.close()` | Disconnect |
90
+ | `.remove(type, listener)` | Remove a listener |
136
91
 
137
- ## See the [full documentation](https://itty.dev/itty-sockets) to continue your journey!
92
+ <br />
138
93
 
94
+ ## See the [full documentation](https://ittysockets.com/docs).
package/connect.d.ts CHANGED
@@ -15,11 +15,17 @@ export type MessageEvent<T = any> = {
15
15
  } & EventBase;
16
16
  export type JoinEvent = {
17
17
  type: 'join';
18
- users: number;
18
+ total: number;
19
+ self?: boolean;
20
+ users?: {
21
+ uid: string;
22
+ alias?: string;
23
+ self?: boolean;
24
+ }[];
19
25
  } & EventBase;
20
26
  export type LeaveEvent = {
21
27
  type: 'leave';
22
- users: number;
28
+ total: number;
23
29
  } & EventBase;
24
30
  export type ErrorEvent = {
25
31
  type: 'error';
@@ -30,6 +36,7 @@ export type IttySocketOptions = {
30
36
  alias?: string;
31
37
  echo?: true;
32
38
  announce?: true;
39
+ list?: true;
33
40
  };
34
41
  type EventUnion<Events> = {
35
42
  [K in Exclude<keyof Events & string, 'message'>]: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "itty-sockets",
3
- "version": "0.8.2",
3
+ "version": "0.9.1",
4
4
  "description": "WebSockets : simplified and minified.",
5
5
  "type": "module",
6
6
  "exports": {