@nexus_js/connect 0.6.0
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/LICENSE +21 -0
- package/README.md +17 -0
- package/dist/broker.d.ts +31 -0
- package/dist/broker.d.ts.map +1 -0
- package/dist/broker.js +47 -0
- package/dist/broker.js.map +1 -0
- package/dist/client.d.ts +38 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +76 -0
- package/dist/client.js.map +1 -0
- package/dist/index.d.ts +38 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +39 -0
- package/dist/index.js.map +1 -0
- package/dist/sse.d.ts +36 -0
- package/dist/sse.d.ts.map +1 -0
- package/dist/sse.js +90 -0
- package/dist/sse.js.map +1 -0
- package/package.json +57 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Nexus Contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# @nexus_js/connect
|
|
2
|
+
|
|
3
|
+
Nexus Connect — Edge-State Sync via SSE. $socket() rune for real-time state across all connected clients..
|
|
4
|
+
|
|
5
|
+
## Documentation
|
|
6
|
+
|
|
7
|
+
All guides, API reference, and examples live on **[nexusjs.dev](https://nexusjs.dev)**.
|
|
8
|
+
|
|
9
|
+
## Links
|
|
10
|
+
|
|
11
|
+
- **Website:** [https://nexusjs.dev](https://nexusjs.dev)
|
|
12
|
+
- **Repository:** [github.com/bierfor/nexus](https://github.com/bierfor/nexus) (see `packages/connect/`)
|
|
13
|
+
- **Issues:** [github.com/bierfor/nexus/issues](https://github.com/bierfor/nexus/issues)
|
|
14
|
+
|
|
15
|
+
## License
|
|
16
|
+
|
|
17
|
+
MIT © Nexus contributors
|
package/dist/broker.d.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Nexus Connect — In-memory message broker.
|
|
3
|
+
*
|
|
4
|
+
* Maintains a pub/sub registry keyed by topic string.
|
|
5
|
+
* Keeps the last published message per topic for late subscribers
|
|
6
|
+
* (same semantics as RxJS BehaviorSubject).
|
|
7
|
+
*
|
|
8
|
+
* Designed to be a singleton per server process. In multi-process/Edge
|
|
9
|
+
* environments, replace the singleton with a Redis/Upstash adapter.
|
|
10
|
+
*/
|
|
11
|
+
export interface ConnectMessage<T = unknown> {
|
|
12
|
+
topic: string;
|
|
13
|
+
data: T;
|
|
14
|
+
id: string;
|
|
15
|
+
ts: number;
|
|
16
|
+
}
|
|
17
|
+
type Subscriber<T> = (msg: ConnectMessage<T>) => void;
|
|
18
|
+
declare class MessageBroker {
|
|
19
|
+
private subs;
|
|
20
|
+
private cache;
|
|
21
|
+
subscribe<T>(topic: string, fn: Subscriber<T>): () => void;
|
|
22
|
+
publish<T>(topic: string, data: T): void;
|
|
23
|
+
/** Number of active SSE listeners for a topic (useful for presence) */
|
|
24
|
+
subscriberCount(topic: string): number;
|
|
25
|
+
/** All currently active topics */
|
|
26
|
+
topics(): string[];
|
|
27
|
+
}
|
|
28
|
+
/** Singleton broker shared across all channels in this server process. */
|
|
29
|
+
export declare const broker: MessageBroker;
|
|
30
|
+
export {};
|
|
31
|
+
//# sourceMappingURL=broker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"broker.d.ts","sourceRoot":"","sources":["../src/broker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,MAAM,WAAW,cAAc,CAAC,CAAC,GAAG,OAAO;IACzC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAG,CAAC,CAAC;IACT,EAAE,EAAK,MAAM,CAAC;IACd,EAAE,EAAK,MAAM,CAAC;CACf;AAED,KAAK,UAAU,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;AAEtD,cAAM,aAAa;IACjB,OAAO,CAAC,IAAI,CAAgD;IAC5D,OAAO,CAAC,KAAK,CAA8C;IAE3D,SAAS,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI;IAa1D,OAAO,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,GAAG,IAAI;IAWxC,uEAAuE;IACvE,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IAItC,kCAAkC;IAClC,MAAM,IAAI,MAAM,EAAE;CAGnB;AAED,0EAA0E;AAC1E,eAAO,MAAM,MAAM,eAAsB,CAAC"}
|
package/dist/broker.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Nexus Connect — In-memory message broker.
|
|
3
|
+
*
|
|
4
|
+
* Maintains a pub/sub registry keyed by topic string.
|
|
5
|
+
* Keeps the last published message per topic for late subscribers
|
|
6
|
+
* (same semantics as RxJS BehaviorSubject).
|
|
7
|
+
*
|
|
8
|
+
* Designed to be a singleton per server process. In multi-process/Edge
|
|
9
|
+
* environments, replace the singleton with a Redis/Upstash adapter.
|
|
10
|
+
*/
|
|
11
|
+
class MessageBroker {
|
|
12
|
+
subs = new Map();
|
|
13
|
+
cache = new Map();
|
|
14
|
+
subscribe(topic, fn) {
|
|
15
|
+
if (!this.subs.has(topic))
|
|
16
|
+
this.subs.set(topic, new Set());
|
|
17
|
+
this.subs.get(topic).add(fn);
|
|
18
|
+
// Replay last message for late subscribers (catch-up semantics)
|
|
19
|
+
const last = this.cache.get(topic);
|
|
20
|
+
if (last)
|
|
21
|
+
queueMicrotask(() => fn(last));
|
|
22
|
+
return () => {
|
|
23
|
+
this.subs.get(topic)?.delete(fn);
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
publish(topic, data) {
|
|
27
|
+
const msg = {
|
|
28
|
+
topic,
|
|
29
|
+
data,
|
|
30
|
+
id: `${Date.now()}-${Math.random().toString(36).slice(2, 7)}`,
|
|
31
|
+
ts: Date.now(),
|
|
32
|
+
};
|
|
33
|
+
this.cache.set(topic, msg);
|
|
34
|
+
this.subs.get(topic)?.forEach((fn) => fn(msg));
|
|
35
|
+
}
|
|
36
|
+
/** Number of active SSE listeners for a topic (useful for presence) */
|
|
37
|
+
subscriberCount(topic) {
|
|
38
|
+
return this.subs.get(topic)?.size ?? 0;
|
|
39
|
+
}
|
|
40
|
+
/** All currently active topics */
|
|
41
|
+
topics() {
|
|
42
|
+
return [...this.subs.keys()].filter((t) => (this.subs.get(t)?.size ?? 0) > 0);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/** Singleton broker shared across all channels in this server process. */
|
|
46
|
+
export const broker = new MessageBroker();
|
|
47
|
+
//# sourceMappingURL=broker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"broker.js","sourceRoot":"","sources":["../src/broker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAWH,MAAM,aAAa;IACT,IAAI,GAAI,IAAI,GAAG,EAAoC,CAAC;IACpD,KAAK,GAAG,IAAI,GAAG,EAAmC,CAAC;IAE3D,SAAS,CAAI,KAAa,EAAE,EAAiB;QAC3C,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC;YAAE,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,GAAG,EAAE,CAAC,CAAC;QAC3D,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAE,CAAC,GAAG,CAAC,EAAyB,CAAC,CAAC;QAErD,gEAAgE;QAChE,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACnC,IAAI,IAAI;YAAE,cAAc,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,IAAyB,CAAC,CAAC,CAAC;QAE9D,OAAO,GAAG,EAAE;YACV,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,EAAyB,CAAC,CAAC;QAC1D,CAAC,CAAC;IACJ,CAAC;IAED,OAAO,CAAI,KAAa,EAAE,IAAO;QAC/B,MAAM,GAAG,GAAsB;YAC7B,KAAK;YACL,IAAI;YACJ,EAAE,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE;YAC7D,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE;SACf,CAAC;QACF,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,GAA8B,CAAC,CAAC;QACtD,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,GAA8B,CAAC,CAAC,CAAC;IAC5E,CAAC;IAED,uEAAuE;IACvE,eAAe,CAAC,KAAa;QAC3B,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,IAAI,IAAI,CAAC,CAAC;IACzC,CAAC;IAED,kCAAkC;IAClC,MAAM;QACJ,OAAO,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAChF,CAAC;CACF;AAED,0EAA0E;AAC1E,MAAM,CAAC,MAAM,MAAM,GAAG,IAAI,aAAa,EAAE,CAAC"}
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Nexus Connect — Client-side $socket() rune.
|
|
3
|
+
*
|
|
4
|
+
* Connects to /_nexus/connect/:topic via SSE and returns a reactive
|
|
5
|
+
* state object whose .value updates in real time whenever the server publishes.
|
|
6
|
+
*
|
|
7
|
+
* Usage in a .nx island:
|
|
8
|
+
* <script>
|
|
9
|
+
* import { $socket } from '@nexus_js/connect/client';
|
|
10
|
+
*
|
|
11
|
+
* const captures = $socket('global-captures', { default: { count: 0 } });
|
|
12
|
+
* // captures.value.count is always up-to-date
|
|
13
|
+
* </script>
|
|
14
|
+
* <p>Global captures: {captures.value.count}</p>
|
|
15
|
+
*/
|
|
16
|
+
export interface SocketState<T> {
|
|
17
|
+
/** Current value — reactive in island components */
|
|
18
|
+
readonly value: T;
|
|
19
|
+
/** Register a callback that fires on every update */
|
|
20
|
+
subscribe: (fn: (value: T, prev: T) => void) => () => void;
|
|
21
|
+
/** Manually close the SSE connection */
|
|
22
|
+
close: () => void;
|
|
23
|
+
/** true while the SSE connection is establishing */
|
|
24
|
+
readonly connecting: boolean;
|
|
25
|
+
/** true if the connection is live */
|
|
26
|
+
readonly connected: boolean;
|
|
27
|
+
}
|
|
28
|
+
export interface SocketOptions<T> {
|
|
29
|
+
default: T;
|
|
30
|
+
/** Optional transform applied to the raw JSON payload */
|
|
31
|
+
transform?: (raw: unknown) => T;
|
|
32
|
+
/** Called on SSE connection error */
|
|
33
|
+
onError?: (err: Event) => void;
|
|
34
|
+
/** Reconnect automatically on error (default: true) */
|
|
35
|
+
reconnect?: boolean;
|
|
36
|
+
}
|
|
37
|
+
export declare function $socket<T>(topic: string, opts: SocketOptions<T>): SocketState<T>;
|
|
38
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,MAAM,WAAW,WAAW,CAAC,CAAC;IAC5B,oDAAoD;IACpD,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC;IAClB,qDAAqD;IACrD,SAAS,EAAE,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,KAAK,IAAI,KAAK,MAAM,IAAI,CAAC;IAC3D,wCAAwC;IACxC,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,oDAAoD;IACpD,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,qCAAqC;IACrC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;CAC7B;AAED,MAAM,WAAW,aAAa,CAAC,CAAC;IAC9B,OAAO,EAAE,CAAC,CAAC;IACX,yDAAyD;IACzD,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,CAAC,CAAC;IAChC,qCAAqC;IACrC,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,IAAI,CAAC;IAC/B,uDAAuD;IACvD,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AASD,wBAAgB,OAAO,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,CAuEhF"}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Nexus Connect — Client-side $socket() rune.
|
|
3
|
+
*
|
|
4
|
+
* Connects to /_nexus/connect/:topic via SSE and returns a reactive
|
|
5
|
+
* state object whose .value updates in real time whenever the server publishes.
|
|
6
|
+
*
|
|
7
|
+
* Usage in a .nx island:
|
|
8
|
+
* <script>
|
|
9
|
+
* import { $socket } from '@nexus_js/connect/client';
|
|
10
|
+
*
|
|
11
|
+
* const captures = $socket('global-captures', { default: { count: 0 } });
|
|
12
|
+
* // captures.value.count is always up-to-date
|
|
13
|
+
* </script>
|
|
14
|
+
* <p>Global captures: {captures.value.count}</p>
|
|
15
|
+
*/
|
|
16
|
+
export function $socket(topic, opts) {
|
|
17
|
+
let current = opts.default;
|
|
18
|
+
let _connecting = true;
|
|
19
|
+
let _connected = false;
|
|
20
|
+
const listeners = new Set();
|
|
21
|
+
let es = null;
|
|
22
|
+
function notify(next) {
|
|
23
|
+
const prev = current;
|
|
24
|
+
current = next;
|
|
25
|
+
if (typeof window !== 'undefined' && window.__NEXUS_DEV__) {
|
|
26
|
+
console.log(`%c[Nexus] 🛰️ Connect%c "${topic}" →`, 'color:#7c3aed;font-weight:700', 'color:#64748b', next);
|
|
27
|
+
}
|
|
28
|
+
listeners.forEach((fn) => fn(next, prev));
|
|
29
|
+
}
|
|
30
|
+
function connect() {
|
|
31
|
+
if (typeof window === 'undefined' || typeof EventSource === 'undefined')
|
|
32
|
+
return;
|
|
33
|
+
es = new EventSource(`/_nexus/connect/${encodeURIComponent(topic)}`);
|
|
34
|
+
es.addEventListener('connected', () => {
|
|
35
|
+
_connecting = false;
|
|
36
|
+
_connected = true;
|
|
37
|
+
if (typeof window !== 'undefined' && window.__NEXUS_DEV__) {
|
|
38
|
+
console.log(`%c[Nexus] 🛰️ Connect%c "${topic}" established`, 'color:#7c3aed;font-weight:700', 'color:#10b981');
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
es.addEventListener('message', (e) => {
|
|
42
|
+
try {
|
|
43
|
+
const raw = JSON.parse(e.data);
|
|
44
|
+
const value = opts.transform ? opts.transform(raw) : raw;
|
|
45
|
+
notify(value);
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
// malformed JSON — ignore
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
es.onerror = (err) => {
|
|
52
|
+
_connected = false;
|
|
53
|
+
_connecting = true;
|
|
54
|
+
opts.onError?.(err);
|
|
55
|
+
// EventSource auto-reconnects by default
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
connect();
|
|
59
|
+
return {
|
|
60
|
+
get value() { return current; },
|
|
61
|
+
get connecting() { return _connecting; },
|
|
62
|
+
get connected() { return _connected; },
|
|
63
|
+
subscribe(fn) {
|
|
64
|
+
listeners.add(fn);
|
|
65
|
+
fn(current, current); // immediate call with current value
|
|
66
|
+
return () => listeners.delete(fn);
|
|
67
|
+
},
|
|
68
|
+
close() {
|
|
69
|
+
es?.close();
|
|
70
|
+
_connected = false;
|
|
71
|
+
_connecting = false;
|
|
72
|
+
listeners.clear();
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @nexus_js/connect — Edge-State Sync
|
|
3
|
+
*
|
|
4
|
+
* Server exports:
|
|
5
|
+
* getChannel(topic) — pub/sub channel for server→client push
|
|
6
|
+
* handleSSERequest() — Web-standard SSE Response handler
|
|
7
|
+
* handleSSERequestNode()— Node.js http.ServerResponse adapter
|
|
8
|
+
* isConnectRequest() — Route guard for /_nexus/connect/* URLs
|
|
9
|
+
* CONNECT_PATH — '/_nexus/connect/'
|
|
10
|
+
*
|
|
11
|
+
* Client exports (import from '@nexus_js/connect/client'):
|
|
12
|
+
* $socket(topic, opts) — reactive SSE subscription rune
|
|
13
|
+
*/
|
|
14
|
+
export { broker } from './broker.js';
|
|
15
|
+
export { handleSSERequest, handleSSERequestNode, isConnectRequest, topicFromUrl, CONNECT_PATH } from './sse.js';
|
|
16
|
+
export interface NexusChannel<T = unknown> {
|
|
17
|
+
topic: string;
|
|
18
|
+
/** Push data to all connected clients subscribed to this topic */
|
|
19
|
+
publish: (data: T) => void;
|
|
20
|
+
/** Subscribe to messages on this topic (server-side listener) */
|
|
21
|
+
subscribe: (fn: (data: T) => void) => () => void;
|
|
22
|
+
/** Number of currently connected SSE clients */
|
|
23
|
+
subscriberCount: () => number;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Returns a typed channel for a given topic.
|
|
27
|
+
* Call publish() from your server frontmatter to push state to clients.
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* // In .nx frontmatter:
|
|
31
|
+
* import { getChannel } from '@nexus_js/connect';
|
|
32
|
+
* const stats = getChannel<{ captures: number }>('global-stats');
|
|
33
|
+
* stats.publish({ captures: await db.count('captures') });
|
|
34
|
+
*/
|
|
35
|
+
export declare function getChannel<T = unknown>(topic: string): NexusChannel<T>;
|
|
36
|
+
/** All currently active (non-empty) topics — useful for admin dashboards */
|
|
37
|
+
export declare function activeTopics(): string[];
|
|
38
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAIhH,MAAM,WAAW,YAAY,CAAC,CAAC,GAAG,OAAO;IACvC,KAAK,EAAY,MAAM,CAAC;IACxB,kEAAkE;IAClE,OAAO,EAAU,CAAC,IAAI,EAAE,CAAC,KAAK,IAAI,CAAC;IACnC,iEAAiE;IACjE,SAAS,EAAQ,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,IAAI,KAAK,MAAM,IAAI,CAAC;IACvD,gDAAgD;IAChD,eAAe,EAAE,MAAM,MAAM,CAAC;CAC/B;AAED;;;;;;;;;GASG;AACH,wBAAgB,UAAU,CAAC,CAAC,GAAG,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,YAAY,CAAC,CAAC,CAAC,CAOtE;AAED,4EAA4E;AAC5E,wBAAgB,YAAY,IAAI,MAAM,EAAE,CAEvC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @nexus_js/connect — Edge-State Sync
|
|
3
|
+
*
|
|
4
|
+
* Server exports:
|
|
5
|
+
* getChannel(topic) — pub/sub channel for server→client push
|
|
6
|
+
* handleSSERequest() — Web-standard SSE Response handler
|
|
7
|
+
* handleSSERequestNode()— Node.js http.ServerResponse adapter
|
|
8
|
+
* isConnectRequest() — Route guard for /_nexus/connect/* URLs
|
|
9
|
+
* CONNECT_PATH — '/_nexus/connect/'
|
|
10
|
+
*
|
|
11
|
+
* Client exports (import from '@nexus_js/connect/client'):
|
|
12
|
+
* $socket(topic, opts) — reactive SSE subscription rune
|
|
13
|
+
*/
|
|
14
|
+
export { broker } from './broker.js';
|
|
15
|
+
export { handleSSERequest, handleSSERequestNode, isConnectRequest, topicFromUrl, CONNECT_PATH } from './sse.js';
|
|
16
|
+
import { broker } from './broker.js';
|
|
17
|
+
/**
|
|
18
|
+
* Returns a typed channel for a given topic.
|
|
19
|
+
* Call publish() from your server frontmatter to push state to clients.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* // In .nx frontmatter:
|
|
23
|
+
* import { getChannel } from '@nexus_js/connect';
|
|
24
|
+
* const stats = getChannel<{ captures: number }>('global-stats');
|
|
25
|
+
* stats.publish({ captures: await db.count('captures') });
|
|
26
|
+
*/
|
|
27
|
+
export function getChannel(topic) {
|
|
28
|
+
return {
|
|
29
|
+
topic,
|
|
30
|
+
publish: (data) => broker.publish(topic, data),
|
|
31
|
+
subscribe: (fn) => broker.subscribe(topic, (msg) => fn(msg.data)),
|
|
32
|
+
subscriberCount: () => broker.subscriberCount(topic),
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
/** All currently active (non-empty) topics — useful for admin dashboards */
|
|
36
|
+
export function activeTopics() {
|
|
37
|
+
return broker.topics();
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAEhH,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAYrC;;;;;;;;;GASG;AACH,MAAM,UAAU,UAAU,CAAc,KAAa;IACnD,OAAO;QACL,KAAK;QACL,OAAO,EAAU,CAAC,IAAO,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,CAAI,KAAK,EAAE,IAAI,CAAC;QAC5D,SAAS,EAAQ,CAAC,EAAqB,EAAE,EAAE,CAAC,MAAM,CAAC,SAAS,CAAI,KAAK,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC7F,eAAe,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,eAAe,CAAC,KAAK,CAAC;KACrD,CAAC;AACJ,CAAC;AAED,4EAA4E;AAC5E,MAAM,UAAU,YAAY;IAC1B,OAAO,MAAM,CAAC,MAAM,EAAE,CAAC;AACzB,CAAC"}
|
package/dist/sse.d.ts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Nexus Connect — Server-Sent Events handler.
|
|
3
|
+
*
|
|
4
|
+
* Returns a streaming Response that stays open until the client disconnects.
|
|
5
|
+
* Works with any Web-standard Request/Response environment (Node 18+, Bun, Deno, Cloudflare Workers).
|
|
6
|
+
*
|
|
7
|
+
* SSE wire format:
|
|
8
|
+
* id: <message-id>\n
|
|
9
|
+
* event: message\n
|
|
10
|
+
* data: <json-payload>\n\n
|
|
11
|
+
*
|
|
12
|
+
* : heartbeat\n\n ← keep-alive comment (every 15s)
|
|
13
|
+
*/
|
|
14
|
+
export declare const CONNECT_PATH = "/_nexus/connect/";
|
|
15
|
+
/** Extract the topic name from a /_nexus/connect/:topic URL. */
|
|
16
|
+
export declare function topicFromUrl(url: URL): string;
|
|
17
|
+
/** Returns true if this request should be handled by Nexus Connect. */
|
|
18
|
+
export declare function isConnectRequest(url: URL): boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Creates a streaming SSE Response for the given topic.
|
|
21
|
+
* The response stays open until the client disconnects (request.signal aborts).
|
|
22
|
+
*/
|
|
23
|
+
export declare function handleSSERequest(request: Request, topic: string): Response;
|
|
24
|
+
/**
|
|
25
|
+
* Node.js adapter — writes SSE directly to a ServerResponse.
|
|
26
|
+
* Use this when you cannot return a Web Response (e.g. in http.createServer callbacks).
|
|
27
|
+
*/
|
|
28
|
+
export declare function handleSSERequestNode(req: {
|
|
29
|
+
signal?: AbortSignal;
|
|
30
|
+
on?: (event: string, fn: () => void) => void;
|
|
31
|
+
}, res: {
|
|
32
|
+
writeHead: (s: number, h: Record<string, string>) => void;
|
|
33
|
+
write: (s: string) => boolean;
|
|
34
|
+
end: () => void;
|
|
35
|
+
}, topic: string): void;
|
|
36
|
+
//# sourceMappingURL=sse.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sse.d.ts","sourceRoot":"","sources":["../src/sse.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAKH,eAAO,MAAM,YAAY,qBAAqB,CAAC;AAE/C,gEAAgE;AAChE,wBAAgB,YAAY,CAAC,GAAG,EAAE,GAAG,GAAG,MAAM,CAE7C;AAED,uEAAuE;AACvE,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAElD;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,QAAQ,CAuC1E;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,GAAG,EAAE;IAAE,MAAM,CAAC,EAAE,WAAW,CAAC;IAAC,EAAE,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,IAAI,KAAK,IAAI,CAAA;CAAE,EAC3E,GAAG,EAAE;IAAE,SAAS,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,IAAI,CAAC;IAAC,KAAK,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC;IAAC,GAAG,EAAE,MAAM,IAAI,CAAA;CAAE,EAClH,KAAK,EAAE,MAAM,GACZ,IAAI,CA2BN"}
|
package/dist/sse.js
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Nexus Connect — Server-Sent Events handler.
|
|
3
|
+
*
|
|
4
|
+
* Returns a streaming Response that stays open until the client disconnects.
|
|
5
|
+
* Works with any Web-standard Request/Response environment (Node 18+, Bun, Deno, Cloudflare Workers).
|
|
6
|
+
*
|
|
7
|
+
* SSE wire format:
|
|
8
|
+
* id: <message-id>\n
|
|
9
|
+
* event: message\n
|
|
10
|
+
* data: <json-payload>\n\n
|
|
11
|
+
*
|
|
12
|
+
* : heartbeat\n\n ← keep-alive comment (every 15s)
|
|
13
|
+
*/
|
|
14
|
+
import { broker } from './broker.js';
|
|
15
|
+
const HEARTBEAT_MS = 15_000;
|
|
16
|
+
export const CONNECT_PATH = '/_nexus/connect/';
|
|
17
|
+
/** Extract the topic name from a /_nexus/connect/:topic URL. */
|
|
18
|
+
export function topicFromUrl(url) {
|
|
19
|
+
return decodeURIComponent(url.pathname.slice(CONNECT_PATH.length));
|
|
20
|
+
}
|
|
21
|
+
/** Returns true if this request should be handled by Nexus Connect. */
|
|
22
|
+
export function isConnectRequest(url) {
|
|
23
|
+
return url.pathname.startsWith(CONNECT_PATH) && url.pathname.length > CONNECT_PATH.length;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Creates a streaming SSE Response for the given topic.
|
|
27
|
+
* The response stays open until the client disconnects (request.signal aborts).
|
|
28
|
+
*/
|
|
29
|
+
export function handleSSERequest(request, topic) {
|
|
30
|
+
const { readable, writable } = new TransformStream();
|
|
31
|
+
const writer = writable.getWriter();
|
|
32
|
+
const encoder = new TextEncoder();
|
|
33
|
+
const send = (chunk) => {
|
|
34
|
+
writer.write(encoder.encode(chunk)).catch(() => { });
|
|
35
|
+
};
|
|
36
|
+
// Initial handshake event
|
|
37
|
+
send(`event: connected\ndata: ${JSON.stringify({ topic, ts: Date.now() })}\n\n`);
|
|
38
|
+
// Subscribe and forward broker messages to the stream
|
|
39
|
+
const unsubscribe = broker.subscribe(topic, (msg) => {
|
|
40
|
+
send(`id: ${msg.id}\nevent: message\ndata: ${JSON.stringify(msg.data)}\n\n`);
|
|
41
|
+
});
|
|
42
|
+
// Heartbeat — prevents proxies from closing idle connections
|
|
43
|
+
const heartbeat = setInterval(() => {
|
|
44
|
+
send(': heartbeat\n\n');
|
|
45
|
+
}, HEARTBEAT_MS);
|
|
46
|
+
// Cleanup when client disconnects
|
|
47
|
+
request.signal.addEventListener('abort', () => {
|
|
48
|
+
clearInterval(heartbeat);
|
|
49
|
+
unsubscribe();
|
|
50
|
+
writer.close().catch(() => { });
|
|
51
|
+
}, { once: true });
|
|
52
|
+
return new Response(readable, {
|
|
53
|
+
status: 200,
|
|
54
|
+
headers: {
|
|
55
|
+
'content-type': 'text/event-stream; charset=utf-8',
|
|
56
|
+
'cache-control': 'no-cache, no-transform',
|
|
57
|
+
'connection': 'keep-alive',
|
|
58
|
+
'x-accel-buffering': 'no',
|
|
59
|
+
'access-control-allow-origin': '*',
|
|
60
|
+
},
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Node.js adapter — writes SSE directly to a ServerResponse.
|
|
65
|
+
* Use this when you cannot return a Web Response (e.g. in http.createServer callbacks).
|
|
66
|
+
*/
|
|
67
|
+
export function handleSSERequestNode(req, res, topic) {
|
|
68
|
+
res.writeHead(200, {
|
|
69
|
+
'content-type': 'text/event-stream; charset=utf-8',
|
|
70
|
+
'cache-control': 'no-cache',
|
|
71
|
+
'connection': 'keep-alive',
|
|
72
|
+
'x-accel-buffering': 'no',
|
|
73
|
+
'access-control-allow-origin': '*',
|
|
74
|
+
});
|
|
75
|
+
res.write(`event: connected\ndata: ${JSON.stringify({ topic, ts: Date.now() })}\n\n`);
|
|
76
|
+
const unsubscribe = broker.subscribe(topic, (msg) => {
|
|
77
|
+
res.write(`id: ${msg.id}\nevent: message\ndata: ${JSON.stringify(msg.data)}\n\n`);
|
|
78
|
+
});
|
|
79
|
+
const heartbeat = setInterval(() => {
|
|
80
|
+
res.write(': heartbeat\n\n');
|
|
81
|
+
}, HEARTBEAT_MS);
|
|
82
|
+
const cleanup = () => {
|
|
83
|
+
clearInterval(heartbeat);
|
|
84
|
+
unsubscribe();
|
|
85
|
+
res.end();
|
|
86
|
+
};
|
|
87
|
+
req.on?.('close', cleanup);
|
|
88
|
+
req.signal?.addEventListener('abort', cleanup, { once: true });
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=sse.js.map
|
package/dist/sse.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sse.js","sourceRoot":"","sources":["../src/sse.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@nexus_js/connect",
|
|
3
|
+
"version": "0.6.0",
|
|
4
|
+
"description": "Nexus Connect — Edge-State Sync via SSE. $socket() rune for real-time state across all connected clients.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./dist/index.js",
|
|
11
|
+
"types": "./dist/index.d.ts"
|
|
12
|
+
},
|
|
13
|
+
"./client": {
|
|
14
|
+
"import": "./dist/client.js",
|
|
15
|
+
"types": "./dist/client.d.ts"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"devDependencies": {
|
|
19
|
+
"@types/node": "^22.0.0",
|
|
20
|
+
"typescript": "^5.5.0",
|
|
21
|
+
"vitest": "^2.0.0"
|
|
22
|
+
},
|
|
23
|
+
"license": "MIT",
|
|
24
|
+
"homepage": "https://nexusjs.dev",
|
|
25
|
+
"repository": {
|
|
26
|
+
"type": "git",
|
|
27
|
+
"url": "https://github.com/bierfor/nexus.git",
|
|
28
|
+
"directory": "packages/connect"
|
|
29
|
+
},
|
|
30
|
+
"bugs": {
|
|
31
|
+
"url": "https://github.com/bierfor/nexus/issues"
|
|
32
|
+
},
|
|
33
|
+
"keywords": [
|
|
34
|
+
"nexus",
|
|
35
|
+
"framework",
|
|
36
|
+
"full-stack",
|
|
37
|
+
"svelte",
|
|
38
|
+
"islands",
|
|
39
|
+
"ssr",
|
|
40
|
+
"vite",
|
|
41
|
+
"server-actions"
|
|
42
|
+
],
|
|
43
|
+
"files": [
|
|
44
|
+
"dist",
|
|
45
|
+
"README.md"
|
|
46
|
+
],
|
|
47
|
+
"publishConfig": {
|
|
48
|
+
"access": "public",
|
|
49
|
+
"registry": "https://registry.npmjs.org/"
|
|
50
|
+
},
|
|
51
|
+
"scripts": {
|
|
52
|
+
"build": "tsc -p tsconfig.json",
|
|
53
|
+
"dev": "tsc -p tsconfig.json --watch",
|
|
54
|
+
"test": "vitest run --passWithNoTests",
|
|
55
|
+
"clean": "rm -rf dist"
|
|
56
|
+
}
|
|
57
|
+
}
|