@synap-core/client 0.1.0 → 0.2.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/dist/chunk-6MAWMLEW.js +66 -0
- package/dist/chunk-BVKLN5W3.js +118 -0
- package/dist/index.cjs +135 -1
- package/dist/index.d.ts +40 -1276
- package/dist/index.js +13 -1
- package/dist/react/provider.js +6 -60
- package/dist/react/usePresence.d.ts +29 -0
- package/dist/react/useYjs.d.ts +24 -0
- package/dist/react.cjs +109 -6
- package/dist/react.d.ts +10 -0
- package/dist/react.js +88 -1
- package/dist/realtime.cjs +109 -73
- package/dist/realtime.d.ts +59 -56
- package/dist/realtime.js +6 -90
- package/package.json +10 -3
package/dist/realtime.d.ts
CHANGED
|
@@ -1,80 +1,83 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Real-
|
|
2
|
+
* Real-Time Client - WebSocket connection management for Synap
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* Manages two WebSocket namespaces:
|
|
5
|
+
* 1. /presence - Generic real-time presence and collaboration
|
|
6
|
+
* 2. /yjs - Yjs CRDT synchronization
|
|
6
7
|
*/
|
|
7
|
-
|
|
8
|
-
* NotificationMessage type definition
|
|
9
|
-
*
|
|
10
|
-
* Matches the type from @synap/realtime but defined here to avoid dependency.
|
|
11
|
-
*/
|
|
12
|
-
export interface NotificationMessage {
|
|
13
|
-
type: string;
|
|
14
|
-
data: Record<string, unknown>;
|
|
15
|
-
requestId?: string;
|
|
16
|
-
timestamp?: string;
|
|
17
|
-
status?: 'success' | 'error' | 'pending';
|
|
18
|
-
}
|
|
8
|
+
import * as Y from 'yjs';
|
|
19
9
|
export interface RealtimeConfig {
|
|
20
|
-
/** WebSocket URL (e.g., 'wss://realtime.synap.app/rooms/user_123/subscribe') */
|
|
21
10
|
url: string;
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
/** Callback when an error occurs */
|
|
27
|
-
onError?: (error: Error) => void;
|
|
28
|
-
/** Callback when connection is established */
|
|
29
|
-
onConnect?: () => void;
|
|
30
|
-
/** Callback when connection is closed */
|
|
31
|
-
onDisconnect?: () => void;
|
|
32
|
-
/** Maximum number of reconnection attempts (default: 5) */
|
|
33
|
-
maxReconnectAttempts?: number;
|
|
34
|
-
/** Reconnection delay in milliseconds (default: 1000) */
|
|
35
|
-
reconnectDelay?: number;
|
|
11
|
+
auth: {
|
|
12
|
+
userId: string;
|
|
13
|
+
userName: string;
|
|
14
|
+
};
|
|
36
15
|
}
|
|
16
|
+
type EventCallback = (...args: any[]) => void;
|
|
37
17
|
/**
|
|
38
|
-
* Real-time
|
|
18
|
+
* Real-time collaboration client
|
|
39
19
|
*
|
|
40
|
-
*
|
|
20
|
+
* Handles presence tracking and Yjs document synchronization.
|
|
41
21
|
*
|
|
42
22
|
* @example
|
|
43
23
|
* ```typescript
|
|
44
|
-
* const realtime = new
|
|
45
|
-
* url: '
|
|
46
|
-
* userId: 'user-123',
|
|
47
|
-
* onMessage: (message) => {
|
|
48
|
-
* console.log('Received:', message);
|
|
49
|
-
* if (message.type === 'note.creation.completed') {
|
|
50
|
-
* // Refresh notes list
|
|
51
|
-
* }
|
|
52
|
-
* },
|
|
24
|
+
* const realtime = new RealtimeClient({
|
|
25
|
+
* url: 'http://localhost:3001',
|
|
26
|
+
* auth: { userId: 'user-123', userName: 'Alice' }
|
|
53
27
|
* });
|
|
54
28
|
*
|
|
55
|
-
*
|
|
29
|
+
* // Connect to presence
|
|
30
|
+
* realtime.connectPresence('view-id', 'whiteboard');
|
|
31
|
+
* realtime.on('user-joined', (user) => console.log(user));
|
|
32
|
+
*
|
|
33
|
+
* // Connect to Yjs
|
|
34
|
+
* const ydoc = realtime.connectYjs('view-id');
|
|
35
|
+
* const ymap = ydoc.getMap('shapes');
|
|
56
36
|
* ```
|
|
57
37
|
*/
|
|
58
|
-
export declare class
|
|
59
|
-
private ws;
|
|
38
|
+
export declare class RealtimeClient {
|
|
60
39
|
private config;
|
|
61
|
-
private
|
|
62
|
-
private
|
|
63
|
-
private
|
|
64
|
-
private reconnectTimer;
|
|
65
|
-
private isIntentionallyDisconnected;
|
|
40
|
+
private presenceSocket;
|
|
41
|
+
private yjsSocket;
|
|
42
|
+
private listeners;
|
|
66
43
|
constructor(config: RealtimeConfig);
|
|
67
44
|
/**
|
|
68
|
-
* Connect to
|
|
45
|
+
* Connect to presence namespace for real-time collaboration
|
|
69
46
|
*/
|
|
70
|
-
|
|
47
|
+
connectPresence(viewId: string, viewType?: string): void;
|
|
71
48
|
/**
|
|
72
|
-
*
|
|
49
|
+
* Connect to Yjs namespace for CRDT synchronization
|
|
50
|
+
*
|
|
51
|
+
* @returns Yjs document that auto-syncs with server
|
|
73
52
|
*/
|
|
74
|
-
|
|
53
|
+
connectYjs(roomName: string): Y.Doc;
|
|
54
|
+
/**
|
|
55
|
+
* Subscribe to events
|
|
56
|
+
*/
|
|
57
|
+
on(event: string, callback: EventCallback): void;
|
|
58
|
+
/**
|
|
59
|
+
* Unsubscribe from events
|
|
60
|
+
*/
|
|
61
|
+
off(event: string, callback: EventCallback): void;
|
|
75
62
|
/**
|
|
76
|
-
*
|
|
63
|
+
* Emit event to all listeners
|
|
77
64
|
*/
|
|
78
|
-
|
|
79
|
-
|
|
65
|
+
private emit;
|
|
66
|
+
/**
|
|
67
|
+
* Move cursor (presence)
|
|
68
|
+
*/
|
|
69
|
+
moveCursor(x: number, y: number): void;
|
|
70
|
+
/**
|
|
71
|
+
* Set typing indicator
|
|
72
|
+
*/
|
|
73
|
+
setTyping(isTyping: boolean): void;
|
|
74
|
+
/**
|
|
75
|
+
* Disconnect all connections
|
|
76
|
+
*/
|
|
77
|
+
disconnect(): void;
|
|
80
78
|
}
|
|
79
|
+
/**
|
|
80
|
+
* Create a real-time client instance
|
|
81
|
+
*/
|
|
82
|
+
export declare function createRealtimeClient(config: RealtimeConfig): RealtimeClient;
|
|
83
|
+
export {};
|
package/dist/realtime.js
CHANGED
|
@@ -1,92 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
reconnectAttempts = 0;
|
|
6
|
-
maxReconnectAttempts;
|
|
7
|
-
reconnectDelay;
|
|
8
|
-
reconnectTimer = null;
|
|
9
|
-
isIntentionallyDisconnected = false;
|
|
10
|
-
constructor(config) {
|
|
11
|
-
this.config = config;
|
|
12
|
-
this.maxReconnectAttempts = config.maxReconnectAttempts ?? 5;
|
|
13
|
-
this.reconnectDelay = config.reconnectDelay ?? 1e3;
|
|
14
|
-
}
|
|
15
|
-
/**
|
|
16
|
-
* Connect to the WebSocket server
|
|
17
|
-
*/
|
|
18
|
-
connect() {
|
|
19
|
-
if (this.ws?.readyState === WebSocket.OPEN) {
|
|
20
|
-
return;
|
|
21
|
-
}
|
|
22
|
-
this.isIntentionallyDisconnected = false;
|
|
23
|
-
const wsUrl = this.config.url;
|
|
24
|
-
try {
|
|
25
|
-
this.ws = new WebSocket(wsUrl);
|
|
26
|
-
this.ws.onopen = () => {
|
|
27
|
-
this.reconnectAttempts = 0;
|
|
28
|
-
this.config.onConnect?.();
|
|
29
|
-
};
|
|
30
|
-
this.ws.onmessage = (event) => {
|
|
31
|
-
try {
|
|
32
|
-
const message = JSON.parse(event.data);
|
|
33
|
-
this.config.onMessage?.(message);
|
|
34
|
-
} catch (error) {
|
|
35
|
-
console.error("Failed to parse WebSocket message:", error);
|
|
36
|
-
this.config.onError?.(
|
|
37
|
-
new Error(`Failed to parse message: ${error instanceof Error ? error.message : String(error)}`)
|
|
38
|
-
);
|
|
39
|
-
}
|
|
40
|
-
};
|
|
41
|
-
this.ws.onerror = () => {
|
|
42
|
-
this.config.onError?.(new Error("WebSocket error"));
|
|
43
|
-
};
|
|
44
|
-
this.ws.onclose = () => {
|
|
45
|
-
this.config.onDisconnect?.();
|
|
46
|
-
if (!this.isIntentionallyDisconnected) {
|
|
47
|
-
this.attemptReconnect();
|
|
48
|
-
}
|
|
49
|
-
};
|
|
50
|
-
} catch (error) {
|
|
51
|
-
this.config.onError?.(
|
|
52
|
-
error instanceof Error ? error : new Error(String(error))
|
|
53
|
-
);
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
/**
|
|
57
|
-
* Disconnect from the WebSocket server
|
|
58
|
-
*/
|
|
59
|
-
disconnect() {
|
|
60
|
-
this.isIntentionallyDisconnected = true;
|
|
61
|
-
if (this.reconnectTimer) {
|
|
62
|
-
clearTimeout(this.reconnectTimer);
|
|
63
|
-
this.reconnectTimer = null;
|
|
64
|
-
}
|
|
65
|
-
if (this.ws) {
|
|
66
|
-
this.ws.close();
|
|
67
|
-
this.ws = null;
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
/**
|
|
71
|
-
* Check if currently connected
|
|
72
|
-
*/
|
|
73
|
-
isConnected() {
|
|
74
|
-
return this.ws?.readyState === WebSocket.OPEN;
|
|
75
|
-
}
|
|
76
|
-
attemptReconnect() {
|
|
77
|
-
if (this.reconnectAttempts >= this.maxReconnectAttempts) {
|
|
78
|
-
this.config.onError?.(
|
|
79
|
-
new Error(`Max reconnection attempts (${this.maxReconnectAttempts}) reached`)
|
|
80
|
-
);
|
|
81
|
-
return;
|
|
82
|
-
}
|
|
83
|
-
this.reconnectAttempts++;
|
|
84
|
-
const delay = this.reconnectDelay * this.reconnectAttempts;
|
|
85
|
-
this.reconnectTimer = setTimeout(() => {
|
|
86
|
-
this.connect();
|
|
87
|
-
}, delay);
|
|
88
|
-
}
|
|
89
|
-
};
|
|
1
|
+
import {
|
|
2
|
+
RealtimeClient,
|
|
3
|
+
createRealtimeClient
|
|
4
|
+
} from "./chunk-BVKLN5W3.js";
|
|
90
5
|
export {
|
|
91
|
-
|
|
6
|
+
RealtimeClient,
|
|
7
|
+
createRealtimeClient
|
|
92
8
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@synap-core/client",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Type-safe client SDK for Synap Core OS",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"publishConfig": {
|
|
@@ -32,9 +32,13 @@
|
|
|
32
32
|
],
|
|
33
33
|
"dependencies": {
|
|
34
34
|
"@trpc/client": "^11.0.0",
|
|
35
|
-
"zod": "^3.22.0"
|
|
35
|
+
"zod": "^3.22.0",
|
|
36
|
+
"socket.io-client": "^4.7.2",
|
|
37
|
+
"yjs": "^13.6.11",
|
|
38
|
+
"lib0": "^0.2.97"
|
|
36
39
|
},
|
|
37
40
|
"peerDependencies": {
|
|
41
|
+
"@synap-core/types": "^0.1.0",
|
|
38
42
|
"@tanstack/react-query": "^5.0.0",
|
|
39
43
|
"@trpc/react-query": "^11.0.0",
|
|
40
44
|
"react": "^18.0.0"
|
|
@@ -58,7 +62,10 @@
|
|
|
58
62
|
"client",
|
|
59
63
|
"sdk",
|
|
60
64
|
"knowledge-management",
|
|
61
|
-
"ai"
|
|
65
|
+
"ai",
|
|
66
|
+
"realtime",
|
|
67
|
+
"websocket",
|
|
68
|
+
"yjs"
|
|
62
69
|
],
|
|
63
70
|
"license": "MIT",
|
|
64
71
|
"repository": {
|