@marianmeres/ws 0.4.1 → 0.5.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/AGENTS.md +63 -15
- package/API.md +232 -61
- package/README.md +176 -80
- package/dist/client/outbox.d.ts +40 -8
- package/dist/client/outbox.js +35 -11
- package/dist/client/rooms.d.ts +5 -5
- package/dist/client/rooms.js +1 -1
- package/dist/client/ws-client.d.ts +132 -15
- package/dist/client/ws-client.js +101 -36
- package/dist/mod.d.ts +23 -4
- package/dist/mod.js +22 -3
- package/dist/protocol/constants.d.ts +35 -16
- package/dist/protocol/constants.js +40 -18
- package/dist/protocol/errors.d.ts +12 -2
- package/dist/protocol/errors.js +13 -3
- package/dist/protocol/frames.d.ts +58 -16
- package/dist/protocol/frames.js +5 -0
- package/package.json +1 -1
|
@@ -11,8 +11,13 @@
|
|
|
11
11
|
*
|
|
12
12
|
* It costs nothing today and it is the only thing that makes a breaking
|
|
13
13
|
* protocol change survivable later.
|
|
14
|
+
*
|
|
15
|
+
* Version 2 split the protocol into a required **core** (handshake, messages
|
|
16
|
+
* in both directions, heartbeat) and an optional **rooms extension**
|
|
17
|
+
* (subscriptions, publishing, presence, broadcast), so a server that only
|
|
18
|
+
* needs a data channel implements the core and nothing else.
|
|
14
19
|
*/
|
|
15
|
-
export declare const PROTOCOL_VERSION =
|
|
20
|
+
export declare const PROTOCOL_VERSION = 2;
|
|
16
21
|
/** Namespace used when the client does not specify one. */
|
|
17
22
|
export declare const DEFAULT_NAMESPACE = "default";
|
|
18
23
|
/**
|
|
@@ -21,34 +26,43 @@ export declare const DEFAULT_NAMESPACE = "default";
|
|
|
21
26
|
* Note these are *protocol* types and have nothing to do with whatever the
|
|
22
27
|
* application puts inside `payload` — the payload is opaque and is never
|
|
23
28
|
* inspected nor mutated by this library.
|
|
29
|
+
*
|
|
30
|
+
* Every server implements the **core** frames. The **rooms extension**
|
|
31
|
+
* frames are sent only when the application uses rooms (`subscribe()`,
|
|
32
|
+
* `publish()`, `broadcast()`, presence), so a server that does not support
|
|
33
|
+
* them never sees one.
|
|
24
34
|
*/
|
|
25
35
|
export declare const FRAME: {
|
|
26
36
|
/** Handshake. Always the first frame; carries the auth payload. */
|
|
27
37
|
readonly AUTH: "auth";
|
|
28
|
-
/** Join one or more rooms, optionally with presence. */
|
|
29
|
-
readonly SUB: "sub";
|
|
30
|
-
/** Leave one or more rooms. */
|
|
31
|
-
readonly UNSUB: "unsub";
|
|
32
|
-
/** Publish into a room within the connection's own namespace. */
|
|
33
|
-
readonly PUB: "pub";
|
|
34
|
-
/** Publish into a room across every namespace. Gated server-side. */
|
|
35
|
-
readonly BROADCAST: "broadcast";
|
|
36
38
|
/** Liveness probe. Answered with `pong`. */
|
|
37
39
|
readonly PING: "ping";
|
|
38
|
-
/** Handshake accepted; carries the
|
|
40
|
+
/** Handshake accepted; carries the protocol version (and, with rooms, identity). */
|
|
39
41
|
readonly HELLO: "hello";
|
|
40
|
-
/** Positive acknowledgement of a
|
|
42
|
+
/** Positive acknowledgement of a frame that carried an `id`; may carry a reply. */
|
|
41
43
|
readonly ACK: "ack";
|
|
42
44
|
/** Negative acknowledgement; carries a `WSErrorInfo`. */
|
|
43
45
|
readonly NACK: "nack";
|
|
44
|
-
/** A message delivered to a subscribed room. */
|
|
45
|
-
readonly MSG: "msg";
|
|
46
|
-
/** A membership change in a presence-enabled room. */
|
|
47
|
-
readonly PRESENCE: "presence";
|
|
48
46
|
/** Reply to `ping`. */
|
|
49
47
|
readonly PONG: "pong";
|
|
50
48
|
/** Uncorrelated error — not tied to any request id. */
|
|
51
49
|
readonly ERROR: "error";
|
|
50
|
+
/**
|
|
51
|
+
* A message. Client -> server it is addressed to the server itself;
|
|
52
|
+
* server -> client it is either a direct message (core) or a room delivery
|
|
53
|
+
* (rooms extension, recognisable by its `room` field).
|
|
54
|
+
*/
|
|
55
|
+
readonly MSG: "msg";
|
|
56
|
+
/** Join one or more rooms, optionally with presence. */
|
|
57
|
+
readonly SUB: "sub";
|
|
58
|
+
/** Leave one or more rooms. */
|
|
59
|
+
readonly UNSUB: "unsub";
|
|
60
|
+
/** Publish into a room within the connection's own namespace. */
|
|
61
|
+
readonly PUB: "pub";
|
|
62
|
+
/** Publish into a room across every namespace. Gated server-side. */
|
|
63
|
+
readonly BROADCAST: "broadcast";
|
|
64
|
+
/** A membership change in a presence-enabled room. */
|
|
65
|
+
readonly PRESENCE: "presence";
|
|
52
66
|
};
|
|
53
67
|
/**
|
|
54
68
|
* WebSocket close codes.
|
|
@@ -99,10 +113,15 @@ export declare const ERROR_CODE: {
|
|
|
99
113
|
readonly BAD_REQUEST: "bad_request";
|
|
100
114
|
/** Frame rate cap exceeded. */
|
|
101
115
|
readonly RATE_LIMITED: "rate_limited";
|
|
116
|
+
/**
|
|
117
|
+
* A frame type this server does not implement — typically a rooms frame
|
|
118
|
+
* sent to a core-only server, or a `msg` to a server with no handler.
|
|
119
|
+
*/
|
|
120
|
+
readonly UNSUPPORTED: "unsupported";
|
|
102
121
|
/** Unexpected server-side failure. */
|
|
103
122
|
readonly INTERNAL: "internal";
|
|
104
123
|
};
|
|
105
|
-
/** Presence event kinds. */
|
|
124
|
+
/** Presence event kinds (rooms extension). */
|
|
106
125
|
export declare const PRESENCE: {
|
|
107
126
|
/** Full membership snapshot, sent on every (re)subscribe. */
|
|
108
127
|
readonly SYNC: "sync";
|
|
@@ -11,8 +11,13 @@
|
|
|
11
11
|
*
|
|
12
12
|
* It costs nothing today and it is the only thing that makes a breaking
|
|
13
13
|
* protocol change survivable later.
|
|
14
|
+
*
|
|
15
|
+
* Version 2 split the protocol into a required **core** (handshake, messages
|
|
16
|
+
* in both directions, heartbeat) and an optional **rooms extension**
|
|
17
|
+
* (subscriptions, publishing, presence, broadcast), so a server that only
|
|
18
|
+
* needs a data channel implements the core and nothing else.
|
|
14
19
|
*/
|
|
15
|
-
export const PROTOCOL_VERSION =
|
|
20
|
+
export const PROTOCOL_VERSION = 2;
|
|
16
21
|
/** Namespace used when the client does not specify one. */
|
|
17
22
|
export const DEFAULT_NAMESPACE = "default";
|
|
18
23
|
/**
|
|
@@ -21,36 +26,48 @@ export const DEFAULT_NAMESPACE = "default";
|
|
|
21
26
|
* Note these are *protocol* types and have nothing to do with whatever the
|
|
22
27
|
* application puts inside `payload` — the payload is opaque and is never
|
|
23
28
|
* inspected nor mutated by this library.
|
|
29
|
+
*
|
|
30
|
+
* Every server implements the **core** frames. The **rooms extension**
|
|
31
|
+
* frames are sent only when the application uses rooms (`subscribe()`,
|
|
32
|
+
* `publish()`, `broadcast()`, presence), so a server that does not support
|
|
33
|
+
* them never sees one.
|
|
24
34
|
*/
|
|
25
35
|
export const FRAME = {
|
|
26
|
-
// client -> server
|
|
36
|
+
// core, client -> server
|
|
27
37
|
/** Handshake. Always the first frame; carries the auth payload. */
|
|
28
38
|
AUTH: "auth",
|
|
29
|
-
/** Join one or more rooms, optionally with presence. */
|
|
30
|
-
SUB: "sub",
|
|
31
|
-
/** Leave one or more rooms. */
|
|
32
|
-
UNSUB: "unsub",
|
|
33
|
-
/** Publish into a room within the connection's own namespace. */
|
|
34
|
-
PUB: "pub",
|
|
35
|
-
/** Publish into a room across every namespace. Gated server-side. */
|
|
36
|
-
BROADCAST: "broadcast",
|
|
37
39
|
/** Liveness probe. Answered with `pong`. */
|
|
38
40
|
PING: "ping",
|
|
39
|
-
// server -> client
|
|
40
|
-
/** Handshake accepted; carries the
|
|
41
|
+
// core, server -> client
|
|
42
|
+
/** Handshake accepted; carries the protocol version (and, with rooms, identity). */
|
|
41
43
|
HELLO: "hello",
|
|
42
|
-
/** Positive acknowledgement of a
|
|
44
|
+
/** Positive acknowledgement of a frame that carried an `id`; may carry a reply. */
|
|
43
45
|
ACK: "ack",
|
|
44
46
|
/** Negative acknowledgement; carries a `WSErrorInfo`. */
|
|
45
47
|
NACK: "nack",
|
|
46
|
-
/** A message delivered to a subscribed room. */
|
|
47
|
-
MSG: "msg",
|
|
48
|
-
/** A membership change in a presence-enabled room. */
|
|
49
|
-
PRESENCE: "presence",
|
|
50
48
|
/** Reply to `ping`. */
|
|
51
49
|
PONG: "pong",
|
|
52
50
|
/** Uncorrelated error — not tied to any request id. */
|
|
53
51
|
ERROR: "error",
|
|
52
|
+
// core, both directions
|
|
53
|
+
/**
|
|
54
|
+
* A message. Client -> server it is addressed to the server itself;
|
|
55
|
+
* server -> client it is either a direct message (core) or a room delivery
|
|
56
|
+
* (rooms extension, recognisable by its `room` field).
|
|
57
|
+
*/
|
|
58
|
+
MSG: "msg",
|
|
59
|
+
// rooms extension, client -> server
|
|
60
|
+
/** Join one or more rooms, optionally with presence. */
|
|
61
|
+
SUB: "sub",
|
|
62
|
+
/** Leave one or more rooms. */
|
|
63
|
+
UNSUB: "unsub",
|
|
64
|
+
/** Publish into a room within the connection's own namespace. */
|
|
65
|
+
PUB: "pub",
|
|
66
|
+
/** Publish into a room across every namespace. Gated server-side. */
|
|
67
|
+
BROADCAST: "broadcast",
|
|
68
|
+
// rooms extension, server -> client
|
|
69
|
+
/** A membership change in a presence-enabled room. */
|
|
70
|
+
PRESENCE: "presence",
|
|
54
71
|
};
|
|
55
72
|
/**
|
|
56
73
|
* WebSocket close codes.
|
|
@@ -104,10 +121,15 @@ export const ERROR_CODE = {
|
|
|
104
121
|
BAD_REQUEST: "bad_request",
|
|
105
122
|
/** Frame rate cap exceeded. */
|
|
106
123
|
RATE_LIMITED: "rate_limited",
|
|
124
|
+
/**
|
|
125
|
+
* A frame type this server does not implement — typically a rooms frame
|
|
126
|
+
* sent to a core-only server, or a `msg` to a server with no handler.
|
|
127
|
+
*/
|
|
128
|
+
UNSUPPORTED: "unsupported",
|
|
107
129
|
/** Unexpected server-side failure. */
|
|
108
130
|
INTERNAL: "internal",
|
|
109
131
|
};
|
|
110
|
-
/** Presence event kinds. */
|
|
132
|
+
/** Presence event kinds (rooms extension). */
|
|
111
133
|
export const PRESENCE = {
|
|
112
134
|
/** Full membership snapshot, sent on every (re)subscribe. */
|
|
113
135
|
SYNC: "sync",
|
|
@@ -58,7 +58,12 @@ export declare class WSConnectTimeoutError extends WSError {
|
|
|
58
58
|
*/
|
|
59
59
|
constructor(ms: number);
|
|
60
60
|
}
|
|
61
|
-
/**
|
|
61
|
+
/**
|
|
62
|
+
* `sendTimeout` elapsed while queued, in flight, or awaiting an ack.
|
|
63
|
+
*
|
|
64
|
+
* A send that awaits no ack — `send()` without `{ ack: true }` — can only hit
|
|
65
|
+
* this while still queued, i.e. when no connection came up in time.
|
|
66
|
+
*/
|
|
62
67
|
export declare class WSTimeoutError extends WSError {
|
|
63
68
|
/**
|
|
64
69
|
* Reports the deadline that was exceeded.
|
|
@@ -80,7 +85,12 @@ export declare class WSOutboxDropError extends WSError {
|
|
|
80
85
|
export declare class WSConnectionLostError extends WSError {
|
|
81
86
|
constructor();
|
|
82
87
|
}
|
|
83
|
-
/**
|
|
88
|
+
/**
|
|
89
|
+
* The server rejected the operation with a `nack`.
|
|
90
|
+
*
|
|
91
|
+
* Also the way a server-side `onMessage` hook rejects a message on purpose:
|
|
92
|
+
* throw one, and its `code` and `message` travel back in the `nack` unchanged.
|
|
93
|
+
*/
|
|
84
94
|
export declare class WSRemoteError extends WSError {
|
|
85
95
|
/** Machine-readable code from the server — see `ERROR_CODE`. */
|
|
86
96
|
readonly code: string;
|
package/dist/protocol/errors.js
CHANGED
|
@@ -64,7 +64,12 @@ export class WSConnectTimeoutError extends WSError {
|
|
|
64
64
|
super(`Not connected within ${ms}ms (still retrying in background)`);
|
|
65
65
|
}
|
|
66
66
|
}
|
|
67
|
-
/**
|
|
67
|
+
/**
|
|
68
|
+
* `sendTimeout` elapsed while queued, in flight, or awaiting an ack.
|
|
69
|
+
*
|
|
70
|
+
* A send that awaits no ack — `send()` without `{ ack: true }` — can only hit
|
|
71
|
+
* this while still queued, i.e. when no connection came up in time.
|
|
72
|
+
*/
|
|
68
73
|
export class WSTimeoutError extends WSError {
|
|
69
74
|
/**
|
|
70
75
|
* Reports the deadline that was exceeded.
|
|
@@ -72,7 +77,7 @@ export class WSTimeoutError extends WSError {
|
|
|
72
77
|
* @param ms - the elapsed `sendTimeout`
|
|
73
78
|
*/
|
|
74
79
|
constructor(ms) {
|
|
75
|
-
super(`
|
|
80
|
+
super(`Send not completed within ${ms}ms`);
|
|
76
81
|
}
|
|
77
82
|
}
|
|
78
83
|
/** The frame was evicted from a full outbox before it could be sent. */
|
|
@@ -92,7 +97,12 @@ export class WSConnectionLostError extends WSError {
|
|
|
92
97
|
super("The connection closed before the server acknowledged the frame; it was not resent");
|
|
93
98
|
}
|
|
94
99
|
}
|
|
95
|
-
/**
|
|
100
|
+
/**
|
|
101
|
+
* The server rejected the operation with a `nack`.
|
|
102
|
+
*
|
|
103
|
+
* Also the way a server-side `onMessage` hook rejects a message on purpose:
|
|
104
|
+
* throw one, and its `code` and `message` travel back in the `nack` unchanged.
|
|
105
|
+
*/
|
|
96
106
|
export class WSRemoteError extends WSError {
|
|
97
107
|
/** Machine-readable code from the server — see `ERROR_CODE`. */
|
|
98
108
|
code;
|
|
@@ -7,6 +7,11 @@
|
|
|
7
7
|
* application. Your payload may contain its own `type` field and nothing will
|
|
8
8
|
* collide.
|
|
9
9
|
*
|
|
10
|
+
* The frames come in two layers. The **core** — `auth`/`hello`, `msg` in both
|
|
11
|
+
* directions, `ack`/`nack`, `ping`/`pong`, `error` — is all a server must
|
|
12
|
+
* implement. The **rooms extension** — `sub`, `unsub`, `pub`, `broadcast`,
|
|
13
|
+
* `presence`, and the routing fields on a delivered `msg` — is opt-in.
|
|
14
|
+
*
|
|
10
15
|
* @module
|
|
11
16
|
*/
|
|
12
17
|
import type { FRAME, PRESENCE } from "./constants.js";
|
|
@@ -18,23 +23,45 @@ export interface WSErrorInfo {
|
|
|
18
23
|
message: string;
|
|
19
24
|
}
|
|
20
25
|
/**
|
|
21
|
-
* A message as delivered to application code
|
|
26
|
+
* A message as delivered to application code — the `message` event fires
|
|
27
|
+
* with one for every inbound `msg` frame.
|
|
22
28
|
*
|
|
23
29
|
* A `msg` frame minus its `type` field *is* a `WSMessage` — there is no
|
|
24
30
|
* translation layer and no divergence between wire names and API names.
|
|
31
|
+
*
|
|
32
|
+
* Only `payload` is guaranteed. A direct message from the server (core) has
|
|
33
|
+
* nothing else; a message delivered through a room (rooms extension) carries
|
|
34
|
+
* every routing field — see {@link WSRoomMessage}. `room` tells them apart.
|
|
25
35
|
*/
|
|
26
36
|
export interface WSMessage<T = unknown> {
|
|
37
|
+
/** Opaque application payload. */
|
|
38
|
+
payload: T;
|
|
39
|
+
/** Room the message was published to. Absent on a direct message. */
|
|
40
|
+
room?: string;
|
|
41
|
+
/** Namespace the message belongs to. Absent on a direct message. */
|
|
42
|
+
namespace?: string;
|
|
43
|
+
/**
|
|
44
|
+
* Originating client id, `null` when injected server-side. Absent on a
|
|
45
|
+
* direct message, which always comes from the server.
|
|
46
|
+
*/
|
|
47
|
+
from?: string | null;
|
|
48
|
+
/** Server-assigned epoch milliseconds. Absent on a direct message. */
|
|
49
|
+
timestamp?: number;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* A message delivered through a room (rooms extension). This is what room
|
|
53
|
+
* handlers receive: every routing field is present.
|
|
54
|
+
*/
|
|
55
|
+
export interface WSRoomMessage<T = unknown> extends WSMessage<T> {
|
|
27
56
|
/** Room the message was published to. */
|
|
28
57
|
room: string;
|
|
29
|
-
/** Namespace the message belongs to. */
|
|
58
|
+
/** Namespace the message belongs to — always the receiver's own. */
|
|
30
59
|
namespace: string;
|
|
31
60
|
/**
|
|
32
61
|
* Originating client id, or `null` when the message was injected
|
|
33
62
|
* server-side (via the service API or the HTTP routes).
|
|
34
63
|
*/
|
|
35
64
|
from: string | null;
|
|
36
|
-
/** Opaque application payload. */
|
|
37
|
-
payload: T;
|
|
38
65
|
/** Server-assigned epoch milliseconds. */
|
|
39
66
|
timestamp: number;
|
|
40
67
|
}
|
|
@@ -42,7 +69,7 @@ export interface WSMessage<T = unknown> {
|
|
|
42
69
|
export type PresenceEventType = (typeof PRESENCE)[keyof typeof PRESENCE];
|
|
43
70
|
/**
|
|
44
71
|
* A membership change in a room the client subscribed to with presence
|
|
45
|
-
* enabled.
|
|
72
|
+
* enabled (rooms extension).
|
|
46
73
|
*
|
|
47
74
|
* `sync` carries the full snapshot and is emitted on every (re)subscribe —
|
|
48
75
|
* crucially including after a reconnect, when membership may have changed
|
|
@@ -62,7 +89,7 @@ export interface WSPresenceEvent {
|
|
|
62
89
|
/** Server-assigned epoch milliseconds. */
|
|
63
90
|
timestamp: number;
|
|
64
91
|
}
|
|
65
|
-
/** A single room subscription request. */
|
|
92
|
+
/** A single room subscription request (rooms extension). */
|
|
66
93
|
export interface SubRequest {
|
|
67
94
|
/** Room name to join. */
|
|
68
95
|
room: string;
|
|
@@ -72,12 +99,24 @@ export interface SubRequest {
|
|
|
72
99
|
/** Frames sent by the client. */
|
|
73
100
|
export type ClientFrame = {
|
|
74
101
|
type: typeof FRAME.AUTH;
|
|
75
|
-
|
|
102
|
+
/**
|
|
103
|
+
* Not sent since protocol 2 and never acknowledged. Kept optional so a
|
|
104
|
+
* server keeps accepting a protocol-1 client that still sends it.
|
|
105
|
+
*/
|
|
106
|
+
id?: string;
|
|
76
107
|
protocol: number;
|
|
77
108
|
payload: unknown;
|
|
78
109
|
/** Preferred client id — the server may override it. */
|
|
79
110
|
clientId?: string;
|
|
111
|
+
/** Requested namespace — sent only when the application chose one. */
|
|
80
112
|
namespace?: string;
|
|
113
|
+
} | {
|
|
114
|
+
type: typeof FRAME.MSG;
|
|
115
|
+
/** Present only when the sender awaits an `ack`/`nack`. */
|
|
116
|
+
id?: string;
|
|
117
|
+
payload: unknown;
|
|
118
|
+
} | {
|
|
119
|
+
type: typeof FRAME.PING;
|
|
81
120
|
} | {
|
|
82
121
|
type: typeof FRAME.SUB;
|
|
83
122
|
id: string;
|
|
@@ -97,36 +136,39 @@ export type ClientFrame = {
|
|
|
97
136
|
id: string;
|
|
98
137
|
room: string;
|
|
99
138
|
payload: unknown;
|
|
100
|
-
} | {
|
|
101
|
-
type: typeof FRAME.PING;
|
|
102
139
|
};
|
|
103
140
|
/** Frames sent by the server. */
|
|
104
141
|
export type ServerFrame = {
|
|
105
142
|
type: typeof FRAME.HELLO;
|
|
106
|
-
clientId: string;
|
|
107
|
-
namespace: string;
|
|
108
143
|
protocol: number;
|
|
144
|
+
/** Assigned client id. Optional in the core; always sent with rooms. */
|
|
145
|
+
clientId?: string;
|
|
146
|
+
/** Assigned namespace. Optional in the core; always sent with rooms. */
|
|
147
|
+
namespace?: string;
|
|
109
148
|
} | {
|
|
110
149
|
type: typeof FRAME.ACK;
|
|
111
150
|
id: string;
|
|
151
|
+
/** Delivery count, on `pub`/`broadcast` acks only. */
|
|
112
152
|
recipients?: number;
|
|
153
|
+
/** The server's reply, on `msg` acks only. Any JSON value. */
|
|
154
|
+
payload?: unknown;
|
|
113
155
|
} | {
|
|
114
156
|
type: typeof FRAME.NACK;
|
|
115
157
|
id: string;
|
|
116
158
|
error: WSErrorInfo;
|
|
117
159
|
} | ({
|
|
118
160
|
type: typeof FRAME.MSG;
|
|
119
|
-
} & WSMessage) |
|
|
120
|
-
type: typeof FRAME.PRESENCE;
|
|
121
|
-
} & WSPresenceEvent) | {
|
|
161
|
+
} & WSMessage) | {
|
|
122
162
|
type: typeof FRAME.PONG;
|
|
123
163
|
} | {
|
|
124
164
|
type: typeof FRAME.ERROR;
|
|
125
165
|
error: WSErrorInfo;
|
|
126
|
-
}
|
|
166
|
+
} | ({
|
|
167
|
+
type: typeof FRAME.PRESENCE;
|
|
168
|
+
} & WSPresenceEvent);
|
|
127
169
|
/** Any frame, in either direction. */
|
|
128
170
|
export type WSFrame = ClientFrame | ServerFrame;
|
|
129
|
-
/** Result of a successful `publish()` / `broadcast()
|
|
171
|
+
/** Result of a successful `publish()` / `broadcast()` (rooms extension). */
|
|
130
172
|
export interface WSPublishResult {
|
|
131
173
|
/**
|
|
132
174
|
* Sockets the message was handed to **on the receiving server instance**.
|
package/dist/protocol/frames.js
CHANGED
|
@@ -7,6 +7,11 @@
|
|
|
7
7
|
* application. Your payload may contain its own `type` field and nothing will
|
|
8
8
|
* collide.
|
|
9
9
|
*
|
|
10
|
+
* The frames come in two layers. The **core** — `auth`/`hello`, `msg` in both
|
|
11
|
+
* directions, `ack`/`nack`, `ping`/`pong`, `error` — is all a server must
|
|
12
|
+
* implement. The **rooms extension** — `sub`, `unsub`, `pub`, `broadcast`,
|
|
13
|
+
* `presence`, and the routing fields on a delivered `msg` — is opt-in.
|
|
14
|
+
*
|
|
10
15
|
* @module
|
|
11
16
|
*/
|
|
12
17
|
export {};
|