svelte-adapter-uws 0.2.21 → 0.2.23

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 CHANGED
@@ -1477,13 +1477,18 @@ export function upgrade({ cookies }) {
1477
1477
  return { id: user.id, name: user.name };
1478
1478
  }
1479
1479
 
1480
- export function subscribe(ws, topic, { platform }) {
1481
- presence.join(ws, topic, platform);
1482
- }
1480
+ export const { subscribe, close } = presence.hooks;
1481
+ ```
1483
1482
 
1484
- export function close(ws, { platform }) {
1485
- presence.leave(ws, platform);
1483
+ The `hooks` object handles everything: `subscribe` calls `join()` for regular topics and sends the current presence list for `__presence:*` topics, `close` calls `leave()`. If you need custom logic (auth gating, topic filtering), wrap the hook:
1484
+
1485
+ ```js
1486
+ export function subscribe(ws, topic, ctx) {
1487
+ if (topic === 'vip' && !ws.getUserData().isVip) return false;
1488
+ presence.hooks.subscribe(ws, topic, ctx);
1486
1489
  }
1490
+
1491
+ export const close = presence.hooks.close;
1487
1492
  ```
1488
1493
 
1489
1494
  Use it on the client:
@@ -1527,6 +1532,7 @@ const presence = createPresence({
1527
1532
  select: (userData) => userData // extract public fields (default: full userData)
1528
1533
  });
1529
1534
 
1535
+ presence.hooks // ready-made { subscribe, close } hooks
1530
1536
  presence.join(ws, topic, platform) // add user to topic (call from subscribe hook)
1531
1537
  presence.leave(ws, platform) // remove from all topics (call from close hook)
1532
1538
  presence.sync(ws, topic, platform) // send list without joining (for observers)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "svelte-adapter-uws",
3
- "version": "0.2.21",
3
+ "version": "0.2.23",
4
4
  "description": "SvelteKit adapter for uWebSockets.js - high-performance C++ HTTP server with built-in WebSocket support",
5
5
  "author": "Kevin Radziszewski",
6
6
  "license": "MIT",
@@ -115,6 +115,25 @@ export interface PresenceTracker<Selected extends Record<string, any> = Record<s
115
115
 
116
116
  /** Clear all presence tracking state. */
117
117
  clear(): void;
118
+
119
+ /**
120
+ * Ready-made WebSocket hooks for zero-config presence.
121
+ *
122
+ * `subscribe` handles both regular topics (calls `join`) and `__presence:*`
123
+ * topics (calls `sync` so the client gets the current list immediately).
124
+ * `close` calls `leave`.
125
+ *
126
+ * @example
127
+ * ```js
128
+ * // src/hooks.ws.js
129
+ * import { presence } from '$lib/server/presence';
130
+ * export const { subscribe, close } = presence.hooks;
131
+ * ```
132
+ */
133
+ hooks: {
134
+ subscribe(ws: WebSocket<any>, topic: string, ctx: { platform: Platform }): void;
135
+ close(ws: WebSocket<any>, ctx: { platform: Platform }): void;
136
+ };
118
137
  }
119
138
 
120
139
  /**
@@ -39,6 +39,10 @@
39
39
  * Get the number of unique users present on a topic.
40
40
  * @property {() => void} clear -
41
41
  * Clear all presence tracking state.
42
+ * @property {{ subscribe: (ws: any, topic: string, ctx: { platform: import('../../index.js').Platform }) => void, close: (ws: any, ctx: { platform: import('../../index.js').Platform }) => void }} hooks -
43
+ * Ready-made WebSocket hooks. Handles join for regular topics, sync for
44
+ * __presence:* topics, and leave on close. Spread into hooks.ws.js for
45
+ * zero-config presence.
42
46
  */
43
47
 
44
48
  /**
@@ -60,16 +64,23 @@
60
64
  *
61
65
  * @example
62
66
  * ```js
63
- * // src/hooks.ws.js
67
+ * // src/hooks.ws.js - zero-config (just spread hooks)
64
68
  * import { presence } from '$lib/server/presence';
65
69
  *
66
- * export function subscribe(ws, topic, { platform }) {
67
- * presence.join(ws, topic, platform);
68
- * }
70
+ * export const { subscribe, close } = presence.hooks;
71
+ * ```
72
+ *
73
+ * @example
74
+ * ```js
75
+ * // src/hooks.ws.js - with custom logic
76
+ * import { presence } from '$lib/server/presence';
69
77
  *
70
- * export function close(ws, { platform }) {
71
- * presence.leave(ws, platform);
78
+ * export function subscribe(ws, topic, ctx) {
79
+ * if (topic === 'vip' && !ws.getUserData().isVip) return false;
80
+ * presence.hooks.subscribe(ws, topic, ctx);
72
81
  * }
82
+ *
83
+ * export const close = presence.hooks.close;
73
84
  * ```
74
85
  *
75
86
  * @example
@@ -115,7 +126,8 @@ export function createPresence(options = {}) {
115
126
  return '__conn:' + (++connCounter);
116
127
  }
117
128
 
118
- return {
129
+ /** @type {PresenceTracker} */
130
+ const tracker = {
119
131
  join(ws, topic, platform) {
120
132
  // Skip internal topics to prevent recursion when the subscribe
121
133
  // hook fires for __presence:* subscriptions
@@ -226,6 +238,24 @@ export function createPresence(options = {}) {
226
238
  wsTopics.clear();
227
239
  topicPresence.clear();
228
240
  connCounter = 0;
241
+ },
242
+
243
+ hooks: {
244
+ subscribe(ws, topic, { platform }) {
245
+ if (topic.startsWith('__presence:')) {
246
+ // Observer subscribing to presence channel directly --
247
+ // sync() subscribes + sends the current list
248
+ tracker.sync(ws, topic.slice(11), platform);
249
+ return;
250
+ }
251
+ // Regular topic -- join presence
252
+ tracker.join(ws, topic, platform);
253
+ },
254
+ close(ws, { platform }) {
255
+ tracker.leave(ws, platform);
256
+ }
229
257
  }
230
258
  };
259
+
260
+ return tracker;
231
261
  }