@flightdev/realtime 0.0.2
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 +410 -0
- package/dist/adapters/sse.d.ts +59 -0
- package/dist/adapters/sse.js +188 -0
- package/dist/adapters/sse.js.map +1 -0
- package/dist/adapters/websocket.d.ts +40 -0
- package/dist/adapters/websocket.js +161 -0
- package/dist/adapters/websocket.js.map +1 -0
- package/dist/chunk-D6OMTDYP.js +85 -0
- package/dist/chunk-D6OMTDYP.js.map +1 -0
- package/dist/frameworks/react.d.ts +81 -0
- package/dist/frameworks/react.js +93 -0
- package/dist/frameworks/react.js.map +1 -0
- package/dist/frameworks/vue.d.ts +29 -0
- package/dist/frameworks/vue.js +55 -0
- package/dist/frameworks/vue.js.map +1 -0
- package/dist/index.d.ts +168 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/package.json +65 -0
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { ref, onUnmounted } from 'vue';
|
|
2
|
+
|
|
3
|
+
// src/frameworks/vue.ts
|
|
4
|
+
function useRealtime(realtime) {
|
|
5
|
+
const state = ref(realtime.state);
|
|
6
|
+
const error = ref(null);
|
|
7
|
+
const unsubState = realtime.onStateChange((s) => {
|
|
8
|
+
state.value = s;
|
|
9
|
+
});
|
|
10
|
+
const unsubError = realtime.onError((e) => {
|
|
11
|
+
error.value = e;
|
|
12
|
+
});
|
|
13
|
+
onUnmounted(() => {
|
|
14
|
+
unsubState();
|
|
15
|
+
unsubError();
|
|
16
|
+
});
|
|
17
|
+
async function connect() {
|
|
18
|
+
try {
|
|
19
|
+
await realtime.connect();
|
|
20
|
+
error.value = null;
|
|
21
|
+
} catch (err) {
|
|
22
|
+
error.value = err;
|
|
23
|
+
throw err;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
function disconnect() {
|
|
27
|
+
realtime.disconnect();
|
|
28
|
+
}
|
|
29
|
+
return { state, connect, disconnect, error };
|
|
30
|
+
}
|
|
31
|
+
function useChannel(realtime, channelName, options = {}) {
|
|
32
|
+
const { maxMessages = 100, event } = options;
|
|
33
|
+
const messages = ref([]);
|
|
34
|
+
const channel = realtime.channel(channelName);
|
|
35
|
+
const handleMessage = (msg) => {
|
|
36
|
+
messages.value = [...messages.value, msg].slice(-maxMessages);
|
|
37
|
+
};
|
|
38
|
+
const unsubscribe = event ? channel.on(event, handleMessage) : channel.subscribe(handleMessage);
|
|
39
|
+
onUnmounted(() => {
|
|
40
|
+
unsubscribe();
|
|
41
|
+
channel.leave();
|
|
42
|
+
});
|
|
43
|
+
function send(data, eventType = "message") {
|
|
44
|
+
channel.send(data, eventType);
|
|
45
|
+
}
|
|
46
|
+
function clear() {
|
|
47
|
+
messages.value = [];
|
|
48
|
+
}
|
|
49
|
+
return { messages, send, clear };
|
|
50
|
+
}
|
|
51
|
+
var vue_default = { useRealtime, useChannel };
|
|
52
|
+
|
|
53
|
+
export { vue_default as default, useChannel, useRealtime };
|
|
54
|
+
//# sourceMappingURL=vue.js.map
|
|
55
|
+
//# sourceMappingURL=vue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/frameworks/vue.ts"],"names":[],"mappings":";;;AAcO,SAAS,YAAY,QAAA,EAA8C;AACtE,EAAA,MAAM,KAAA,GAAQ,GAAA,CAAqB,QAAA,CAAS,KAAK,CAAA;AACjD,EAAA,MAAM,KAAA,GAAQ,IAAkB,IAAI,CAAA;AAEpC,EAAA,MAAM,UAAA,GAAa,QAAA,CAAS,aAAA,CAAc,CAAC,CAAA,KAAM;AAAE,IAAA,KAAA,CAAM,KAAA,GAAQ,CAAA;AAAA,EAAG,CAAC,CAAA;AACrE,EAAA,MAAM,UAAA,GAAa,QAAA,CAAS,OAAA,CAAQ,CAAC,CAAA,KAAM;AAAE,IAAA,KAAA,CAAM,KAAA,GAAQ,CAAA;AAAA,EAAG,CAAC,CAAA;AAE/D,EAAA,WAAA,CAAY,MAAM;AACd,IAAA,UAAA,EAAW;AACX,IAAA,UAAA,EAAW;AAAA,EACf,CAAC,CAAA;AAED,EAAA,eAAe,OAAA,GAAU;AACrB,IAAA,IAAI;AACA,MAAA,MAAM,SAAS,OAAA,EAAQ;AACvB,MAAA,KAAA,CAAM,KAAA,GAAQ,IAAA;AAAA,IAClB,SAAS,GAAA,EAAK;AACV,MAAA,KAAA,CAAM,KAAA,GAAQ,GAAA;AACd,MAAA,MAAM,GAAA;AAAA,IACV;AAAA,EACJ;AAEA,EAAA,SAAS,UAAA,GAAa;AAClB,IAAA,QAAA,CAAS,UAAA,EAAW;AAAA,EACxB;AAEA,EAAA,OAAO,EAAE,KAAA,EAAO,OAAA,EAAS,UAAA,EAAY,KAAA,EAAM;AAC/C;AAQO,SAAS,UAAA,CACZ,QAAA,EACA,WAAA,EACA,OAAA,GAAoD,EAAC,EAClC;AACnB,EAAA,MAAM,EAAE,WAAA,GAAc,GAAA,EAAK,KAAA,EAAM,GAAI,OAAA;AACrC,EAAA,MAAM,QAAA,GAAW,GAAA,CAA0B,EAAE,CAAA;AAC7C,EAAA,MAAM,OAAA,GAAU,QAAA,CAAS,OAAA,CAAW,WAAW,CAAA;AAE/C,EAAA,MAAM,aAAA,GAAgB,CAAC,GAAA,KAA4B;AAC/C,IAAA,QAAA,CAAS,KAAA,GAAQ,CAAC,GAAG,QAAA,CAAS,OAAO,GAAG,CAAA,CAAE,KAAA,CAAM,CAAC,WAAW,CAAA;AAAA,EAChE,CAAA;AAEA,EAAA,MAAM,WAAA,GAAc,QACd,OAAA,CAAQ,EAAA,CAAG,OAAO,aAAa,CAAA,GAC/B,OAAA,CAAQ,SAAA,CAAU,aAAa,CAAA;AAErC,EAAA,WAAA,CAAY,MAAM;AACd,IAAA,WAAA,EAAY;AACZ,IAAA,OAAA,CAAQ,KAAA,EAAM;AAAA,EAClB,CAAC,CAAA;AAED,EAAA,SAAS,IAAA,CAAK,IAAA,EAAS,SAAA,GAAY,SAAA,EAAW;AAC1C,IAAA,OAAA,CAAQ,IAAA,CAAK,MAAM,SAAS,CAAA;AAAA,EAChC;AAEA,EAAA,SAAS,KAAA,GAAQ;AACb,IAAA,QAAA,CAAS,QAAQ,EAAC;AAAA,EACtB;AAEA,EAAA,OAAO,EAAE,QAAA,EAAU,IAAA,EAAM,KAAA,EAAM;AACnC;AAEA,IAAO,WAAA,GAAQ,EAAE,WAAA,EAAa,UAAA","file":"vue.js","sourcesContent":["/**\r\n * Vue Composables for @flightdev/realtime\r\n */\r\n\r\nimport { ref, onUnmounted, type Ref } from 'vue';\r\nimport type { RealtimeService, RealtimeMessage, ConnectionState } from '../index.js';\r\n\r\nexport interface UseRealtimeReturn {\r\n state: Ref<ConnectionState>;\r\n connect: () => Promise<void>;\r\n disconnect: () => void;\r\n error: Ref<Error | null>;\r\n}\r\n\r\nexport function useRealtime(realtime: RealtimeService): UseRealtimeReturn {\r\n const state = ref<ConnectionState>(realtime.state);\r\n const error = ref<Error | null>(null);\r\n\r\n const unsubState = realtime.onStateChange((s) => { state.value = s; });\r\n const unsubError = realtime.onError((e) => { error.value = e; });\r\n\r\n onUnmounted(() => {\r\n unsubState();\r\n unsubError();\r\n });\r\n\r\n async function connect() {\r\n try {\r\n await realtime.connect();\r\n error.value = null;\r\n } catch (err) {\r\n error.value = err as Error;\r\n throw err;\r\n }\r\n }\r\n\r\n function disconnect() {\r\n realtime.disconnect();\r\n }\r\n\r\n return { state, connect, disconnect, error };\r\n}\r\n\r\nexport interface UseChannelReturn<T> {\r\n messages: Ref<RealtimeMessage<T>[]>;\r\n send: (data: T, event?: string) => void;\r\n clear: () => void;\r\n}\r\n\r\nexport function useChannel<T = unknown>(\r\n realtime: RealtimeService,\r\n channelName: string,\r\n options: { maxMessages?: number; event?: string } = {}\r\n): UseChannelReturn<T> {\r\n const { maxMessages = 100, event } = options;\r\n const messages = ref<RealtimeMessage<T>[]>([]) as Ref<RealtimeMessage<T>[]>;\r\n const channel = realtime.channel<T>(channelName);\r\n\r\n const handleMessage = (msg: RealtimeMessage<T>) => {\r\n messages.value = [...messages.value, msg].slice(-maxMessages);\r\n };\r\n\r\n const unsubscribe = event\r\n ? channel.on(event, handleMessage)\r\n : channel.subscribe(handleMessage);\r\n\r\n onUnmounted(() => {\r\n unsubscribe();\r\n channel.leave();\r\n });\r\n\r\n function send(data: T, eventType = 'message') {\r\n channel.send(data, eventType);\r\n }\r\n\r\n function clear() {\r\n messages.value = [];\r\n }\r\n\r\n return { messages, send, clear };\r\n}\r\n\r\nexport default { useRealtime, useChannel };\r\n"]}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @flightdev/realtime - Agnostic Real-time Communication
|
|
3
|
+
*
|
|
4
|
+
* Flight provides real-time primitives, you choose the transport.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```typescript
|
|
8
|
+
* import { createRealtime } from '@flightdev/realtime';
|
|
9
|
+
* import { websocket } from '@flightdev/realtime/websocket';
|
|
10
|
+
*
|
|
11
|
+
* const realtime = createRealtime(websocket({ port: 3001 }));
|
|
12
|
+
*
|
|
13
|
+
* // Create a channel
|
|
14
|
+
* const chat = realtime.channel('chat');
|
|
15
|
+
*
|
|
16
|
+
* // Broadcast a message
|
|
17
|
+
* chat.broadcast({ message: 'Hello!' });
|
|
18
|
+
*
|
|
19
|
+
* // Subscribe to messages
|
|
20
|
+
* chat.subscribe((message) => console.log(message));
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
/** Real-time message payload */
|
|
24
|
+
interface RealtimeMessage<T = unknown> {
|
|
25
|
+
/** Unique message ID */
|
|
26
|
+
id: string;
|
|
27
|
+
/** Channel name */
|
|
28
|
+
channel: string;
|
|
29
|
+
/** Event type */
|
|
30
|
+
event: string;
|
|
31
|
+
/** Message payload */
|
|
32
|
+
data: T;
|
|
33
|
+
/** Timestamp */
|
|
34
|
+
timestamp: number;
|
|
35
|
+
/** Sender ID (optional) */
|
|
36
|
+
senderId?: string;
|
|
37
|
+
}
|
|
38
|
+
/** Connection state */
|
|
39
|
+
type ConnectionState = 'connecting' | 'connected' | 'disconnected' | 'reconnecting';
|
|
40
|
+
/** Subscription callback */
|
|
41
|
+
type SubscriptionCallback<T = unknown> = (message: RealtimeMessage<T>) => void;
|
|
42
|
+
/** Unsubscribe function */
|
|
43
|
+
type Unsubscribe = () => void;
|
|
44
|
+
/** Channel options */
|
|
45
|
+
interface ChannelOptions {
|
|
46
|
+
/** Require authentication */
|
|
47
|
+
auth?: boolean;
|
|
48
|
+
/** Private channel (single user) */
|
|
49
|
+
private?: boolean;
|
|
50
|
+
/** Presence tracking */
|
|
51
|
+
presence?: boolean;
|
|
52
|
+
}
|
|
53
|
+
/** Presence info */
|
|
54
|
+
interface PresenceInfo<T = unknown> {
|
|
55
|
+
/** User ID */
|
|
56
|
+
userId: string;
|
|
57
|
+
/** User info */
|
|
58
|
+
info: T;
|
|
59
|
+
/** Joined at timestamp */
|
|
60
|
+
joinedAt: number;
|
|
61
|
+
}
|
|
62
|
+
/** Real-time channel */
|
|
63
|
+
interface RealtimeChannel<T = unknown> {
|
|
64
|
+
/** Channel name */
|
|
65
|
+
readonly name: string;
|
|
66
|
+
/** Subscribe to all messages on this channel */
|
|
67
|
+
subscribe(callback: SubscriptionCallback<T>): Unsubscribe;
|
|
68
|
+
/** Subscribe to a specific event */
|
|
69
|
+
on(event: string, callback: SubscriptionCallback<T>): Unsubscribe;
|
|
70
|
+
/** Broadcast a message to all subscribers */
|
|
71
|
+
broadcast(data: T, event?: string): void;
|
|
72
|
+
/** Send a message (alias for broadcast) */
|
|
73
|
+
send(data: T, event?: string): void;
|
|
74
|
+
/** Leave the channel */
|
|
75
|
+
leave(): void;
|
|
76
|
+
/** Get presence information (if enabled) */
|
|
77
|
+
getPresence?(): Promise<PresenceInfo[]>;
|
|
78
|
+
/** Track user presence */
|
|
79
|
+
trackPresence?(info: unknown): void;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Real-time Adapter Interface
|
|
83
|
+
*
|
|
84
|
+
* Implement this to create a custom transport.
|
|
85
|
+
* Flight provides WebSocket and SSE adapters.
|
|
86
|
+
*/
|
|
87
|
+
interface RealtimeAdapter {
|
|
88
|
+
/** Adapter name */
|
|
89
|
+
readonly name: string;
|
|
90
|
+
/** Current connection state */
|
|
91
|
+
readonly state: ConnectionState;
|
|
92
|
+
/** Connect to the server */
|
|
93
|
+
connect(): Promise<void>;
|
|
94
|
+
/** Disconnect from the server */
|
|
95
|
+
disconnect(): void;
|
|
96
|
+
/** Join a channel */
|
|
97
|
+
channel<T = unknown>(name: string, options?: ChannelOptions): RealtimeChannel<T>;
|
|
98
|
+
/** Subscribe to connection state changes */
|
|
99
|
+
onStateChange(callback: (state: ConnectionState) => void): Unsubscribe;
|
|
100
|
+
/** Subscribe to errors */
|
|
101
|
+
onError(callback: (error: Error) => void): Unsubscribe;
|
|
102
|
+
/** Send a raw message */
|
|
103
|
+
send(channel: string, event: string, data: unknown): void;
|
|
104
|
+
/** Handle incoming message (for server-side) */
|
|
105
|
+
handleMessage?(handler: (message: RealtimeMessage) => void): void;
|
|
106
|
+
}
|
|
107
|
+
/** Adapter factory type */
|
|
108
|
+
type RealtimeAdapterFactory<TConfig = unknown> = (config?: TConfig) => RealtimeAdapter;
|
|
109
|
+
/** Real-time service options */
|
|
110
|
+
interface RealtimeServiceOptions {
|
|
111
|
+
/** Auto-connect on creation */
|
|
112
|
+
autoConnect?: boolean;
|
|
113
|
+
/** Reconnect on disconnect */
|
|
114
|
+
reconnect?: boolean;
|
|
115
|
+
/** Maximum reconnect attempts */
|
|
116
|
+
maxReconnectAttempts?: number;
|
|
117
|
+
/** Reconnect delay in ms */
|
|
118
|
+
reconnectDelay?: number;
|
|
119
|
+
}
|
|
120
|
+
/** Real-time service */
|
|
121
|
+
interface RealtimeService {
|
|
122
|
+
/** The underlying adapter */
|
|
123
|
+
readonly adapter: RealtimeAdapter;
|
|
124
|
+
/** Current connection state */
|
|
125
|
+
readonly state: ConnectionState;
|
|
126
|
+
/** Connect to the server */
|
|
127
|
+
connect(): Promise<void>;
|
|
128
|
+
/** Disconnect from the server */
|
|
129
|
+
disconnect(): void;
|
|
130
|
+
/** Get or create a channel */
|
|
131
|
+
channel<T = unknown>(name: string, options?: ChannelOptions): RealtimeChannel<T>;
|
|
132
|
+
/** Subscribe to connection state changes */
|
|
133
|
+
onStateChange(callback: (state: ConnectionState) => void): Unsubscribe;
|
|
134
|
+
/** Subscribe to errors */
|
|
135
|
+
onError(callback: (error: Error) => void): Unsubscribe;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Create a real-time service
|
|
139
|
+
*
|
|
140
|
+
* @example
|
|
141
|
+
* ```typescript
|
|
142
|
+
* import { createRealtime } from '@flightdev/realtime';
|
|
143
|
+
* import { websocket } from '@flightdev/realtime/websocket';
|
|
144
|
+
*
|
|
145
|
+
* const realtime = createRealtime(websocket({ port: 3001 }));
|
|
146
|
+
*
|
|
147
|
+
* await realtime.connect();
|
|
148
|
+
*
|
|
149
|
+
* const chat = realtime.channel('chat');
|
|
150
|
+
* chat.on('message', (msg) => console.log(msg));
|
|
151
|
+
* chat.send({ text: 'Hello!' }, 'message');
|
|
152
|
+
* ```
|
|
153
|
+
*/
|
|
154
|
+
declare function createRealtime(adapter: RealtimeAdapter, options?: RealtimeServiceOptions): RealtimeService;
|
|
155
|
+
/**
|
|
156
|
+
* Create a message object
|
|
157
|
+
*/
|
|
158
|
+
declare function createMessage<T>(channel: string, event: string, data: T, senderId?: string): RealtimeMessage<T>;
|
|
159
|
+
/**
|
|
160
|
+
* Parse a message from JSON string
|
|
161
|
+
*/
|
|
162
|
+
declare function parseMessage(json: string): RealtimeMessage | null;
|
|
163
|
+
/**
|
|
164
|
+
* Serialize a message to JSON string
|
|
165
|
+
*/
|
|
166
|
+
declare function serializeMessage(message: RealtimeMessage): string;
|
|
167
|
+
|
|
168
|
+
export { type ChannelOptions, type ConnectionState, type PresenceInfo, type RealtimeAdapter, type RealtimeAdapterFactory, type RealtimeChannel, type RealtimeMessage, type RealtimeService, type RealtimeServiceOptions, type SubscriptionCallback, type Unsubscribe, createMessage, createRealtime, parseMessage, serializeMessage };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
|
package/package.json
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@flightdev/realtime",
|
|
3
|
+
"version": "0.0.2",
|
|
4
|
+
"description": "Agnostic real-time communication for Flight Framework. Choose your transport: WebSocket, SSE, Pusher, or custom.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"exports": {
|
|
7
|
+
".": {
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"import": "./dist/index.js"
|
|
10
|
+
},
|
|
11
|
+
"./websocket": {
|
|
12
|
+
"types": "./dist/adapters/websocket.d.ts",
|
|
13
|
+
"import": "./dist/adapters/websocket.js"
|
|
14
|
+
},
|
|
15
|
+
"./sse": {
|
|
16
|
+
"types": "./dist/adapters/sse.d.ts",
|
|
17
|
+
"import": "./dist/adapters/sse.js"
|
|
18
|
+
},
|
|
19
|
+
"./react": {
|
|
20
|
+
"types": "./dist/frameworks/react.d.ts",
|
|
21
|
+
"import": "./dist/frameworks/react.js"
|
|
22
|
+
},
|
|
23
|
+
"./vue": {
|
|
24
|
+
"types": "./dist/frameworks/vue.d.ts",
|
|
25
|
+
"import": "./dist/frameworks/vue.js"
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
"files": [
|
|
29
|
+
"dist"
|
|
30
|
+
],
|
|
31
|
+
"dependencies": {},
|
|
32
|
+
"peerDependencies": {
|
|
33
|
+
"react": ">=18.0.0",
|
|
34
|
+
"vue": ">=3.0.0"
|
|
35
|
+
},
|
|
36
|
+
"peerDependenciesMeta": {
|
|
37
|
+
"react": {
|
|
38
|
+
"optional": true
|
|
39
|
+
},
|
|
40
|
+
"vue": {
|
|
41
|
+
"optional": true
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
"devDependencies": {
|
|
45
|
+
"@types/node": "^22.0.0",
|
|
46
|
+
"@types/react": "^19.0.0",
|
|
47
|
+
"tsup": "^8.0.0",
|
|
48
|
+
"typescript": "^5.7.0",
|
|
49
|
+
"vitest": "^2.0.0"
|
|
50
|
+
},
|
|
51
|
+
"keywords": [
|
|
52
|
+
"flight",
|
|
53
|
+
"realtime",
|
|
54
|
+
"websocket",
|
|
55
|
+
"sse",
|
|
56
|
+
"pubsub"
|
|
57
|
+
],
|
|
58
|
+
"license": "MIT",
|
|
59
|
+
"scripts": {
|
|
60
|
+
"build": "tsup",
|
|
61
|
+
"dev": "tsup --watch",
|
|
62
|
+
"test": "vitest run",
|
|
63
|
+
"typecheck": "tsc --noEmit"
|
|
64
|
+
}
|
|
65
|
+
}
|