@matter/general 0.16.0-alpha.0-20251006-3fe1e7c57 → 0.16.0-alpha.0-20251013-89bb7099d
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/cjs/codec/Base64Codec.js +2 -2
- package/dist/cjs/codec/Base64Codec.js.map +1 -1
- package/dist/cjs/environment/Environment.d.ts +12 -18
- package/dist/cjs/environment/Environment.d.ts.map +1 -1
- package/dist/cjs/environment/Environment.js +17 -32
- package/dist/cjs/environment/Environment.js.map +1 -1
- package/dist/cjs/environment/Environmental.d.ts +16 -2
- package/dist/cjs/environment/Environmental.d.ts.map +1 -1
- package/dist/cjs/log/Logger.js +1 -1
- package/dist/cjs/net/Network.d.ts +4 -0
- package/dist/cjs/net/Network.d.ts.map +1 -1
- package/dist/cjs/net/Network.js +6 -0
- package/dist/cjs/net/Network.js.map +1 -1
- package/dist/cjs/net/ServerAddress.d.ts +1 -0
- package/dist/cjs/net/ServerAddress.d.ts.map +1 -1
- package/dist/cjs/net/ServerAddress.js +13 -0
- package/dist/cjs/net/ServerAddress.js.map +1 -1
- package/dist/cjs/net/http/HttpEndpoint.d.ts +53 -0
- package/dist/cjs/net/http/HttpEndpoint.d.ts.map +1 -0
- package/dist/cjs/net/http/HttpEndpoint.js +22 -0
- package/dist/cjs/net/http/HttpEndpoint.js.map +6 -0
- package/dist/cjs/net/http/HttpEndpointFactory.d.ts +23 -0
- package/dist/cjs/net/http/HttpEndpointFactory.d.ts.map +1 -0
- package/dist/cjs/net/http/HttpEndpointFactory.js +39 -0
- package/dist/cjs/net/http/HttpEndpointFactory.js.map +6 -0
- package/dist/cjs/net/http/HttpEndpointGroup.d.ts +17 -0
- package/dist/cjs/net/http/HttpEndpointGroup.d.ts.map +1 -0
- package/dist/cjs/net/http/HttpEndpointGroup.js +56 -0
- package/dist/cjs/net/http/HttpEndpointGroup.js.map +6 -0
- package/dist/cjs/net/http/HttpService.d.ts +20 -0
- package/dist/cjs/net/http/HttpService.d.ts.map +1 -0
- package/dist/cjs/net/http/HttpService.js +83 -0
- package/dist/cjs/net/http/HttpService.js.map +6 -0
- package/dist/cjs/net/http/HttpSharedEndpoint.d.ts +16 -0
- package/dist/cjs/net/http/HttpSharedEndpoint.d.ts.map +1 -0
- package/dist/cjs/net/http/HttpSharedEndpoint.js +92 -0
- package/dist/cjs/net/http/HttpSharedEndpoint.js.map +6 -0
- package/dist/cjs/net/http/index.d.ts +11 -0
- package/dist/cjs/net/http/index.d.ts.map +1 -0
- package/dist/cjs/net/http/index.js +28 -0
- package/dist/cjs/net/http/index.js.map +6 -0
- package/dist/cjs/net/index.d.ts +2 -0
- package/dist/cjs/net/index.d.ts.map +1 -1
- package/dist/cjs/net/index.js +2 -0
- package/dist/cjs/net/index.js.map +1 -1
- package/dist/cjs/net/mqtt/MqttEndpoint.d.ts +39 -0
- package/dist/cjs/net/mqtt/MqttEndpoint.d.ts.map +1 -0
- package/dist/cjs/net/mqtt/MqttEndpoint.js +36 -0
- package/dist/cjs/net/mqtt/MqttEndpoint.js.map +6 -0
- package/dist/cjs/net/mqtt/MqttEndpointFactory.d.ts +15 -0
- package/dist/cjs/net/mqtt/MqttEndpointFactory.d.ts.map +1 -0
- package/dist/cjs/net/mqtt/MqttEndpointFactory.js +31 -0
- package/dist/cjs/net/mqtt/MqttEndpointFactory.js.map +6 -0
- package/dist/cjs/net/mqtt/MqttService.d.ts +19 -0
- package/dist/cjs/net/mqtt/MqttService.d.ts.map +1 -0
- package/dist/cjs/net/mqtt/MqttService.js +52 -0
- package/dist/cjs/net/mqtt/MqttService.js.map +6 -0
- package/dist/cjs/net/mqtt/index.d.ts +9 -0
- package/dist/cjs/net/mqtt/index.d.ts.map +1 -0
- package/dist/cjs/net/mqtt/index.js +26 -0
- package/dist/cjs/net/mqtt/index.js.map +6 -0
- package/dist/cjs/net/udp/UdpChannel.d.ts +31 -2
- package/dist/cjs/net/udp/UdpChannel.d.ts.map +1 -1
- package/dist/cjs/net/udp/UdpMulticastServer.d.ts.map +1 -1
- package/dist/cjs/net/udp/UdpMulticastServer.js +6 -3
- package/dist/cjs/net/udp/UdpMulticastServer.js.map +1 -1
- package/dist/cjs/storage/StorageService.d.ts +5 -1
- package/dist/cjs/storage/StorageService.d.ts.map +1 -1
- package/dist/cjs/storage/StorageService.js +6 -1
- package/dist/cjs/storage/StorageService.js.map +1 -1
- package/dist/cjs/time/Duration.d.ts +1 -1
- package/dist/cjs/util/Abort.d.ts +4 -1
- package/dist/cjs/util/Abort.d.ts.map +1 -1
- package/dist/cjs/util/Abort.js +19 -3
- package/dist/cjs/util/Abort.js.map +1 -1
- package/dist/cjs/util/Construction.d.ts +1 -1
- package/dist/cjs/util/Multiplex.js +1 -1
- package/dist/cjs/util/Multiplex.js.map +1 -1
- package/dist/cjs/util/String.d.ts +5 -1
- package/dist/cjs/util/String.d.ts.map +1 -1
- package/dist/cjs/util/String.js +16 -0
- package/dist/cjs/util/String.js.map +1 -1
- package/dist/esm/codec/Base64Codec.js +2 -2
- package/dist/esm/codec/Base64Codec.js.map +1 -1
- package/dist/esm/environment/Environment.d.ts +12 -18
- package/dist/esm/environment/Environment.d.ts.map +1 -1
- package/dist/esm/environment/Environment.js +17 -32
- package/dist/esm/environment/Environment.js.map +1 -1
- package/dist/esm/environment/Environmental.d.ts +16 -2
- package/dist/esm/environment/Environmental.d.ts.map +1 -1
- package/dist/esm/log/Logger.js +1 -1
- package/dist/esm/net/Network.d.ts +4 -0
- package/dist/esm/net/Network.d.ts.map +1 -1
- package/dist/esm/net/Network.js +6 -0
- package/dist/esm/net/Network.js.map +1 -1
- package/dist/esm/net/ServerAddress.d.ts +1 -0
- package/dist/esm/net/ServerAddress.d.ts.map +1 -1
- package/dist/esm/net/ServerAddress.js +13 -0
- package/dist/esm/net/ServerAddress.js.map +1 -1
- package/dist/esm/net/http/HttpEndpoint.d.ts +53 -0
- package/dist/esm/net/http/HttpEndpoint.d.ts.map +1 -0
- package/dist/esm/net/http/HttpEndpoint.js +6 -0
- package/dist/esm/net/http/HttpEndpoint.js.map +6 -0
- package/dist/esm/net/http/HttpEndpointFactory.d.ts +23 -0
- package/dist/esm/net/http/HttpEndpointFactory.d.ts.map +1 -0
- package/dist/esm/net/http/HttpEndpointFactory.js +19 -0
- package/dist/esm/net/http/HttpEndpointFactory.js.map +6 -0
- package/dist/esm/net/http/HttpEndpointGroup.d.ts +17 -0
- package/dist/esm/net/http/HttpEndpointGroup.d.ts.map +1 -0
- package/dist/esm/net/http/HttpEndpointGroup.js +36 -0
- package/dist/esm/net/http/HttpEndpointGroup.js.map +6 -0
- package/dist/esm/net/http/HttpService.d.ts +20 -0
- package/dist/esm/net/http/HttpService.d.ts.map +1 -0
- package/dist/esm/net/http/HttpService.js +63 -0
- package/dist/esm/net/http/HttpService.js.map +6 -0
- package/dist/esm/net/http/HttpSharedEndpoint.d.ts +16 -0
- package/dist/esm/net/http/HttpSharedEndpoint.d.ts.map +1 -0
- package/dist/esm/net/http/HttpSharedEndpoint.js +72 -0
- package/dist/esm/net/http/HttpSharedEndpoint.js.map +6 -0
- package/dist/esm/net/http/index.d.ts +11 -0
- package/dist/esm/net/http/index.d.ts.map +1 -0
- package/dist/esm/net/http/index.js +11 -0
- package/dist/esm/net/http/index.js.map +6 -0
- package/dist/esm/net/index.d.ts +2 -0
- package/dist/esm/net/index.d.ts.map +1 -1
- package/dist/esm/net/index.js +2 -0
- package/dist/esm/net/index.js.map +1 -1
- package/dist/esm/net/mqtt/MqttEndpoint.d.ts +39 -0
- package/dist/esm/net/mqtt/MqttEndpoint.d.ts.map +1 -0
- package/dist/esm/net/mqtt/MqttEndpoint.js +16 -0
- package/dist/esm/net/mqtt/MqttEndpoint.js.map +6 -0
- package/dist/esm/net/mqtt/MqttEndpointFactory.d.ts +15 -0
- package/dist/esm/net/mqtt/MqttEndpointFactory.d.ts.map +1 -0
- package/dist/esm/net/mqtt/MqttEndpointFactory.js +11 -0
- package/dist/esm/net/mqtt/MqttEndpointFactory.js.map +6 -0
- package/dist/esm/net/mqtt/MqttService.d.ts +19 -0
- package/dist/esm/net/mqtt/MqttService.d.ts.map +1 -0
- package/dist/esm/net/mqtt/MqttService.js +32 -0
- package/dist/esm/net/mqtt/MqttService.js.map +6 -0
- package/dist/esm/net/mqtt/index.d.ts +9 -0
- package/dist/esm/net/mqtt/index.d.ts.map +1 -0
- package/dist/esm/net/mqtt/index.js +9 -0
- package/dist/esm/net/mqtt/index.js.map +6 -0
- package/dist/esm/net/udp/UdpChannel.d.ts +31 -2
- package/dist/esm/net/udp/UdpChannel.d.ts.map +1 -1
- package/dist/esm/net/udp/UdpMulticastServer.d.ts.map +1 -1
- package/dist/esm/net/udp/UdpMulticastServer.js +6 -3
- package/dist/esm/net/udp/UdpMulticastServer.js.map +1 -1
- package/dist/esm/storage/StorageService.d.ts +5 -1
- package/dist/esm/storage/StorageService.d.ts.map +1 -1
- package/dist/esm/storage/StorageService.js +6 -1
- package/dist/esm/storage/StorageService.js.map +1 -1
- package/dist/esm/time/Duration.d.ts +1 -1
- package/dist/esm/util/Abort.d.ts +4 -1
- package/dist/esm/util/Abort.d.ts.map +1 -1
- package/dist/esm/util/Abort.js +19 -3
- package/dist/esm/util/Abort.js.map +1 -1
- package/dist/esm/util/Construction.d.ts +1 -1
- package/dist/esm/util/Multiplex.js +1 -1
- package/dist/esm/util/Multiplex.js.map +1 -1
- package/dist/esm/util/String.d.ts +5 -1
- package/dist/esm/util/String.d.ts.map +1 -1
- package/dist/esm/util/String.js +16 -0
- package/dist/esm/util/String.js.map +1 -1
- package/package.json +2 -2
- package/src/codec/Base64Codec.ts +2 -2
- package/src/environment/Environment.ts +35 -52
- package/src/environment/Environmental.ts +17 -2
- package/src/log/Logger.ts +1 -1
- package/src/net/Network.ts +4 -0
- package/src/net/ServerAddress.ts +16 -0
- package/src/net/http/HttpEndpoint.ts +60 -0
- package/src/net/http/HttpEndpointFactory.ts +27 -0
- package/src/net/http/HttpEndpointGroup.ts +43 -0
- package/src/net/http/HttpService.ts +75 -0
- package/src/net/http/HttpSharedEndpoint.ts +88 -0
- package/src/net/http/index.ts +11 -0
- package/src/net/index.ts +2 -0
- package/src/net/mqtt/MqttEndpoint.ts +50 -0
- package/src/net/mqtt/MqttEndpointFactory.ts +17 -0
- package/src/net/mqtt/MqttService.ts +40 -0
- package/src/net/mqtt/index.ts +9 -0
- package/src/net/udp/UdpChannel.ts +35 -2
- package/src/net/udp/UdpMulticastServer.ts +3 -0
- package/src/storage/StorageService.ts +14 -1
- package/src/time/Duration.ts +1 -1
- package/src/util/Abort.ts +28 -4
- package/src/util/Construction.ts +2 -2
- package/src/util/Multiplex.ts +1 -1
- package/src/util/String.ts +25 -6
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2022-2025 Matter.js Authors
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { Logger } from "#log/Logger.js";
|
|
8
|
+
import { HttpEndpoint } from "./HttpEndpoint.js";
|
|
9
|
+
|
|
10
|
+
const logger = Logger.get("HttpSharedEntpoint");
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Shared access to a single underlying HTTP endpoint.
|
|
14
|
+
*/
|
|
15
|
+
export class HttpSharedEndpoint {
|
|
16
|
+
#create: () => Promise<HttpEndpoint>;
|
|
17
|
+
#target?: Promise<HttpEndpoint>;
|
|
18
|
+
#instances = new Set<HttpEndpoint>();
|
|
19
|
+
#isTls: boolean;
|
|
20
|
+
|
|
21
|
+
constructor(isTls: boolean, create: () => Promise<HttpEndpoint>) {
|
|
22
|
+
this.#isTls = isTls;
|
|
23
|
+
this.#create = create;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
get isTls() {
|
|
27
|
+
return this.#isTls;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
async use() {
|
|
31
|
+
if (this.#target === undefined) {
|
|
32
|
+
this.#target = this.#createTarget();
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
await this.#target;
|
|
36
|
+
|
|
37
|
+
const instance: HttpEndpoint = {
|
|
38
|
+
http: undefined,
|
|
39
|
+
ws: undefined,
|
|
40
|
+
|
|
41
|
+
close: async () => {
|
|
42
|
+
this.#instances.delete(instance);
|
|
43
|
+
if (!this.#instances.size) {
|
|
44
|
+
try {
|
|
45
|
+
await (await this.#target)?.close();
|
|
46
|
+
} catch (e) {
|
|
47
|
+
logger.error("Error closing HTTP endpoint", e);
|
|
48
|
+
} finally {
|
|
49
|
+
this.#target = undefined;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
this.#instances.add(instance);
|
|
56
|
+
|
|
57
|
+
return instance;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
async #createTarget() {
|
|
61
|
+
const target = await this.#create();
|
|
62
|
+
|
|
63
|
+
target.http = async request => {
|
|
64
|
+
for (const instance of this.#instances) {
|
|
65
|
+
const response = await instance.http?.(request);
|
|
66
|
+
if (response) {
|
|
67
|
+
return response;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
target.ws = async (request, connect) => {
|
|
73
|
+
let connected = false;
|
|
74
|
+
for (const instance of this.#instances) {
|
|
75
|
+
await instance.ws?.(request, async () => {
|
|
76
|
+
connected = true;
|
|
77
|
+
return connect();
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
if (connected) {
|
|
81
|
+
break;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
return target;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2022-2025 Matter.js Authors
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export * from "./HttpEndpoint.js";
|
|
8
|
+
export * from "./HttpEndpointFactory.js";
|
|
9
|
+
export * from "./HttpEndpointGroup.js";
|
|
10
|
+
export * from "./HttpService.js";
|
|
11
|
+
export * from "./HttpSharedEndpoint.js";
|
package/src/net/index.ts
CHANGED
|
@@ -7,7 +7,9 @@
|
|
|
7
7
|
export * from "./AppAddress.js";
|
|
8
8
|
export * from "./Channel.js";
|
|
9
9
|
export * from "./ConnectionlessTransport.js";
|
|
10
|
+
export * from "./http/index.js";
|
|
10
11
|
export * from "./mock/index.js";
|
|
12
|
+
export * from "./mqtt/index.js";
|
|
11
13
|
export * from "./Network.js";
|
|
12
14
|
export * from "./RetrySchedule.js";
|
|
13
15
|
export * from "./ServerAddress.js";
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2022-2025 Matter.js Authors
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { Environment } from "#environment/Environment.js";
|
|
8
|
+
import { AppAddress } from "#net/AppAddress.js";
|
|
9
|
+
import { Abort } from "#util/Abort.js";
|
|
10
|
+
import { Bytes } from "#util/Bytes.js";
|
|
11
|
+
import { MaybePromise } from "#util/Promises.js";
|
|
12
|
+
|
|
13
|
+
export interface MqttEndpoint {
|
|
14
|
+
subscribe(
|
|
15
|
+
topic: string,
|
|
16
|
+
options?: MqttEndpoint.SubscriptionOptions,
|
|
17
|
+
): AsyncIterableIterator<MqttEndpoint.Message, void, void>;
|
|
18
|
+
publish(message: MqttEndpoint.Message): Promise<void>;
|
|
19
|
+
|
|
20
|
+
close(): Promise<void>;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export namespace MqttEndpoint {
|
|
24
|
+
export interface Message {
|
|
25
|
+
topic: string;
|
|
26
|
+
payload: Bytes | string | null;
|
|
27
|
+
retain?: boolean;
|
|
28
|
+
contentType?: string;
|
|
29
|
+
responseTopic?: string;
|
|
30
|
+
correlationData?: Bytes;
|
|
31
|
+
qos?: 0 | 1 | 2;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function Message(message: Message) {
|
|
35
|
+
return message;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface ConnectionOptions {
|
|
39
|
+
address: AppAddress.Definition;
|
|
40
|
+
environment?: Environment;
|
|
41
|
+
will?: Message;
|
|
42
|
+
onUp?: (endpoint: MqttEndpoint) => MaybePromise<void>;
|
|
43
|
+
onDown?: (endpoint: MqttEndpoint) => MaybePromise<void>;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export interface SubscriptionOptions {
|
|
47
|
+
noLocal?: boolean;
|
|
48
|
+
abort?: Abort.Signal;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2022-2025 Matter.js Authors
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { MqttEndpoint } from "./MqttEndpoint.js";
|
|
8
|
+
import type { MqttService } from "./MqttService.js";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Connects to an MQTT broker.
|
|
12
|
+
*
|
|
13
|
+
* MQTT adapters should implement this class. Clients should access via {@link MqttService}.
|
|
14
|
+
*/
|
|
15
|
+
export abstract class MqttEndpointFactory {
|
|
16
|
+
abstract connect(options: MqttEndpoint.ConnectionOptions): Promise<MqttEndpoint>;
|
|
17
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2022-2025 Matter.js Authors
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { Environment } from "#environment/Environment.js";
|
|
8
|
+
import { Environmental } from "#environment/Environmental.js";
|
|
9
|
+
import { ImplementationError } from "#MatterError.js";
|
|
10
|
+
import { AppAddress } from "#net/AppAddress.js";
|
|
11
|
+
import { MqttEndpoint } from "./MqttEndpoint.js";
|
|
12
|
+
import { MqttEndpointFactory } from "./MqttEndpointFactory.js";
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Provides connections to MQTT brokers.
|
|
16
|
+
*/
|
|
17
|
+
export class MqttService {
|
|
18
|
+
#factory: MqttEndpointFactory;
|
|
19
|
+
|
|
20
|
+
constructor(factory: MqttEndpointFactory) {
|
|
21
|
+
this.#factory = factory;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
static [Environmental.create](env: Environment) {
|
|
25
|
+
const factory = env.get(MqttEndpointFactory);
|
|
26
|
+
const instance = new this(factory);
|
|
27
|
+
env.set(MqttService, instance);
|
|
28
|
+
return instance;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
connect(options: MqttEndpoint.ConnectionOptions) {
|
|
32
|
+
const addr = AppAddress.for(options.address);
|
|
33
|
+
|
|
34
|
+
if (addr.appProtocol !== "mqtt") {
|
|
35
|
+
throw new ImplementationError(`Unsupported address ${addr} for MQTT connection`);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return this.#factory.connect(options);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -11,13 +11,46 @@ import { ConnectionlessTransport } from "../ConnectionlessTransport.js";
|
|
|
11
11
|
/** @see {@link MatterSpecification.v12.Core} § 4.4.4 */
|
|
12
12
|
export const MAX_UDP_MESSAGE_SIZE = 1280 - 48; // 48 bytes IP and UDP header size for IPv6
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
/**
|
|
15
|
+
* UDP socket address type.
|
|
16
|
+
*
|
|
17
|
+
* "udp4" and "udp6" are IPv4 and IPv6 exclusively. "udp" binds both IPv4 and IPv6 addresses.
|
|
18
|
+
*/
|
|
19
|
+
export type UdpSocketType = "udp" | "udp4" | "udp6";
|
|
15
20
|
|
|
16
21
|
export interface UdpChannelOptions {
|
|
17
|
-
|
|
22
|
+
/**
|
|
23
|
+
* UDP channel type. "udp4" and "udp6" mean IPv4 and IPv6 respectively. "udp" is dual-mode IPv4/IPv6.
|
|
24
|
+
*/
|
|
18
25
|
type: UdpSocketType;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* The port to listen on. undefined or 0 directs the operating system to select an open port.
|
|
29
|
+
*/
|
|
30
|
+
listeningPort?: number;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* The address to listen on, either a hostname or IP address in correct format based on {@link type}.
|
|
34
|
+
*
|
|
35
|
+
* undefined directs the operating system to listen on all addresses on the port. "0.0.0.0" is wildcard IPv4 and
|
|
36
|
+
* "::" is wildcard IPv6.
|
|
37
|
+
*
|
|
38
|
+
* "0.0.0.0" is not allowed if {@link type} is "udp".
|
|
39
|
+
*/
|
|
19
40
|
listeningAddress?: string;
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Specifies a specific network interface.
|
|
44
|
+
*
|
|
45
|
+
* This is required for multicast sockets.
|
|
46
|
+
*/
|
|
20
47
|
netInterface?: string;
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Address+port pairs are normally may normally only be opened by a single socket. This allows shared access to a
|
|
51
|
+
* port.
|
|
52
|
+
*/
|
|
53
|
+
reuseAddress?: boolean;
|
|
21
54
|
}
|
|
22
55
|
|
|
23
56
|
export interface UdpChannel {
|
|
@@ -39,6 +39,7 @@ export class UdpMulticastServer {
|
|
|
39
39
|
type: "udp4",
|
|
40
40
|
netInterface,
|
|
41
41
|
listeningPort,
|
|
42
|
+
reuseAddress: true,
|
|
42
43
|
});
|
|
43
44
|
await ipv4UdpChannel.addMembership(broadcastAddressIpv4);
|
|
44
45
|
} catch (error) {
|
|
@@ -52,6 +53,7 @@ export class UdpMulticastServer {
|
|
|
52
53
|
type: "udp6",
|
|
53
54
|
netInterface,
|
|
54
55
|
listeningPort,
|
|
56
|
+
reuseAddress: true,
|
|
55
57
|
});
|
|
56
58
|
await ipv6UdpChannel.addMembership(broadcastAddressIpv6);
|
|
57
59
|
return new UdpMulticastServer(
|
|
@@ -160,6 +162,7 @@ export class UdpMulticastServer {
|
|
|
160
162
|
type: iPv4 ? "udp4" : "udp6",
|
|
161
163
|
listeningPort: this.broadcastPort,
|
|
162
164
|
netInterface,
|
|
165
|
+
reuseAddress: true,
|
|
163
166
|
});
|
|
164
167
|
}
|
|
165
168
|
|
|
@@ -18,9 +18,17 @@ export class StorageService {
|
|
|
18
18
|
#factory?: (namespace: string) => Storage;
|
|
19
19
|
#location?: string;
|
|
20
20
|
|
|
21
|
-
constructor(
|
|
21
|
+
constructor(
|
|
22
|
+
environment: Environment,
|
|
23
|
+
factory?: (namespace: string) => Storage,
|
|
24
|
+
resolver?: (...paths: string[]) => string,
|
|
25
|
+
) {
|
|
22
26
|
environment.set(StorageService, this);
|
|
23
27
|
this.#factory = factory;
|
|
28
|
+
|
|
29
|
+
// Fallback resolver is dumb and probably not useful; expected to be replaced by platform implementation if
|
|
30
|
+
// file resolution is necessary
|
|
31
|
+
this.resolve = resolver ?? ((...paths: []) => paths.join("/"));
|
|
24
32
|
}
|
|
25
33
|
|
|
26
34
|
static [Environmental.create](environment: Environment) {
|
|
@@ -61,6 +69,11 @@ export class StorageService {
|
|
|
61
69
|
this.#location = location;
|
|
62
70
|
}
|
|
63
71
|
|
|
72
|
+
/**
|
|
73
|
+
* Join one or more relative paths to some platform-dependent notion of an absolute storage path.
|
|
74
|
+
*/
|
|
75
|
+
resolve: (...paths: string[]) => string;
|
|
76
|
+
|
|
64
77
|
[Diagnostic.value]() {
|
|
65
78
|
return [
|
|
66
79
|
"Persistence",
|
package/src/time/Duration.ts
CHANGED
|
@@ -19,7 +19,7 @@ import type { Millis, Seconds, TimeUnit } from "./TimeUnit.js";
|
|
|
19
19
|
* Math operators always result in millisecond values and can thus be converted back to an interval using
|
|
20
20
|
* {@link Millis}. For example, `Millisecs(Hours(1) + Minutes(30))` would produce a 90 minute {@link Duration}.
|
|
21
21
|
*/
|
|
22
|
-
export type Duration = Branded<number, "
|
|
22
|
+
export type Duration = Branded<number, "Duration"> | 0;
|
|
23
23
|
|
|
24
24
|
/**
|
|
25
25
|
* Create an interval from a number or string.
|
package/src/util/Abort.ts
CHANGED
|
@@ -4,6 +4,10 @@
|
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
+
import { TimeoutError } from "#MatterError.js";
|
|
8
|
+
import { Duration } from "#time/Duration.js";
|
|
9
|
+
import { Time, Timer } from "#time/Time.js";
|
|
10
|
+
|
|
7
11
|
/**
|
|
8
12
|
* Utilities for implementing abort logic.
|
|
9
13
|
*/
|
|
@@ -72,20 +76,40 @@ export namespace Abort {
|
|
|
72
76
|
* aborts.
|
|
73
77
|
*
|
|
74
78
|
* Closing the returned controller unregisters with the input controller. It does not perform an abort.
|
|
79
|
+
*
|
|
80
|
+
* {@link timeout} is a convenience for adding a timeout.
|
|
75
81
|
*/
|
|
76
|
-
export function subtask(signal: Signal | undefined): DisposableController {
|
|
82
|
+
export function subtask(signal: Signal | undefined, timeout?: Duration): DisposableController {
|
|
83
|
+
let timer: Timer | undefined;
|
|
84
|
+
|
|
77
85
|
if (signal && "signal" in signal) {
|
|
78
86
|
signal = signal.signal;
|
|
79
87
|
}
|
|
80
88
|
|
|
81
89
|
const controller = new AbortController() as DisposableController;
|
|
82
90
|
|
|
91
|
+
if (timeout) {
|
|
92
|
+
timer = Time.getPeriodicTimer("subtask timeout", timeout, () => {
|
|
93
|
+
if (controller.signal.aborted) {
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
controller.abort(new TimeoutError());
|
|
98
|
+
});
|
|
99
|
+
timer.start();
|
|
100
|
+
}
|
|
101
|
+
|
|
83
102
|
if (signal) {
|
|
84
|
-
const outerHandler = () => controller.abort();
|
|
103
|
+
const outerHandler = () => controller.abort(signal.reason);
|
|
85
104
|
signal.addEventListener("abort", outerHandler);
|
|
86
|
-
controller[Symbol.dispose] = () =>
|
|
105
|
+
controller[Symbol.dispose] = () => {
|
|
106
|
+
signal.removeEventListener("abort", outerHandler);
|
|
107
|
+
timer?.stop();
|
|
108
|
+
};
|
|
87
109
|
} else {
|
|
88
|
-
controller[Symbol.dispose] = () => {
|
|
110
|
+
controller[Symbol.dispose] = () => {
|
|
111
|
+
timer?.stop();
|
|
112
|
+
};
|
|
89
113
|
}
|
|
90
114
|
|
|
91
115
|
return controller;
|
package/src/util/Construction.ts
CHANGED
|
@@ -39,7 +39,7 @@ export async function asyncNew<const A extends any[], const C extends new (...ar
|
|
|
39
39
|
* Construction happens in the initializer parameter of {@link Construction} or via {@link Construction.construct} on
|
|
40
40
|
* the subject. You invoke in your constructor and place in a property called "construction".
|
|
41
41
|
*
|
|
42
|
-
*
|
|
42
|
+
* Destruction is optional and happens in the destructor parameter of {@link Construction#close} or via
|
|
43
43
|
* {@link Construction.destruct} on the subject. Typically you invoke in a "close" method of the subject.
|
|
44
44
|
*
|
|
45
45
|
* If construction or destruction is not asynchronous (does not return a Promise) then they complete synchronously,
|
|
@@ -430,7 +430,7 @@ export function Construction<const T extends Constructable>(
|
|
|
430
430
|
}
|
|
431
431
|
: invokeDestruct;
|
|
432
432
|
|
|
433
|
-
// Destruction phase 1 - move to
|
|
433
|
+
// Destruction phase 1 - move to destroying state
|
|
434
434
|
function beginDestruction() {
|
|
435
435
|
if (status === Lifecycle.Status.Destroying || status === Lifecycle.Status.Destroyed) {
|
|
436
436
|
return self.closed;
|
package/src/util/Multiplex.ts
CHANGED
|
@@ -43,7 +43,7 @@ export class BasicMultiplex implements PromiseLike<void> {
|
|
|
43
43
|
if (description) {
|
|
44
44
|
message = `${message} in ${description}`;
|
|
45
45
|
}
|
|
46
|
-
logger.error(message
|
|
46
|
+
logger.error(`${message}:`, e);
|
|
47
47
|
})
|
|
48
48
|
.finally(() => this.#workers.delete(entry)),
|
|
49
49
|
description,
|
package/src/util/String.ts
CHANGED
|
@@ -104,7 +104,7 @@ export function decamelize(name: string, separator = "-") {
|
|
|
104
104
|
/**
|
|
105
105
|
* Like JSON.stringify but targets well-formed JS and is slightly more readable.
|
|
106
106
|
*/
|
|
107
|
-
export function serialize(value:
|
|
107
|
+
export function serialize(value: unknown) {
|
|
108
108
|
const visited = new Set();
|
|
109
109
|
|
|
110
110
|
function asValidKey(key: string) {
|
|
@@ -114,15 +114,15 @@ export function serialize(value: any) {
|
|
|
114
114
|
return JSON.stringify(key);
|
|
115
115
|
}
|
|
116
116
|
|
|
117
|
-
function serializeOne(value:
|
|
117
|
+
function serializeOne(value: unknown): string | undefined {
|
|
118
118
|
if (value === undefined) {
|
|
119
119
|
return;
|
|
120
120
|
}
|
|
121
121
|
if (value === null) {
|
|
122
122
|
return "null";
|
|
123
123
|
}
|
|
124
|
-
if (value[serialize.SERIALIZE]) {
|
|
125
|
-
return value[serialize.SERIALIZE]();
|
|
124
|
+
if ((value as { [serialize.SERIALIZE](): string })[serialize.SERIALIZE]) {
|
|
125
|
+
return (value as { [serialize.SERIALIZE](): string })[serialize.SERIALIZE]();
|
|
126
126
|
}
|
|
127
127
|
if (typeof value === "function") {
|
|
128
128
|
return;
|
|
@@ -147,7 +147,7 @@ export function serialize(value: any) {
|
|
|
147
147
|
if (visited.has(value)) {
|
|
148
148
|
return;
|
|
149
149
|
}
|
|
150
|
-
if (value.toJSON) {
|
|
150
|
+
if ((value as { toJSON(): string }).toJSON) {
|
|
151
151
|
value = JSON.parse(JSON.stringify(value));
|
|
152
152
|
}
|
|
153
153
|
|
|
@@ -161,7 +161,7 @@ export function serialize(value: any) {
|
|
|
161
161
|
return "[]";
|
|
162
162
|
}
|
|
163
163
|
|
|
164
|
-
const entries = Object.entries(value)
|
|
164
|
+
const entries = Object.entries(value as {})
|
|
165
165
|
.map(([k, v]) => [k, serializeOne(v)])
|
|
166
166
|
.filter(([_k, v]) => v !== undefined)
|
|
167
167
|
.map(([k, v]) => `${asValidKey(k ?? "")}: ${v}`);
|
|
@@ -179,6 +179,25 @@ export function serialize(value: any) {
|
|
|
179
179
|
return serializeOne(value);
|
|
180
180
|
}
|
|
181
181
|
|
|
182
|
+
/**
|
|
183
|
+
* Like {@link JSON.stringify} but with support for additional standard objects.
|
|
184
|
+
*/
|
|
185
|
+
export function asJson(value: unknown, space?: number) {
|
|
186
|
+
return JSON.stringify(
|
|
187
|
+
value,
|
|
188
|
+
(_key, value) => {
|
|
189
|
+
if (typeof value === "bigint") {
|
|
190
|
+
return value.toString();
|
|
191
|
+
}
|
|
192
|
+
if (Bytes.isBytes(value)) {
|
|
193
|
+
return Bytes.toHex(value);
|
|
194
|
+
}
|
|
195
|
+
return value;
|
|
196
|
+
},
|
|
197
|
+
space,
|
|
198
|
+
);
|
|
199
|
+
}
|
|
200
|
+
|
|
182
201
|
export namespace serialize {
|
|
183
202
|
/**
|
|
184
203
|
* Custom serialization function key.
|