@openlfcp/client 0.2.0-beta.6 → 0.2.0-beta.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/connection.d.ts +9 -0
- package/dist/connection.js +12 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/sync-client.js +16 -2
- package/package.json +5 -5
package/dist/connection.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { LfcpError } from "@openlfcp/core";
|
|
1
2
|
import { type AnyMessage, type ClientConnectionState, type ClientHandshakeConfig, type ReadySession } from "@openlfcp/wire";
|
|
2
3
|
/**
|
|
3
4
|
* One LFCP connection over a WebSocket (LFCP-WIRE-01 §30, §31, §34-§38,
|
|
@@ -36,6 +37,14 @@ export interface WebSocketLike {
|
|
|
36
37
|
export type WebSocketFactory = (url: string, protocols: readonly string[]) => WebSocketLike;
|
|
37
38
|
/** The platform WebSocket (globalThis.WebSocket); throws if the runtime has none. */
|
|
38
39
|
export declare function platformWebSocket(): WebSocketFactory;
|
|
40
|
+
/**
|
|
41
|
+
* A send on a connection that is not READY: it closed while the caller was
|
|
42
|
+
* working (an ordinary network loss, not a fault of the caller's). Nothing
|
|
43
|
+
* was sent. Still an LfcpError UNSUPPORTED_VALUE, as before.
|
|
44
|
+
*/
|
|
45
|
+
export declare class ConnectionNotReady extends LfcpError {
|
|
46
|
+
constructor();
|
|
47
|
+
}
|
|
39
48
|
/** §30: the only LFCP subprotocol. */
|
|
40
49
|
export declare const LFCP_SUBPROTOCOL = "lfcp-1";
|
|
41
50
|
export interface ConnectionEvents {
|
package/dist/connection.js
CHANGED
|
@@ -7,6 +7,17 @@ export function platformWebSocket() {
|
|
|
7
7
|
throw new LfcpError("UNSUPPORTED_VALUE", "this runtime has no global WebSocket; inject a factory");
|
|
8
8
|
return (url, protocols) => new ctor(url, [...protocols]);
|
|
9
9
|
}
|
|
10
|
+
/**
|
|
11
|
+
* A send on a connection that is not READY: it closed while the caller was
|
|
12
|
+
* working (an ordinary network loss, not a fault of the caller's). Nothing
|
|
13
|
+
* was sent. Still an LfcpError UNSUPPORTED_VALUE, as before.
|
|
14
|
+
*/
|
|
15
|
+
export class ConnectionNotReady extends LfcpError {
|
|
16
|
+
constructor() {
|
|
17
|
+
super("UNSUPPORTED_VALUE", "the connection is not READY");
|
|
18
|
+
this.name = "ConnectionNotReady";
|
|
19
|
+
}
|
|
20
|
+
}
|
|
10
21
|
/** §30: the only LFCP subprotocol. */
|
|
11
22
|
export const LFCP_SUBPROTOCOL = "lfcp-1";
|
|
12
23
|
const BYTES = (data) => {
|
|
@@ -147,7 +158,7 @@ export class LfcpConnection {
|
|
|
147
158
|
/** Sends already encoded message bytes (e.g. an OutboundMessage) on a READY session. */
|
|
148
159
|
sendEncoded(bytes) {
|
|
149
160
|
if (this.#state !== "READY" || this.#socket === null)
|
|
150
|
-
throw new
|
|
161
|
+
throw new ConnectionNotReady();
|
|
151
162
|
if (bytes.length > this.#limit())
|
|
152
163
|
throw new LfcpError("MESSAGE_TOO_LARGE", `${bytes.length} bytes exceed the session limit ${this.#limit()}`);
|
|
153
164
|
this.#socket.send(bytes);
|
package/dist/index.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ export { type ApplyOutcome, type DataProfileHandler, DataUnitApplier, type DataU
|
|
|
4
4
|
export { ACCEPTANCE_DURABILITY, type BatchStatus, type BatchStatusName, batchStatus, batchStatuses, } from "./batch-status.js";
|
|
5
5
|
export { type CheckpointSource, ProfileCheckpointer } from "./checkpoint.js";
|
|
6
6
|
export { type ClaimJournal, pendingInvitationClaims } from "./claim-journal.js";
|
|
7
|
-
export { type ConnectionEvents, type ConnectionOptions, LFCP_SUBPROTOCOL, LfcpConnection, platformWebSocket, type WebSocketFactory, type WebSocketLike, } from "./connection.js";
|
|
7
|
+
export { type ConnectionEvents, ConnectionNotReady, type ConnectionOptions, LFCP_SUBPROTOCOL, LfcpConnection, platformWebSocket, type WebSocketFactory, type WebSocketLike, } from "./connection.js";
|
|
8
8
|
export { type CreateDataUnitOptions, type CreatedDataUnit, createDataUnit } from "./data-unit.js";
|
|
9
9
|
export { EngineGuard, type EngineItem, isEngineTrap, type Suspicion, snapshotItem, unitItem, } from "./engine-guard.js";
|
|
10
10
|
export { type AcceptedInvitation, type AcceptInvitationOptions, type AcceptInvitationProgress, type AcceptInvitationStage, abandonInvitationClaim, acceptInvitation, type CreatedInvitation, type CreateInvitationOptions, createInvitation, DEFAULT_INVITATION_ABILITIES, InvitationLink, type ResumeInvitationClaimOptions, resumeInvitationClaim, } from "./invite.js";
|
package/dist/index.js
CHANGED
|
@@ -4,7 +4,7 @@ export { DataUnitApplier, } from "./apply.js";
|
|
|
4
4
|
export { ACCEPTANCE_DURABILITY, batchStatus, batchStatuses, } from "./batch-status.js";
|
|
5
5
|
export { ProfileCheckpointer } from "./checkpoint.js";
|
|
6
6
|
export { pendingInvitationClaims } from "./claim-journal.js";
|
|
7
|
-
export { LFCP_SUBPROTOCOL, LfcpConnection, platformWebSocket, } from "./connection.js";
|
|
7
|
+
export { ConnectionNotReady, LFCP_SUBPROTOCOL, LfcpConnection, platformWebSocket, } from "./connection.js";
|
|
8
8
|
export { createDataUnit } from "./data-unit.js";
|
|
9
9
|
export { EngineGuard, isEngineTrap, snapshotItem, unitItem, } from "./engine-guard.js";
|
|
10
10
|
export { abandonInvitationClaim, acceptInvitation, createInvitation, DEFAULT_INVITATION_ABILITIES, InvitationLink, resumeInvitationClaim, } from "./invite.js";
|
package/dist/sync-client.js
CHANGED
|
@@ -6,7 +6,7 @@ import { encode } from "@openlfcp/wire/cbor";
|
|
|
6
6
|
import { afterAccepted, afterMismatch, RECOVERY_TRANSIENT_ATTEMPTS, RECOVERY_TRANSIENT_CODES, startRecovery, } from "./access-recovery.js";
|
|
7
7
|
import { ACCEPTANCE_DURABILITY, batchStatus, batchStatuses, recordEvidence, } from "./batch-status.js";
|
|
8
8
|
import { readClaimJournal } from "./claim-journal.js";
|
|
9
|
-
import { LfcpConnection } from "./connection.js";
|
|
9
|
+
import { ConnectionNotReady, LfcpConnection } from "./connection.js";
|
|
10
10
|
import { EngineGuard, isEngineTrap, snapshotItem } from "./engine-guard.js";
|
|
11
11
|
import { resourceSyncState, snapshotFrontier } from "./outbound.js";
|
|
12
12
|
import { controlRecordWrites, createQueuedSnapshot, keyPackageWrites } from "./queue.js";
|
|
@@ -349,6 +349,11 @@ export class SyncClient {
|
|
|
349
349
|
this.#queue = this.#queue
|
|
350
350
|
.then(() => (this.#trapped ? undefined : fn()))
|
|
351
351
|
.catch((e) => {
|
|
352
|
+
// The connection closed while a handler worked: nothing was sent, and
|
|
353
|
+
// its closing (queued here) starts over at the next READY. An
|
|
354
|
+
// ordinary outcome, not an INTERNAL error.
|
|
355
|
+
if (e instanceof ConnectionNotReady)
|
|
356
|
+
return;
|
|
352
357
|
if (!isEngineTrap(e)) {
|
|
353
358
|
this.#emit({
|
|
354
359
|
type: "error",
|
|
@@ -534,10 +539,19 @@ export class SyncClient {
|
|
|
534
539
|
// -------------------------------------------------------------------------
|
|
535
540
|
// plumbing
|
|
536
541
|
#request(request, message) {
|
|
542
|
+
try {
|
|
543
|
+
this.#connection.send(message);
|
|
544
|
+
}
|
|
545
|
+
catch (e) {
|
|
546
|
+
// Never waiting for an answer to what was not sent (the connection's
|
|
547
|
+
// closing already failed the requests it saw).
|
|
548
|
+
if (e instanceof ConnectionNotReady && request.kind === "host")
|
|
549
|
+
request.reject(new Error("the connection closed before RESOURCE_HOSTED: not READY"));
|
|
550
|
+
throw e;
|
|
551
|
+
}
|
|
537
552
|
const key = toHex(message.messageId);
|
|
538
553
|
this.#requests.set(key, request);
|
|
539
554
|
this.#sentAt.set(key, this.#o.now());
|
|
540
|
-
this.#connection.send(message);
|
|
541
555
|
}
|
|
542
556
|
/**
|
|
543
557
|
* Requests unanswered for requestTimeoutMs on a live connection (§70: a
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openlfcp/client",
|
|
3
|
-
"version": "0.2.0-beta.
|
|
3
|
+
"version": "0.2.0-beta.7",
|
|
4
4
|
"description": "LFCP client: session, Control Plane and Data Plane synchronization.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"openlfcp",
|
|
@@ -42,9 +42,9 @@
|
|
|
42
42
|
"tag": "beta"
|
|
43
43
|
},
|
|
44
44
|
"dependencies": {
|
|
45
|
-
"@openlfcp/core": "^0.2.0-beta.
|
|
46
|
-
"@openlfcp/crypto": "^0.2.0-beta.
|
|
47
|
-
"@openlfcp/storage": "^0.2.0-beta.
|
|
48
|
-
"@openlfcp/wire": "^0.2.0-beta.
|
|
45
|
+
"@openlfcp/core": "^0.2.0-beta.7",
|
|
46
|
+
"@openlfcp/crypto": "^0.2.0-beta.7",
|
|
47
|
+
"@openlfcp/storage": "^0.2.0-beta.7",
|
|
48
|
+
"@openlfcp/wire": "^0.2.0-beta.7"
|
|
49
49
|
}
|
|
50
50
|
}
|