@graphorin/protocol 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/CHANGELOG.md +15 -0
- package/LICENSE +21 -0
- package/README.md +71 -0
- package/dist/client-message.d.ts +478 -0
- package/dist/client-message.d.ts.map +1 -0
- package/dist/client-message.js +128 -0
- package/dist/client-message.js.map +1 -0
- package/dist/close-codes.d.ts +49 -0
- package/dist/close-codes.d.ts.map +1 -0
- package/dist/close-codes.js +41 -0
- package/dist/close-codes.js.map +1 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +27 -0
- package/dist/index.js.map +1 -0
- package/dist/server-message.d.ts +459 -0
- package/dist/server-message.d.ts.map +1 -0
- package/dist/server-message.js +185 -0
- package/dist/server-message.js.map +1 -0
- package/dist/subprotocol.d.ts +70 -0
- package/dist/subprotocol.d.ts.map +1 -0
- package/dist/subprotocol.js +87 -0
- package/dist/subprotocol.js.map +1 -0
- package/package.json +79 -0
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
|
|
3
|
+
//#region src/client-message.ts
|
|
4
|
+
/**
|
|
5
|
+
* `ClientMessage` — discriminated union of every frame a Graphorin
|
|
6
|
+
* WebSocket client may send to the server. The wire is hybrid: the
|
|
7
|
+
* control plane uses JSON-RPC-shaped requests / notifications; the
|
|
8
|
+
* data plane uses typed push events emitted exclusively by the server
|
|
9
|
+
* (see `./server-message.ts`).
|
|
10
|
+
*
|
|
11
|
+
* Every frame carries the `v: '1'` literal so future revisions can
|
|
12
|
+
* negotiate forward-compatible additions without a subprotocol bump.
|
|
13
|
+
* The matching subprotocol identifier is `graphorin.protocol.v1`
|
|
14
|
+
* (see `./subprotocol.ts`).
|
|
15
|
+
*
|
|
16
|
+
* @packageDocumentation
|
|
17
|
+
*/
|
|
18
|
+
const RpcId = z.union([z.string().min(1), z.number().int()]);
|
|
19
|
+
const InitializeParams = z.object({
|
|
20
|
+
clientInfo: z.object({
|
|
21
|
+
name: z.string().min(1),
|
|
22
|
+
version: z.string().min(1)
|
|
23
|
+
}).strict(),
|
|
24
|
+
capabilities: z.record(z.string(), z.unknown()).optional()
|
|
25
|
+
}).strict();
|
|
26
|
+
const SubscribeParams = z.object({
|
|
27
|
+
subject: z.string().min(1),
|
|
28
|
+
sinceEventId: z.string().min(1).optional()
|
|
29
|
+
}).strict();
|
|
30
|
+
const UnsubscribeParams = z.object({ subscriptionId: z.string().min(1) }).strict();
|
|
31
|
+
const RunCancelParams = z.object({
|
|
32
|
+
runId: z.string().min(1),
|
|
33
|
+
reason: z.string().min(1).optional(),
|
|
34
|
+
drain: z.boolean().optional(),
|
|
35
|
+
onPendingApprovals: z.enum(["deny", "preserve"]).optional()
|
|
36
|
+
}).strict();
|
|
37
|
+
const PingParams = z.object({ nonce: z.string().min(1).optional() }).strict().optional();
|
|
38
|
+
const InitializeRequest = z.object({
|
|
39
|
+
v: z.literal("1"),
|
|
40
|
+
jsonrpc: z.literal("2.0"),
|
|
41
|
+
id: RpcId,
|
|
42
|
+
method: z.literal("initialize"),
|
|
43
|
+
params: InitializeParams
|
|
44
|
+
}).strict();
|
|
45
|
+
const SubscribeRequest = z.object({
|
|
46
|
+
v: z.literal("1"),
|
|
47
|
+
jsonrpc: z.literal("2.0"),
|
|
48
|
+
id: RpcId,
|
|
49
|
+
method: z.literal("subscription.subscribe"),
|
|
50
|
+
params: SubscribeParams
|
|
51
|
+
}).strict();
|
|
52
|
+
const UnsubscribeRequest = z.object({
|
|
53
|
+
v: z.literal("1"),
|
|
54
|
+
jsonrpc: z.literal("2.0"),
|
|
55
|
+
id: RpcId,
|
|
56
|
+
method: z.literal("subscription.unsubscribe"),
|
|
57
|
+
params: UnsubscribeParams
|
|
58
|
+
}).strict();
|
|
59
|
+
const RunCancelRequest = z.object({
|
|
60
|
+
v: z.literal("1"),
|
|
61
|
+
jsonrpc: z.literal("2.0"),
|
|
62
|
+
id: RpcId,
|
|
63
|
+
method: z.literal("run.cancel"),
|
|
64
|
+
params: RunCancelParams
|
|
65
|
+
}).strict();
|
|
66
|
+
const PingRequest = z.object({
|
|
67
|
+
v: z.literal("1"),
|
|
68
|
+
jsonrpc: z.literal("2.0"),
|
|
69
|
+
id: RpcId,
|
|
70
|
+
method: z.literal("ping"),
|
|
71
|
+
params: PingParams
|
|
72
|
+
}).strict();
|
|
73
|
+
const CancelledNotification = z.object({
|
|
74
|
+
v: z.literal("1"),
|
|
75
|
+
jsonrpc: z.literal("2.0"),
|
|
76
|
+
method: z.literal("notifications/cancelled"),
|
|
77
|
+
params: z.object({ requestId: z.string().min(1) }).strict()
|
|
78
|
+
}).strict();
|
|
79
|
+
/**
|
|
80
|
+
* Zod schema for every legal client → server frame. Use
|
|
81
|
+
* {@link ClientMessageSchema}.safeParse() inside the server upgrade
|
|
82
|
+
* handler before dispatching to the corresponding subscription /
|
|
83
|
+
* cancel / ping handler.
|
|
84
|
+
*
|
|
85
|
+
* @stable
|
|
86
|
+
*/
|
|
87
|
+
const ClientMessageSchema = z.discriminatedUnion("method", [
|
|
88
|
+
InitializeRequest,
|
|
89
|
+
SubscribeRequest,
|
|
90
|
+
UnsubscribeRequest,
|
|
91
|
+
RunCancelRequest,
|
|
92
|
+
PingRequest,
|
|
93
|
+
CancelledNotification
|
|
94
|
+
]);
|
|
95
|
+
/**
|
|
96
|
+
* Type guard helpers — one per `method` literal — so consumers can
|
|
97
|
+
* narrow the `ClientMessage` union without re-stringifying the
|
|
98
|
+
* discriminator.
|
|
99
|
+
*
|
|
100
|
+
* @stable
|
|
101
|
+
*/
|
|
102
|
+
function isInitializeRequest(message) {
|
|
103
|
+
return message.method === "initialize";
|
|
104
|
+
}
|
|
105
|
+
/** @stable */
|
|
106
|
+
function isSubscribeRequest(message) {
|
|
107
|
+
return message.method === "subscription.subscribe";
|
|
108
|
+
}
|
|
109
|
+
/** @stable */
|
|
110
|
+
function isUnsubscribeRequest(message) {
|
|
111
|
+
return message.method === "subscription.unsubscribe";
|
|
112
|
+
}
|
|
113
|
+
/** @stable */
|
|
114
|
+
function isRunCancelRequest(message) {
|
|
115
|
+
return message.method === "run.cancel";
|
|
116
|
+
}
|
|
117
|
+
/** @stable */
|
|
118
|
+
function isPingRequest(message) {
|
|
119
|
+
return message.method === "ping";
|
|
120
|
+
}
|
|
121
|
+
/** @stable */
|
|
122
|
+
function isCancelledNotification(message) {
|
|
123
|
+
return message.method === "notifications/cancelled";
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
//#endregion
|
|
127
|
+
export { ClientMessageSchema, isCancelledNotification, isInitializeRequest, isPingRequest, isRunCancelRequest, isSubscribeRequest, isUnsubscribeRequest };
|
|
128
|
+
//# sourceMappingURL=client-message.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client-message.js","names":[],"sources":["../src/client-message.ts"],"sourcesContent":["/**\n * `ClientMessage` — discriminated union of every frame a Graphorin\n * WebSocket client may send to the server. The wire is hybrid: the\n * control plane uses JSON-RPC-shaped requests / notifications; the\n * data plane uses typed push events emitted exclusively by the server\n * (see `./server-message.ts`).\n *\n * Every frame carries the `v: '1'` literal so future revisions can\n * negotiate forward-compatible additions without a subprotocol bump.\n * The matching subprotocol identifier is `graphorin.protocol.v1`\n * (see `./subprotocol.ts`).\n *\n * @packageDocumentation\n */\n\nimport { z } from 'zod';\n\nconst RpcId = z.union([z.string().min(1), z.number().int()]);\n\nconst InitializeParams = z\n .object({\n clientInfo: z\n .object({\n name: z.string().min(1),\n version: z.string().min(1),\n })\n .strict(),\n capabilities: z.record(z.string(), z.unknown()).optional(),\n })\n .strict();\n\nconst SubscribeParams = z\n .object({\n subject: z.string().min(1),\n // IP-21: `sinceEventId` is the resumption cursor. `lastSequenceId` was a\n // dead wire field — the client never set it and the server never read it.\n sinceEventId: z.string().min(1).optional(),\n })\n .strict();\n\nconst UnsubscribeParams = z\n .object({\n subscriptionId: z.string().min(1),\n })\n .strict();\n\nconst RunCancelParams = z\n .object({\n runId: z.string().min(1),\n reason: z.string().min(1).optional(),\n drain: z.boolean().optional(),\n onPendingApprovals: z.enum(['deny', 'preserve']).optional(),\n })\n .strict();\n\nconst PingParams = z\n .object({\n nonce: z.string().min(1).optional(),\n })\n .strict()\n .optional();\n\nconst InitializeRequest = z\n .object({\n v: z.literal('1'),\n jsonrpc: z.literal('2.0'),\n id: RpcId,\n method: z.literal('initialize'),\n params: InitializeParams,\n })\n .strict();\n\nconst SubscribeRequest = z\n .object({\n v: z.literal('1'),\n jsonrpc: z.literal('2.0'),\n id: RpcId,\n method: z.literal('subscription.subscribe'),\n params: SubscribeParams,\n })\n .strict();\n\nconst UnsubscribeRequest = z\n .object({\n v: z.literal('1'),\n jsonrpc: z.literal('2.0'),\n id: RpcId,\n method: z.literal('subscription.unsubscribe'),\n params: UnsubscribeParams,\n })\n .strict();\n\nconst RunCancelRequest = z\n .object({\n v: z.literal('1'),\n jsonrpc: z.literal('2.0'),\n id: RpcId,\n method: z.literal('run.cancel'),\n params: RunCancelParams,\n })\n .strict();\n\nconst PingRequest = z\n .object({\n v: z.literal('1'),\n jsonrpc: z.literal('2.0'),\n id: RpcId,\n method: z.literal('ping'),\n params: PingParams,\n })\n .strict();\n\nconst CancelledNotification = z\n .object({\n v: z.literal('1'),\n jsonrpc: z.literal('2.0'),\n method: z.literal('notifications/cancelled'),\n params: z.object({ requestId: z.string().min(1) }).strict(),\n })\n .strict();\n\n/**\n * Zod schema for every legal client → server frame. Use\n * {@link ClientMessageSchema}.safeParse() inside the server upgrade\n * handler before dispatching to the corresponding subscription /\n * cancel / ping handler.\n *\n * @stable\n */\nexport const ClientMessageSchema = z.discriminatedUnion('method', [\n InitializeRequest,\n SubscribeRequest,\n UnsubscribeRequest,\n RunCancelRequest,\n PingRequest,\n CancelledNotification,\n]);\n\n/**\n * Inferred TypeScript union for the `ClientMessage` discriminator. A\n * value satisfying this type round-trips through\n * {@link ClientMessageSchema} without throwing.\n *\n * @stable\n */\nexport type ClientMessage = z.infer<typeof ClientMessageSchema>;\n\n/**\n * Convenience type for the JSON-RPC `id` slot. Matches the Graphorin\n * subset (string + integer; no `null`, no float).\n *\n * @stable\n */\nexport type ClientMessageId = z.infer<typeof RpcId>;\n\n/**\n * Type guard helpers — one per `method` literal — so consumers can\n * narrow the `ClientMessage` union without re-stringifying the\n * discriminator.\n *\n * @stable\n */\nexport function isInitializeRequest(\n message: ClientMessage,\n): message is z.infer<typeof InitializeRequest> {\n return message.method === 'initialize';\n}\n\n/** @stable */\nexport function isSubscribeRequest(\n message: ClientMessage,\n): message is z.infer<typeof SubscribeRequest> {\n return message.method === 'subscription.subscribe';\n}\n\n/** @stable */\nexport function isUnsubscribeRequest(\n message: ClientMessage,\n): message is z.infer<typeof UnsubscribeRequest> {\n return message.method === 'subscription.unsubscribe';\n}\n\n/** @stable */\nexport function isRunCancelRequest(\n message: ClientMessage,\n): message is z.infer<typeof RunCancelRequest> {\n return message.method === 'run.cancel';\n}\n\n/** @stable */\nexport function isPingRequest(message: ClientMessage): message is z.infer<typeof PingRequest> {\n return message.method === 'ping';\n}\n\n/** @stable */\nexport function isCancelledNotification(\n message: ClientMessage,\n): message is z.infer<typeof CancelledNotification> {\n return message.method === 'notifications/cancelled';\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
//#region src/close-codes.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Custom WebSocket close-code taxonomy used by `@graphorin/server`
|
|
4
|
+
* and `@graphorin/client`. The numeric values live in the 4xxx
|
|
5
|
+
* application-private range per RFC 6455 § 7.4.
|
|
6
|
+
*
|
|
7
|
+
* @packageDocumentation
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Discriminator for every Graphorin-defined close code. The
|
|
11
|
+
* matching numeric value is exposed via {@link CLOSE_CODE_VALUES}.
|
|
12
|
+
*
|
|
13
|
+
* @stable
|
|
14
|
+
*/
|
|
15
|
+
type GraphorinCloseReason = 'auth.required' | 'auth.invalid' | 'auth.revoked' | 'auth.scope_denied' | 'rate.limited' | 'flow.throttled' | 'server.shutdown' | 'protocol.violation';
|
|
16
|
+
/**
|
|
17
|
+
* Numeric close-code constants. The pair `(value, reason)` round-trips
|
|
18
|
+
* via {@link closeCodeReason} / {@link closeCodeFor}.
|
|
19
|
+
*
|
|
20
|
+
* @stable
|
|
21
|
+
*/
|
|
22
|
+
declare const CLOSE_CODE_VALUES: Readonly<{
|
|
23
|
+
readonly 'auth.required': 4001;
|
|
24
|
+
readonly 'auth.invalid': 4002;
|
|
25
|
+
readonly 'auth.revoked': 4003;
|
|
26
|
+
readonly 'auth.scope_denied': 4004;
|
|
27
|
+
readonly 'rate.limited': 4005;
|
|
28
|
+
readonly 'flow.throttled': 4006;
|
|
29
|
+
readonly 'server.shutdown': 4007;
|
|
30
|
+
readonly 'protocol.violation': 4008;
|
|
31
|
+
}>;
|
|
32
|
+
/**
|
|
33
|
+
* Return the numeric close code for a Graphorin reason discriminator.
|
|
34
|
+
*
|
|
35
|
+
* @stable
|
|
36
|
+
*/
|
|
37
|
+
declare function closeCodeFor(reason: GraphorinCloseReason): number;
|
|
38
|
+
/**
|
|
39
|
+
* Resolve a numeric close code back to its Graphorin reason
|
|
40
|
+
* discriminator. Returns `undefined` for codes outside the
|
|
41
|
+
* Graphorin range so callers can still surface the raw RFC 6455
|
|
42
|
+
* reason for unrelated codes.
|
|
43
|
+
*
|
|
44
|
+
* @stable
|
|
45
|
+
*/
|
|
46
|
+
declare function closeCodeReason(code: number): GraphorinCloseReason | undefined;
|
|
47
|
+
//#endregion
|
|
48
|
+
export { CLOSE_CODE_VALUES, GraphorinCloseReason, closeCodeFor, closeCodeReason };
|
|
49
|
+
//# sourceMappingURL=close-codes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"close-codes.d.ts","names":[],"sources":["../src/close-codes.ts"],"sourcesContent":[],"mappings":";;AAcA;AAgBA;AAgBA;AAkBA;;;;;;;;;KAlDY,oBAAA;;;;;;;cAgBC,mBAAiB;;;;;;;;;;;;;;;iBAgBd,YAAA,SAAqB;;;;;;;;;iBAkBrB,eAAA,gBAA+B"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
//#region src/close-codes.ts
|
|
2
|
+
/**
|
|
3
|
+
* Numeric close-code constants. The pair `(value, reason)` round-trips
|
|
4
|
+
* via {@link closeCodeReason} / {@link closeCodeFor}.
|
|
5
|
+
*
|
|
6
|
+
* @stable
|
|
7
|
+
*/
|
|
8
|
+
const CLOSE_CODE_VALUES = Object.freeze({
|
|
9
|
+
"auth.required": 4001,
|
|
10
|
+
"auth.invalid": 4002,
|
|
11
|
+
"auth.revoked": 4003,
|
|
12
|
+
"auth.scope_denied": 4004,
|
|
13
|
+
"rate.limited": 4005,
|
|
14
|
+
"flow.throttled": 4006,
|
|
15
|
+
"server.shutdown": 4007,
|
|
16
|
+
"protocol.violation": 4008
|
|
17
|
+
});
|
|
18
|
+
/**
|
|
19
|
+
* Return the numeric close code for a Graphorin reason discriminator.
|
|
20
|
+
*
|
|
21
|
+
* @stable
|
|
22
|
+
*/
|
|
23
|
+
function closeCodeFor(reason) {
|
|
24
|
+
return CLOSE_CODE_VALUES[reason];
|
|
25
|
+
}
|
|
26
|
+
const REVERSE_LOOKUP = new Map(Object.entries(CLOSE_CODE_VALUES).map(([reason, code]) => [code, reason]));
|
|
27
|
+
/**
|
|
28
|
+
* Resolve a numeric close code back to its Graphorin reason
|
|
29
|
+
* discriminator. Returns `undefined` for codes outside the
|
|
30
|
+
* Graphorin range so callers can still surface the raw RFC 6455
|
|
31
|
+
* reason for unrelated codes.
|
|
32
|
+
*
|
|
33
|
+
* @stable
|
|
34
|
+
*/
|
|
35
|
+
function closeCodeReason(code) {
|
|
36
|
+
return REVERSE_LOOKUP.get(code);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
//#endregion
|
|
40
|
+
export { CLOSE_CODE_VALUES, closeCodeFor, closeCodeReason };
|
|
41
|
+
//# sourceMappingURL=close-codes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"close-codes.js","names":["REVERSE_LOOKUP: ReadonlyMap<number, GraphorinCloseReason>"],"sources":["../src/close-codes.ts"],"sourcesContent":["/**\n * Custom WebSocket close-code taxonomy used by `@graphorin/server`\n * and `@graphorin/client`. The numeric values live in the 4xxx\n * application-private range per RFC 6455 § 7.4.\n *\n * @packageDocumentation\n */\n\n/**\n * Discriminator for every Graphorin-defined close code. The\n * matching numeric value is exposed via {@link CLOSE_CODE_VALUES}.\n *\n * @stable\n */\nexport type GraphorinCloseReason =\n | 'auth.required'\n | 'auth.invalid'\n | 'auth.revoked'\n | 'auth.scope_denied'\n | 'rate.limited'\n | 'flow.throttled'\n | 'server.shutdown'\n | 'protocol.violation';\n\n/**\n * Numeric close-code constants. The pair `(value, reason)` round-trips\n * via {@link closeCodeReason} / {@link closeCodeFor}.\n *\n * @stable\n */\nexport const CLOSE_CODE_VALUES = Object.freeze({\n 'auth.required': 4001,\n 'auth.invalid': 4002,\n 'auth.revoked': 4003,\n 'auth.scope_denied': 4004,\n 'rate.limited': 4005,\n 'flow.throttled': 4006,\n 'server.shutdown': 4007,\n 'protocol.violation': 4008,\n} as const satisfies Record<GraphorinCloseReason, number>);\n\n/**\n * Return the numeric close code for a Graphorin reason discriminator.\n *\n * @stable\n */\nexport function closeCodeFor(reason: GraphorinCloseReason): number {\n return CLOSE_CODE_VALUES[reason];\n}\n\nconst REVERSE_LOOKUP: ReadonlyMap<number, GraphorinCloseReason> = new Map(\n (Object.entries(CLOSE_CODE_VALUES) as ReadonlyArray<[GraphorinCloseReason, number]>).map(\n ([reason, code]) => [code, reason],\n ),\n);\n\n/**\n * Resolve a numeric close code back to its Graphorin reason\n * discriminator. Returns `undefined` for codes outside the\n * Graphorin range so callers can still surface the raw RFC 6455\n * reason for unrelated codes.\n *\n * @stable\n */\nexport function closeCodeReason(code: number): GraphorinCloseReason | undefined {\n return REVERSE_LOOKUP.get(code);\n}\n"],"mappings":";;;;;;;AA8BA,MAAa,oBAAoB,OAAO,OAAO;CAC7C,iBAAiB;CACjB,gBAAgB;CAChB,gBAAgB;CAChB,qBAAqB;CACrB,gBAAgB;CAChB,kBAAkB;CAClB,mBAAmB;CACnB,sBAAsB;CACvB,CAAyD;;;;;;AAO1D,SAAgB,aAAa,QAAsC;AACjE,QAAO,kBAAkB;;AAG3B,MAAMA,iBAA4D,IAAI,IACnE,OAAO,QAAQ,kBAAkB,CAAmD,KAClF,CAAC,QAAQ,UAAU,CAAC,MAAM,OAAO,CACnC,CACF;;;;;;;;;AAUD,SAAgB,gBAAgB,MAAgD;AAC9E,QAAO,eAAe,IAAI,KAAK"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { ClientMessage, ClientMessageId, ClientMessageSchema, isCancelledNotification, isInitializeRequest, isPingRequest, isRunCancelRequest, isSubscribeRequest, isUnsubscribeRequest } from "./client-message.js";
|
|
2
|
+
import { CLOSE_CODE_VALUES, GraphorinCloseReason, closeCodeFor, closeCodeReason } from "./close-codes.js";
|
|
3
|
+
import { RPC_ERROR_CODES, ServerErrorFrame, ServerEventFrame, ServerLifecycleFrame, ServerMessage, ServerMessageSchema, ServerPongFrame, ServerReplayMarkerFrame, ServerRpcFailure, ServerRpcSuccess, ServerSubscribedFrame, ServerUnsubscribedFrame, isErrorFrame, isEventFrame, isLifecycleFrame, isPongFrame, isReplayMarkerFrame, isRpcFailure, isRpcSuccess, isSubscribedFrame, isUnsubscribedFrame } from "./server-message.js";
|
|
4
|
+
import { PROTOCOL_VERSION, SUBPROTOCOL_NAME, TICKET_SUBPROTOCOL_PREFIX, formatTicketSubprotocol, negotiateSubprotocol, parseTicketSubprotocol } from "./subprotocol.js";
|
|
5
|
+
|
|
6
|
+
//#region src/index.d.ts
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* `@graphorin/protocol` — wire-format contract for the Graphorin
|
|
10
|
+
* WebSocket subprotocol.
|
|
11
|
+
*
|
|
12
|
+
* The package is the **single source of truth** for the shape of
|
|
13
|
+
* every frame exchanged over `wss://.../v1/ws`. Both
|
|
14
|
+
* `@graphorin/server` and `@graphorin/client` import their schemas
|
|
15
|
+
* from here so the two implementations cannot drift.
|
|
16
|
+
*
|
|
17
|
+
* Browser-friendly: the only runtime dependency is
|
|
18
|
+
* [`zod`](https://zod.dev). No Node-only imports, no DOM-only
|
|
19
|
+
* imports.
|
|
20
|
+
*
|
|
21
|
+
* @packageDocumentation
|
|
22
|
+
*/
|
|
23
|
+
/** Canonical version constant. Mirrors the `package.json` version. */
|
|
24
|
+
declare const VERSION = "0.5.0";
|
|
25
|
+
//#endregion
|
|
26
|
+
export { CLOSE_CODE_VALUES, ClientMessage, ClientMessageId, ClientMessageSchema, GraphorinCloseReason, PROTOCOL_VERSION, RPC_ERROR_CODES, SUBPROTOCOL_NAME, ServerErrorFrame, ServerEventFrame, ServerLifecycleFrame, ServerMessage, ServerMessageSchema, ServerPongFrame, ServerReplayMarkerFrame, ServerRpcFailure, ServerRpcSuccess, ServerSubscribedFrame, ServerUnsubscribedFrame, TICKET_SUBPROTOCOL_PREFIX, VERSION, closeCodeFor, closeCodeReason, formatTicketSubprotocol, isCancelledNotification, isErrorFrame, isEventFrame, isInitializeRequest, isLifecycleFrame, isPingRequest, isPongFrame, isReplayMarkerFrame, isRpcFailure, isRpcSuccess, isRunCancelRequest, isSubscribeRequest, isSubscribedFrame, isUnsubscribeRequest, isUnsubscribedFrame, negotiateSubprotocol, parseTicketSubprotocol };
|
|
27
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/index.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;;;AAiBA;;;;;;;;;;cAAa,OAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { ClientMessageSchema, isCancelledNotification, isInitializeRequest, isPingRequest, isRunCancelRequest, isSubscribeRequest, isUnsubscribeRequest } from "./client-message.js";
|
|
2
|
+
import { CLOSE_CODE_VALUES, closeCodeFor, closeCodeReason } from "./close-codes.js";
|
|
3
|
+
import { RPC_ERROR_CODES, ServerMessageSchema, isErrorFrame, isEventFrame, isLifecycleFrame, isPongFrame, isReplayMarkerFrame, isRpcFailure, isRpcSuccess, isSubscribedFrame, isUnsubscribedFrame } from "./server-message.js";
|
|
4
|
+
import { PROTOCOL_VERSION, SUBPROTOCOL_NAME, TICKET_SUBPROTOCOL_PREFIX, formatTicketSubprotocol, negotiateSubprotocol, parseTicketSubprotocol } from "./subprotocol.js";
|
|
5
|
+
|
|
6
|
+
//#region src/index.ts
|
|
7
|
+
/**
|
|
8
|
+
* `@graphorin/protocol` — wire-format contract for the Graphorin
|
|
9
|
+
* WebSocket subprotocol.
|
|
10
|
+
*
|
|
11
|
+
* The package is the **single source of truth** for the shape of
|
|
12
|
+
* every frame exchanged over `wss://.../v1/ws`. Both
|
|
13
|
+
* `@graphorin/server` and `@graphorin/client` import their schemas
|
|
14
|
+
* from here so the two implementations cannot drift.
|
|
15
|
+
*
|
|
16
|
+
* Browser-friendly: the only runtime dependency is
|
|
17
|
+
* [`zod`](https://zod.dev). No Node-only imports, no DOM-only
|
|
18
|
+
* imports.
|
|
19
|
+
*
|
|
20
|
+
* @packageDocumentation
|
|
21
|
+
*/
|
|
22
|
+
/** Canonical version constant. Mirrors the `package.json` version. */
|
|
23
|
+
const VERSION = "0.5.0";
|
|
24
|
+
|
|
25
|
+
//#endregion
|
|
26
|
+
export { CLOSE_CODE_VALUES, ClientMessageSchema, PROTOCOL_VERSION, RPC_ERROR_CODES, SUBPROTOCOL_NAME, ServerMessageSchema, TICKET_SUBPROTOCOL_PREFIX, VERSION, closeCodeFor, closeCodeReason, formatTicketSubprotocol, isCancelledNotification, isErrorFrame, isEventFrame, isInitializeRequest, isLifecycleFrame, isPingRequest, isPongFrame, isReplayMarkerFrame, isRpcFailure, isRpcSuccess, isRunCancelRequest, isSubscribeRequest, isSubscribedFrame, isUnsubscribeRequest, isUnsubscribedFrame, negotiateSubprotocol, parseTicketSubprotocol };
|
|
27
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["/**\n * `@graphorin/protocol` — wire-format contract for the Graphorin\n * WebSocket subprotocol.\n *\n * The package is the **single source of truth** for the shape of\n * every frame exchanged over `wss://.../v1/ws`. Both\n * `@graphorin/server` and `@graphorin/client` import their schemas\n * from here so the two implementations cannot drift.\n *\n * Browser-friendly: the only runtime dependency is\n * [`zod`](https://zod.dev). No Node-only imports, no DOM-only\n * imports.\n *\n * @packageDocumentation\n */\n\n/** Canonical version constant. Mirrors the `package.json` version. */\nexport const VERSION = '0.5.0';\n\nexport * from './client-message.js';\nexport * from './close-codes.js';\nexport * from './server-message.js';\nexport * from './subprotocol.js';\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAiBA,MAAa,UAAU"}
|