@hydranium/protocol 1.0.0-next.132 → 1.0.0-next.135
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/lib/client/data-connection.d.ts +11 -6
- package/lib/client/data-connection.d.ts.map +1 -1
- package/lib/client/data-connection.js +14 -8
- package/lib/client/data-connection.js.map +1 -1
- package/lib/data/data-server-protocol.d.ts +2 -1
- package/lib/data/data-server-protocol.d.ts.map +1 -1
- package/lib/errors.d.ts +72 -16
- package/lib/errors.d.ts.map +1 -1
- package/lib/errors.js +96 -17
- package/lib/errors.js.map +1 -1
- package/lib/messages/index.d.ts +1 -1
- package/lib/messages/index.d.ts.map +1 -1
- package/lib/messages/index.js +3 -1
- package/lib/messages/index.js.map +1 -1
- package/package.json +1 -1
- package/src/client/data-connection.ts +14 -8
- package/src/data/data-server-protocol.ts +2 -1
- package/src/errors.ts +119 -18
- package/src/messages/index.ts +1 -1
|
@@ -87,13 +87,18 @@ export declare class DataConnection<TTransfer extends TransferElement, TServer e
|
|
|
87
87
|
* given. Pass a `label` naming the participant; without one it is
|
|
88
88
|
* `session`. Synchronous: the registration is sent at once, and the
|
|
89
89
|
* session's calls wait for it. The server refuses an id live anywhere in
|
|
90
|
-
* its process, and every call of that session then rejects with
|
|
91
|
-
* `
|
|
90
|
+
* its process, and every call of that session then rejects with an error
|
|
91
|
+
* `isDuplicateClientIdError` recognises; an id the server reserves beyond
|
|
92
|
+
* {@link FRAMEWORK_CLIENT_IDS}, such as the integrity author, with one
|
|
93
|
+
* `isReservedClientIdError` recognises. Only the code crosses the wire, so
|
|
94
|
+
* test with those guards rather than `instanceof`.
|
|
92
95
|
*
|
|
93
|
-
* Throws
|
|
94
|
-
*
|
|
95
|
-
*
|
|
96
|
-
*
|
|
96
|
+
* Throws a {@link ReservedClientIdError} for an id in
|
|
97
|
+
* {@link FRAMEWORK_CLIENT_IDS} — those are authors the SERVER emits rather
|
|
98
|
+
* than participants, so a session holding one would read the framework's
|
|
99
|
+
* own broadcasts as its own echoes and drop them — and a
|
|
100
|
+
* {@link DuplicateClientIdError} for an id a live session on this
|
|
101
|
+
* connection already holds.
|
|
97
102
|
*/
|
|
98
103
|
createSession(label?: string, clientId?: string): DataSession<TTransfer, TServer>;
|
|
99
104
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data-connection.d.ts","sourceRoot":"","sources":["../../src/client/data-connection.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,EAAE,OAAO,EAAE,KAAK,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAErD,OAAO,EAGJ,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EACvB,KAAK,YAAY,EACjB,KAAK,SAAS,EACd,KAAK,iCAAiC,EACxC,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"data-connection.d.ts","sourceRoot":"","sources":["../../src/client/data-connection.ts"],"names":[],"mappings":"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"}
|
|
@@ -12,6 +12,7 @@ exports.DataConnectionWithEvents = exports.DataConnection = void 0;
|
|
|
12
12
|
const vscode_jsonrpc_1 = require("vscode-jsonrpc");
|
|
13
13
|
const client_ids_1 = require("../client-ids");
|
|
14
14
|
const data_1 = require("../data");
|
|
15
|
+
const errors_1 = require("../errors");
|
|
15
16
|
const data_events_1 = require("./data-events");
|
|
16
17
|
const data_session_1 = require("./data-session");
|
|
17
18
|
const rpc_connection_1 = require("./rpc-connection");
|
|
@@ -72,22 +73,27 @@ class DataConnection extends rpc_connection_1.RpcConnection {
|
|
|
72
73
|
* given. Pass a `label` naming the participant; without one it is
|
|
73
74
|
* `session`. Synchronous: the registration is sent at once, and the
|
|
74
75
|
* session's calls wait for it. The server refuses an id live anywhere in
|
|
75
|
-
* its process, and every call of that session then rejects with
|
|
76
|
-
* `
|
|
76
|
+
* its process, and every call of that session then rejects with an error
|
|
77
|
+
* `isDuplicateClientIdError` recognises; an id the server reserves beyond
|
|
78
|
+
* {@link FRAMEWORK_CLIENT_IDS}, such as the integrity author, with one
|
|
79
|
+
* `isReservedClientIdError` recognises. Only the code crosses the wire, so
|
|
80
|
+
* test with those guards rather than `instanceof`.
|
|
77
81
|
*
|
|
78
|
-
* Throws
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
+
* Throws a {@link ReservedClientIdError} for an id in
|
|
83
|
+
* {@link FRAMEWORK_CLIENT_IDS} — those are authors the SERVER emits rather
|
|
84
|
+
* than participants, so a session holding one would read the framework's
|
|
85
|
+
* own broadcasts as its own echoes and drop them — and a
|
|
86
|
+
* {@link DuplicateClientIdError} for an id a live session on this
|
|
87
|
+
* connection already holds.
|
|
82
88
|
*/
|
|
83
89
|
createSession(label = 'session', clientId) {
|
|
84
90
|
this.assertLive();
|
|
85
91
|
const id = clientId ?? `${label}#${globalThis.crypto.randomUUID()}`;
|
|
86
92
|
if (client_ids_1.FRAMEWORK_CLIENT_IDS.includes(id)) {
|
|
87
|
-
throw new
|
|
93
|
+
throw new errors_1.ReservedClientIdError(id);
|
|
88
94
|
}
|
|
89
95
|
if ([...this.sessions].some(session => session.clientId === id)) {
|
|
90
|
-
throw new
|
|
96
|
+
throw new errors_1.DuplicateClientIdError(id);
|
|
91
97
|
}
|
|
92
98
|
const session = this.sessionFactory(id, {
|
|
93
99
|
connected: () => this.connected(),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data-connection.js","sourceRoot":"","sources":["../../src/client/data-connection.ts"],"names":[],"mappings":";AAAA;;;;;;;kFAOkF;;;AAElF,mDAAqD;AACrD,8CAAqD;AACrD,kCAQiB;
|
|
1
|
+
{"version":3,"file":"data-connection.js","sourceRoot":"","sources":["../../src/client/data-connection.ts"],"names":[],"mappings":"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"}
|
|
@@ -34,7 +34,8 @@ export interface DocumentServerProtocol<TTransfer extends TransferElement, TDiag
|
|
|
34
34
|
/**
|
|
35
35
|
* Register `args.clientId` as a client session owned by this connection.
|
|
36
36
|
* Rejects with a `DuplicateClientIdError` code when the id is live anywhere
|
|
37
|
-
* in the server process
|
|
37
|
+
* in the server process, and with a `ReservedClientIdError` code when the
|
|
38
|
+
* framework reserves it.
|
|
38
39
|
*
|
|
39
40
|
* A request carrying a registered id acts as that session: it writes only
|
|
40
41
|
* what the session has open, failing with a `DocumentNotOpenError` code
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data-server-protocol.d.ts","sourceRoot":"","sources":["../../src/data/data-server-protocol.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,KAAK,EAAE,cAAc,EAAE,gBAAgB,EAAE,aAAa,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAC3H,OAAO,KAAK,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,sCAAsC,CAAC;AAChG,OAAO,KAAK,EACT,oBAAoB,EACpB,4BAA4B,EAC5B,iCAAiC,EACjC,0BAA0B,EAC1B,2BAA2B,EAC3B,4BAA4B,EAC9B,MAAM,UAAU,CAAC;AAClB,OAAO,KAAK,EACT,gBAAgB,EAChB,uBAAuB,EACvB,iBAAiB,EACjB,oBAAoB,EACpB,oBAAoB,EACpB,wBAAwB,EACxB,sBAAsB,EACtB,0BAA0B,EAC1B,2BAA2B,EAC7B,MAAM,YAAY,CAAC;AAEpB;;;;;;;;;;;;;;;GAeG;AACH,MAAM,WAAW,sBAAsB,CAAC,SAAS,SAAS,eAAe,EAAE,WAAW,SAAS,kBAAkB,GAAG,kBAAkB;IACnI
|
|
1
|
+
{"version":3,"file":"data-server-protocol.d.ts","sourceRoot":"","sources":["../../src/data/data-server-protocol.ts"],"names":[],"mappings":"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"}
|
package/lib/errors.d.ts
CHANGED
|
@@ -9,24 +9,46 @@
|
|
|
9
9
|
import { ResponseError } from 'vscode-jsonrpc';
|
|
10
10
|
import { type HydraniumMessageData } from './messages/primitives';
|
|
11
11
|
/**
|
|
12
|
-
* The catalogue declaration behind {@link ConflictError}'s sentence.
|
|
12
|
+
* The catalogue declaration behind {@link ConflictError}'s sentence. It words
|
|
13
|
+
* the version mismatch rather than stating it: the two numbers mean nothing to
|
|
14
|
+
* an end user, and they stay in {@link ConflictErrorData}.
|
|
13
15
|
*
|
|
14
16
|
* Its English must keep containing {@link CONFLICT_ERROR_MESSAGE_MARKER}: the
|
|
15
17
|
* marker is tier 3 of {@link isConflictError}'s ladder, and it matches on text.
|
|
16
18
|
* That tier only ever works untranslated, which is why it is the last resort
|
|
17
19
|
* behind the numeric code rather than the primary check.
|
|
18
20
|
*/
|
|
19
|
-
export declare const STALE_BASED_UPDATE: import("./messages/primitives").MessageDefinition<"
|
|
21
|
+
export declare const STALE_BASED_UPDATE: import("./messages/primitives").MessageDefinition<"The edit to {uri} was not applied: it was made to an older version of the document.">;
|
|
20
22
|
/**
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
+
* Every JSON-RPC error code the framework raises, from any package, keyed by
|
|
24
|
+
* the error it identifies.
|
|
25
|
+
*
|
|
26
|
+
* The framework reserves the block 42000 to 42999 for these, and an adopter's
|
|
27
|
+
* own codes stay outside it: after an RPC a guard matches on the code alone, so
|
|
28
|
+
* an adopter's error carrying one of these reads as the framework's. A new code
|
|
29
|
+
* takes the next unused number in the block, whichever package raises it, and
|
|
30
|
+
* is declared here, where tests hold every code distinct and inside the block.
|
|
31
|
+
* The block sits clear of the range JSON-RPC 2.0 reserves for itself, -32768
|
|
32
|
+
* to -32000.
|
|
33
|
+
*/
|
|
34
|
+
export declare const HYDRANIUM_ERROR_CODES: {
|
|
35
|
+
readonly conflict: 42001;
|
|
36
|
+
readonly noActiveProfile: 42002;
|
|
37
|
+
readonly referenceSettleTimeout: 42003;
|
|
38
|
+
readonly sessionClosed: 42004;
|
|
39
|
+
readonly documentNotOpen: 42005;
|
|
40
|
+
readonly duplicateClientId: 42006;
|
|
41
|
+
readonly reservedClientId: 42007;
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* JSON-RPC error code for {@link ConflictError}.
|
|
23
45
|
*
|
|
24
46
|
* The code is the load-bearing identifier across realm boundaries —
|
|
25
47
|
* `code` is a first-class field on the JSON-RPC error envelope and
|
|
26
48
|
* survives wire reconstruction; the custom `Error` subclass name does
|
|
27
49
|
* not.
|
|
28
50
|
*/
|
|
29
|
-
export declare const CONFLICT_ERROR_CODE
|
|
51
|
+
export declare const CONFLICT_ERROR_CODE: 42001;
|
|
30
52
|
/**
|
|
31
53
|
* Structured payload carried in {@link ConflictError.data}, and the only place
|
|
32
54
|
* a post-RPC caller can read the version mismatch from.
|
|
@@ -86,11 +108,13 @@ export declare class ConflictError extends ResponseError<ConflictErrorData> {
|
|
|
86
108
|
* JSON-RPC code for {@link SessionClosedError}, beside {@link CONFLICT_ERROR_CODE}
|
|
87
109
|
* and for the same reason: the code survives reconstruction, the class does not.
|
|
88
110
|
*/
|
|
89
|
-
export declare const SESSION_CLOSED_ERROR_CODE
|
|
111
|
+
export declare const SESSION_CLOSED_ERROR_CODE: 42004;
|
|
90
112
|
/** JSON-RPC code for {@link DocumentNotOpenError}. */
|
|
91
|
-
export declare const DOCUMENT_NOT_OPEN_ERROR_CODE
|
|
113
|
+
export declare const DOCUMENT_NOT_OPEN_ERROR_CODE: 42005;
|
|
92
114
|
/** JSON-RPC code for {@link DuplicateClientIdError}. */
|
|
93
|
-
export declare const DUPLICATE_CLIENT_ID_ERROR_CODE
|
|
115
|
+
export declare const DUPLICATE_CLIENT_ID_ERROR_CODE: 42006;
|
|
116
|
+
/** JSON-RPC code for {@link ReservedClientIdError}. */
|
|
117
|
+
export declare const RESERVED_CLIENT_ID_ERROR_CODE: 42007;
|
|
94
118
|
/**
|
|
95
119
|
* The catalogue declaration behind {@link SessionClosedError}'s default
|
|
96
120
|
* sentence. It names no client id: the sentence can reach an end user, and the
|
|
@@ -117,6 +141,16 @@ export declare class SessionClosedError extends ResponseError<SessionClosedError
|
|
|
117
141
|
constructor(clientId: string, message?: string);
|
|
118
142
|
get clientId(): string;
|
|
119
143
|
}
|
|
144
|
+
/**
|
|
145
|
+
* The catalogue declaration behind {@link DocumentNotOpenError}'s sentence. The
|
|
146
|
+
* client id stays in {@link DocumentNotOpenErrorData.clientId}.
|
|
147
|
+
*/
|
|
148
|
+
export declare const DOCUMENT_NOT_OPEN: import("./messages/primitives").MessageDefinition<"The document {uri} is not open in this editing session.">;
|
|
149
|
+
/** Structured payload carried in {@link DocumentNotOpenError.data}. */
|
|
150
|
+
export interface DocumentNotOpenErrorData extends HydraniumMessageData {
|
|
151
|
+
readonly uri: string;
|
|
152
|
+
readonly clientId: string;
|
|
153
|
+
}
|
|
120
154
|
/**
|
|
121
155
|
* Thrown when a client session writes a document it does not have open.
|
|
122
156
|
*
|
|
@@ -124,23 +158,42 @@ export declare class SessionClosedError extends ResponseError<SessionClosedError
|
|
|
124
158
|
* that never opened and to one whose open was closed underneath it — by the
|
|
125
159
|
* session itself, or by the document being deleted.
|
|
126
160
|
*/
|
|
127
|
-
export declare class DocumentNotOpenError extends ResponseError<{
|
|
128
|
-
readonly uri: string;
|
|
129
|
-
readonly clientId: string;
|
|
130
|
-
}> {
|
|
161
|
+
export declare class DocumentNotOpenError extends ResponseError<DocumentNotOpenErrorData> {
|
|
131
162
|
constructor(uri: string, clientId: string);
|
|
132
163
|
get uri(): string;
|
|
133
164
|
get clientId(): string;
|
|
134
165
|
}
|
|
166
|
+
/**
|
|
167
|
+
* The catalogue declaration behind {@link DuplicateClientIdError}'s sentence.
|
|
168
|
+
* The client id stays in {@link DuplicateClientIdErrorData.clientId}.
|
|
169
|
+
*/
|
|
170
|
+
export declare const DUPLICATE_CLIENT_ID: import("./messages/primitives").MessageDefinition<"Could not start an editing session: its identifier is still in use by another editor.">;
|
|
171
|
+
/** Structured payload carried in {@link DuplicateClientIdError.data}. */
|
|
172
|
+
export interface DuplicateClientIdErrorData extends HydraniumMessageData {
|
|
173
|
+
readonly clientId: string;
|
|
174
|
+
}
|
|
135
175
|
/**
|
|
136
176
|
* Thrown when a client session is started under an id that is already live in
|
|
137
|
-
* the process
|
|
177
|
+
* the process. The id frees up once its holder ends or closes its last
|
|
178
|
+
* document, so a caller may retry.
|
|
138
179
|
*
|
|
139
180
|
* Ids are unique process-wide because the id is also the author label on every
|
|
140
181
|
* version and the key a client recognises its own echoes by; two participants
|
|
141
182
|
* sharing one would each take the other's writes for their own.
|
|
142
183
|
*/
|
|
143
|
-
export declare class DuplicateClientIdError extends ResponseError<{
|
|
184
|
+
export declare class DuplicateClientIdError extends ResponseError<DuplicateClientIdErrorData> {
|
|
185
|
+
constructor(clientId: string);
|
|
186
|
+
get clientId(): string;
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Thrown when a client session is started under an id the framework reserves
|
|
190
|
+
* for one of its own participants. A reserved id never frees up, so a caller
|
|
191
|
+
* that retries on {@link DuplicateClientIdError} stops on this one.
|
|
192
|
+
*
|
|
193
|
+
* It carries no message identity: a host that picks a reserved id has a bug,
|
|
194
|
+
* and no sentence addressed to an end user is true for it.
|
|
195
|
+
*/
|
|
196
|
+
export declare class ReservedClientIdError extends ResponseError<{
|
|
144
197
|
readonly clientId: string;
|
|
145
198
|
}> {
|
|
146
199
|
constructor(clientId: string);
|
|
@@ -155,6 +208,8 @@ export declare function isSessionClosedError(error: unknown): error is SessionCl
|
|
|
155
208
|
export declare function isDocumentNotOpenError(error: unknown): error is DocumentNotOpenError;
|
|
156
209
|
/** Whether `error` is a {@link DuplicateClientIdError}; see {@link isSessionClosedError}. */
|
|
157
210
|
export declare function isDuplicateClientIdError(error: unknown): error is DuplicateClientIdError;
|
|
211
|
+
/** Whether `error` is a {@link ReservedClientIdError}; see {@link isSessionClosedError}. */
|
|
212
|
+
export declare function isReservedClientIdError(error: unknown): error is ReservedClientIdError;
|
|
158
213
|
/**
|
|
159
214
|
* Type guard for {@link ConflictError}. Detection ladder:
|
|
160
215
|
*
|
|
@@ -164,8 +219,9 @@ export declare function isDuplicateClientIdError(error: unknown): error is Dupli
|
|
|
164
219
|
* canonical wire-side check; the JSON-RPC `code` field is preserved
|
|
165
220
|
* across reconstruction, so any adopter catching after an RPC call
|
|
166
221
|
* hits this branch.
|
|
167
|
-
* 3. `error.message
|
|
168
|
-
* for transports that re-wrap the message
|
|
222
|
+
* 3. `error.message` contains the marker {@link STALE_BASED_UPDATE}'s
|
|
223
|
+
* English carries — fallback for transports that re-wrap the message
|
|
224
|
+
* and drop the code (rare).
|
|
169
225
|
*
|
|
170
226
|
* `instanceof ConflictError` alone would silently return `false` on the
|
|
171
227
|
* reconstructed shape, so callers do not use it.
|
package/lib/errors.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAiB,KAAK,oBAAoB,EAAe,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
|
package/lib/errors.js
CHANGED
|
@@ -8,32 +8,66 @@
|
|
|
8
8
|
* SPDX-License-Identifier: MIT
|
|
9
9
|
********************************************************************************/
|
|
10
10
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
-
exports.DuplicateClientIdError = exports.DocumentNotOpenError = exports.SessionClosedError = exports.SESSION_CLOSED = exports.DUPLICATE_CLIENT_ID_ERROR_CODE = exports.DOCUMENT_NOT_OPEN_ERROR_CODE = exports.SESSION_CLOSED_ERROR_CODE = exports.ConflictError = exports.CONFLICT_ERROR_CODE = exports.STALE_BASED_UPDATE = void 0;
|
|
11
|
+
exports.ReservedClientIdError = exports.DuplicateClientIdError = exports.DUPLICATE_CLIENT_ID = exports.DocumentNotOpenError = exports.DOCUMENT_NOT_OPEN = exports.SessionClosedError = exports.SESSION_CLOSED = exports.RESERVED_CLIENT_ID_ERROR_CODE = exports.DUPLICATE_CLIENT_ID_ERROR_CODE = exports.DOCUMENT_NOT_OPEN_ERROR_CODE = exports.SESSION_CLOSED_ERROR_CODE = exports.ConflictError = exports.CONFLICT_ERROR_CODE = exports.HYDRANIUM_ERROR_CODES = exports.STALE_BASED_UPDATE = void 0;
|
|
12
12
|
exports.isSessionClosedError = isSessionClosedError;
|
|
13
13
|
exports.isDocumentNotOpenError = isDocumentNotOpenError;
|
|
14
14
|
exports.isDuplicateClientIdError = isDuplicateClientIdError;
|
|
15
|
+
exports.isReservedClientIdError = isReservedClientIdError;
|
|
15
16
|
exports.isConflictError = isConflictError;
|
|
16
17
|
const vscode_jsonrpc_1 = require("vscode-jsonrpc");
|
|
17
18
|
const primitives_1 = require("./messages/primitives");
|
|
19
|
+
/*
|
|
20
|
+
* Every error here is a typed error: a caller reacts to it, so it has a class,
|
|
21
|
+
* a JSON-RPC code and an `is*` guard, and an English message. A typed error
|
|
22
|
+
* also carries a message identity where the framework can write an end-user
|
|
23
|
+
* sentence that needs no context. A URI may stay in that sentence; a client id
|
|
24
|
+
* or a raw version stays out of it, worded or left to `data`.
|
|
25
|
+
*
|
|
26
|
+
* An error nothing reacts to does not belong here: it stays a plain `Error`, or
|
|
27
|
+
* a named subclass without a code, at its throw site, since a code and a guard
|
|
28
|
+
* are public API that no caller would use.
|
|
29
|
+
*/
|
|
18
30
|
/**
|
|
19
|
-
* The catalogue declaration behind {@link ConflictError}'s sentence.
|
|
31
|
+
* The catalogue declaration behind {@link ConflictError}'s sentence. It words
|
|
32
|
+
* the version mismatch rather than stating it: the two numbers mean nothing to
|
|
33
|
+
* an end user, and they stay in {@link ConflictErrorData}.
|
|
20
34
|
*
|
|
21
35
|
* Its English must keep containing {@link CONFLICT_ERROR_MESSAGE_MARKER}: the
|
|
22
36
|
* marker is tier 3 of {@link isConflictError}'s ladder, and it matches on text.
|
|
23
37
|
* That tier only ever works untranslated, which is why it is the last resort
|
|
24
38
|
* behind the numeric code rather than the primary check.
|
|
25
39
|
*/
|
|
26
|
-
exports.STALE_BASED_UPDATE = (0, primitives_1.defineMessage)('hydranium/protocol/stale-based-update', '
|
|
40
|
+
exports.STALE_BASED_UPDATE = (0, primitives_1.defineMessage)('hydranium/protocol/stale-based-update', 'The edit to {uri} was not applied: it was made to an older version of the document.');
|
|
41
|
+
/**
|
|
42
|
+
* Every JSON-RPC error code the framework raises, from any package, keyed by
|
|
43
|
+
* the error it identifies.
|
|
44
|
+
*
|
|
45
|
+
* The framework reserves the block 42000 to 42999 for these, and an adopter's
|
|
46
|
+
* own codes stay outside it: after an RPC a guard matches on the code alone, so
|
|
47
|
+
* an adopter's error carrying one of these reads as the framework's. A new code
|
|
48
|
+
* takes the next unused number in the block, whichever package raises it, and
|
|
49
|
+
* is declared here, where tests hold every code distinct and inside the block.
|
|
50
|
+
* The block sits clear of the range JSON-RPC 2.0 reserves for itself, -32768
|
|
51
|
+
* to -32000.
|
|
52
|
+
*/
|
|
53
|
+
exports.HYDRANIUM_ERROR_CODES = {
|
|
54
|
+
conflict: 42001,
|
|
55
|
+
noActiveProfile: 42002,
|
|
56
|
+
referenceSettleTimeout: 42003,
|
|
57
|
+
sessionClosed: 42004,
|
|
58
|
+
documentNotOpen: 42005,
|
|
59
|
+
duplicateClientId: 42006,
|
|
60
|
+
reservedClientId: 42007
|
|
61
|
+
};
|
|
27
62
|
/**
|
|
28
|
-
*
|
|
29
|
-
* Outside the reserved range (-32768 .. -32000) per JSON-RPC 2.0.
|
|
63
|
+
* JSON-RPC error code for {@link ConflictError}.
|
|
30
64
|
*
|
|
31
65
|
* The code is the load-bearing identifier across realm boundaries —
|
|
32
66
|
* `code` is a first-class field on the JSON-RPC error envelope and
|
|
33
67
|
* survives wire reconstruction; the custom `Error` subclass name does
|
|
34
68
|
* not.
|
|
35
69
|
*/
|
|
36
|
-
exports.CONFLICT_ERROR_CODE =
|
|
70
|
+
exports.CONFLICT_ERROR_CODE = exports.HYDRANIUM_ERROR_CODES.conflict;
|
|
37
71
|
/**
|
|
38
72
|
* Thrown by a client session's `update` / `save` when the caller-
|
|
39
73
|
* supplied based-on version no longer matches the server's current text-
|
|
@@ -65,11 +99,15 @@ exports.CONFLICT_ERROR_CODE = 1001;
|
|
|
65
99
|
*/
|
|
66
100
|
class ConflictError extends vscode_jsonrpc_1.ResponseError {
|
|
67
101
|
constructor(uri, expectedVersion, actualVersion) {
|
|
68
|
-
const params = { uri, expectedVersion, actualVersion };
|
|
69
102
|
// The identity rides alongside the typed payload rather than replacing
|
|
70
103
|
// it: `isConflictError`'s name check is surface an adopter may bind, so
|
|
71
104
|
// adding the identity widens the payload rather than reshaping it.
|
|
72
|
-
super(exports.CONFLICT_ERROR_CODE, exports.STALE_BASED_UPDATE.format(
|
|
105
|
+
super(exports.CONFLICT_ERROR_CODE, exports.STALE_BASED_UPDATE.format({ uri }), {
|
|
106
|
+
uri,
|
|
107
|
+
expectedVersion,
|
|
108
|
+
actualVersion,
|
|
109
|
+
...(0, primitives_1.messageData)(exports.STALE_BASED_UPDATE, { uri })
|
|
110
|
+
});
|
|
73
111
|
this.name = 'ConflictError';
|
|
74
112
|
// ResponseError's constructor calls `Object.setPrototypeOf(this,
|
|
75
113
|
// ResponseError.prototype)` to keep its own prototype chain intact across
|
|
@@ -103,11 +141,13 @@ exports.ConflictError = ConflictError;
|
|
|
103
141
|
* JSON-RPC code for {@link SessionClosedError}, beside {@link CONFLICT_ERROR_CODE}
|
|
104
142
|
* and for the same reason: the code survives reconstruction, the class does not.
|
|
105
143
|
*/
|
|
106
|
-
exports.SESSION_CLOSED_ERROR_CODE =
|
|
144
|
+
exports.SESSION_CLOSED_ERROR_CODE = exports.HYDRANIUM_ERROR_CODES.sessionClosed;
|
|
107
145
|
/** JSON-RPC code for {@link DocumentNotOpenError}. */
|
|
108
|
-
exports.DOCUMENT_NOT_OPEN_ERROR_CODE =
|
|
146
|
+
exports.DOCUMENT_NOT_OPEN_ERROR_CODE = exports.HYDRANIUM_ERROR_CODES.documentNotOpen;
|
|
109
147
|
/** JSON-RPC code for {@link DuplicateClientIdError}. */
|
|
110
|
-
exports.DUPLICATE_CLIENT_ID_ERROR_CODE =
|
|
148
|
+
exports.DUPLICATE_CLIENT_ID_ERROR_CODE = exports.HYDRANIUM_ERROR_CODES.duplicateClientId;
|
|
149
|
+
/** JSON-RPC code for {@link ReservedClientIdError}. */
|
|
150
|
+
exports.RESERVED_CLIENT_ID_ERROR_CODE = exports.HYDRANIUM_ERROR_CODES.reservedClientId;
|
|
111
151
|
/**
|
|
112
152
|
* The catalogue declaration behind {@link SessionClosedError}'s default
|
|
113
153
|
* sentence. It names no client id: the sentence can reach an end user, and the
|
|
@@ -138,6 +178,11 @@ class SessionClosedError extends vscode_jsonrpc_1.ResponseError {
|
|
|
138
178
|
}
|
|
139
179
|
}
|
|
140
180
|
exports.SessionClosedError = SessionClosedError;
|
|
181
|
+
/**
|
|
182
|
+
* The catalogue declaration behind {@link DocumentNotOpenError}'s sentence. The
|
|
183
|
+
* client id stays in {@link DocumentNotOpenErrorData.clientId}.
|
|
184
|
+
*/
|
|
185
|
+
exports.DOCUMENT_NOT_OPEN = (0, primitives_1.defineMessage)('hydranium/protocol/document-not-open', 'The document {uri} is not open in this editing session.');
|
|
141
186
|
/**
|
|
142
187
|
* Thrown when a client session writes a document it does not have open.
|
|
143
188
|
*
|
|
@@ -147,7 +192,11 @@ exports.SessionClosedError = SessionClosedError;
|
|
|
147
192
|
*/
|
|
148
193
|
class DocumentNotOpenError extends vscode_jsonrpc_1.ResponseError {
|
|
149
194
|
constructor(uri, clientId) {
|
|
150
|
-
super(exports.DOCUMENT_NOT_OPEN_ERROR_CODE,
|
|
195
|
+
super(exports.DOCUMENT_NOT_OPEN_ERROR_CODE, exports.DOCUMENT_NOT_OPEN.format({ uri }), {
|
|
196
|
+
uri,
|
|
197
|
+
clientId,
|
|
198
|
+
...(0, primitives_1.messageData)(exports.DOCUMENT_NOT_OPEN, { uri })
|
|
199
|
+
});
|
|
151
200
|
this.name = 'DocumentNotOpenError';
|
|
152
201
|
Object.setPrototypeOf(this, DocumentNotOpenError.prototype);
|
|
153
202
|
}
|
|
@@ -159,9 +208,15 @@ class DocumentNotOpenError extends vscode_jsonrpc_1.ResponseError {
|
|
|
159
208
|
}
|
|
160
209
|
}
|
|
161
210
|
exports.DocumentNotOpenError = DocumentNotOpenError;
|
|
211
|
+
/**
|
|
212
|
+
* The catalogue declaration behind {@link DuplicateClientIdError}'s sentence.
|
|
213
|
+
* The client id stays in {@link DuplicateClientIdErrorData.clientId}.
|
|
214
|
+
*/
|
|
215
|
+
exports.DUPLICATE_CLIENT_ID = (0, primitives_1.defineMessage)('hydranium/protocol/duplicate-client-id', 'Could not start an editing session: its identifier is still in use by another editor.');
|
|
162
216
|
/**
|
|
163
217
|
* Thrown when a client session is started under an id that is already live in
|
|
164
|
-
* the process
|
|
218
|
+
* the process. The id frees up once its holder ends or closes its last
|
|
219
|
+
* document, so a caller may retry.
|
|
165
220
|
*
|
|
166
221
|
* Ids are unique process-wide because the id is also the author label on every
|
|
167
222
|
* version and the key a client recognises its own echoes by; two participants
|
|
@@ -169,7 +224,7 @@ exports.DocumentNotOpenError = DocumentNotOpenError;
|
|
|
169
224
|
*/
|
|
170
225
|
class DuplicateClientIdError extends vscode_jsonrpc_1.ResponseError {
|
|
171
226
|
constructor(clientId) {
|
|
172
|
-
super(exports.DUPLICATE_CLIENT_ID_ERROR_CODE,
|
|
227
|
+
super(exports.DUPLICATE_CLIENT_ID_ERROR_CODE, exports.DUPLICATE_CLIENT_ID.format(), { clientId, ...(0, primitives_1.messageData)(exports.DUPLICATE_CLIENT_ID) });
|
|
173
228
|
this.name = 'DuplicateClientIdError';
|
|
174
229
|
Object.setPrototypeOf(this, DuplicateClientIdError.prototype);
|
|
175
230
|
}
|
|
@@ -178,6 +233,25 @@ class DuplicateClientIdError extends vscode_jsonrpc_1.ResponseError {
|
|
|
178
233
|
}
|
|
179
234
|
}
|
|
180
235
|
exports.DuplicateClientIdError = DuplicateClientIdError;
|
|
236
|
+
/**
|
|
237
|
+
* Thrown when a client session is started under an id the framework reserves
|
|
238
|
+
* for one of its own participants. A reserved id never frees up, so a caller
|
|
239
|
+
* that retries on {@link DuplicateClientIdError} stops on this one.
|
|
240
|
+
*
|
|
241
|
+
* It carries no message identity: a host that picks a reserved id has a bug,
|
|
242
|
+
* and no sentence addressed to an end user is true for it.
|
|
243
|
+
*/
|
|
244
|
+
class ReservedClientIdError extends vscode_jsonrpc_1.ResponseError {
|
|
245
|
+
constructor(clientId) {
|
|
246
|
+
super(exports.RESERVED_CLIENT_ID_ERROR_CODE, `Client id ${clientId} is reserved for a framework participant`, { clientId });
|
|
247
|
+
this.name = 'ReservedClientIdError';
|
|
248
|
+
Object.setPrototypeOf(this, ReservedClientIdError.prototype);
|
|
249
|
+
}
|
|
250
|
+
get clientId() {
|
|
251
|
+
return this.data.clientId;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
exports.ReservedClientIdError = ReservedClientIdError;
|
|
181
255
|
/**
|
|
182
256
|
* Whether `error` is a {@link SessionClosedError}: by name in-process, by code
|
|
183
257
|
* after an RPC, where it arrives as a plain `ResponseError`.
|
|
@@ -193,13 +267,17 @@ function isDocumentNotOpenError(error) {
|
|
|
193
267
|
function isDuplicateClientIdError(error) {
|
|
194
268
|
return hasErrorIdentity(error, 'DuplicateClientIdError', exports.DUPLICATE_CLIENT_ID_ERROR_CODE);
|
|
195
269
|
}
|
|
270
|
+
/** Whether `error` is a {@link ReservedClientIdError}; see {@link isSessionClosedError}. */
|
|
271
|
+
function isReservedClientIdError(error) {
|
|
272
|
+
return hasErrorIdentity(error, 'ReservedClientIdError', exports.RESERVED_CLIENT_ID_ERROR_CODE);
|
|
273
|
+
}
|
|
196
274
|
function hasErrorIdentity(error, name, code) {
|
|
197
275
|
return error instanceof Error && (error.name === name || error.code === code);
|
|
198
276
|
}
|
|
199
277
|
/** Marker substring present in every {@link ConflictError} message, used by
|
|
200
278
|
* {@link isConflictError} as a fallback when a transport re-wraps the error
|
|
201
279
|
* and drops the JSON-RPC code. */
|
|
202
|
-
const CONFLICT_ERROR_MESSAGE_MARKER = '
|
|
280
|
+
const CONFLICT_ERROR_MESSAGE_MARKER = ': it was made to an older version of the document';
|
|
203
281
|
/**
|
|
204
282
|
* Type guard for {@link ConflictError}. Detection ladder:
|
|
205
283
|
*
|
|
@@ -209,8 +287,9 @@ const CONFLICT_ERROR_MESSAGE_MARKER = 'Stale-based update for ';
|
|
|
209
287
|
* canonical wire-side check; the JSON-RPC `code` field is preserved
|
|
210
288
|
* across reconstruction, so any adopter catching after an RPC call
|
|
211
289
|
* hits this branch.
|
|
212
|
-
* 3. `error.message
|
|
213
|
-
* for transports that re-wrap the message
|
|
290
|
+
* 3. `error.message` contains the marker {@link STALE_BASED_UPDATE}'s
|
|
291
|
+
* English carries — fallback for transports that re-wrap the message
|
|
292
|
+
* and drop the code (rare).
|
|
214
293
|
*
|
|
215
294
|
* `instanceof ConflictError` alone would silently return `false` on the
|
|
216
295
|
* reconstructed shape, so callers do not use it.
|
package/lib/errors.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":";AAAA;;;;;;;kFAOkF;;;
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":";AAAA;;;;;;;kFAOkF;;;AA0SlF,oDAEC;AAGD,wDAEC;AAGD,4DAEC;AAGD,0DAEC;AA2BD,0CAYC;AAhWD,mDAA+C;AAC/C,sDAA8F;AAE9F;;;;;;;;;;GAUG;AAEH;;;;;;;;;GASG;AACU,QAAA,kBAAkB,GAAG,IAAA,0BAAa,EAC5C,uCAAuC,EACvC,qFAAqF,CACvF,CAAC;AAEF;;;;;;;;;;;GAWG;AACU,QAAA,qBAAqB,GAAG;IAClC,QAAQ,EAAE,KAAK;IACf,eAAe,EAAE,KAAK;IACtB,sBAAsB,EAAE,KAAK;IAC7B,aAAa,EAAE,KAAK;IACpB,eAAe,EAAE,KAAK;IACtB,iBAAiB,EAAE,KAAK;IACxB,gBAAgB,EAAE,KAAK;CAChB,CAAC;AAEX;;;;;;;GAOG;AACU,QAAA,mBAAmB,GAAG,6BAAqB,CAAC,QAAQ,CAAC;AAclE;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,MAAa,aAAc,SAAQ,8BAAgC;IAChE,YAAY,GAAW,EAAE,eAAuB,EAAE,aAAqB;QACpE,uEAAuE;QACvE,wEAAwE;QACxE,mEAAmE;QACnE,KAAK,CAAC,2BAAmB,EAAE,0BAAkB,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE;YAC5D,GAAG;YACH,eAAe;YACf,aAAa;YACb,GAAG,IAAA,wBAAW,EAAC,0BAAkB,EAAE,EAAE,GAAG,EAAE,CAAC;SAC7C,CAAC,CAAC;QACH,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;QAC5B,iEAAiE;QACjE,0EAA0E;QAC1E,qEAAqE;QACrE,gEAAgE;QAChE,yEAAyE;QACzE,SAAS;QACT,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,aAAa,CAAC,SAAS,CAAC,CAAC;IACxD,CAAC;IAED,IAAI,GAAG;QACJ,OAAO,IAAI,CAAC,IAAK,CAAC,GAAG,CAAC;IACzB,CAAC;IAED;;;;;;;OAOG;IACH,IAAI,eAAe;QAChB,OAAO,IAAI,CAAC,IAAK,CAAC,eAAe,CAAC;IACrC,CAAC;IAED,iGAAiG;IACjG,IAAI,aAAa;QACd,OAAO,IAAI,CAAC,IAAK,CAAC,aAAa,CAAC;IACnC,CAAC;CACH;AAzCD,sCAyCC;AAED;;;GAGG;AACU,QAAA,yBAAyB,GAAG,6BAAqB,CAAC,aAAa,CAAC;AAC7E,sDAAsD;AACzC,QAAA,4BAA4B,GAAG,6BAAqB,CAAC,eAAe,CAAC;AAClF,wDAAwD;AAC3C,QAAA,8BAA8B,GAAG,6BAAqB,CAAC,iBAAiB,CAAC;AACtF,uDAAuD;AAC1C,QAAA,6BAA6B,GAAG,6BAAqB,CAAC,gBAAgB,CAAC;AAEpF;;;;GAIG;AACU,QAAA,cAAc,GAAG,IAAA,0BAAa,EAAC,mCAAmC,EAAE,gCAAgC,CAAC,CAAC;AAOnH;;;;;;GAMG;AACH,MAAa,kBAAmB,SAAQ,8BAAqC;IAC1E;;;;OAIG;IACH,YAAY,QAAgB,EAAE,OAAO,GAAG,sBAAc,CAAC,MAAM,EAAE;QAC5D,KAAK,CAAC,iCAAyB,EAAE,OAAO,EAAE,EAAE,QAAQ,EAAE,GAAG,IAAA,wBAAW,EAAC,sBAAc,CAAC,EAAE,CAAC,CAAC;QACxF,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAC;QACjC,wEAAwE;QACxE,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,kBAAkB,CAAC,SAAS,CAAC,CAAC;IAC7D,CAAC;IAED,IAAI,QAAQ;QACT,OAAO,IAAI,CAAC,IAAK,CAAC,QAAQ,CAAC;IAC9B,CAAC;CACH;AAhBD,gDAgBC;AAED;;;GAGG;AACU,QAAA,iBAAiB,GAAG,IAAA,0BAAa,EAC3C,sCAAsC,EACtC,yDAAyD,CAC3D,CAAC;AAQF;;;;;;GAMG;AACH,MAAa,oBAAqB,SAAQ,8BAAuC;IAC9E,YAAY,GAAW,EAAE,QAAgB;QACtC,KAAK,CAAC,oCAA4B,EAAE,yBAAiB,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE;YACpE,GAAG;YACH,QAAQ;YACR,GAAG,IAAA,wBAAW,EAAC,yBAAiB,EAAE,EAAE,GAAG,EAAE,CAAC;SAC5C,CAAC,CAAC;QACH,IAAI,CAAC,IAAI,GAAG,sBAAsB,CAAC;QACnC,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,oBAAoB,CAAC,SAAS,CAAC,CAAC;IAC/D,CAAC;IAED,IAAI,GAAG;QACJ,OAAO,IAAI,CAAC,IAAK,CAAC,GAAG,CAAC;IACzB,CAAC;IAED,IAAI,QAAQ;QACT,OAAO,IAAI,CAAC,IAAK,CAAC,QAAQ,CAAC;IAC9B,CAAC;CACH;AAlBD,oDAkBC;AAED;;;GAGG;AACU,QAAA,mBAAmB,GAAG,IAAA,0BAAa,EAC7C,wCAAwC,EACxC,uFAAuF,CACzF,CAAC;AAOF;;;;;;;;GAQG;AACH,MAAa,sBAAuB,SAAQ,8BAAyC;IAClF,YAAY,QAAgB;QACzB,KAAK,CAAC,sCAA8B,EAAE,2BAAmB,CAAC,MAAM,EAAE,EAAE,EAAE,QAAQ,EAAE,GAAG,IAAA,wBAAW,EAAC,2BAAmB,CAAC,EAAE,CAAC,CAAC;QACvH,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAC;QACrC,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,sBAAsB,CAAC,SAAS,CAAC,CAAC;IACjE,CAAC;IAED,IAAI,QAAQ;QACT,OAAO,IAAI,CAAC,IAAK,CAAC,QAAQ,CAAC;IAC9B,CAAC;CACH;AAVD,wDAUC;AAED;;;;;;;GAOG;AACH,MAAa,qBAAsB,SAAQ,8BAA4C;IACpF,YAAY,QAAgB;QACzB,KAAK,CAAC,qCAA6B,EAAE,aAAa,QAAQ,0CAA0C,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC;QACpH,IAAI,CAAC,IAAI,GAAG,uBAAuB,CAAC;QACpC,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,qBAAqB,CAAC,SAAS,CAAC,CAAC;IAChE,CAAC;IAED,IAAI,QAAQ;QACT,OAAO,IAAI,CAAC,IAAK,CAAC,QAAQ,CAAC;IAC9B,CAAC;CACH;AAVD,sDAUC;AAED;;;GAGG;AACH,SAAgB,oBAAoB,CAAC,KAAc;IAChD,OAAO,gBAAgB,CAAC,KAAK,EAAE,oBAAoB,EAAE,iCAAyB,CAAC,CAAC;AACnF,CAAC;AAED,2FAA2F;AAC3F,SAAgB,sBAAsB,CAAC,KAAc;IAClD,OAAO,gBAAgB,CAAC,KAAK,EAAE,sBAAsB,EAAE,oCAA4B,CAAC,CAAC;AACxF,CAAC;AAED,6FAA6F;AAC7F,SAAgB,wBAAwB,CAAC,KAAc;IACpD,OAAO,gBAAgB,CAAC,KAAK,EAAE,wBAAwB,EAAE,sCAA8B,CAAC,CAAC;AAC5F,CAAC;AAED,4FAA4F;AAC5F,SAAgB,uBAAuB,CAAC,KAAc;IACnD,OAAO,gBAAgB,CAAC,KAAK,EAAE,uBAAuB,EAAE,qCAA6B,CAAC,CAAC;AAC1F,CAAC;AAED,SAAS,gBAAgB,CAAC,KAAc,EAAE,IAAY,EAAE,IAAY;IACjE,OAAO,KAAK,YAAY,KAAK,IAAI,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,IAAK,KAAyC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;AACtH,CAAC;AAED;;mCAEmC;AACnC,MAAM,6BAA6B,GAAG,mDAAmD,CAAC;AAE1F;;;;;;;;;;;;;;;GAeG;AACH,SAAgB,eAAe,CAAC,KAAc;IAC3C,IAAI,CAAC,CAAC,KAAK,YAAY,KAAK,CAAC,EAAE,CAAC;QAC7B,OAAO,KAAK,CAAC;IAChB,CAAC;IACD,IAAI,KAAK,CAAC,IAAI,KAAK,eAAe,EAAE,CAAC;QAClC,OAAO,IAAI,CAAC;IACf,CAAC;IACD,MAAM,IAAI,GAAI,KAAyC,CAAC,IAAI,CAAC;IAC7D,IAAI,IAAI,KAAK,2BAAmB,EAAE,CAAC;QAChC,OAAO,IAAI,CAAC;IACf,CAAC;IACD,OAAO,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,6BAA6B,CAAC,CAAC;AACrG,CAAC"}
|
package/lib/messages/index.d.ts
CHANGED
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
* The English is a fallback, not a contract; the code is the contract.
|
|
23
23
|
*/
|
|
24
24
|
export * from './primitives';
|
|
25
|
-
export { SESSION_CLOSED, STALE_BASED_UPDATE } from '../errors';
|
|
25
|
+
export { DOCUMENT_NOT_OPEN, DUPLICATE_CLIENT_ID, SESSION_CLOSED, STALE_BASED_UPDATE } from '../errors';
|
|
26
26
|
export { DATA_SERVER_CONNECT_FAILED, DATA_SERVER_NOT_READY } from '../client/rpc-connection';
|
|
27
27
|
export { DATA_SESSION_RESTORE_FAILED, DATA_SESSION_UNSAVED_LOST } from '../client/data-session';
|
|
28
28
|
export { RELAY_REPLAY_FAILED, RELAY_TRANSPORT_OPEN_FAILED, RELAY_TRANSPORT_READ_FAILED, RELAY_TRANSPORT_WRITE_FAILED } from '../client/message-relay';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/messages/index.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF;;;;;;;;;;;;;;GAcG;AAEH,cAAc,cAAc,CAAC;AAE7B,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/messages/index.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF;;;;;;;;;;;;;;GAcG;AAEH,cAAc,cAAc,CAAC;AAE7B,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AACvG,OAAO,EAAE,0BAA0B,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAC7F,OAAO,EAAE,2BAA2B,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AAChG,OAAO,EACJ,mBAAmB,EACnB,2BAA2B,EAC3B,2BAA2B,EAC3B,4BAA4B,EAC9B,MAAM,yBAAyB,CAAC"}
|
package/lib/messages/index.js
CHANGED
|
@@ -22,7 +22,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
22
22
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
23
23
|
};
|
|
24
24
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
|
-
exports.RELAY_TRANSPORT_WRITE_FAILED = exports.RELAY_TRANSPORT_READ_FAILED = exports.RELAY_TRANSPORT_OPEN_FAILED = exports.RELAY_REPLAY_FAILED = exports.DATA_SESSION_UNSAVED_LOST = exports.DATA_SESSION_RESTORE_FAILED = exports.DATA_SERVER_NOT_READY = exports.DATA_SERVER_CONNECT_FAILED = exports.STALE_BASED_UPDATE = exports.SESSION_CLOSED = void 0;
|
|
25
|
+
exports.RELAY_TRANSPORT_WRITE_FAILED = exports.RELAY_TRANSPORT_READ_FAILED = exports.RELAY_TRANSPORT_OPEN_FAILED = exports.RELAY_REPLAY_FAILED = exports.DATA_SESSION_UNSAVED_LOST = exports.DATA_SESSION_RESTORE_FAILED = exports.DATA_SERVER_NOT_READY = exports.DATA_SERVER_CONNECT_FAILED = exports.STALE_BASED_UPDATE = exports.SESSION_CLOSED = exports.DUPLICATE_CLIENT_ID = exports.DOCUMENT_NOT_OPEN = void 0;
|
|
26
26
|
/**
|
|
27
27
|
* The message-externalization mechanism, plus every user-facing message
|
|
28
28
|
* `@hydranium/protocol` itself raises.
|
|
@@ -40,6 +40,8 @@ exports.RELAY_TRANSPORT_WRITE_FAILED = exports.RELAY_TRANSPORT_READ_FAILED = exp
|
|
|
40
40
|
*/
|
|
41
41
|
__exportStar(require("./primitives"), exports);
|
|
42
42
|
var errors_1 = require("../errors");
|
|
43
|
+
Object.defineProperty(exports, "DOCUMENT_NOT_OPEN", { enumerable: true, get: function () { return errors_1.DOCUMENT_NOT_OPEN; } });
|
|
44
|
+
Object.defineProperty(exports, "DUPLICATE_CLIENT_ID", { enumerable: true, get: function () { return errors_1.DUPLICATE_CLIENT_ID; } });
|
|
43
45
|
Object.defineProperty(exports, "SESSION_CLOSED", { enumerable: true, get: function () { return errors_1.SESSION_CLOSED; } });
|
|
44
46
|
Object.defineProperty(exports, "STALE_BASED_UPDATE", { enumerable: true, get: function () { return errors_1.STALE_BASED_UPDATE; } });
|
|
45
47
|
var rpc_connection_1 = require("../client/rpc-connection");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/messages/index.ts"],"names":[],"mappings":";AAAA;;;;;;;kFAOkF;;;;;;;;;;;;;;;;;AAElF;;;;;;;;;;;;;;GAcG;AAEH,+CAA6B;AAE7B,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/messages/index.ts"],"names":[],"mappings":";AAAA;;;;;;;kFAOkF;;;;;;;;;;;;;;;;;AAElF;;;;;;;;;;;;;;GAcG;AAEH,+CAA6B;AAE7B,oCAAuG;AAA9F,2GAAA,iBAAiB,OAAA;AAAE,6GAAA,mBAAmB,OAAA;AAAE,wGAAA,cAAc,OAAA;AAAE,4GAAA,kBAAkB,OAAA;AACnF,2DAA6F;AAApF,4HAAA,0BAA0B,OAAA;AAAE,uHAAA,qBAAqB,OAAA;AAC1D,uDAAgG;AAAvF,2HAAA,2BAA2B,OAAA;AAAE,yHAAA,yBAAyB,OAAA;AAC/D,yDAKiC;AAJ9B,oHAAA,mBAAmB,OAAA;AACnB,4HAAA,2BAA2B,OAAA;AAC3B,4HAAA,2BAA2B,OAAA;AAC3B,6HAAA,4BAA4B,OAAA"}
|
package/package.json
CHANGED
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
type ProjectOf,
|
|
19
19
|
type TransferDocumentDirtyChangedEvent
|
|
20
20
|
} from '../data';
|
|
21
|
+
import { DuplicateClientIdError, ReservedClientIdError } from '../errors';
|
|
21
22
|
import type { TransferElement } from '../transfer-element';
|
|
22
23
|
import { DataEvents } from './data-events';
|
|
23
24
|
import type { DataPort } from './data-port';
|
|
@@ -138,22 +139,27 @@ export class DataConnection<
|
|
|
138
139
|
* given. Pass a `label` naming the participant; without one it is
|
|
139
140
|
* `session`. Synchronous: the registration is sent at once, and the
|
|
140
141
|
* session's calls wait for it. The server refuses an id live anywhere in
|
|
141
|
-
* its process, and every call of that session then rejects with
|
|
142
|
-
* `
|
|
142
|
+
* its process, and every call of that session then rejects with an error
|
|
143
|
+
* `isDuplicateClientIdError` recognises; an id the server reserves beyond
|
|
144
|
+
* {@link FRAMEWORK_CLIENT_IDS}, such as the integrity author, with one
|
|
145
|
+
* `isReservedClientIdError` recognises. Only the code crosses the wire, so
|
|
146
|
+
* test with those guards rather than `instanceof`.
|
|
143
147
|
*
|
|
144
|
-
* Throws
|
|
145
|
-
*
|
|
146
|
-
*
|
|
147
|
-
*
|
|
148
|
+
* Throws a {@link ReservedClientIdError} for an id in
|
|
149
|
+
* {@link FRAMEWORK_CLIENT_IDS} — those are authors the SERVER emits rather
|
|
150
|
+
* than participants, so a session holding one would read the framework's
|
|
151
|
+
* own broadcasts as its own echoes and drop them — and a
|
|
152
|
+
* {@link DuplicateClientIdError} for an id a live session on this
|
|
153
|
+
* connection already holds.
|
|
148
154
|
*/
|
|
149
155
|
createSession(label = 'session', clientId?: string): DataSession<TTransfer, TServer> {
|
|
150
156
|
this.assertLive();
|
|
151
157
|
const id = clientId ?? `${label}#${globalThis.crypto.randomUUID()}`;
|
|
152
158
|
if (FRAMEWORK_CLIENT_IDS.includes(id)) {
|
|
153
|
-
throw new
|
|
159
|
+
throw new ReservedClientIdError(id);
|
|
154
160
|
}
|
|
155
161
|
if ([...this.sessions].some(session => session.clientId === id)) {
|
|
156
|
-
throw new
|
|
162
|
+
throw new DuplicateClientIdError(id);
|
|
157
163
|
}
|
|
158
164
|
const session = this.sessionFactory(
|
|
159
165
|
id,
|
|
@@ -53,7 +53,8 @@ export interface DocumentServerProtocol<TTransfer extends TransferElement, TDiag
|
|
|
53
53
|
/**
|
|
54
54
|
* Register `args.clientId` as a client session owned by this connection.
|
|
55
55
|
* Rejects with a `DuplicateClientIdError` code when the id is live anywhere
|
|
56
|
-
* in the server process
|
|
56
|
+
* in the server process, and with a `ReservedClientIdError` code when the
|
|
57
|
+
* framework reserves it.
|
|
57
58
|
*
|
|
58
59
|
* A request carrying a registered id acts as that session: it writes only
|
|
59
60
|
* what the session has open, failing with a `DocumentNotOpenError` code
|
package/src/errors.ts
CHANGED
|
@@ -10,8 +10,22 @@
|
|
|
10
10
|
import { ResponseError } from 'vscode-jsonrpc';
|
|
11
11
|
import { defineMessage, type HydraniumMessageData, messageData } from './messages/primitives';
|
|
12
12
|
|
|
13
|
+
/*
|
|
14
|
+
* Every error here is a typed error: a caller reacts to it, so it has a class,
|
|
15
|
+
* a JSON-RPC code and an `is*` guard, and an English message. A typed error
|
|
16
|
+
* also carries a message identity where the framework can write an end-user
|
|
17
|
+
* sentence that needs no context. A URI may stay in that sentence; a client id
|
|
18
|
+
* or a raw version stays out of it, worded or left to `data`.
|
|
19
|
+
*
|
|
20
|
+
* An error nothing reacts to does not belong here: it stays a plain `Error`, or
|
|
21
|
+
* a named subclass without a code, at its throw site, since a code and a guard
|
|
22
|
+
* are public API that no caller would use.
|
|
23
|
+
*/
|
|
24
|
+
|
|
13
25
|
/**
|
|
14
|
-
* The catalogue declaration behind {@link ConflictError}'s sentence.
|
|
26
|
+
* The catalogue declaration behind {@link ConflictError}'s sentence. It words
|
|
27
|
+
* the version mismatch rather than stating it: the two numbers mean nothing to
|
|
28
|
+
* an end user, and they stay in {@link ConflictErrorData}.
|
|
15
29
|
*
|
|
16
30
|
* Its English must keep containing {@link CONFLICT_ERROR_MESSAGE_MARKER}: the
|
|
17
31
|
* marker is tier 3 of {@link isConflictError}'s ladder, and it matches on text.
|
|
@@ -20,19 +34,40 @@ import { defineMessage, type HydraniumMessageData, messageData } from './message
|
|
|
20
34
|
*/
|
|
21
35
|
export const STALE_BASED_UPDATE = defineMessage(
|
|
22
36
|
'hydranium/protocol/stale-based-update',
|
|
23
|
-
'
|
|
37
|
+
'The edit to {uri} was not applied: it was made to an older version of the document.'
|
|
24
38
|
);
|
|
25
39
|
|
|
26
40
|
/**
|
|
27
|
-
*
|
|
28
|
-
*
|
|
41
|
+
* Every JSON-RPC error code the framework raises, from any package, keyed by
|
|
42
|
+
* the error it identifies.
|
|
43
|
+
*
|
|
44
|
+
* The framework reserves the block 42000 to 42999 for these, and an adopter's
|
|
45
|
+
* own codes stay outside it: after an RPC a guard matches on the code alone, so
|
|
46
|
+
* an adopter's error carrying one of these reads as the framework's. A new code
|
|
47
|
+
* takes the next unused number in the block, whichever package raises it, and
|
|
48
|
+
* is declared here, where tests hold every code distinct and inside the block.
|
|
49
|
+
* The block sits clear of the range JSON-RPC 2.0 reserves for itself, -32768
|
|
50
|
+
* to -32000.
|
|
51
|
+
*/
|
|
52
|
+
export const HYDRANIUM_ERROR_CODES = {
|
|
53
|
+
conflict: 42001,
|
|
54
|
+
noActiveProfile: 42002,
|
|
55
|
+
referenceSettleTimeout: 42003,
|
|
56
|
+
sessionClosed: 42004,
|
|
57
|
+
documentNotOpen: 42005,
|
|
58
|
+
duplicateClientId: 42006,
|
|
59
|
+
reservedClientId: 42007
|
|
60
|
+
} as const;
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* JSON-RPC error code for {@link ConflictError}.
|
|
29
64
|
*
|
|
30
65
|
* The code is the load-bearing identifier across realm boundaries —
|
|
31
66
|
* `code` is a first-class field on the JSON-RPC error envelope and
|
|
32
67
|
* survives wire reconstruction; the custom `Error` subclass name does
|
|
33
68
|
* not.
|
|
34
69
|
*/
|
|
35
|
-
export const CONFLICT_ERROR_CODE =
|
|
70
|
+
export const CONFLICT_ERROR_CODE = HYDRANIUM_ERROR_CODES.conflict;
|
|
36
71
|
|
|
37
72
|
/**
|
|
38
73
|
* Structured payload carried in {@link ConflictError.data}, and the only place
|
|
@@ -77,11 +112,15 @@ export interface ConflictErrorData extends HydraniumMessageData {
|
|
|
77
112
|
*/
|
|
78
113
|
export class ConflictError extends ResponseError<ConflictErrorData> {
|
|
79
114
|
constructor(uri: string, expectedVersion: number, actualVersion: number) {
|
|
80
|
-
const params = { uri, expectedVersion, actualVersion };
|
|
81
115
|
// The identity rides alongside the typed payload rather than replacing
|
|
82
116
|
// it: `isConflictError`'s name check is surface an adopter may bind, so
|
|
83
117
|
// adding the identity widens the payload rather than reshaping it.
|
|
84
|
-
super(CONFLICT_ERROR_CODE, STALE_BASED_UPDATE.format(
|
|
118
|
+
super(CONFLICT_ERROR_CODE, STALE_BASED_UPDATE.format({ uri }), {
|
|
119
|
+
uri,
|
|
120
|
+
expectedVersion,
|
|
121
|
+
actualVersion,
|
|
122
|
+
...messageData(STALE_BASED_UPDATE, { uri })
|
|
123
|
+
});
|
|
85
124
|
this.name = 'ConflictError';
|
|
86
125
|
// ResponseError's constructor calls `Object.setPrototypeOf(this,
|
|
87
126
|
// ResponseError.prototype)` to keep its own prototype chain intact across
|
|
@@ -118,11 +157,13 @@ export class ConflictError extends ResponseError<ConflictErrorData> {
|
|
|
118
157
|
* JSON-RPC code for {@link SessionClosedError}, beside {@link CONFLICT_ERROR_CODE}
|
|
119
158
|
* and for the same reason: the code survives reconstruction, the class does not.
|
|
120
159
|
*/
|
|
121
|
-
export const SESSION_CLOSED_ERROR_CODE =
|
|
160
|
+
export const SESSION_CLOSED_ERROR_CODE = HYDRANIUM_ERROR_CODES.sessionClosed;
|
|
122
161
|
/** JSON-RPC code for {@link DocumentNotOpenError}. */
|
|
123
|
-
export const DOCUMENT_NOT_OPEN_ERROR_CODE =
|
|
162
|
+
export const DOCUMENT_NOT_OPEN_ERROR_CODE = HYDRANIUM_ERROR_CODES.documentNotOpen;
|
|
124
163
|
/** JSON-RPC code for {@link DuplicateClientIdError}. */
|
|
125
|
-
export const DUPLICATE_CLIENT_ID_ERROR_CODE =
|
|
164
|
+
export const DUPLICATE_CLIENT_ID_ERROR_CODE = HYDRANIUM_ERROR_CODES.duplicateClientId;
|
|
165
|
+
/** JSON-RPC code for {@link ReservedClientIdError}. */
|
|
166
|
+
export const RESERVED_CLIENT_ID_ERROR_CODE = HYDRANIUM_ERROR_CODES.reservedClientId;
|
|
126
167
|
|
|
127
168
|
/**
|
|
128
169
|
* The catalogue declaration behind {@link SessionClosedError}'s default
|
|
@@ -161,6 +202,21 @@ export class SessionClosedError extends ResponseError<SessionClosedErrorData> {
|
|
|
161
202
|
}
|
|
162
203
|
}
|
|
163
204
|
|
|
205
|
+
/**
|
|
206
|
+
* The catalogue declaration behind {@link DocumentNotOpenError}'s sentence. The
|
|
207
|
+
* client id stays in {@link DocumentNotOpenErrorData.clientId}.
|
|
208
|
+
*/
|
|
209
|
+
export const DOCUMENT_NOT_OPEN = defineMessage(
|
|
210
|
+
'hydranium/protocol/document-not-open',
|
|
211
|
+
'The document {uri} is not open in this editing session.'
|
|
212
|
+
);
|
|
213
|
+
|
|
214
|
+
/** Structured payload carried in {@link DocumentNotOpenError.data}. */
|
|
215
|
+
export interface DocumentNotOpenErrorData extends HydraniumMessageData {
|
|
216
|
+
readonly uri: string;
|
|
217
|
+
readonly clientId: string;
|
|
218
|
+
}
|
|
219
|
+
|
|
164
220
|
/**
|
|
165
221
|
* Thrown when a client session writes a document it does not have open.
|
|
166
222
|
*
|
|
@@ -168,9 +224,13 @@ export class SessionClosedError extends ResponseError<SessionClosedErrorData> {
|
|
|
168
224
|
* that never opened and to one whose open was closed underneath it — by the
|
|
169
225
|
* session itself, or by the document being deleted.
|
|
170
226
|
*/
|
|
171
|
-
export class DocumentNotOpenError extends ResponseError<
|
|
227
|
+
export class DocumentNotOpenError extends ResponseError<DocumentNotOpenErrorData> {
|
|
172
228
|
constructor(uri: string, clientId: string) {
|
|
173
|
-
super(DOCUMENT_NOT_OPEN_ERROR_CODE,
|
|
229
|
+
super(DOCUMENT_NOT_OPEN_ERROR_CODE, DOCUMENT_NOT_OPEN.format({ uri }), {
|
|
230
|
+
uri,
|
|
231
|
+
clientId,
|
|
232
|
+
...messageData(DOCUMENT_NOT_OPEN, { uri })
|
|
233
|
+
});
|
|
174
234
|
this.name = 'DocumentNotOpenError';
|
|
175
235
|
Object.setPrototypeOf(this, DocumentNotOpenError.prototype);
|
|
176
236
|
}
|
|
@@ -184,17 +244,32 @@ export class DocumentNotOpenError extends ResponseError<{ readonly uri: string;
|
|
|
184
244
|
}
|
|
185
245
|
}
|
|
186
246
|
|
|
247
|
+
/**
|
|
248
|
+
* The catalogue declaration behind {@link DuplicateClientIdError}'s sentence.
|
|
249
|
+
* The client id stays in {@link DuplicateClientIdErrorData.clientId}.
|
|
250
|
+
*/
|
|
251
|
+
export const DUPLICATE_CLIENT_ID = defineMessage(
|
|
252
|
+
'hydranium/protocol/duplicate-client-id',
|
|
253
|
+
'Could not start an editing session: its identifier is still in use by another editor.'
|
|
254
|
+
);
|
|
255
|
+
|
|
256
|
+
/** Structured payload carried in {@link DuplicateClientIdError.data}. */
|
|
257
|
+
export interface DuplicateClientIdErrorData extends HydraniumMessageData {
|
|
258
|
+
readonly clientId: string;
|
|
259
|
+
}
|
|
260
|
+
|
|
187
261
|
/**
|
|
188
262
|
* Thrown when a client session is started under an id that is already live in
|
|
189
|
-
* the process
|
|
263
|
+
* the process. The id frees up once its holder ends or closes its last
|
|
264
|
+
* document, so a caller may retry.
|
|
190
265
|
*
|
|
191
266
|
* Ids are unique process-wide because the id is also the author label on every
|
|
192
267
|
* version and the key a client recognises its own echoes by; two participants
|
|
193
268
|
* sharing one would each take the other's writes for their own.
|
|
194
269
|
*/
|
|
195
|
-
export class DuplicateClientIdError extends ResponseError<
|
|
270
|
+
export class DuplicateClientIdError extends ResponseError<DuplicateClientIdErrorData> {
|
|
196
271
|
constructor(clientId: string) {
|
|
197
|
-
super(DUPLICATE_CLIENT_ID_ERROR_CODE,
|
|
272
|
+
super(DUPLICATE_CLIENT_ID_ERROR_CODE, DUPLICATE_CLIENT_ID.format(), { clientId, ...messageData(DUPLICATE_CLIENT_ID) });
|
|
198
273
|
this.name = 'DuplicateClientIdError';
|
|
199
274
|
Object.setPrototypeOf(this, DuplicateClientIdError.prototype);
|
|
200
275
|
}
|
|
@@ -204,6 +279,26 @@ export class DuplicateClientIdError extends ResponseError<{ readonly clientId: s
|
|
|
204
279
|
}
|
|
205
280
|
}
|
|
206
281
|
|
|
282
|
+
/**
|
|
283
|
+
* Thrown when a client session is started under an id the framework reserves
|
|
284
|
+
* for one of its own participants. A reserved id never frees up, so a caller
|
|
285
|
+
* that retries on {@link DuplicateClientIdError} stops on this one.
|
|
286
|
+
*
|
|
287
|
+
* It carries no message identity: a host that picks a reserved id has a bug,
|
|
288
|
+
* and no sentence addressed to an end user is true for it.
|
|
289
|
+
*/
|
|
290
|
+
export class ReservedClientIdError extends ResponseError<{ readonly clientId: string }> {
|
|
291
|
+
constructor(clientId: string) {
|
|
292
|
+
super(RESERVED_CLIENT_ID_ERROR_CODE, `Client id ${clientId} is reserved for a framework participant`, { clientId });
|
|
293
|
+
this.name = 'ReservedClientIdError';
|
|
294
|
+
Object.setPrototypeOf(this, ReservedClientIdError.prototype);
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
get clientId(): string {
|
|
298
|
+
return this.data!.clientId;
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
|
|
207
302
|
/**
|
|
208
303
|
* Whether `error` is a {@link SessionClosedError}: by name in-process, by code
|
|
209
304
|
* after an RPC, where it arrives as a plain `ResponseError`.
|
|
@@ -222,6 +317,11 @@ export function isDuplicateClientIdError(error: unknown): error is DuplicateClie
|
|
|
222
317
|
return hasErrorIdentity(error, 'DuplicateClientIdError', DUPLICATE_CLIENT_ID_ERROR_CODE);
|
|
223
318
|
}
|
|
224
319
|
|
|
320
|
+
/** Whether `error` is a {@link ReservedClientIdError}; see {@link isSessionClosedError}. */
|
|
321
|
+
export function isReservedClientIdError(error: unknown): error is ReservedClientIdError {
|
|
322
|
+
return hasErrorIdentity(error, 'ReservedClientIdError', RESERVED_CLIENT_ID_ERROR_CODE);
|
|
323
|
+
}
|
|
324
|
+
|
|
225
325
|
function hasErrorIdentity(error: unknown, name: string, code: number): boolean {
|
|
226
326
|
return error instanceof Error && (error.name === name || (error as Partial<ResponseError<unknown>>).code === code);
|
|
227
327
|
}
|
|
@@ -229,7 +329,7 @@ function hasErrorIdentity(error: unknown, name: string, code: number): boolean {
|
|
|
229
329
|
/** Marker substring present in every {@link ConflictError} message, used by
|
|
230
330
|
* {@link isConflictError} as a fallback when a transport re-wraps the error
|
|
231
331
|
* and drops the JSON-RPC code. */
|
|
232
|
-
const CONFLICT_ERROR_MESSAGE_MARKER = '
|
|
332
|
+
const CONFLICT_ERROR_MESSAGE_MARKER = ': it was made to an older version of the document';
|
|
233
333
|
|
|
234
334
|
/**
|
|
235
335
|
* Type guard for {@link ConflictError}. Detection ladder:
|
|
@@ -240,8 +340,9 @@ const CONFLICT_ERROR_MESSAGE_MARKER = 'Stale-based update for ';
|
|
|
240
340
|
* canonical wire-side check; the JSON-RPC `code` field is preserved
|
|
241
341
|
* across reconstruction, so any adopter catching after an RPC call
|
|
242
342
|
* hits this branch.
|
|
243
|
-
* 3. `error.message
|
|
244
|
-
* for transports that re-wrap the message
|
|
343
|
+
* 3. `error.message` contains the marker {@link STALE_BASED_UPDATE}'s
|
|
344
|
+
* English carries — fallback for transports that re-wrap the message
|
|
345
|
+
* and drop the code (rare).
|
|
245
346
|
*
|
|
246
347
|
* `instanceof ConflictError` alone would silently return `false` on the
|
|
247
348
|
* reconstructed shape, so callers do not use it.
|
package/src/messages/index.ts
CHANGED
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
|
|
26
26
|
export * from './primitives';
|
|
27
27
|
|
|
28
|
-
export { SESSION_CLOSED, STALE_BASED_UPDATE } from '../errors';
|
|
28
|
+
export { DOCUMENT_NOT_OPEN, DUPLICATE_CLIENT_ID, SESSION_CLOSED, STALE_BASED_UPDATE } from '../errors';
|
|
29
29
|
export { DATA_SERVER_CONNECT_FAILED, DATA_SERVER_NOT_READY } from '../client/rpc-connection';
|
|
30
30
|
export { DATA_SESSION_RESTORE_FAILED, DATA_SESSION_UNSAVED_LOST } from '../client/data-session';
|
|
31
31
|
export {
|