svelte-realtime 0.5.10 → 0.5.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/package.json +1 -1
- package/vite.d.ts +43 -43
- package/vite.js +52 -7
package/package.json
CHANGED
package/vite.d.ts
CHANGED
|
@@ -1,43 +1,43 @@
|
|
|
1
|
-
import type { Plugin } from 'vite';
|
|
2
|
-
|
|
3
|
-
export interface SvelteRealtimeOptions {
|
|
4
|
-
/**
|
|
5
|
-
* Directory containing live modules.
|
|
6
|
-
* @default 'src/live'
|
|
7
|
-
*/
|
|
8
|
-
dir?: string;
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Generate `$types.d.ts` in the live directory for typed `$live/` imports.
|
|
12
|
-
* Strips the `ctx` parameter from live functions and wraps streams in `Readable<T>`.
|
|
13
|
-
* @default true
|
|
14
|
-
*/
|
|
15
|
-
typedImports?: boolean;
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Enable the in-browser DevTools overlay in dev mode.
|
|
19
|
-
* Toggle with Ctrl+Shift+L. Shows active streams, pending RPCs, and connection status.
|
|
20
|
-
* Stripped from production builds.
|
|
21
|
-
* @default true
|
|
22
|
-
*/
|
|
23
|
-
devtools?: boolean;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Vite plugin for svelte-realtime.
|
|
28
|
-
*
|
|
29
|
-
* Resolves `$live/` imports to virtual modules:
|
|
30
|
-
* - On the server (SSR): re-exports the real module from `src/live/`
|
|
31
|
-
* - On the client: generates lightweight stubs that call `__rpc()` / `__stream()`
|
|
32
|
-
*
|
|
33
|
-
* @example
|
|
34
|
-
* ```js
|
|
35
|
-
* // vite.config.js
|
|
36
|
-
* import { sveltekit } from '@sveltejs/kit/vite';
|
|
37
|
-
* import uws from 'svelte-adapter-uws/vite';
|
|
38
|
-
* import realtime from 'svelte-realtime/vite';
|
|
39
|
-
*
|
|
40
|
-
* export default { plugins: [sveltekit(), uws(), realtime()] };
|
|
41
|
-
* ```
|
|
42
|
-
*/
|
|
43
|
-
export default function svelteRealtime(options?: SvelteRealtimeOptions): Plugin;
|
|
1
|
+
import type { Plugin } from 'vite';
|
|
2
|
+
|
|
3
|
+
export interface SvelteRealtimeOptions {
|
|
4
|
+
/**
|
|
5
|
+
* Directory containing live modules.
|
|
6
|
+
* @default 'src/live'
|
|
7
|
+
*/
|
|
8
|
+
dir?: string;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Generate `$types.d.ts` in the live directory for typed `$live/` imports.
|
|
12
|
+
* Strips the `ctx` parameter from live functions and wraps streams in `Readable<T>`.
|
|
13
|
+
* @default true
|
|
14
|
+
*/
|
|
15
|
+
typedImports?: boolean;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Enable the in-browser DevTools overlay in dev mode.
|
|
19
|
+
* Toggle with Ctrl+Shift+L. Shows active streams, pending RPCs, and connection status.
|
|
20
|
+
* Stripped from production builds.
|
|
21
|
+
* @default true
|
|
22
|
+
*/
|
|
23
|
+
devtools?: boolean;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Vite plugin for svelte-realtime.
|
|
28
|
+
*
|
|
29
|
+
* Resolves `$live/` imports to virtual modules:
|
|
30
|
+
* - On the server (SSR): re-exports the real module from `src/live/`
|
|
31
|
+
* - On the client: generates lightweight stubs that call `__rpc()` / `__stream()`
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* ```js
|
|
35
|
+
* // vite.config.js
|
|
36
|
+
* import { sveltekit } from '@sveltejs/kit/vite';
|
|
37
|
+
* import uws from 'svelte-adapter-uws/vite';
|
|
38
|
+
* import realtime from 'svelte-realtime/vite';
|
|
39
|
+
*
|
|
40
|
+
* export default { plugins: [sveltekit(), uws(), realtime()] };
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
export default function svelteRealtime(options?: SvelteRealtimeOptions): Plugin;
|
package/vite.js
CHANGED
|
@@ -4,6 +4,9 @@ import { resolve, relative, dirname, sep, posix } from 'path';
|
|
|
4
4
|
|
|
5
5
|
const VIRTUAL_PREFIX = '\0live:';
|
|
6
6
|
const REGISTRY_ID = '\0live:__registry';
|
|
7
|
+
// Public specifier user code (the injected hooks import) can reference; the
|
|
8
|
+
// resolveId hook maps it to REGISTRY_ID.
|
|
9
|
+
const REGISTRY_PUBLIC_ID = '/@svelte-realtime-registry';
|
|
7
10
|
const LIVE_EXPORT_RE = /export\s+const\s+(\w+)\s*=\s*live\s*\(/g;
|
|
8
11
|
const VALIDATED_EXPORT_RE = /export\s+const\s+(\w+)\s*=\s*live\.validated\s*\(/g;
|
|
9
12
|
const STREAM_EXPORT_RE = /export\s+const\s+(\w+)\s*=\s*live\.stream\s*\(/g;
|
|
@@ -692,7 +695,7 @@ export default function svelteRealtime(options) {
|
|
|
692
695
|
|
|
693
696
|
resolveId(id) {
|
|
694
697
|
if (id === REGISTRY_ID) return REGISTRY_ID;
|
|
695
|
-
if (id ===
|
|
698
|
+
if (id === REGISTRY_PUBLIC_ID) return REGISTRY_ID;
|
|
696
699
|
if (id.startsWith('$live/')) {
|
|
697
700
|
const modulePath = id.slice(6); // strip '$live/'
|
|
698
701
|
return VIRTUAL_PREFIX + modulePath;
|
|
@@ -742,6 +745,39 @@ export default function svelteRealtime(options) {
|
|
|
742
745
|
return null;
|
|
743
746
|
},
|
|
744
747
|
|
|
748
|
+
transform(code, id, options) {
|
|
749
|
+
// Co-locate the live registry with the WebSocket hooks module in
|
|
750
|
+
// dev. svelte-adapter-uws loads src/hooks.ws.* via ssrLoadModule and
|
|
751
|
+
// binds its `message` handler to whatever `svelte-realtime/server`
|
|
752
|
+
// instance that load produced. On a cold `npm run dev`, Vite's
|
|
753
|
+
// first-run dependency optimization tears down and rebuilds the SSR
|
|
754
|
+
// module graph, so the registry load fired on the server's
|
|
755
|
+
// 'listening' event can land in a DIFFERENT `svelte-realtime/server`
|
|
756
|
+
// instance than the one the adapter's `message` reads - leaving the
|
|
757
|
+
// registry empty and every RPC / stream failing with "no such live
|
|
758
|
+
// function registered" until a restart with a warm cache. Importing
|
|
759
|
+
// the registry FROM the hooks module makes it a dependency in the
|
|
760
|
+
// exact same graph, so the handler and its registrations always share
|
|
761
|
+
// one instance - the first `npm run dev` behaves identically to every
|
|
762
|
+
// one after it. Production build packaging uses the SSR-input path in
|
|
763
|
+
// config() below, so this dev-only seam never touches built output.
|
|
764
|
+
if (!isDev) return null;
|
|
765
|
+
// Only the server (SSR) graph loads hooks.ws; gating on ssr keeps
|
|
766
|
+
// the server-side registry import out of any client bundle even if
|
|
767
|
+
// a client module ever pulled the hooks file in.
|
|
768
|
+
const ssr = options?.ssr ?? isSsr;
|
|
769
|
+
if (!ssr) return null;
|
|
770
|
+
const clean = id.split('?')[0].split(sep).join('/');
|
|
771
|
+
// Scope to THIS project's src/hooks.ws.{js,ts,mjs} (root-anchored so a
|
|
772
|
+
// sibling package's hooks file in a monorepo is never rewritten with
|
|
773
|
+
// our registry). Mirrors the .js/.ts/.mjs set the adapter discovers.
|
|
774
|
+
const rootNorm = root.split(sep).join('/');
|
|
775
|
+
if (!clean.startsWith(rootNorm + '/')) return null;
|
|
776
|
+
if (!/\/src\/hooks\.ws\.(?:js|ts|mjs)$/.test(clean)) return null;
|
|
777
|
+
if (code.includes(REGISTRY_PUBLIC_ID)) return null;
|
|
778
|
+
return { code: `import ${JSON.stringify(REGISTRY_PUBLIC_ID)};\n` + code, map: null };
|
|
779
|
+
},
|
|
780
|
+
|
|
745
781
|
config(config, { command }) {
|
|
746
782
|
// During SSR build, inject the registry as an additional input
|
|
747
783
|
if (command === 'build' && config.build?.ssr) {
|
|
@@ -2093,7 +2129,7 @@ function _findLiveFiles(dir) {
|
|
|
2093
2129
|
}
|
|
2094
2130
|
|
|
2095
2131
|
/**
|
|
2096
|
-
* Check that src/hooks.ws.{js,ts} exists and exports the `message` handler.
|
|
2132
|
+
* Check that src/hooks.ws.{js,ts,mjs} exists and exports the `message` handler.
|
|
2097
2133
|
* Warns at build/dev startup if the file is missing or misconfigured.
|
|
2098
2134
|
* @param {string} root
|
|
2099
2135
|
* @param {string} liveDir
|
|
@@ -2104,9 +2140,11 @@ function _checkHooksFile(root, liveDir, dir) {
|
|
|
2104
2140
|
if (files.length === 0) return;
|
|
2105
2141
|
|
|
2106
2142
|
const hooksPath = resolve(root, 'src/hooks.ws');
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
const found =
|
|
2143
|
+
// Match the extension set the adapter discovers (js, ts, mjs) so a project
|
|
2144
|
+
// using hooks.ws.mjs is not falsely told its hooks file is missing.
|
|
2145
|
+
const found = ['.js', '.ts', '.mjs']
|
|
2146
|
+
.map((ext) => hooksPath + ext)
|
|
2147
|
+
.find((p) => existsSync(p)) || null;
|
|
2110
2148
|
|
|
2111
2149
|
if (!found) {
|
|
2112
2150
|
console.warn(
|
|
@@ -2123,11 +2161,18 @@ function _checkHooksFile(root, liveDir, dir) {
|
|
|
2123
2161
|
let source;
|
|
2124
2162
|
try { source = readFileSync(found, 'utf-8'); } catch { return; }
|
|
2125
2163
|
|
|
2126
|
-
|
|
2164
|
+
// Recognise every way a hooks file can export `message`:
|
|
2165
|
+
// - direct re-export: export { message } from 'svelte-realtime/server'
|
|
2166
|
+
// - import-then-export: import { message } from '...'; export { message }
|
|
2167
|
+
// (the scaffold and e2e fixture both use this two-statement form)
|
|
2168
|
+
// - local declaration: export const/function message = ...
|
|
2169
|
+
// The specifier-list regex covers the first two without needing a `from`
|
|
2170
|
+
// clause; a leading `from` (the direct re-export) still satisfies it.
|
|
2171
|
+
const hasMessage = /export\s*\{[^}]*\bmessage\b[^}]*\}/.test(source)
|
|
2127
2172
|
|| /export\s+(?:const|function|async\s+function)\s+message\b/.test(source);
|
|
2128
2173
|
|
|
2129
2174
|
if (!hasMessage) {
|
|
2130
|
-
const name =
|
|
2175
|
+
const name = 'src/hooks.ws' + (found.match(/\.(?:js|ts|mjs)$/)?.[0] || '.js');
|
|
2131
2176
|
console.warn(
|
|
2132
2177
|
`[svelte-realtime] ${name} exists but does not export a \`message\` handler - ` +
|
|
2133
2178
|
`WebSocket RPC calls from ${dir}/ will go unhandled.\n` +
|