svelte-adapter-uws 0.2.16 → 0.2.17
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 +70 -57
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -40,22 +40,27 @@ I've been loving Svelte and SvelteKit for a long time. I always wanted to expand
|
|
|
40
40
|
- [Seeding initial state](#seeding-initial-state)
|
|
41
41
|
|
|
42
42
|
**Plugins**
|
|
43
|
-
- [Replay (SSR gap)](#replay-
|
|
44
|
-
- [Presence](#presence
|
|
45
|
-
- [Typed channels](#typed-channels
|
|
46
|
-
- [Throttle/debounce](#throttledebounce
|
|
43
|
+
- [Replay (SSR gap)](#replay-ssr-gap)
|
|
44
|
+
- [Presence](#presence)
|
|
45
|
+
- [Typed channels](#typed-channels)
|
|
46
|
+
- [Throttle/debounce](#throttledebounce)
|
|
47
47
|
|
|
48
48
|
**Deployment & scaling**
|
|
49
49
|
- [Deploying with Docker](#deploying-with-docker)
|
|
50
50
|
- [Clustering](#clustering)
|
|
51
51
|
- [Performance](#performance)
|
|
52
52
|
|
|
53
|
+
**Examples**
|
|
54
|
+
- [Full example: real-time todo list](#full-example-real-time-todo-list)
|
|
55
|
+
|
|
53
56
|
**Help**
|
|
54
57
|
- [Troubleshooting](#troubleshooting)
|
|
55
58
|
- [License](#license)
|
|
56
59
|
|
|
57
60
|
---
|
|
58
61
|
|
|
62
|
+
**Getting started**
|
|
63
|
+
|
|
59
64
|
## Installation
|
|
60
65
|
|
|
61
66
|
### Starting from scratch
|
|
@@ -318,6 +323,8 @@ SSL_CERT=./cert.pem SSL_KEY=./key.pem PORT=443 node build
|
|
|
318
323
|
|
|
319
324
|
---
|
|
320
325
|
|
|
326
|
+
**Configuration**
|
|
327
|
+
|
|
321
328
|
## Adapter options
|
|
322
329
|
|
|
323
330
|
```js
|
|
@@ -443,6 +450,56 @@ SSL_CERT=./cert.pem SSL_KEY=./key.pem PORT=443 HOST=0.0.0.0 BODY_SIZE_LIMIT=10M
|
|
|
443
450
|
|
|
444
451
|
---
|
|
445
452
|
|
|
453
|
+
## TypeScript setup
|
|
454
|
+
|
|
455
|
+
Add the platform type to your `src/app.d.ts`:
|
|
456
|
+
|
|
457
|
+
```ts
|
|
458
|
+
import type { Platform as AdapterPlatform } from 'svelte-adapter-uws';
|
|
459
|
+
|
|
460
|
+
declare global {
|
|
461
|
+
namespace App {
|
|
462
|
+
interface Platform extends AdapterPlatform {}
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
export {};
|
|
467
|
+
```
|
|
468
|
+
|
|
469
|
+
Now `event.platform.publish()`, `event.platform.topic()`, etc. are fully typed.
|
|
470
|
+
|
|
471
|
+
---
|
|
472
|
+
|
|
473
|
+
## Svelte 4 support
|
|
474
|
+
|
|
475
|
+
This adapter supports both Svelte 4 and Svelte 5. All examples in this README use Svelte 5 syntax (`$props()`, runes). If you're on Svelte 4, here's how to translate:
|
|
476
|
+
|
|
477
|
+
**Svelte 5 (used in examples)**
|
|
478
|
+
```svelte
|
|
479
|
+
<script>
|
|
480
|
+
import { crud } from 'svelte-adapter-uws/client';
|
|
481
|
+
|
|
482
|
+
let { data } = $props();
|
|
483
|
+
const todos = crud('todos', data.todos);
|
|
484
|
+
</script>
|
|
485
|
+
```
|
|
486
|
+
|
|
487
|
+
**Svelte 4 equivalent**
|
|
488
|
+
```svelte
|
|
489
|
+
<script>
|
|
490
|
+
import { crud } from 'svelte-adapter-uws/client';
|
|
491
|
+
|
|
492
|
+
export let data;
|
|
493
|
+
const todos = crud('todos', data.todos);
|
|
494
|
+
</script>
|
|
495
|
+
```
|
|
496
|
+
|
|
497
|
+
The only difference is how you receive props. The client store API (`on`, `crud`, `lookup`, `latest`, `count`, `once`, `status`, `connect`) works identically in both versions - it uses `svelte/store` which hasn't changed.
|
|
498
|
+
|
|
499
|
+
---
|
|
500
|
+
|
|
501
|
+
**WebSocket deep dive**
|
|
502
|
+
|
|
446
503
|
## WebSocket handler (`hooks.ws`)
|
|
447
504
|
|
|
448
505
|
### No handler needed (simplest)
|
|
@@ -1184,7 +1241,7 @@ export async function subscribe(ws, topic, { platform }) {
|
|
|
1184
1241
|
|
|
1185
1242
|
Opt-in modules that build on top of the adapter's public API. They don't change any core behavior -- if you don't import them, they don't exist. Each plugin ships in its own subdirectory under `plugins/` with separate server and client entry points.
|
|
1186
1243
|
|
|
1187
|
-
### Replay
|
|
1244
|
+
### Replay (SSR gap)
|
|
1188
1245
|
|
|
1189
1246
|
When you combine SSR with WebSocket live updates, there's a gap between server-side data loading and the moment the client's WebSocket connects. Messages published during that window are lost.
|
|
1190
1247
|
|
|
@@ -1302,12 +1359,10 @@ const messages = onReplay('chat', { since: data.seq }).scan([], reducer);
|
|
|
1302
1359
|
|
|
1303
1360
|
---
|
|
1304
1361
|
|
|
1305
|
-
### Presence
|
|
1362
|
+
### Presence
|
|
1306
1363
|
|
|
1307
1364
|
Track who's connected to a topic in real time. Handles multi-tab dedup (same user with two tabs open = one presence entry), broadcasts join/leave events, and provides a live store on the client.
|
|
1308
1365
|
|
|
1309
|
-
Like the replay plugin, this is opt-in and has zero impact on the adapter core.
|
|
1310
|
-
|
|
1311
1366
|
#### Setup
|
|
1312
1367
|
|
|
1313
1368
|
Create a shared presence instance:
|
|
@@ -1413,7 +1468,7 @@ If no `key` field is found in the selected data (e.g. no auth), each connection
|
|
|
1413
1468
|
- **Single-worker only.** Each worker tracks its own presence. In clustered mode, the list reflects only the local worker's connections.
|
|
1414
1469
|
- **Requires subscription.** The client must subscribe to the topic (via `on()`, `crud()`, etc.) for the server's `subscribe` hook to fire. `presence('room')` alone shows you the list but doesn't register you as present unless you're also subscribed to `room`.
|
|
1415
1470
|
|
|
1416
|
-
### Typed channels
|
|
1471
|
+
### Typed channels
|
|
1417
1472
|
|
|
1418
1473
|
Define message schemas per topic so event names and data shapes are validated at publish time. Catches typos and shape mismatches before they reach the wire -- instead of silently sending garbage that the client ignores.
|
|
1419
1474
|
|
|
@@ -1497,7 +1552,7 @@ You can still use `crud()`, `lookup()`, `latest()`, etc. directly with the topic
|
|
|
1497
1552
|
- **Runtime only.** The validation happens at publish/send time, not at compile time. TypeScript generics give you autocomplete for event names, but data shape checking is runtime.
|
|
1498
1553
|
- **No dependency on Zod.** The plugin accepts any validator function or any object with a `.parse()` method. You bring your own validation library (or use plain functions).
|
|
1499
1554
|
|
|
1500
|
-
### Throttle/debounce
|
|
1555
|
+
### Throttle/debounce
|
|
1501
1556
|
|
|
1502
1557
|
Per-topic publish rate limiting. Wraps `platform.publish()` to coalesce rapid-fire updates (mouse position, typing indicators, live metrics). Sends the latest value at most once per interval. No timers to manage yourself.
|
|
1503
1558
|
|
|
@@ -1583,53 +1638,7 @@ t=260 [timer fires, 100ms] --> sends {q:"hel"}
|
|
|
1583
1638
|
|
|
1584
1639
|
---
|
|
1585
1640
|
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
Add the platform type to your `src/app.d.ts`:
|
|
1589
|
-
|
|
1590
|
-
```ts
|
|
1591
|
-
import type { Platform as AdapterPlatform } from 'svelte-adapter-uws';
|
|
1592
|
-
|
|
1593
|
-
declare global {
|
|
1594
|
-
namespace App {
|
|
1595
|
-
interface Platform extends AdapterPlatform {}
|
|
1596
|
-
}
|
|
1597
|
-
}
|
|
1598
|
-
|
|
1599
|
-
export {};
|
|
1600
|
-
```
|
|
1601
|
-
|
|
1602
|
-
Now `event.platform.publish()`, `event.platform.topic()`, etc. are fully typed.
|
|
1603
|
-
|
|
1604
|
-
---
|
|
1605
|
-
|
|
1606
|
-
## Svelte 4 support
|
|
1607
|
-
|
|
1608
|
-
This adapter supports both Svelte 4 and Svelte 5. All examples in this README use Svelte 5 syntax (`$props()`, runes). If you're on Svelte 4, here's how to translate:
|
|
1609
|
-
|
|
1610
|
-
**Svelte 5 (used in examples)**
|
|
1611
|
-
```svelte
|
|
1612
|
-
<script>
|
|
1613
|
-
import { crud } from 'svelte-adapter-uws/client';
|
|
1614
|
-
|
|
1615
|
-
let { data } = $props();
|
|
1616
|
-
const todos = crud('todos', data.todos);
|
|
1617
|
-
</script>
|
|
1618
|
-
```
|
|
1619
|
-
|
|
1620
|
-
**Svelte 4 equivalent**
|
|
1621
|
-
```svelte
|
|
1622
|
-
<script>
|
|
1623
|
-
import { crud } from 'svelte-adapter-uws/client';
|
|
1624
|
-
|
|
1625
|
-
export let data;
|
|
1626
|
-
const todos = crud('todos', data.todos);
|
|
1627
|
-
</script>
|
|
1628
|
-
```
|
|
1629
|
-
|
|
1630
|
-
The only difference is how you receive props. The client store API (`on`, `crud`, `lookup`, `latest`, `count`, `once`, `status`, `connect`) works identically in both versions - it uses `svelte/store` which hasn't changed.
|
|
1631
|
-
|
|
1632
|
-
---
|
|
1641
|
+
**Deployment & scaling**
|
|
1633
1642
|
|
|
1634
1643
|
## Deploying with Docker
|
|
1635
1644
|
|
|
@@ -1784,6 +1793,8 @@ node bench/run-compare.mjs # full comparison vs adapter-node + socket.io
|
|
|
1784
1793
|
|
|
1785
1794
|
---
|
|
1786
1795
|
|
|
1796
|
+
**Examples**
|
|
1797
|
+
|
|
1787
1798
|
## Full example: real-time todo list
|
|
1788
1799
|
|
|
1789
1800
|
Here's a complete example tying everything together.
|
|
@@ -1879,6 +1890,8 @@ Open the page in two browser tabs. Create, toggle, or delete a todo in one tab -
|
|
|
1879
1890
|
|
|
1880
1891
|
---
|
|
1881
1892
|
|
|
1893
|
+
**Help**
|
|
1894
|
+
|
|
1882
1895
|
## Troubleshooting
|
|
1883
1896
|
|
|
1884
1897
|
### "WebSocket works in production but not in dev"
|
package/package.json
CHANGED