svelte-realtime 0.4.9 → 0.4.11
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 +15 -0
- package/client.d.ts +7 -0
- package/client.js +10 -5
- package/package.json +2 -2
- package/server.js +1 -1
package/README.md
CHANGED
|
@@ -874,10 +874,25 @@ Call `configure()` once at app startup. The hooks fire on state transitions only
|
|
|
874
874
|
|
|
875
875
|
| Option | Description |
|
|
876
876
|
|---|---|
|
|
877
|
+
| `url` | Full WebSocket URL for cross-origin or native app usage (e.g. `'wss://api.example.com/ws'`) |
|
|
877
878
|
| `onConnect()` | Called when the WebSocket connection opens after a reconnect |
|
|
878
879
|
| `onDisconnect()` | Called when the WebSocket connection closes |
|
|
879
880
|
| `beforeReconnect()` | Called before each reconnection attempt (can be async) |
|
|
880
881
|
|
|
882
|
+
### Cross-origin and native app usage
|
|
883
|
+
|
|
884
|
+
When using svelte-realtime from a client that runs on a different origin (Svelte Native, React Native, or any standalone app), pass the `url` option to point at your SvelteKit backend:
|
|
885
|
+
|
|
886
|
+
```js
|
|
887
|
+
import { configure } from 'svelte-realtime/client';
|
|
888
|
+
|
|
889
|
+
configure({
|
|
890
|
+
url: 'wss://my-sveltekit-app.com/ws'
|
|
891
|
+
});
|
|
892
|
+
```
|
|
893
|
+
|
|
894
|
+
When `url` is set, the default same-origin WebSocket URL is bypassed entirely. All RPC calls, streams, and pub/sub work the same way. Requires `svelte-adapter-uws` 0.4.8+.
|
|
895
|
+
|
|
881
896
|
---
|
|
882
897
|
|
|
883
898
|
## Combine stores
|
package/client.d.ts
CHANGED
|
@@ -157,6 +157,13 @@ export interface OfflineEntry {
|
|
|
157
157
|
}
|
|
158
158
|
|
|
159
159
|
export function configure(config: {
|
|
160
|
+
/**
|
|
161
|
+
* Full WebSocket URL to connect to. Enables cross-origin and native app usage
|
|
162
|
+
* (Svelte Native, React Native, standalone clients). When set, the default
|
|
163
|
+
* same-origin URL is bypassed entirely.
|
|
164
|
+
* @example 'wss://my-app.com/ws'
|
|
165
|
+
*/
|
|
166
|
+
url?: string;
|
|
160
167
|
/** Called when the WebSocket connection opens (not on initial connect, only reconnects). */
|
|
161
168
|
onConnect?(): void;
|
|
162
169
|
/** Called when the WebSocket connection closes. */
|
package/client.js
CHANGED
|
@@ -526,8 +526,6 @@ function _createStream(path, options, dynamicArgs) {
|
|
|
526
526
|
let subCount = 0;
|
|
527
527
|
let pendingId = null;
|
|
528
528
|
|
|
529
|
-
/** @type {boolean} */
|
|
530
|
-
let _hydrated = false;
|
|
531
529
|
|
|
532
530
|
/** @type {number | null} Last known sequence number for replay */
|
|
533
531
|
let _lastSeq = null;
|
|
@@ -928,6 +926,10 @@ function _createStream(path, options, dynamicArgs) {
|
|
|
928
926
|
for (const evt of response.data) {
|
|
929
927
|
_applyMerge(evt);
|
|
930
928
|
}
|
|
929
|
+
} else if (response.channel && currentValue !== undefined) {
|
|
930
|
+
// Channel fast-path returns an empty placeholder (null or []).
|
|
931
|
+
// Keep the existing value (hydrated SSR data or previously
|
|
932
|
+
// accumulated events) so the store never flashes to empty.
|
|
931
933
|
} else {
|
|
932
934
|
currentValue = response.data;
|
|
933
935
|
}
|
|
@@ -1223,7 +1225,6 @@ function _createStream(path, options, dynamicArgs) {
|
|
|
1223
1225
|
currentValue = initialData;
|
|
1224
1226
|
_rebuildIndex();
|
|
1225
1227
|
store.set(currentValue);
|
|
1226
|
-
_hydrated = true;
|
|
1227
1228
|
return this;
|
|
1228
1229
|
},
|
|
1229
1230
|
|
|
@@ -1513,7 +1514,7 @@ function _checkArgs(path, args) {
|
|
|
1513
1514
|
* @typedef {{ path: string, args: any[], queuedAt: number, resolve: Function, reject: Function }} OfflineEntry
|
|
1514
1515
|
*/
|
|
1515
1516
|
|
|
1516
|
-
/** @type {{ onConnect?: () => void, onDisconnect?: () => void, timeout?: number, offline?: { queue?: boolean, maxQueue?: number, maxAge?: number, replay?: 'sequential' | 'batch' | ((queue: OfflineEntry[]) => OfflineEntry[]), beforeReplay?: (call: { path: string, args: any[], queuedAt: number }) => boolean, onReplayError?: (call: { path: string, args: any[], queuedAt: number }, error: any) => void } }} */
|
|
1517
|
+
/** @type {{ url?: string, onConnect?: () => void, onDisconnect?: () => void, timeout?: number, offline?: { queue?: boolean, maxQueue?: number, maxAge?: number, replay?: 'sequential' | 'batch' | ((queue: OfflineEntry[]) => OfflineEntry[]), beforeReplay?: (call: { path: string, args: any[], queuedAt: number }) => boolean, onReplayError?: (call: { path: string, args: any[], queuedAt: number }, error: any) => void } }} */
|
|
1517
1518
|
let _clientConfig = {};
|
|
1518
1519
|
|
|
1519
1520
|
/** @type {boolean} */
|
|
@@ -1531,11 +1532,15 @@ let _replayingQueue = false;
|
|
|
1531
1532
|
/**
|
|
1532
1533
|
* Configure client-side connection hooks and offline queue.
|
|
1533
1534
|
*
|
|
1534
|
-
* @param {{ onConnect?: () => void, onDisconnect?: () => void, offline?: { queue?: boolean, maxQueue?: number, maxAge?: number, replay?: 'sequential' | 'batch' | ((queue: OfflineEntry[]) => OfflineEntry[]), beforeReplay?: (call: { path: string, args: any[], queuedAt: number }) => boolean, onReplayError?: (call: { path: string, args: any[], queuedAt: number }, error: any) => void } }} config
|
|
1535
|
+
* @param {{ url?: string, onConnect?: () => void, onDisconnect?: () => void, offline?: { queue?: boolean, maxQueue?: number, maxAge?: number, replay?: 'sequential' | 'batch' | ((queue: OfflineEntry[]) => OfflineEntry[]), beforeReplay?: (call: { path: string, args: any[], queuedAt: number }) => boolean, onReplayError?: (call: { path: string, args: any[], queuedAt: number }, error: any) => void } }} config
|
|
1535
1536
|
*/
|
|
1536
1537
|
export function configure(config) {
|
|
1537
1538
|
_clientConfig = config;
|
|
1538
1539
|
|
|
1540
|
+
if (config.url) {
|
|
1541
|
+
_connect({ url: config.url });
|
|
1542
|
+
}
|
|
1543
|
+
|
|
1539
1544
|
if (!_configListenerAttached) {
|
|
1540
1545
|
_configListenerAttached = true;
|
|
1541
1546
|
let isFirst = true;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "svelte-realtime",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.11",
|
|
4
4
|
"description": "Realtime RPC and reactive subscriptions for SvelteKit, built on svelte-adapter-uws",
|
|
5
5
|
"author": "Kevin Radziszewski",
|
|
6
6
|
"license": "MIT",
|
|
@@ -69,7 +69,7 @@
|
|
|
69
69
|
"peerDependencies": {
|
|
70
70
|
"@sveltejs/kit": "^2.0.0",
|
|
71
71
|
"svelte": "^4.0.0 || ^5.0.0",
|
|
72
|
-
"svelte-adapter-uws": ">=0.4.
|
|
72
|
+
"svelte-adapter-uws": ">=0.4.8"
|
|
73
73
|
},
|
|
74
74
|
"devDependencies": {
|
|
75
75
|
"vitest": "^4.0.18"
|
package/server.js
CHANGED
|
@@ -2102,7 +2102,7 @@ async function _executeSingleRpc(ws, msg, platform, options) {
|
|
|
2102
2102
|
// Channel fast-path
|
|
2103
2103
|
if (/** @type {any} */ (fn).__isChannel) {
|
|
2104
2104
|
const emptyValue = streamOpts.merge === 'set' ? null : [];
|
|
2105
|
-
return { id, ok: true, data: emptyValue, topic, merge: streamOpts.merge, key: streamOpts.key, max: streamOpts.max };
|
|
2105
|
+
return { id, ok: true, data: emptyValue, topic, merge: streamOpts.merge, key: streamOpts.key, max: streamOpts.max, channel: true };
|
|
2106
2106
|
}
|
|
2107
2107
|
|
|
2108
2108
|
// Delta sync
|