@dxos/edge-client 0.6.12-main.c974201 → 0.6.12-main.f9d0246
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/lib/browser/chunk-ZWJXA37R.mjs +113 -0
- package/dist/lib/browser/chunk-ZWJXA37R.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +66 -163
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/testing/index.mjs +122 -0
- package/dist/lib/browser/testing/index.mjs.map +7 -0
- package/dist/lib/node/chunk-ANV2HBEH.cjs +136 -0
- package/dist/lib/node/chunk-ANV2HBEH.cjs.map +7 -0
- package/dist/lib/node/index.cjs +65 -160
- package/dist/lib/node/index.cjs.map +4 -4
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node/testing/index.cjs +152 -0
- package/dist/lib/node/testing/index.cjs.map +7 -0
- package/dist/lib/node-esm/chunk-HNVT57AU.mjs +115 -0
- package/dist/lib/node-esm/chunk-HNVT57AU.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +65 -163
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/testing/index.mjs +123 -0
- package/dist/lib/node-esm/testing/index.mjs.map +7 -0
- package/dist/types/src/edge-client.d.ts +5 -2
- package/dist/types/src/edge-client.d.ts.map +1 -1
- package/dist/types/src/errors.d.ts +4 -1
- package/dist/types/src/errors.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +1 -0
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/testing/index.d.ts +2 -0
- package/dist/types/src/testing/index.d.ts.map +1 -0
- package/dist/types/src/testing/test-utils.d.ts +20 -0
- package/dist/types/src/testing/test-utils.d.ts.map +1 -0
- package/package.json +24 -12
- package/src/edge-client.test.ts +31 -5
- package/src/edge-client.ts +22 -8
- package/src/errors.ts +8 -2
- package/src/index.ts +1 -0
- package/src/testing/index.ts +5 -0
- package/src/testing/test-utils.ts +111 -0
- package/src/websocket.test.ts +6 -5
- package/dist/types/src/test-utils.d.ts +0 -11
- package/dist/types/src/test-utils.d.ts.map +0 -1
- package/src/test-utils.ts +0 -49
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
// packages/core/mesh/edge-client/src/protocol.ts
|
|
2
|
+
import { invariant } from "@dxos/invariant";
|
|
3
|
+
import { buf, bufWkt } from "@dxos/protocols/buf";
|
|
4
|
+
import { MessageSchema } from "@dxos/protocols/buf/dxos/edge/messenger_pb";
|
|
5
|
+
import { bufferToArray } from "@dxos/util";
|
|
6
|
+
var __dxlog_file = "/home/runner/work/dxos/dxos/packages/core/mesh/edge-client/src/protocol.ts";
|
|
7
|
+
var getTypename = (typeName) => `type.googleapis.com/${typeName}`;
|
|
8
|
+
var Protocol = class {
|
|
9
|
+
constructor(types) {
|
|
10
|
+
this._typeRegistry = buf.createRegistry(...types);
|
|
11
|
+
}
|
|
12
|
+
get typeRegistry() {
|
|
13
|
+
return this._typeRegistry;
|
|
14
|
+
}
|
|
15
|
+
toJson(message) {
|
|
16
|
+
try {
|
|
17
|
+
return buf.toJson(MessageSchema, message, {
|
|
18
|
+
registry: this.typeRegistry
|
|
19
|
+
});
|
|
20
|
+
} catch (err) {
|
|
21
|
+
return {
|
|
22
|
+
type: this.getPayloadType(message)
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Return the payload with the given type.
|
|
28
|
+
*/
|
|
29
|
+
getPayload(message, type) {
|
|
30
|
+
invariant(message.payload, void 0, {
|
|
31
|
+
F: __dxlog_file,
|
|
32
|
+
L: 40,
|
|
33
|
+
S: this,
|
|
34
|
+
A: [
|
|
35
|
+
"message.payload",
|
|
36
|
+
""
|
|
37
|
+
]
|
|
38
|
+
});
|
|
39
|
+
const payloadTypename = this.getPayloadType(message);
|
|
40
|
+
if (type && type.typeName !== payloadTypename) {
|
|
41
|
+
throw new Error(`Unexpected payload type: ${payloadTypename}; expected ${type.typeName}`);
|
|
42
|
+
}
|
|
43
|
+
invariant(bufWkt.anyIs(message.payload, type), `Unexpected payload type: ${payloadTypename}}`, {
|
|
44
|
+
F: __dxlog_file,
|
|
45
|
+
L: 46,
|
|
46
|
+
S: this,
|
|
47
|
+
A: [
|
|
48
|
+
"bufWkt.anyIs(message.payload, type)",
|
|
49
|
+
"`Unexpected payload type: ${payloadTypename}}`"
|
|
50
|
+
]
|
|
51
|
+
});
|
|
52
|
+
const payload = bufWkt.anyUnpack(message.payload, this.typeRegistry);
|
|
53
|
+
invariant(payload, `Empty payload: ${payloadTypename}}`, {
|
|
54
|
+
F: __dxlog_file,
|
|
55
|
+
L: 48,
|
|
56
|
+
S: this,
|
|
57
|
+
A: [
|
|
58
|
+
"payload",
|
|
59
|
+
"`Empty payload: ${payloadTypename}}`"
|
|
60
|
+
]
|
|
61
|
+
});
|
|
62
|
+
return payload;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Get the payload type.
|
|
66
|
+
*/
|
|
67
|
+
getPayloadType(message) {
|
|
68
|
+
if (!message.payload) {
|
|
69
|
+
return void 0;
|
|
70
|
+
}
|
|
71
|
+
const [, type] = message.payload.typeUrl.split("/");
|
|
72
|
+
return type;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Create a packed message.
|
|
76
|
+
*/
|
|
77
|
+
createMessage(type, { source, target, payload, serviceId }) {
|
|
78
|
+
return buf.create(MessageSchema, {
|
|
79
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
80
|
+
source,
|
|
81
|
+
target,
|
|
82
|
+
serviceId,
|
|
83
|
+
payload: payload ? bufWkt.anyPack(type, buf.create(type, payload)) : void 0
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
var toUint8Array = async (data) => {
|
|
88
|
+
if (data instanceof Buffer) {
|
|
89
|
+
return bufferToArray(data);
|
|
90
|
+
}
|
|
91
|
+
if (data instanceof Blob) {
|
|
92
|
+
return new Uint8Array(await data.arrayBuffer());
|
|
93
|
+
}
|
|
94
|
+
throw new Error(`Unexpected datatype: ${data}`);
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
// packages/core/mesh/edge-client/src/defs.ts
|
|
98
|
+
import { bufWkt as bufWkt2 } from "@dxos/protocols/buf";
|
|
99
|
+
import { SwarmRequestSchema, SwarmResponseSchema, TextMessageSchema } from "@dxos/protocols/buf/dxos/edge/messenger_pb";
|
|
100
|
+
var protocol = new Protocol([
|
|
101
|
+
SwarmRequestSchema,
|
|
102
|
+
SwarmResponseSchema,
|
|
103
|
+
TextMessageSchema,
|
|
104
|
+
bufWkt2.AnySchema
|
|
105
|
+
]);
|
|
106
|
+
|
|
107
|
+
export {
|
|
108
|
+
getTypename,
|
|
109
|
+
Protocol,
|
|
110
|
+
toUint8Array,
|
|
111
|
+
protocol
|
|
112
|
+
};
|
|
113
|
+
//# sourceMappingURL=chunk-ZWJXA37R.mjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/protocol.ts", "../../../src/defs.ts"],
|
|
4
|
+
"sourcesContent": ["//\n// Copyright 2024 DXOS.org\n//\n\nimport { invariant } from '@dxos/invariant';\nimport { buf, bufWkt } from '@dxos/protocols/buf';\nimport { type Message, MessageSchema, type PeerSchema } from '@dxos/protocols/buf/dxos/edge/messenger_pb';\nimport { bufferToArray } from '@dxos/util';\n\nexport type PeerData = buf.MessageInitShape<typeof PeerSchema>;\n\nexport const getTypename = (typeName: string) => `type.googleapis.com/${typeName}`;\n\n/**\n * NOTE: The type registry should be extended with all message types.\n */\nexport class Protocol {\n private readonly _typeRegistry: buf.Registry;\n\n constructor(types: buf.DescMessage[]) {\n this._typeRegistry = buf.createRegistry(...types);\n }\n\n get typeRegistry(): buf.Registry {\n return this._typeRegistry;\n }\n\n toJson(message: Message): any {\n try {\n return buf.toJson(MessageSchema, message, { registry: this.typeRegistry });\n } catch (err) {\n return { type: this.getPayloadType(message) };\n }\n }\n\n /**\n * Return the payload with the given type.\n */\n getPayload<Desc extends buf.DescMessage>(message: Message, type: Desc): buf.MessageShape<Desc> {\n invariant(message.payload);\n const payloadTypename = this.getPayloadType(message);\n if (type && type.typeName !== payloadTypename) {\n throw new Error(`Unexpected payload type: ${payloadTypename}; expected ${type.typeName}`);\n }\n\n invariant(bufWkt.anyIs(message.payload, type), `Unexpected payload type: ${payloadTypename}}`);\n const payload = bufWkt.anyUnpack(message.payload, this.typeRegistry) as buf.MessageShape<Desc>;\n invariant(payload, `Empty payload: ${payloadTypename}}`);\n return payload;\n }\n\n /**\n * Get the payload type.\n */\n getPayloadType(message: Message): string | undefined {\n if (!message.payload) {\n return undefined;\n }\n\n const [, type] = message.payload.typeUrl.split('/');\n return type;\n }\n\n /**\n * Create a packed message.\n */\n createMessage<Desc extends buf.DescMessage>(\n type: Desc,\n {\n source,\n target,\n payload,\n serviceId,\n }: {\n source?: PeerData;\n target?: PeerData[];\n payload?: buf.MessageInitShape<Desc>;\n serviceId?: string;\n },\n ) {\n return buf.create(MessageSchema, {\n timestamp: new Date().toISOString(),\n source,\n target,\n serviceId,\n payload: payload ? bufWkt.anyPack(type, buf.create(type, payload)) : undefined,\n });\n }\n}\n\n/**\n * Convert websocket data to Uint8Array.\n */\nexport const toUint8Array = async (data: any): Promise<Uint8Array> => {\n // Node.\n if (data instanceof Buffer) {\n return bufferToArray(data);\n }\n\n // Browser.\n if (data instanceof Blob) {\n return new Uint8Array(await (data as Blob).arrayBuffer());\n }\n\n throw new Error(`Unexpected datatype: ${data}`);\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { bufWkt } from '@dxos/protocols/buf';\nimport { SwarmRequestSchema, SwarmResponseSchema, TextMessageSchema } from '@dxos/protocols/buf/dxos/edge/messenger_pb';\n\nimport { Protocol } from './protocol';\n\nexport const protocol = new Protocol([SwarmRequestSchema, SwarmResponseSchema, TextMessageSchema, bufWkt.AnySchema]);\n"],
|
|
5
|
+
"mappings": ";AAIA,SAASA,iBAAiB;AAC1B,SAASC,KAAKC,cAAc;AAC5B,SAAuBC,qBAAsC;AAC7D,SAASC,qBAAqB;;AAIvB,IAAMC,cAAc,CAACC,aAAqB,uBAAuBA,QAAAA;AAKjE,IAAMC,WAAN,MAAMA;EAGXC,YAAYC,OAA0B;AACpC,SAAKC,gBAAgBT,IAAIU,eAAc,GAAIF,KAAAA;EAC7C;EAEA,IAAIG,eAA6B;AAC/B,WAAO,KAAKF;EACd;EAEAG,OAAOC,SAAuB;AAC5B,QAAI;AACF,aAAOb,IAAIY,OAAOV,eAAeW,SAAS;QAAEC,UAAU,KAAKH;MAAa,CAAA;IAC1E,SAASI,KAAK;AACZ,aAAO;QAAEC,MAAM,KAAKC,eAAeJ,OAAAA;MAAS;IAC9C;EACF;;;;EAKAK,WAAyCL,SAAkBG,MAAoC;AAC7FjB,cAAUc,QAAQM,SAAO,QAAA;;;;;;;;;AACzB,UAAMC,kBAAkB,KAAKH,eAAeJ,OAAAA;AAC5C,QAAIG,QAAQA,KAAKX,aAAae,iBAAiB;AAC7C,YAAM,IAAIC,MAAM,4BAA4BD,eAAAA,cAA6BJ,KAAKX,QAAQ,EAAE;IAC1F;AAEAN,cAAUE,OAAOqB,MAAMT,QAAQM,SAASH,IAAAA,GAAO,4BAA4BI,eAAAA,KAAkB;;;;;;;;;AAC7F,UAAMD,UAAUlB,OAAOsB,UAAUV,QAAQM,SAAS,KAAKR,YAAY;AACnEZ,cAAUoB,SAAS,kBAAkBC,eAAAA,KAAkB;;;;;;;;;AACvD,WAAOD;EACT;;;;EAKAF,eAAeJ,SAAsC;AACnD,QAAI,CAACA,QAAQM,SAAS;AACpB,aAAOK;IACT;AAEA,UAAM,CAAA,EAAGR,IAAAA,IAAQH,QAAQM,QAAQM,QAAQC,MAAM,GAAA;AAC/C,WAAOV;EACT;;;;EAKAW,cACEX,MACA,EACEY,QACAC,QACAV,SACAW,UAAS,GAOX;AACA,WAAO9B,IAAI+B,OAAO7B,eAAe;MAC/B8B,YAAW,oBAAIC,KAAAA,GAAOC,YAAW;MACjCN;MACAC;MACAC;MACAX,SAASA,UAAUlB,OAAOkC,QAAQnB,MAAMhB,IAAI+B,OAAOf,MAAMG,OAAAA,CAAAA,IAAYK;IACvE,CAAA;EACF;AACF;AAKO,IAAMY,eAAe,OAAOC,SAAAA;AAEjC,MAAIA,gBAAgBC,QAAQ;AAC1B,WAAOnC,cAAckC,IAAAA;EACvB;AAGA,MAAIA,gBAAgBE,MAAM;AACxB,WAAO,IAAIC,WAAW,MAAOH,KAAcI,YAAW,CAAA;EACxD;AAEA,QAAM,IAAIpB,MAAM,wBAAwBgB,IAAAA,EAAM;AAChD;;;ACrGA,SAASK,UAAAA,eAAc;AACvB,SAASC,oBAAoBC,qBAAqBC,yBAAyB;AAIpE,IAAMC,WAAW,IAAIC,SAAS;EAACC;EAAoBC;EAAqBC;EAAmBC,QAAOC;CAAU;",
|
|
6
|
+
"names": ["invariant", "buf", "bufWkt", "MessageSchema", "bufferToArray", "getTypename", "typeName", "Protocol", "constructor", "types", "_typeRegistry", "createRegistry", "typeRegistry", "toJson", "message", "registry", "err", "type", "getPayloadType", "getPayload", "payload", "payloadTypename", "Error", "anyIs", "anyUnpack", "undefined", "typeUrl", "split", "createMessage", "source", "target", "serviceId", "create", "timestamp", "Date", "toISOString", "anyPack", "toUint8Array", "data", "Buffer", "Blob", "Uint8Array", "arrayBuffer", "bufWkt", "SwarmRequestSchema", "SwarmResponseSchema", "TextMessageSchema", "protocol", "Protocol", "SwarmRequestSchema", "SwarmResponseSchema", "TextMessageSchema", "bufWkt", "AnySchema"]
|
|
7
|
+
}
|
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Protocol,
|
|
3
|
+
getTypename,
|
|
4
|
+
protocol,
|
|
5
|
+
toUint8Array
|
|
6
|
+
} from "./chunk-ZWJXA37R.mjs";
|
|
7
|
+
|
|
1
8
|
// packages/core/mesh/edge-client/src/index.ts
|
|
2
9
|
export * from "@dxos/protocols/buf/dxos/edge/messenger_pb";
|
|
3
10
|
|
|
@@ -5,123 +12,19 @@ export * from "@dxos/protocols/buf/dxos/edge/messenger_pb";
|
|
|
5
12
|
import WebSocket from "isomorphic-ws";
|
|
6
13
|
import { Trigger, Event, scheduleTaskInterval, scheduleTask, TriggerState } from "@dxos/async";
|
|
7
14
|
import { Context, LifecycleState as LifecycleState2, Resource as Resource2 } from "@dxos/context";
|
|
8
|
-
import { invariant as invariant2 } from "@dxos/invariant";
|
|
9
15
|
import { log as log2 } from "@dxos/log";
|
|
10
|
-
import { buf
|
|
11
|
-
import { MessageSchema as MessageSchema2 } from "@dxos/protocols/buf/dxos/edge/messenger_pb";
|
|
12
|
-
|
|
13
|
-
// packages/core/mesh/edge-client/src/defs.ts
|
|
14
|
-
import { bufWkt as bufWkt2 } from "@dxos/protocols/buf";
|
|
15
|
-
import { SwarmRequestSchema, SwarmResponseSchema, TextMessageSchema } from "@dxos/protocols/buf/dxos/edge/messenger_pb";
|
|
16
|
-
|
|
17
|
-
// packages/core/mesh/edge-client/src/protocol.ts
|
|
18
|
-
import { invariant } from "@dxos/invariant";
|
|
19
|
-
import { buf, bufWkt } from "@dxos/protocols/buf";
|
|
16
|
+
import { buf } from "@dxos/protocols/buf";
|
|
20
17
|
import { MessageSchema } from "@dxos/protocols/buf/dxos/edge/messenger_pb";
|
|
21
|
-
import { bufferToArray } from "@dxos/util";
|
|
22
|
-
var __dxlog_file = "/home/runner/work/dxos/dxos/packages/core/mesh/edge-client/src/protocol.ts";
|
|
23
|
-
var getTypename = (typeName) => `type.googleapis.com/${typeName}`;
|
|
24
|
-
var Protocol = class {
|
|
25
|
-
constructor(types) {
|
|
26
|
-
this._typeRegistry = buf.createRegistry(...types);
|
|
27
|
-
}
|
|
28
|
-
get typeRegistry() {
|
|
29
|
-
return this._typeRegistry;
|
|
30
|
-
}
|
|
31
|
-
toJson(message) {
|
|
32
|
-
try {
|
|
33
|
-
return buf.toJson(MessageSchema, message, {
|
|
34
|
-
registry: this.typeRegistry
|
|
35
|
-
});
|
|
36
|
-
} catch (err) {
|
|
37
|
-
return {
|
|
38
|
-
type: this.getPayloadType(message)
|
|
39
|
-
};
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
/**
|
|
43
|
-
* Return the payload with the given type.
|
|
44
|
-
*/
|
|
45
|
-
getPayload(message, type) {
|
|
46
|
-
invariant(message.payload, void 0, {
|
|
47
|
-
F: __dxlog_file,
|
|
48
|
-
L: 40,
|
|
49
|
-
S: this,
|
|
50
|
-
A: [
|
|
51
|
-
"message.payload",
|
|
52
|
-
""
|
|
53
|
-
]
|
|
54
|
-
});
|
|
55
|
-
const payloadTypename = this.getPayloadType(message);
|
|
56
|
-
if (type && type.typeName !== payloadTypename) {
|
|
57
|
-
throw new Error(`Unexpected payload type: ${payloadTypename}; expected ${type.typeName}`);
|
|
58
|
-
}
|
|
59
|
-
invariant(bufWkt.anyIs(message.payload, type), `Unexpected payload type: ${payloadTypename}}`, {
|
|
60
|
-
F: __dxlog_file,
|
|
61
|
-
L: 46,
|
|
62
|
-
S: this,
|
|
63
|
-
A: [
|
|
64
|
-
"bufWkt.anyIs(message.payload, type)",
|
|
65
|
-
"`Unexpected payload type: ${payloadTypename}}`"
|
|
66
|
-
]
|
|
67
|
-
});
|
|
68
|
-
const payload = bufWkt.anyUnpack(message.payload, this.typeRegistry);
|
|
69
|
-
invariant(payload, `Empty payload: ${payloadTypename}}`, {
|
|
70
|
-
F: __dxlog_file,
|
|
71
|
-
L: 48,
|
|
72
|
-
S: this,
|
|
73
|
-
A: [
|
|
74
|
-
"payload",
|
|
75
|
-
"`Empty payload: ${payloadTypename}}`"
|
|
76
|
-
]
|
|
77
|
-
});
|
|
78
|
-
return payload;
|
|
79
|
-
}
|
|
80
|
-
/**
|
|
81
|
-
* Get the payload type.
|
|
82
|
-
*/
|
|
83
|
-
getPayloadType(message) {
|
|
84
|
-
if (!message.payload) {
|
|
85
|
-
return void 0;
|
|
86
|
-
}
|
|
87
|
-
const [, type] = message.payload.typeUrl.split("/");
|
|
88
|
-
return type;
|
|
89
|
-
}
|
|
90
|
-
/**
|
|
91
|
-
* Create a packed message.
|
|
92
|
-
*/
|
|
93
|
-
createMessage(type, { source, target, payload, serviceId }) {
|
|
94
|
-
return buf.create(MessageSchema, {
|
|
95
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
96
|
-
source,
|
|
97
|
-
target,
|
|
98
|
-
serviceId,
|
|
99
|
-
payload: payload ? bufWkt.anyPack(type, buf.create(type, payload)) : void 0
|
|
100
|
-
});
|
|
101
|
-
}
|
|
102
|
-
};
|
|
103
|
-
var toUint8Array = async (data) => {
|
|
104
|
-
if (data instanceof Buffer) {
|
|
105
|
-
return bufferToArray(data);
|
|
106
|
-
}
|
|
107
|
-
if (data instanceof Blob) {
|
|
108
|
-
return new Uint8Array(await data.arrayBuffer());
|
|
109
|
-
}
|
|
110
|
-
throw new Error(`Unexpected datatype: ${data}`);
|
|
111
|
-
};
|
|
112
|
-
|
|
113
|
-
// packages/core/mesh/edge-client/src/defs.ts
|
|
114
|
-
var protocol = new Protocol([
|
|
115
|
-
SwarmRequestSchema,
|
|
116
|
-
SwarmResponseSchema,
|
|
117
|
-
TextMessageSchema,
|
|
118
|
-
bufWkt2.AnySchema
|
|
119
|
-
]);
|
|
120
18
|
|
|
121
19
|
// packages/core/mesh/edge-client/src/errors.ts
|
|
122
|
-
var
|
|
20
|
+
var EdgeConnectionClosedError = class extends Error {
|
|
123
21
|
constructor() {
|
|
124
|
-
super("
|
|
22
|
+
super("Edge connection closed.");
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
var EdgeIdentityChangedError = class extends Error {
|
|
26
|
+
constructor() {
|
|
27
|
+
super("Edge identity changed.");
|
|
125
28
|
}
|
|
126
29
|
};
|
|
127
30
|
|
|
@@ -136,7 +39,7 @@ function _ts_decorate(decorators, target, key, desc) {
|
|
|
136
39
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
137
40
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
138
41
|
}
|
|
139
|
-
var
|
|
42
|
+
var __dxlog_file = "/home/runner/work/dxos/dxos/packages/core/mesh/edge-client/src/persistent-lifecycle.ts";
|
|
140
43
|
var INIT_RESTART_DELAY = 100;
|
|
141
44
|
var DEFAULT_MAX_RESTART_DELAY = 5e3;
|
|
142
45
|
var PersistentLifecycle = class extends Resource {
|
|
@@ -157,7 +60,7 @@ var PersistentLifecycle = class extends Resource {
|
|
|
157
60
|
log.warn("Restart failed", {
|
|
158
61
|
err
|
|
159
62
|
}, {
|
|
160
|
-
F:
|
|
63
|
+
F: __dxlog_file,
|
|
161
64
|
L: 64,
|
|
162
65
|
S: this,
|
|
163
66
|
C: (f, a) => f(...a)
|
|
@@ -169,7 +72,7 @@ var PersistentLifecycle = class extends Resource {
|
|
|
169
72
|
log.warn("Start failed", {
|
|
170
73
|
err
|
|
171
74
|
}, {
|
|
172
|
-
F:
|
|
75
|
+
F: __dxlog_file,
|
|
173
76
|
L: 69,
|
|
174
77
|
S: this,
|
|
175
78
|
C: (f, a) => f(...a)
|
|
@@ -186,7 +89,7 @@ var PersistentLifecycle = class extends Resource {
|
|
|
186
89
|
log(`restarting in ${this._restartAfter}ms`, {
|
|
187
90
|
state: this._lifecycleState
|
|
188
91
|
}, {
|
|
189
|
-
F:
|
|
92
|
+
F: __dxlog_file,
|
|
190
93
|
L: 81,
|
|
191
94
|
S: this,
|
|
192
95
|
C: (f, a) => f(...a)
|
|
@@ -219,7 +122,7 @@ _ts_decorate([
|
|
|
219
122
|
], PersistentLifecycle.prototype, "scheduleRestart", null);
|
|
220
123
|
|
|
221
124
|
// packages/core/mesh/edge-client/src/edge-client.ts
|
|
222
|
-
var
|
|
125
|
+
var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/core/mesh/edge-client/src/edge-client.ts";
|
|
223
126
|
var DEFAULT_TIMEOUT = 1e4;
|
|
224
127
|
var SIGNAL_KEEPALIVE_INTERVAL = 5e3;
|
|
225
128
|
var EdgeClient = class extends Resource2 {
|
|
@@ -229,6 +132,7 @@ var EdgeClient = class extends Resource2 {
|
|
|
229
132
|
this._peerKey = _peerKey;
|
|
230
133
|
this._config = _config;
|
|
231
134
|
this.reconnect = new Event();
|
|
135
|
+
this.connected = new Event();
|
|
232
136
|
this._persistentLifecycle = new PersistentLifecycle({
|
|
233
137
|
start: async () => this._openWebSocket(),
|
|
234
138
|
stop: async () => this._closeWebSocket(),
|
|
@@ -239,7 +143,6 @@ var EdgeClient = class extends Resource2 {
|
|
|
239
143
|
this._ws = void 0;
|
|
240
144
|
this._keepaliveCtx = void 0;
|
|
241
145
|
this._heartBeatContext = void 0;
|
|
242
|
-
this._protocol = this._config.protocol ?? protocol;
|
|
243
146
|
}
|
|
244
147
|
// TODO(burdon): Attach logging.
|
|
245
148
|
get info() {
|
|
@@ -249,6 +152,9 @@ var EdgeClient = class extends Resource2 {
|
|
|
249
152
|
device: this._peerKey
|
|
250
153
|
};
|
|
251
154
|
}
|
|
155
|
+
get isConnected() {
|
|
156
|
+
return Boolean(this._ws) && this._ready.state === TriggerState.RESOLVED;
|
|
157
|
+
}
|
|
252
158
|
get identityKey() {
|
|
253
159
|
return this._identityKey;
|
|
254
160
|
}
|
|
@@ -271,8 +177,8 @@ var EdgeClient = class extends Resource2 {
|
|
|
271
177
|
log2("opening...", {
|
|
272
178
|
info: this.info
|
|
273
179
|
}, {
|
|
274
|
-
F:
|
|
275
|
-
L:
|
|
180
|
+
F: __dxlog_file2,
|
|
181
|
+
L: 105,
|
|
276
182
|
S: this,
|
|
277
183
|
C: (f, a) => f(...a)
|
|
278
184
|
});
|
|
@@ -280,8 +186,8 @@ var EdgeClient = class extends Resource2 {
|
|
|
280
186
|
log2.warn("Error while opening connection", {
|
|
281
187
|
err
|
|
282
188
|
}, {
|
|
283
|
-
F:
|
|
284
|
-
L:
|
|
189
|
+
F: __dxlog_file2,
|
|
190
|
+
L: 107,
|
|
285
191
|
S: this,
|
|
286
192
|
C: (f, a) => f(...a)
|
|
287
193
|
});
|
|
@@ -294,8 +200,8 @@ var EdgeClient = class extends Resource2 {
|
|
|
294
200
|
log2("closing...", {
|
|
295
201
|
peerKey: this._peerKey
|
|
296
202
|
}, {
|
|
297
|
-
F:
|
|
298
|
-
L:
|
|
203
|
+
F: __dxlog_file2,
|
|
204
|
+
L: 115,
|
|
299
205
|
S: this,
|
|
300
206
|
C: (f, a) => f(...a)
|
|
301
207
|
});
|
|
@@ -306,17 +212,18 @@ var EdgeClient = class extends Resource2 {
|
|
|
306
212
|
this._ws = new WebSocket(url);
|
|
307
213
|
this._ws.onopen = () => {
|
|
308
214
|
log2("opened", this.info, {
|
|
309
|
-
F:
|
|
310
|
-
L:
|
|
215
|
+
F: __dxlog_file2,
|
|
216
|
+
L: 124,
|
|
311
217
|
S: this,
|
|
312
218
|
C: (f, a) => f(...a)
|
|
313
219
|
});
|
|
314
220
|
this._ready.wake();
|
|
221
|
+
this.connected.emit();
|
|
315
222
|
};
|
|
316
223
|
this._ws.onclose = () => {
|
|
317
224
|
log2("closed", this.info, {
|
|
318
|
-
F:
|
|
319
|
-
L:
|
|
225
|
+
F: __dxlog_file2,
|
|
226
|
+
L: 129,
|
|
320
227
|
S: this,
|
|
321
228
|
C: (f, a) => f(...a)
|
|
322
229
|
});
|
|
@@ -327,8 +234,8 @@ var EdgeClient = class extends Resource2 {
|
|
|
327
234
|
error: event.error,
|
|
328
235
|
info: event.message
|
|
329
236
|
}, {
|
|
330
|
-
F:
|
|
331
|
-
L:
|
|
237
|
+
F: __dxlog_file2,
|
|
238
|
+
L: 133,
|
|
332
239
|
S: this,
|
|
333
240
|
C: (f, a) => f(...a)
|
|
334
241
|
});
|
|
@@ -340,13 +247,13 @@ var EdgeClient = class extends Resource2 {
|
|
|
340
247
|
return;
|
|
341
248
|
}
|
|
342
249
|
const data = await toUint8Array(event.data);
|
|
343
|
-
const message =
|
|
250
|
+
const message = buf.fromBinary(MessageSchema, data);
|
|
344
251
|
log2("received", {
|
|
345
252
|
peerKey: this._peerKey,
|
|
346
253
|
payload: protocol.getPayloadType(message)
|
|
347
254
|
}, {
|
|
348
|
-
F:
|
|
349
|
-
L:
|
|
255
|
+
F: __dxlog_file2,
|
|
256
|
+
L: 146,
|
|
350
257
|
S: this,
|
|
351
258
|
C: (f, a) => f(...a)
|
|
352
259
|
});
|
|
@@ -359,8 +266,8 @@ var EdgeClient = class extends Resource2 {
|
|
|
359
266
|
err,
|
|
360
267
|
payload: protocol.getPayloadType(message)
|
|
361
268
|
}, {
|
|
362
|
-
F:
|
|
363
|
-
L:
|
|
269
|
+
F: __dxlog_file2,
|
|
270
|
+
L: 152,
|
|
364
271
|
S: this,
|
|
365
272
|
C: (f, a) => f(...a)
|
|
366
273
|
});
|
|
@@ -372,8 +279,8 @@ var EdgeClient = class extends Resource2 {
|
|
|
372
279
|
timeout: this._config.timeout ?? DEFAULT_TIMEOUT
|
|
373
280
|
});
|
|
374
281
|
this._keepaliveCtx = new Context(void 0, {
|
|
375
|
-
F:
|
|
376
|
-
L:
|
|
282
|
+
F: __dxlog_file2,
|
|
283
|
+
L: 159
|
|
377
284
|
});
|
|
378
285
|
scheduleTaskInterval(this._keepaliveCtx, async () => {
|
|
379
286
|
this._ws?.send("__ping__");
|
|
@@ -386,7 +293,7 @@ var EdgeClient = class extends Resource2 {
|
|
|
386
293
|
return;
|
|
387
294
|
}
|
|
388
295
|
try {
|
|
389
|
-
this._ready.throw(new
|
|
296
|
+
this._ready.throw(this.isOpen ? new EdgeIdentityChangedError() : new EdgeConnectionClosedError());
|
|
390
297
|
this._ready.reset();
|
|
391
298
|
void this._keepaliveCtx?.dispose();
|
|
392
299
|
this._keepaliveCtx = void 0;
|
|
@@ -407,8 +314,8 @@ var EdgeClient = class extends Resource2 {
|
|
|
407
314
|
log2.warn("Error closing websocket", {
|
|
408
315
|
err
|
|
409
316
|
}, {
|
|
410
|
-
F:
|
|
411
|
-
L:
|
|
317
|
+
F: __dxlog_file2,
|
|
318
|
+
L: 195,
|
|
412
319
|
S: this,
|
|
413
320
|
C: (f, a) => f(...a)
|
|
414
321
|
});
|
|
@@ -420,38 +327,32 @@ var EdgeClient = class extends Resource2 {
|
|
|
420
327
|
*/
|
|
421
328
|
async send(message) {
|
|
422
329
|
if (this._ready.state !== TriggerState.RESOLVED) {
|
|
330
|
+
log2("waiting for websocket to become ready", void 0, {
|
|
331
|
+
F: __dxlog_file2,
|
|
332
|
+
L: 205,
|
|
333
|
+
S: this,
|
|
334
|
+
C: (f, a) => f(...a)
|
|
335
|
+
});
|
|
423
336
|
await this._ready.wait({
|
|
424
337
|
timeout: this._config.timeout ?? DEFAULT_TIMEOUT
|
|
425
338
|
});
|
|
426
339
|
}
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
""
|
|
434
|
-
]
|
|
435
|
-
});
|
|
436
|
-
invariant2(!message.source || message.source.peerKey === this._peerKey, void 0, {
|
|
437
|
-
F: __dxlog_file3,
|
|
438
|
-
L: 203,
|
|
439
|
-
S: this,
|
|
440
|
-
A: [
|
|
441
|
-
"!message.source || message.source.peerKey === this._peerKey",
|
|
442
|
-
""
|
|
443
|
-
]
|
|
444
|
-
});
|
|
340
|
+
if (!this._ws) {
|
|
341
|
+
throw new EdgeConnectionClosedError();
|
|
342
|
+
}
|
|
343
|
+
if (message.source && (message.source.peerKey !== this._peerKey || message.source.identityKey !== this.identityKey)) {
|
|
344
|
+
throw new EdgeIdentityChangedError();
|
|
345
|
+
}
|
|
445
346
|
log2("sending...", {
|
|
446
347
|
peerKey: this._peerKey,
|
|
447
348
|
payload: protocol.getPayloadType(message)
|
|
448
349
|
}, {
|
|
449
|
-
F:
|
|
450
|
-
L:
|
|
350
|
+
F: __dxlog_file2,
|
|
351
|
+
L: 218,
|
|
451
352
|
S: this,
|
|
452
353
|
C: (f, a) => f(...a)
|
|
453
354
|
});
|
|
454
|
-
this._ws.send(
|
|
355
|
+
this._ws.send(buf.toBinary(MessageSchema, message));
|
|
455
356
|
}
|
|
456
357
|
_onHeartbeat() {
|
|
457
358
|
if (this._lifecycleState !== LifecycleState2.OPEN) {
|
|
@@ -459,8 +360,8 @@ var EdgeClient = class extends Resource2 {
|
|
|
459
360
|
}
|
|
460
361
|
void this._heartBeatContext?.dispose();
|
|
461
362
|
this._heartBeatContext = new Context(void 0, {
|
|
462
|
-
F:
|
|
463
|
-
L:
|
|
363
|
+
F: __dxlog_file2,
|
|
364
|
+
L: 227
|
|
464
365
|
});
|
|
465
366
|
scheduleTask(this._heartBeatContext, () => {
|
|
466
367
|
this._persistentLifecycle.scheduleRestart();
|
|
@@ -469,6 +370,8 @@ var EdgeClient = class extends Resource2 {
|
|
|
469
370
|
};
|
|
470
371
|
export {
|
|
471
372
|
EdgeClient,
|
|
373
|
+
EdgeConnectionClosedError,
|
|
374
|
+
EdgeIdentityChangedError,
|
|
472
375
|
Protocol,
|
|
473
376
|
getTypename,
|
|
474
377
|
protocol,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../../../src/index.ts", "../../../src/edge-client.ts", "../../../src/
|
|
4
|
-
"sourcesContent": ["//\n// Copyright 2024 DXOS.org\n//\n\nexport * from '@dxos/protocols/buf/dxos/edge/messenger_pb';\n\nexport * from './edge-client';\nexport * from './defs';\nexport * from './protocol';\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport WebSocket from 'isomorphic-ws';\n\nimport { Trigger, Event, scheduleTaskInterval, scheduleTask, TriggerState } from '@dxos/async';\nimport { Context, LifecycleState, Resource, type Lifecycle } from '@dxos/context';\nimport { invariant } from '@dxos/invariant';\nimport { log } from '@dxos/log';\nimport { buf } from '@dxos/protocols/buf';\nimport { type Message, MessageSchema } from '@dxos/protocols/buf/dxos/edge/messenger_pb';\n\nimport { protocol } from './defs';\nimport { WebsocketClosedError } from './errors';\nimport { PersistentLifecycle } from './persistent-lifecycle';\nimport { type Protocol, toUint8Array } from './protocol';\n\nconst DEFAULT_TIMEOUT = 10_000;\nconst SIGNAL_KEEPALIVE_INTERVAL = 5_000;\n\nexport type MessageListener = (message: Message) => void | Promise<void>;\n\nexport interface EdgeConnection extends Required<Lifecycle> {\n reconnect: Event;\n\n get info(): any;\n get identityKey(): string;\n get peerKey(): string;\n get isOpen(): boolean;\n setIdentity(params: { peerKey: string; identityKey: string }): void;\n addListener(listener: MessageListener): () => void;\n send(message: Message): Promise<void>;\n}\n\nexport type MessengerConfig = {\n socketEndpoint: string;\n timeout?: number;\n protocol?: Protocol;\n};\n\n/**\n * Messenger client.\n */\nexport class EdgeClient extends Resource implements EdgeConnection {\n public reconnect = new Event();\n private readonly _persistentLifecycle = new PersistentLifecycle({\n start: async () => this._openWebSocket(),\n stop: async () => this._closeWebSocket(),\n onRestart: async () => this.reconnect.emit(),\n });\n\n private readonly _listeners = new Set<MessageListener>();\n private readonly _protocol: Protocol;\n private _ready = new Trigger();\n private _ws?: WebSocket = undefined;\n private _keepaliveCtx?: Context = undefined;\n private _heartBeatContext?: Context = undefined;\n\n constructor(\n private _identityKey: string,\n private _peerKey: string,\n private readonly _config: MessengerConfig,\n ) {\n super();\n this._protocol = this._config.protocol ?? protocol;\n }\n\n // TODO(burdon): Attach logging.\n public get info() {\n return {\n open: this.isOpen,\n identity: this._identityKey,\n device: this._peerKey,\n };\n }\n\n get identityKey() {\n return this._identityKey;\n }\n\n get peerKey() {\n return this._peerKey;\n }\n\n setIdentity({ peerKey, identityKey }: { peerKey: string; identityKey: string }) {\n this._peerKey = peerKey;\n this._identityKey = identityKey;\n this._persistentLifecycle.scheduleRestart();\n }\n\n public addListener(listener: MessageListener): () => void {\n this._listeners.add(listener);\n return () => this._listeners.delete(listener);\n }\n\n /**\n * Open connection to messaging service.\n */\n protected override async _open() {\n log('opening...', { info: this.info });\n this._persistentLifecycle.open().catch((err) => {\n log.warn('Error while opening connection', { err });\n });\n }\n\n /**\n * Close connection and free resources.\n */\n protected override async _close() {\n log('closing...', { peerKey: this._peerKey });\n await this._persistentLifecycle.close();\n }\n\n private async _openWebSocket() {\n const url = new URL(`/ws/${this._identityKey}/${this._peerKey}`, this._config.socketEndpoint);\n this._ws = new WebSocket(url);\n\n this._ws.onopen = () => {\n log('opened', this.info);\n this._ready.wake();\n };\n this._ws.onclose = () => {\n log('closed', this.info);\n this._persistentLifecycle.scheduleRestart();\n };\n this._ws.onerror = (event) => {\n log.warn('EdgeClient socket error', { error: event.error, info: event.message });\n this._persistentLifecycle.scheduleRestart();\n };\n /**\n * https://developer.mozilla.org/en-US/docs/Web/API/MessageEvent/data\n */\n this._ws.onmessage = async (event) => {\n if (event.data === '__pong__') {\n this._onHeartbeat();\n return;\n }\n const data = await toUint8Array(event.data);\n const message = buf.fromBinary(MessageSchema, data);\n log('received', { peerKey: this._peerKey, payload: protocol.getPayloadType(message) });\n if (message) {\n for (const listener of this._listeners) {\n try {\n await listener(message);\n } catch (err) {\n log.error('processing', { err, payload: protocol.getPayloadType(message) });\n }\n }\n }\n };\n\n await this._ready.wait({ timeout: this._config.timeout ?? DEFAULT_TIMEOUT });\n this._keepaliveCtx = new Context();\n scheduleTaskInterval(\n this._keepaliveCtx,\n async () => {\n // TODO(mykola): use RFC6455 ping/pong once implemented in the browser?\n // Cloudflare's worker responds to this `without interrupting hibernation`. https://developers.cloudflare.com/durable-objects/api/websockets/#setwebsocketautoresponse\n this._ws?.send('__ping__');\n },\n SIGNAL_KEEPALIVE_INTERVAL,\n );\n this._ws.send('__ping__');\n this._onHeartbeat();\n }\n\n private async _closeWebSocket() {\n if (!this._ws) {\n return;\n }\n try {\n this._ready.throw(new WebsocketClosedError());\n this._ready.reset();\n void this._keepaliveCtx?.dispose();\n this._keepaliveCtx = undefined;\n void this._heartBeatContext?.dispose();\n this._heartBeatContext = undefined;\n\n // NOTE: Remove event handlers to avoid scheduling restart.\n this._ws.onopen = () => {};\n this._ws.onclose = () => {};\n this._ws.onerror = () => {};\n this._ws.close();\n this._ws = undefined;\n } catch (err) {\n if (err instanceof Error && err.message.includes('WebSocket is closed before the connection is established.')) {\n return;\n }\n log.warn('Error closing websocket', { err });\n }\n }\n\n /**\n * Send message.\n * NOTE: The message is guaranteed to be delivered but the service must respond with a message to confirm processing.\n */\n public async send(message: Message): Promise<void> {\n if (this._ready.state !== TriggerState.RESOLVED) {\n await this._ready.wait({ timeout: this._config.timeout ?? DEFAULT_TIMEOUT });\n }\n invariant(this._ws);\n invariant(!message.source || message.source.peerKey === this._peerKey);\n log('sending...', { peerKey: this._peerKey, payload: protocol.getPayloadType(message) });\n this._ws.send(buf.toBinary(MessageSchema, message));\n }\n\n private _onHeartbeat() {\n if (this._lifecycleState !== LifecycleState.OPEN) {\n return;\n }\n void this._heartBeatContext?.dispose();\n this._heartBeatContext = new Context();\n scheduleTask(\n this._heartBeatContext,\n () => {\n this._persistentLifecycle.scheduleRestart();\n },\n 2 * SIGNAL_KEEPALIVE_INTERVAL,\n );\n }\n}\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { bufWkt } from '@dxos/protocols/buf';\nimport { SwarmRequestSchema, SwarmResponseSchema, TextMessageSchema } from '@dxos/protocols/buf/dxos/edge/messenger_pb';\n\nimport { Protocol } from './protocol';\n\nexport const protocol = new Protocol([SwarmRequestSchema, SwarmResponseSchema, TextMessageSchema, bufWkt.AnySchema]);\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { invariant } from '@dxos/invariant';\nimport { buf, bufWkt } from '@dxos/protocols/buf';\nimport { type Message, MessageSchema, type PeerSchema } from '@dxos/protocols/buf/dxos/edge/messenger_pb';\nimport { bufferToArray } from '@dxos/util';\n\nexport type PeerData = buf.MessageInitShape<typeof PeerSchema>;\n\nexport const getTypename = (typeName: string) => `type.googleapis.com/${typeName}`;\n\n/**\n * NOTE: The type registry should be extended with all message types.\n */\nexport class Protocol {\n private readonly _typeRegistry: buf.Registry;\n\n constructor(types: buf.DescMessage[]) {\n this._typeRegistry = buf.createRegistry(...types);\n }\n\n get typeRegistry(): buf.Registry {\n return this._typeRegistry;\n }\n\n toJson(message: Message): any {\n try {\n return buf.toJson(MessageSchema, message, { registry: this.typeRegistry });\n } catch (err) {\n return { type: this.getPayloadType(message) };\n }\n }\n\n /**\n * Return the payload with the given type.\n */\n getPayload<Desc extends buf.DescMessage>(message: Message, type: Desc): buf.MessageShape<Desc> {\n invariant(message.payload);\n const payloadTypename = this.getPayloadType(message);\n if (type && type.typeName !== payloadTypename) {\n throw new Error(`Unexpected payload type: ${payloadTypename}; expected ${type.typeName}`);\n }\n\n invariant(bufWkt.anyIs(message.payload, type), `Unexpected payload type: ${payloadTypename}}`);\n const payload = bufWkt.anyUnpack(message.payload, this.typeRegistry) as buf.MessageShape<Desc>;\n invariant(payload, `Empty payload: ${payloadTypename}}`);\n return payload;\n }\n\n /**\n * Get the payload type.\n */\n getPayloadType(message: Message): string | undefined {\n if (!message.payload) {\n return undefined;\n }\n\n const [, type] = message.payload.typeUrl.split('/');\n return type;\n }\n\n /**\n * Create a packed message.\n */\n createMessage<Desc extends buf.DescMessage>(\n type: Desc,\n {\n source,\n target,\n payload,\n serviceId,\n }: {\n source?: PeerData;\n target?: PeerData[];\n payload?: buf.MessageInitShape<Desc>;\n serviceId?: string;\n },\n ) {\n return buf.create(MessageSchema, {\n timestamp: new Date().toISOString(),\n source,\n target,\n serviceId,\n payload: payload ? bufWkt.anyPack(type, buf.create(type, payload)) : undefined,\n });\n }\n}\n\n/**\n * Convert websocket data to Uint8Array.\n */\nexport const toUint8Array = async (data: any): Promise<Uint8Array> => {\n // Node.\n if (data instanceof Buffer) {\n return bufferToArray(data);\n }\n\n // Browser.\n if (data instanceof Blob) {\n return new Uint8Array(await (data as Blob).arrayBuffer());\n }\n\n throw new Error(`Unexpected datatype: ${data}`);\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nexport class WebsocketClosedError extends Error {\n constructor() {\n super('WebSocket connection closed');\n }\n}\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { DeferredTask, sleep, synchronized } from '@dxos/async';\nimport { cancelWithContext, LifecycleState, Resource } from '@dxos/context';\nimport { warnAfterTimeout } from '@dxos/debug';\nimport { log } from '@dxos/log';\n\nconst INIT_RESTART_DELAY = 100;\nconst DEFAULT_MAX_RESTART_DELAY = 5000;\n\nexport type PersistentLifecycleParams = {\n /**\n * Create connection.\n * If promise resolves successfully, connection is considered established.\n */\n start: () => Promise<void>;\n\n /**\n * Reset connection to initial state.\n */\n stop: () => Promise<void>;\n\n /**\n * Called after successful start.\n */\n onRestart?: () => Promise<void>;\n\n /**\n * Maximum delay between restartion attempts.\n * Default: 5000ms\n */\n maxRestartDelay?: number;\n};\n\n/**\n * Handles restarts (e.g. persists connection).\n * Restarts are scheduled with exponential backoff.\n */\nexport class PersistentLifecycle extends Resource {\n private readonly _start: () => Promise<void>;\n private readonly _stop: () => Promise<void>;\n private readonly _onRestart?: () => Promise<void>;\n private readonly _maxRestartDelay: number;\n\n private _restartTask?: DeferredTask = undefined;\n private _restartAfter = 0;\n\n constructor({ start, stop, onRestart, maxRestartDelay = DEFAULT_MAX_RESTART_DELAY }: PersistentLifecycleParams) {\n super();\n this._start = start;\n this._stop = stop;\n this._onRestart = onRestart;\n this._maxRestartDelay = maxRestartDelay;\n }\n\n @synchronized\n protected override async _open() {\n this._restartTask = new DeferredTask(this._ctx, async () => {\n try {\n await this._restart();\n } catch (err) {\n log.warn('Restart failed', { err });\n this._restartTask?.schedule();\n }\n });\n await this._start().catch((err) => {\n log.warn('Start failed', { err });\n this._restartTask?.schedule();\n });\n }\n\n protected override async _close() {\n await this._restartTask?.join();\n await this._stop();\n this._restartTask = undefined;\n }\n\n private async _restart() {\n log(`restarting in ${this._restartAfter}ms`, { state: this._lifecycleState });\n await this._stop();\n if (this._lifecycleState !== LifecycleState.OPEN) {\n return;\n }\n await cancelWithContext(this._ctx!, sleep(this._restartAfter));\n this._restartAfter = Math.min(Math.max(this._restartAfter * 2, INIT_RESTART_DELAY), this._maxRestartDelay);\n\n // May fail if the connection is not established.\n await warnAfterTimeout(5_000, 'Connection establishment takes too long', () => this._start());\n\n this._restartAfter = 0;\n await this._onRestart?.();\n }\n\n /**\n * Scheduling restart should be done from outside.\n */\n @synchronized\n scheduleRestart() {\n if (this._lifecycleState !== LifecycleState.OPEN) {\n return;\n }\n this._restartTask!.schedule();\n }\n}\n"],
|
|
5
|
-
"mappings": "
|
|
6
|
-
"names": ["WebSocket", "Trigger", "Event", "scheduleTaskInterval", "scheduleTask", "TriggerState", "Context", "LifecycleState", "Resource", "
|
|
3
|
+
"sources": ["../../../src/index.ts", "../../../src/edge-client.ts", "../../../src/errors.ts", "../../../src/persistent-lifecycle.ts"],
|
|
4
|
+
"sourcesContent": ["//\n// Copyright 2024 DXOS.org\n//\n\nexport * from '@dxos/protocols/buf/dxos/edge/messenger_pb';\n\nexport * from './edge-client';\nexport * from './defs';\nexport * from './protocol';\nexport * from './errors';\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport WebSocket from 'isomorphic-ws';\n\nimport { Trigger, Event, scheduleTaskInterval, scheduleTask, TriggerState } from '@dxos/async';\nimport { Context, LifecycleState, Resource, type Lifecycle } from '@dxos/context';\nimport { log } from '@dxos/log';\nimport { buf } from '@dxos/protocols/buf';\nimport { type Message, MessageSchema } from '@dxos/protocols/buf/dxos/edge/messenger_pb';\n\nimport { protocol } from './defs';\nimport { EdgeConnectionClosedError, EdgeIdentityChangedError } from './errors';\nimport { PersistentLifecycle } from './persistent-lifecycle';\nimport { type Protocol, toUint8Array } from './protocol';\n\nconst DEFAULT_TIMEOUT = 10_000;\nconst SIGNAL_KEEPALIVE_INTERVAL = 5_000;\n\nexport type MessageListener = (message: Message) => void | Promise<void>;\n\nexport interface EdgeConnection extends Required<Lifecycle> {\n connected: Event;\n reconnect: Event;\n\n get info(): any;\n get identityKey(): string;\n get peerKey(): string;\n get isOpen(): boolean;\n get isConnected(): boolean;\n setIdentity(params: { peerKey: string; identityKey: string }): void;\n addListener(listener: MessageListener): () => void;\n send(message: Message): Promise<void>;\n}\n\nexport type MessengerConfig = {\n socketEndpoint: string;\n timeout?: number;\n protocol?: Protocol;\n};\n\n/**\n * Messenger client.\n */\nexport class EdgeClient extends Resource implements EdgeConnection {\n public readonly reconnect = new Event();\n public readonly connected = new Event();\n private readonly _persistentLifecycle = new PersistentLifecycle({\n start: async () => this._openWebSocket(),\n stop: async () => this._closeWebSocket(),\n onRestart: async () => this.reconnect.emit(),\n });\n\n private readonly _listeners = new Set<MessageListener>();\n private _ready = new Trigger();\n private _ws?: WebSocket = undefined;\n private _keepaliveCtx?: Context = undefined;\n private _heartBeatContext?: Context = undefined;\n\n constructor(\n private _identityKey: string,\n private _peerKey: string,\n private readonly _config: MessengerConfig,\n ) {\n super();\n }\n\n // TODO(burdon): Attach logging.\n public get info() {\n return {\n open: this.isOpen,\n identity: this._identityKey,\n device: this._peerKey,\n };\n }\n\n get isConnected() {\n return Boolean(this._ws) && this._ready.state === TriggerState.RESOLVED;\n }\n\n get identityKey() {\n return this._identityKey;\n }\n\n get peerKey() {\n return this._peerKey;\n }\n\n setIdentity({ peerKey, identityKey }: { peerKey: string; identityKey: string }) {\n this._peerKey = peerKey;\n this._identityKey = identityKey;\n this._persistentLifecycle.scheduleRestart();\n }\n\n public addListener(listener: MessageListener): () => void {\n this._listeners.add(listener);\n return () => this._listeners.delete(listener);\n }\n\n /**\n * Open connection to messaging service.\n */\n protected override async _open() {\n log('opening...', { info: this.info });\n this._persistentLifecycle.open().catch((err) => {\n log.warn('Error while opening connection', { err });\n });\n }\n\n /**\n * Close connection and free resources.\n */\n protected override async _close() {\n log('closing...', { peerKey: this._peerKey });\n await this._persistentLifecycle.close();\n }\n\n private async _openWebSocket() {\n const url = new URL(`/ws/${this._identityKey}/${this._peerKey}`, this._config.socketEndpoint);\n this._ws = new WebSocket(url);\n\n this._ws.onopen = () => {\n log('opened', this.info);\n this._ready.wake();\n this.connected.emit();\n };\n this._ws.onclose = () => {\n log('closed', this.info);\n this._persistentLifecycle.scheduleRestart();\n };\n this._ws.onerror = (event) => {\n log.warn('EdgeClient socket error', { error: event.error, info: event.message });\n this._persistentLifecycle.scheduleRestart();\n };\n /**\n * https://developer.mozilla.org/en-US/docs/Web/API/MessageEvent/data\n */\n this._ws.onmessage = async (event) => {\n if (event.data === '__pong__') {\n this._onHeartbeat();\n return;\n }\n const data = await toUint8Array(event.data);\n const message = buf.fromBinary(MessageSchema, data);\n log('received', { peerKey: this._peerKey, payload: protocol.getPayloadType(message) });\n if (message) {\n for (const listener of this._listeners) {\n try {\n await listener(message);\n } catch (err) {\n log.error('processing', { err, payload: protocol.getPayloadType(message) });\n }\n }\n }\n };\n\n await this._ready.wait({ timeout: this._config.timeout ?? DEFAULT_TIMEOUT });\n this._keepaliveCtx = new Context();\n scheduleTaskInterval(\n this._keepaliveCtx,\n async () => {\n // TODO(mykola): use RFC6455 ping/pong once implemented in the browser?\n // Cloudflare's worker responds to this `without interrupting hibernation`. https://developers.cloudflare.com/durable-objects/api/websockets/#setwebsocketautoresponse\n this._ws?.send('__ping__');\n },\n SIGNAL_KEEPALIVE_INTERVAL,\n );\n this._ws.send('__ping__');\n this._onHeartbeat();\n }\n\n private async _closeWebSocket() {\n if (!this._ws) {\n return;\n }\n try {\n this._ready.throw(this.isOpen ? new EdgeIdentityChangedError() : new EdgeConnectionClosedError());\n this._ready.reset();\n void this._keepaliveCtx?.dispose();\n this._keepaliveCtx = undefined;\n void this._heartBeatContext?.dispose();\n this._heartBeatContext = undefined;\n\n // NOTE: Remove event handlers to avoid scheduling restart.\n this._ws.onopen = () => {};\n this._ws.onclose = () => {};\n this._ws.onerror = () => {};\n this._ws.close();\n this._ws = undefined;\n } catch (err) {\n if (err instanceof Error && err.message.includes('WebSocket is closed before the connection is established.')) {\n return;\n }\n log.warn('Error closing websocket', { err });\n }\n }\n\n /**\n * Send message.\n * NOTE: The message is guaranteed to be delivered but the service must respond with a message to confirm processing.\n */\n public async send(message: Message): Promise<void> {\n if (this._ready.state !== TriggerState.RESOLVED) {\n log('waiting for websocket to become ready');\n await this._ready.wait({ timeout: this._config.timeout ?? DEFAULT_TIMEOUT });\n }\n if (!this._ws) {\n throw new EdgeConnectionClosedError();\n }\n if (\n message.source &&\n (message.source.peerKey !== this._peerKey || message.source.identityKey !== this.identityKey)\n ) {\n throw new EdgeIdentityChangedError();\n }\n\n log('sending...', { peerKey: this._peerKey, payload: protocol.getPayloadType(message) });\n this._ws.send(buf.toBinary(MessageSchema, message));\n }\n\n private _onHeartbeat() {\n if (this._lifecycleState !== LifecycleState.OPEN) {\n return;\n }\n void this._heartBeatContext?.dispose();\n this._heartBeatContext = new Context();\n scheduleTask(\n this._heartBeatContext,\n () => {\n this._persistentLifecycle.scheduleRestart();\n },\n 2 * SIGNAL_KEEPALIVE_INTERVAL,\n );\n }\n}\n", "//\n// Copyright 2024 DXOS.org\n//\n\nexport class EdgeConnectionClosedError extends Error {\n constructor() {\n super('Edge connection closed.');\n }\n}\n\nexport class EdgeIdentityChangedError extends Error {\n constructor() {\n super('Edge identity changed.');\n }\n}\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { DeferredTask, sleep, synchronized } from '@dxos/async';\nimport { cancelWithContext, LifecycleState, Resource } from '@dxos/context';\nimport { warnAfterTimeout } from '@dxos/debug';\nimport { log } from '@dxos/log';\n\nconst INIT_RESTART_DELAY = 100;\nconst DEFAULT_MAX_RESTART_DELAY = 5000;\n\nexport type PersistentLifecycleParams = {\n /**\n * Create connection.\n * If promise resolves successfully, connection is considered established.\n */\n start: () => Promise<void>;\n\n /**\n * Reset connection to initial state.\n */\n stop: () => Promise<void>;\n\n /**\n * Called after successful start.\n */\n onRestart?: () => Promise<void>;\n\n /**\n * Maximum delay between restartion attempts.\n * Default: 5000ms\n */\n maxRestartDelay?: number;\n};\n\n/**\n * Handles restarts (e.g. persists connection).\n * Restarts are scheduled with exponential backoff.\n */\nexport class PersistentLifecycle extends Resource {\n private readonly _start: () => Promise<void>;\n private readonly _stop: () => Promise<void>;\n private readonly _onRestart?: () => Promise<void>;\n private readonly _maxRestartDelay: number;\n\n private _restartTask?: DeferredTask = undefined;\n private _restartAfter = 0;\n\n constructor({ start, stop, onRestart, maxRestartDelay = DEFAULT_MAX_RESTART_DELAY }: PersistentLifecycleParams) {\n super();\n this._start = start;\n this._stop = stop;\n this._onRestart = onRestart;\n this._maxRestartDelay = maxRestartDelay;\n }\n\n @synchronized\n protected override async _open() {\n this._restartTask = new DeferredTask(this._ctx, async () => {\n try {\n await this._restart();\n } catch (err) {\n log.warn('Restart failed', { err });\n this._restartTask?.schedule();\n }\n });\n await this._start().catch((err) => {\n log.warn('Start failed', { err });\n this._restartTask?.schedule();\n });\n }\n\n protected override async _close() {\n await this._restartTask?.join();\n await this._stop();\n this._restartTask = undefined;\n }\n\n private async _restart() {\n log(`restarting in ${this._restartAfter}ms`, { state: this._lifecycleState });\n await this._stop();\n if (this._lifecycleState !== LifecycleState.OPEN) {\n return;\n }\n await cancelWithContext(this._ctx!, sleep(this._restartAfter));\n this._restartAfter = Math.min(Math.max(this._restartAfter * 2, INIT_RESTART_DELAY), this._maxRestartDelay);\n\n // May fail if the connection is not established.\n await warnAfterTimeout(5_000, 'Connection establishment takes too long', () => this._start());\n\n this._restartAfter = 0;\n await this._onRestart?.();\n }\n\n /**\n * Scheduling restart should be done from outside.\n */\n @synchronized\n scheduleRestart() {\n if (this._lifecycleState !== LifecycleState.OPEN) {\n return;\n }\n this._restartTask!.schedule();\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["WebSocket", "Trigger", "Event", "scheduleTaskInterval", "scheduleTask", "TriggerState", "Context", "LifecycleState", "Resource", "log", "buf", "MessageSchema", "EdgeConnectionClosedError", "Error", "constructor", "EdgeIdentityChangedError", "DeferredTask", "sleep", "synchronized", "cancelWithContext", "LifecycleState", "Resource", "warnAfterTimeout", "log", "INIT_RESTART_DELAY", "DEFAULT_MAX_RESTART_DELAY", "PersistentLifecycle", "constructor", "start", "stop", "onRestart", "maxRestartDelay", "_restartTask", "undefined", "_restartAfter", "_start", "_stop", "_onRestart", "_maxRestartDelay", "_open", "_ctx", "_restart", "err", "warn", "schedule", "catch", "_close", "join", "state", "_lifecycleState", "OPEN", "Math", "min", "max", "scheduleRestart", "DEFAULT_TIMEOUT", "SIGNAL_KEEPALIVE_INTERVAL", "EdgeClient", "Resource", "constructor", "_identityKey", "_peerKey", "_config", "reconnect", "Event", "connected", "_persistentLifecycle", "PersistentLifecycle", "start", "_openWebSocket", "stop", "_closeWebSocket", "onRestart", "emit", "_listeners", "Set", "_ready", "Trigger", "_ws", "undefined", "_keepaliveCtx", "_heartBeatContext", "info", "open", "isOpen", "identity", "device", "isConnected", "Boolean", "state", "TriggerState", "RESOLVED", "identityKey", "peerKey", "setIdentity", "scheduleRestart", "addListener", "listener", "add", "delete", "_open", "log", "catch", "err", "warn", "_close", "close", "url", "URL", "socketEndpoint", "WebSocket", "onopen", "wake", "onclose", "onerror", "event", "error", "message", "onmessage", "data", "_onHeartbeat", "toUint8Array", "buf", "fromBinary", "MessageSchema", "payload", "protocol", "getPayloadType", "wait", "timeout", "Context", "scheduleTaskInterval", "send", "throw", "EdgeIdentityChangedError", "EdgeConnectionClosedError", "reset", "dispose", "Error", "includes", "source", "toBinary", "_lifecycleState", "LifecycleState", "OPEN", "scheduleTask"]
|
|
7
7
|
}
|