@matter/general 0.16.0-alpha.0-20251205-dfb1e1556 → 0.16.0-alpha.0-20251207-37e501b18
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/MatterError.js +2 -2
- package/dist/cjs/MatterError.js.map +1 -1
- package/dist/cjs/codec/DerTypes.d.ts.map +1 -1
- package/dist/cjs/codec/DerTypes.js +2 -1
- package/dist/cjs/codec/DerTypes.js.map +1 -1
- package/dist/cjs/environment/Environment.d.ts +4 -1
- package/dist/cjs/environment/Environment.d.ts.map +1 -1
- package/dist/cjs/environment/Environment.js +83 -3
- package/dist/cjs/environment/Environment.js.map +1 -1
- package/dist/cjs/environment/RuntimeService.d.ts +3 -44
- package/dist/cjs/environment/RuntimeService.d.ts.map +1 -1
- package/dist/cjs/environment/RuntimeService.js +65 -10
- package/dist/cjs/environment/RuntimeService.js.map +2 -2
- package/dist/cjs/environment/Worker.d.ts +56 -0
- package/dist/cjs/environment/Worker.d.ts.map +1 -0
- package/dist/cjs/environment/Worker.js +44 -0
- package/dist/cjs/environment/Worker.js.map +6 -0
- package/dist/cjs/environment/index.d.ts +1 -0
- package/dist/cjs/environment/index.d.ts.map +1 -1
- package/dist/cjs/environment/index.js +1 -0
- package/dist/cjs/environment/index.js.map +1 -1
- package/dist/cjs/log/Diagnostic.d.ts +11 -1
- package/dist/cjs/log/Diagnostic.d.ts.map +1 -1
- package/dist/cjs/log/Diagnostic.js +3 -0
- package/dist/cjs/log/Diagnostic.js.map +1 -1
- package/dist/cjs/log/DiagnosticPresentation.d.ts +4 -0
- package/dist/cjs/log/DiagnosticPresentation.d.ts.map +1 -1
- package/dist/cjs/log/DiagnosticPresentation.js +3 -2
- package/dist/cjs/log/DiagnosticPresentation.js.map +1 -1
- package/dist/cjs/log/DiagnosticSource.d.ts +1 -1
- package/dist/cjs/log/DiagnosticSource.d.ts.map +1 -1
- package/dist/cjs/log/DiagnosticSource.js +5 -1
- package/dist/cjs/log/DiagnosticSource.js.map +1 -1
- package/dist/cjs/log/LogFormat.js +2 -2
- package/dist/cjs/log/LogFormat.js.map +1 -1
- package/dist/cjs/net/Channel.d.ts +1 -1
- package/dist/cjs/net/Channel.d.ts.map +1 -1
- package/dist/cjs/net/Channel.js +1 -1
- package/dist/cjs/net/Channel.js.map +1 -1
- package/dist/cjs/net/mock/MockUdpChannel.d.ts +1 -1
- package/dist/cjs/net/mock/MockUdpChannel.d.ts.map +1 -1
- package/dist/cjs/net/mock/NetworkSimulator.d.ts.map +1 -1
- package/dist/cjs/net/mock/NetworkSimulator.js +2 -1
- package/dist/cjs/net/mock/NetworkSimulator.js.map +1 -1
- package/dist/cjs/net/udp/UdpChannel.d.ts +5 -1
- package/dist/cjs/net/udp/UdpChannel.d.ts.map +1 -1
- package/dist/cjs/net/udp/UdpMulticastServer.d.ts +4 -6
- package/dist/cjs/net/udp/UdpMulticastServer.d.ts.map +1 -1
- package/dist/cjs/net/udp/UdpMulticastServer.js +114 -37
- package/dist/cjs/net/udp/UdpMulticastServer.js.map +1 -1
- package/dist/cjs/time/StandardTime.d.ts +38 -0
- package/dist/cjs/time/StandardTime.d.ts.map +1 -0
- package/dist/cjs/time/StandardTime.js +172 -0
- package/dist/cjs/time/StandardTime.js.map +6 -0
- package/dist/cjs/time/Time.d.ts +4 -23
- package/dist/cjs/time/Time.d.ts.map +1 -1
- package/dist/cjs/time/Time.js +12 -88
- package/dist/cjs/time/Time.js.map +1 -1
- package/dist/cjs/time/Timestamp.d.ts +5 -0
- package/dist/cjs/time/Timestamp.d.ts.map +1 -1
- package/dist/cjs/time/Timestamp.js +4 -0
- package/dist/cjs/time/Timestamp.js.map +1 -1
- package/dist/cjs/time/index.d.ts +1 -0
- package/dist/cjs/time/index.d.ts.map +1 -1
- package/dist/cjs/time/index.js +1 -0
- package/dist/cjs/time/index.js.map +1 -1
- package/dist/cjs/transaction/Transaction.d.ts +12 -4
- package/dist/cjs/transaction/Transaction.d.ts.map +1 -1
- package/dist/cjs/transaction/Transaction.js +4 -4
- package/dist/cjs/transaction/Transaction.js.map +1 -1
- package/dist/cjs/transaction/Tx.d.ts +2 -1
- package/dist/cjs/transaction/Tx.d.ts.map +1 -1
- package/dist/cjs/transaction/Tx.js +92 -6
- package/dist/cjs/transaction/Tx.js.map +1 -1
- package/dist/cjs/util/Abort.js +1 -1
- package/dist/cjs/util/Abort.js.map +1 -1
- package/dist/cjs/util/Construction.d.ts +2 -1
- package/dist/cjs/util/Construction.d.ts.map +1 -1
- package/dist/cjs/util/Construction.js +60 -16
- package/dist/cjs/util/Construction.js.map +2 -2
- package/dist/cjs/util/DataReadQueue.d.ts +1 -5
- package/dist/cjs/util/DataReadQueue.d.ts.map +1 -1
- package/dist/cjs/util/DataReadQueue.js +12 -11
- package/dist/cjs/util/DataReadQueue.js.map +1 -1
- package/dist/cjs/util/FormattedText.d.ts +1 -1
- package/dist/cjs/util/FormattedText.d.ts.map +1 -1
- package/dist/cjs/util/FormattedText.js +1 -3
- package/dist/cjs/util/FormattedText.js.map +1 -1
- package/dist/cjs/util/Lifetime.d.ts +97 -0
- package/dist/cjs/util/Lifetime.d.ts.map +1 -0
- package/dist/cjs/util/Lifetime.js +166 -0
- package/dist/cjs/util/Lifetime.js.map +6 -0
- package/dist/cjs/util/Multiplex.js +2 -2
- package/dist/cjs/util/Multiplex.js.map +1 -1
- package/dist/cjs/util/Observable.d.ts +27 -26
- package/dist/cjs/util/Observable.d.ts.map +1 -1
- package/dist/cjs/util/Observable.js +76 -35
- package/dist/cjs/util/Observable.js.map +2 -2
- package/dist/cjs/util/String.d.ts +5 -29
- package/dist/cjs/util/String.d.ts.map +1 -1
- package/dist/cjs/util/String.js +16 -158
- package/dist/cjs/util/String.js.map +2 -2
- package/dist/cjs/util/identifier-case.d.ts +19 -0
- package/dist/cjs/util/identifier-case.d.ts.map +1 -0
- package/dist/cjs/util/identifier-case.js +99 -0
- package/dist/cjs/util/identifier-case.js.map +6 -0
- package/dist/cjs/util/index.d.ts +3 -0
- package/dist/cjs/util/index.d.ts.map +1 -1
- package/dist/cjs/util/index.js +3 -0
- package/dist/cjs/util/index.js.map +1 -1
- package/dist/cjs/util/serialize.d.ts +25 -0
- package/dist/cjs/util/serialize.d.ts.map +1 -0
- package/dist/cjs/util/serialize.js +116 -0
- package/dist/cjs/util/serialize.js.map +6 -0
- package/dist/esm/MatterError.js +1 -1
- package/dist/esm/codec/DerTypes.d.ts.map +1 -1
- package/dist/esm/codec/DerTypes.js +2 -1
- package/dist/esm/codec/DerTypes.js.map +1 -1
- package/dist/esm/environment/Environment.d.ts +4 -1
- package/dist/esm/environment/Environment.d.ts.map +1 -1
- package/dist/esm/environment/Environment.js +83 -3
- package/dist/esm/environment/Environment.js.map +1 -1
- package/dist/esm/environment/RuntimeService.d.ts +3 -44
- package/dist/esm/environment/RuntimeService.d.ts.map +1 -1
- package/dist/esm/environment/RuntimeService.js +65 -10
- package/dist/esm/environment/RuntimeService.js.map +2 -2
- package/dist/esm/environment/Worker.d.ts +56 -0
- package/dist/esm/environment/Worker.d.ts.map +1 -0
- package/dist/esm/environment/Worker.js +24 -0
- package/dist/esm/environment/Worker.js.map +6 -0
- package/dist/esm/environment/index.d.ts +1 -0
- package/dist/esm/environment/index.d.ts.map +1 -1
- package/dist/esm/environment/index.js +1 -0
- package/dist/esm/environment/index.js.map +1 -1
- package/dist/esm/log/Diagnostic.d.ts +11 -1
- package/dist/esm/log/Diagnostic.d.ts.map +1 -1
- package/dist/esm/log/Diagnostic.js +3 -0
- package/dist/esm/log/Diagnostic.js.map +1 -1
- package/dist/esm/log/DiagnosticPresentation.d.ts +4 -0
- package/dist/esm/log/DiagnosticPresentation.d.ts.map +1 -1
- package/dist/esm/log/DiagnosticPresentation.js +3 -2
- package/dist/esm/log/DiagnosticPresentation.js.map +1 -1
- package/dist/esm/log/DiagnosticSource.d.ts +1 -1
- package/dist/esm/log/DiagnosticSource.d.ts.map +1 -1
- package/dist/esm/log/DiagnosticSource.js +5 -1
- package/dist/esm/log/DiagnosticSource.js.map +1 -1
- package/dist/esm/log/LogFormat.js +1 -1
- package/dist/esm/log/LogFormat.js.map +1 -1
- package/dist/esm/net/Channel.d.ts +1 -1
- package/dist/esm/net/Channel.d.ts.map +1 -1
- package/dist/esm/net/Channel.js +1 -1
- package/dist/esm/net/Channel.js.map +1 -1
- package/dist/esm/net/mock/MockUdpChannel.d.ts +1 -1
- package/dist/esm/net/mock/MockUdpChannel.d.ts.map +1 -1
- package/dist/esm/net/mock/NetworkSimulator.d.ts.map +1 -1
- package/dist/esm/net/mock/NetworkSimulator.js +2 -1
- package/dist/esm/net/mock/NetworkSimulator.js.map +1 -1
- package/dist/esm/net/udp/UdpChannel.d.ts +5 -1
- package/dist/esm/net/udp/UdpChannel.d.ts.map +1 -1
- package/dist/esm/net/udp/UdpMulticastServer.d.ts +4 -6
- package/dist/esm/net/udp/UdpMulticastServer.d.ts.map +1 -1
- package/dist/esm/net/udp/UdpMulticastServer.js +114 -37
- package/dist/esm/net/udp/UdpMulticastServer.js.map +1 -1
- package/dist/esm/time/StandardTime.d.ts +38 -0
- package/dist/esm/time/StandardTime.d.ts.map +1 -0
- package/dist/esm/time/StandardTime.js +152 -0
- package/dist/esm/time/StandardTime.js.map +6 -0
- package/dist/esm/time/Time.d.ts +4 -23
- package/dist/esm/time/Time.d.ts.map +1 -1
- package/dist/esm/time/Time.js +12 -88
- package/dist/esm/time/Time.js.map +1 -1
- package/dist/esm/time/Timestamp.d.ts +5 -0
- package/dist/esm/time/Timestamp.d.ts.map +1 -1
- package/dist/esm/time/Timestamp.js +4 -0
- package/dist/esm/time/Timestamp.js.map +1 -1
- package/dist/esm/time/index.d.ts +1 -0
- package/dist/esm/time/index.d.ts.map +1 -1
- package/dist/esm/time/index.js +1 -0
- package/dist/esm/time/index.js.map +1 -1
- package/dist/esm/transaction/Transaction.d.ts +12 -4
- package/dist/esm/transaction/Transaction.d.ts.map +1 -1
- package/dist/esm/transaction/Transaction.js +4 -4
- package/dist/esm/transaction/Transaction.js.map +1 -1
- package/dist/esm/transaction/Tx.d.ts +2 -1
- package/dist/esm/transaction/Tx.d.ts.map +1 -1
- package/dist/esm/transaction/Tx.js +92 -6
- package/dist/esm/transaction/Tx.js.map +1 -1
- package/dist/esm/util/Abort.js +1 -1
- package/dist/esm/util/Abort.js.map +1 -1
- package/dist/esm/util/Construction.d.ts +2 -1
- package/dist/esm/util/Construction.d.ts.map +1 -1
- package/dist/esm/util/Construction.js +60 -16
- package/dist/esm/util/Construction.js.map +2 -2
- package/dist/esm/util/DataReadQueue.d.ts +1 -5
- package/dist/esm/util/DataReadQueue.d.ts.map +1 -1
- package/dist/esm/util/DataReadQueue.js +12 -11
- package/dist/esm/util/DataReadQueue.js.map +1 -1
- package/dist/esm/util/FormattedText.d.ts +1 -1
- package/dist/esm/util/FormattedText.d.ts.map +1 -1
- package/dist/esm/util/FormattedText.js +2 -4
- package/dist/esm/util/FormattedText.js.map +1 -1
- package/dist/esm/util/Lifetime.d.ts +97 -0
- package/dist/esm/util/Lifetime.d.ts.map +1 -0
- package/dist/esm/util/Lifetime.js +146 -0
- package/dist/esm/util/Lifetime.js.map +6 -0
- package/dist/esm/util/Multiplex.js +2 -2
- package/dist/esm/util/Multiplex.js.map +1 -1
- package/dist/esm/util/Observable.d.ts +27 -26
- package/dist/esm/util/Observable.d.ts.map +1 -1
- package/dist/esm/util/Observable.js +76 -35
- package/dist/esm/util/Observable.js.map +2 -2
- package/dist/esm/util/String.d.ts +5 -29
- package/dist/esm/util/String.d.ts.map +1 -1
- package/dist/esm/util/String.js +16 -158
- package/dist/esm/util/String.js.map +2 -2
- package/dist/esm/util/identifier-case.d.ts +19 -0
- package/dist/esm/util/identifier-case.d.ts.map +1 -0
- package/dist/esm/util/identifier-case.js +79 -0
- package/dist/esm/util/identifier-case.js.map +6 -0
- package/dist/esm/util/index.d.ts +3 -0
- package/dist/esm/util/index.d.ts.map +1 -1
- package/dist/esm/util/index.js +3 -0
- package/dist/esm/util/index.js.map +1 -1
- package/dist/esm/util/serialize.d.ts +25 -0
- package/dist/esm/util/serialize.d.ts.map +1 -0
- package/dist/esm/util/serialize.js +96 -0
- package/dist/esm/util/serialize.js.map +6 -0
- package/package.json +2 -2
- package/src/MatterError.ts +1 -1
- package/src/codec/DerTypes.ts +2 -1
- package/src/environment/Environment.ts +29 -4
- package/src/environment/RuntimeService.ts +19 -55
- package/src/environment/Worker.ts +75 -0
- package/src/environment/index.ts +1 -0
- package/src/log/Diagnostic.ts +15 -1
- package/src/log/DiagnosticPresentation.ts +7 -2
- package/src/log/DiagnosticSource.ts +5 -1
- package/src/log/LogFormat.ts +1 -1
- package/src/net/Channel.ts +2 -2
- package/src/net/mock/MockUdpChannel.ts +1 -1
- package/src/net/mock/NetworkSimulator.ts +2 -1
- package/src/net/udp/UdpChannel.ts +6 -1
- package/src/net/udp/UdpMulticastServer.ts +72 -34
- package/src/time/StandardTime.ts +122 -0
- package/src/time/Time.ts +13 -105
- package/src/time/Timestamp.ts +8 -0
- package/src/time/index.ts +1 -0
- package/src/transaction/Transaction.ts +19 -6
- package/src/transaction/Tx.ts +49 -2
- package/src/util/Abort.ts +1 -1
- package/src/util/Construction.ts +76 -18
- package/src/util/DataReadQueue.ts +14 -12
- package/src/util/FormattedText.ts +1 -1
- package/src/util/Lifetime.ts +284 -0
- package/src/util/Multiplex.ts +2 -2
- package/src/util/Observable.ts +132 -53
- package/src/util/String.ts +14 -215
- package/src/util/identifier-case.ts +101 -0
- package/src/util/index.ts +3 -0
- package/src/util/serialize.ts +129 -0
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
import { MatterAggregateError } from "#MatterError.js";
|
|
8
8
|
import { Minutes } from "#time/TimeUnit.js";
|
|
9
9
|
import { Bytes } from "#util/Bytes.js";
|
|
10
|
+
import { Lifetime } from "#util/Lifetime.js";
|
|
10
11
|
import { Logger } from "../../log/Logger.js";
|
|
11
12
|
import { Cache } from "../../util/Cache.js";
|
|
12
13
|
import { asError } from "../../util/Error.js";
|
|
@@ -22,41 +23,67 @@ export interface UdpMulticastServerOptions {
|
|
|
22
23
|
broadcastAddressIpv6: string;
|
|
23
24
|
broadcastAddressIpv4?: string;
|
|
24
25
|
netInterface?: string;
|
|
26
|
+
lifetime?: Lifetime.Owner;
|
|
25
27
|
}
|
|
26
28
|
|
|
27
29
|
export class UdpMulticastServer {
|
|
30
|
+
#lifetime: Lifetime;
|
|
31
|
+
readonly network: Network;
|
|
32
|
+
readonly netInterface: string | undefined;
|
|
33
|
+
readonly #broadcastAddressIpv4: string | undefined;
|
|
34
|
+
readonly #broadcastAddressIpv6: string;
|
|
35
|
+
readonly #broadcastPort: number;
|
|
36
|
+
readonly #serverIpv4: UdpChannel | undefined;
|
|
37
|
+
readonly #serverIpv6: UdpChannel;
|
|
38
|
+
|
|
28
39
|
static async create({
|
|
29
40
|
netInterface,
|
|
30
41
|
broadcastAddressIpv4,
|
|
31
42
|
broadcastAddressIpv6,
|
|
32
43
|
listeningPort,
|
|
33
44
|
network,
|
|
45
|
+
lifetime: lifetimeOwner,
|
|
34
46
|
}: UdpMulticastServerOptions) {
|
|
35
|
-
|
|
36
|
-
|
|
47
|
+
const lifetime = (lifetimeOwner || Lifetime.process)?.join("multicast server");
|
|
48
|
+
|
|
49
|
+
try {
|
|
50
|
+
let ipv4UdpChannel: UdpChannel | undefined = undefined;
|
|
51
|
+
if (broadcastAddressIpv4 !== undefined) {
|
|
52
|
+
try {
|
|
53
|
+
ipv4UdpChannel = await network.createUdpChannel({
|
|
54
|
+
lifetime,
|
|
55
|
+
type: "udp4",
|
|
56
|
+
netInterface,
|
|
57
|
+
listeningPort,
|
|
58
|
+
reuseAddress: true,
|
|
59
|
+
});
|
|
60
|
+
await ipv4UdpChannel.addMembership(broadcastAddressIpv4);
|
|
61
|
+
} catch (error) {
|
|
62
|
+
NoAddressAvailableError.accept(error);
|
|
63
|
+
logger.info(
|
|
64
|
+
`IPv4 UDP channel not created because IPv4 is not available: ${asError(error).message}`,
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
let ipv6UdpChannel;
|
|
37
70
|
try {
|
|
38
|
-
|
|
39
|
-
|
|
71
|
+
ipv6UdpChannel = await network.createUdpChannel({
|
|
72
|
+
lifetime,
|
|
73
|
+
type: "udp6",
|
|
40
74
|
netInterface,
|
|
41
75
|
listeningPort,
|
|
42
76
|
reuseAddress: true,
|
|
43
77
|
});
|
|
44
|
-
await
|
|
78
|
+
await ipv6UdpChannel.addMembership(broadcastAddressIpv6);
|
|
45
79
|
} catch (error) {
|
|
46
80
|
NoAddressAvailableError.accept(error);
|
|
47
|
-
logger.info(`
|
|
81
|
+
logger.info(`IPv6 UDP interface not created because IPv6 is not available, but required my Matter`);
|
|
82
|
+
throw error;
|
|
48
83
|
}
|
|
49
|
-
}
|
|
50
84
|
|
|
51
|
-
try {
|
|
52
|
-
const ipv6UdpChannel = await network.createUdpChannel({
|
|
53
|
-
type: "udp6",
|
|
54
|
-
netInterface,
|
|
55
|
-
listeningPort,
|
|
56
|
-
reuseAddress: true,
|
|
57
|
-
});
|
|
58
|
-
await ipv6UdpChannel.addMembership(broadcastAddressIpv6);
|
|
59
85
|
return new UdpMulticastServer(
|
|
86
|
+
lifetime,
|
|
60
87
|
network,
|
|
61
88
|
broadcastAddressIpv4,
|
|
62
89
|
broadcastAddressIpv6,
|
|
@@ -66,8 +93,7 @@ export class UdpMulticastServer {
|
|
|
66
93
|
netInterface,
|
|
67
94
|
);
|
|
68
95
|
} catch (error) {
|
|
69
|
-
|
|
70
|
-
logger.info(`IPv6 UDP interface not created because IPv6 is not available, but required my Matter.`);
|
|
96
|
+
lifetime[Symbol.dispose]();
|
|
71
97
|
throw error;
|
|
72
98
|
}
|
|
73
99
|
}
|
|
@@ -80,28 +106,38 @@ export class UdpMulticastServer {
|
|
|
80
106
|
);
|
|
81
107
|
|
|
82
108
|
private constructor(
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
109
|
+
lifetime: Lifetime,
|
|
110
|
+
network: Network,
|
|
111
|
+
broadcastAddressIpv4: string | undefined,
|
|
112
|
+
broadcastAddressIpv6: string,
|
|
113
|
+
broadcastPort: number,
|
|
114
|
+
serverIpv4: UdpChannel | undefined,
|
|
115
|
+
serverIpv6: UdpChannel,
|
|
116
|
+
netInterface: string | undefined,
|
|
117
|
+
) {
|
|
118
|
+
this.#lifetime = lifetime;
|
|
119
|
+
this.network = network;
|
|
120
|
+
this.#broadcastAddressIpv4 = broadcastAddressIpv4;
|
|
121
|
+
this.#broadcastAddressIpv6 = broadcastAddressIpv6;
|
|
122
|
+
this.#broadcastPort = broadcastPort;
|
|
123
|
+
this.#serverIpv4 = serverIpv4;
|
|
124
|
+
this.#serverIpv6 = serverIpv6;
|
|
125
|
+
this.netInterface = netInterface;
|
|
126
|
+
}
|
|
91
127
|
|
|
92
128
|
get supportsIpv4() {
|
|
93
|
-
return this
|
|
129
|
+
return this.#serverIpv4 !== undefined;
|
|
94
130
|
}
|
|
95
131
|
|
|
96
132
|
onMessage(listener: (message: Bytes, peerAddress: string, netInterface: string) => void) {
|
|
97
|
-
this
|
|
133
|
+
this.#serverIpv4?.onData((netInterface, peerAddress, _port, message) => {
|
|
98
134
|
if (netInterface === undefined) {
|
|
99
135
|
// Ignore Network packages not coming over any known interface
|
|
100
136
|
return;
|
|
101
137
|
}
|
|
102
138
|
listener(message, peerAddress, netInterface);
|
|
103
139
|
});
|
|
104
|
-
this
|
|
140
|
+
this.#serverIpv6.onData((netInterface, peerAddress, _port, message) => {
|
|
105
141
|
if (netInterface === undefined) {
|
|
106
142
|
// Ignore Network packages not coming over any known interface
|
|
107
143
|
return;
|
|
@@ -118,7 +154,7 @@ export class UdpMulticastServer {
|
|
|
118
154
|
try {
|
|
119
155
|
await (
|
|
120
156
|
await this.broadcastChannels.get(netInterface, isIPv4(uniCastTarget))
|
|
121
|
-
).send(uniCastTarget, this
|
|
157
|
+
).send(uniCastTarget, this.#broadcastPort, message);
|
|
122
158
|
} catch (error) {
|
|
123
159
|
logger.info(`${netInterface} ${uniCastTarget}: ${asError(error).message}`);
|
|
124
160
|
}
|
|
@@ -136,7 +172,7 @@ export class UdpMulticastServer {
|
|
|
136
172
|
await MatterAggregateError.allSettled(
|
|
137
173
|
ips.map(async ip => {
|
|
138
174
|
const iPv4 = ipV4.includes(ip);
|
|
139
|
-
const broadcastTarget = iPv4 ? this
|
|
175
|
+
const broadcastTarget = iPv4 ? this.#broadcastAddressIpv4 : this.#broadcastAddressIpv6;
|
|
140
176
|
if (broadcastTarget === undefined) {
|
|
141
177
|
// IPv4 but disabled, so just resolve
|
|
142
178
|
return;
|
|
@@ -144,7 +180,7 @@ export class UdpMulticastServer {
|
|
|
144
180
|
try {
|
|
145
181
|
await (
|
|
146
182
|
await this.broadcastChannels.get(netInterface, iPv4)
|
|
147
|
-
).send(broadcastTarget, this
|
|
183
|
+
).send(broadcastTarget, this.#broadcastPort, message);
|
|
148
184
|
} catch (error) {
|
|
149
185
|
logger.info(`${netInterface}: ${asError(error).message}`);
|
|
150
186
|
}
|
|
@@ -159,16 +195,18 @@ export class UdpMulticastServer {
|
|
|
159
195
|
|
|
160
196
|
private async createBroadcastChannel(netInterface: string, iPv4: string): Promise<UdpChannel> {
|
|
161
197
|
return await this.network.createUdpChannel({
|
|
198
|
+
lifetime: this.#lifetime,
|
|
162
199
|
type: iPv4 ? "udp4" : "udp6",
|
|
163
|
-
listeningPort: this
|
|
200
|
+
listeningPort: this.#broadcastPort,
|
|
164
201
|
netInterface,
|
|
165
202
|
reuseAddress: true,
|
|
166
203
|
});
|
|
167
204
|
}
|
|
168
205
|
|
|
169
206
|
async close() {
|
|
170
|
-
|
|
171
|
-
await this
|
|
207
|
+
using _closing = this.#lifetime.closing();
|
|
208
|
+
await this.#serverIpv4?.close();
|
|
209
|
+
await this.#serverIpv6.close();
|
|
172
210
|
await this.broadcastChannels.close();
|
|
173
211
|
}
|
|
174
212
|
}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2022-2025 Matter.js Authors
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { ImplementationError } from "#MatterError.js";
|
|
8
|
+
import { Boot } from "#util/Boot.js";
|
|
9
|
+
import { decamelize } from "#util/identifier-case.js";
|
|
10
|
+
import { Lifetime } from "#util/Lifetime.js";
|
|
11
|
+
import { Duration } from "./Duration.js";
|
|
12
|
+
import { Time, Timer } from "./Time.js";
|
|
13
|
+
import { Instant } from "./TimeUnit.js";
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* A {@link Timer} implementation that uses standard JavaScript timers.
|
|
17
|
+
*/
|
|
18
|
+
export class StandardTime extends Time {
|
|
19
|
+
override getTimer(name: string, duration: Duration, callback: Timer.Callback) {
|
|
20
|
+
return new StandardTimer(name, duration, callback, false);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
override getPeriodicTimer(name: string, duration: Duration, callback: Timer.Callback) {
|
|
24
|
+
return new StandardTimer(name, duration, callback, true);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* A {@link Timer} implementation that uses standard JavaScript functions.
|
|
30
|
+
*/
|
|
31
|
+
export class StandardTimer implements Timer {
|
|
32
|
+
#timerId: unknown;
|
|
33
|
+
#utility = false;
|
|
34
|
+
#interval = Instant; // Real value installed in constructor
|
|
35
|
+
isRunning = false;
|
|
36
|
+
|
|
37
|
+
get systemId() {
|
|
38
|
+
return Number(this.#timerId);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
constructor(
|
|
42
|
+
readonly name: string,
|
|
43
|
+
duration: Duration,
|
|
44
|
+
private readonly callback: Timer.Callback,
|
|
45
|
+
readonly isPeriodic: boolean,
|
|
46
|
+
) {
|
|
47
|
+
this.interval = duration;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* The timer's interval.
|
|
52
|
+
*
|
|
53
|
+
* You can change this value but changes have no effect until the timer restarts.
|
|
54
|
+
*/
|
|
55
|
+
set interval(interval: Duration) {
|
|
56
|
+
if (interval < 0 || interval > 2147483647) {
|
|
57
|
+
throw new ImplementationError(
|
|
58
|
+
`Invalid intervalMs: ${interval}. The value must be between 0 and 32-bit maximum value (2147483647)`,
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
this.#interval = interval;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
get interval() {
|
|
65
|
+
return this.#interval;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
get utility() {
|
|
69
|
+
return this.#utility;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
set utility(utility: boolean) {
|
|
73
|
+
if (utility === this.#utility) {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Support node.js-style environments to control whether the timer blocks process exit
|
|
78
|
+
if (this.#timerId !== undefined) {
|
|
79
|
+
const timerId = this.#timerId as { ref?: () => void; unref?: () => void };
|
|
80
|
+
if (utility) {
|
|
81
|
+
timerId.unref?.();
|
|
82
|
+
} else {
|
|
83
|
+
timerId.ref?.();
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
this.#utility = utility;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
start() {
|
|
91
|
+
if (this.isRunning) this.stop();
|
|
92
|
+
Time.register(this);
|
|
93
|
+
this.isRunning = true;
|
|
94
|
+
this.#timerId = (this.isPeriodic ? setInterval : setTimeout)(() => {
|
|
95
|
+
using lifetime = Lifetime(decamelize(this.name, " "));
|
|
96
|
+
if (!this.isPeriodic) {
|
|
97
|
+
Time.unregister(this);
|
|
98
|
+
this.isRunning = false;
|
|
99
|
+
}
|
|
100
|
+
this.callback(lifetime);
|
|
101
|
+
}, this.interval);
|
|
102
|
+
return this;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
stop() {
|
|
106
|
+
(this.isPeriodic ? clearInterval : clearTimeout)(this.#timerId as ReturnType<typeof setTimeout>);
|
|
107
|
+
Time.unregister(this);
|
|
108
|
+
this.isRunning = false;
|
|
109
|
+
return this;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
Boot.init(() => {
|
|
114
|
+
Time.default = new StandardTime();
|
|
115
|
+
|
|
116
|
+
Time.startup.systemMs = Time.startup.processMs = Time.nowMs;
|
|
117
|
+
|
|
118
|
+
// Hook for testing frameworks
|
|
119
|
+
if (typeof MatterHooks !== "undefined") {
|
|
120
|
+
MatterHooks?.timeSetup?.(Time);
|
|
121
|
+
}
|
|
122
|
+
});
|
package/src/time/Time.ts
CHANGED
|
@@ -4,13 +4,13 @@
|
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import {
|
|
7
|
+
import { DiagnosticPresentation } from "#log/DiagnosticPresentation.js";
|
|
8
|
+
import { NoProviderError } from "#MatterError.js";
|
|
8
9
|
import { CancelablePromise } from "#util/Cancelable.js";
|
|
9
|
-
import {
|
|
10
|
+
import type { Lifetime } from "#util/Lifetime.js";
|
|
10
11
|
import { Diagnostic } from "../log/Diagnostic.js";
|
|
11
12
|
import { DiagnosticSource } from "../log/DiagnosticSource.js";
|
|
12
13
|
import { Duration } from "./Duration.js";
|
|
13
|
-
import { Instant } from "./TimeUnit.js";
|
|
14
14
|
import type { Timestamp } from "./Timestamp.js";
|
|
15
15
|
|
|
16
16
|
const registry = new Set<Timer>();
|
|
@@ -53,8 +53,8 @@ export class Time {
|
|
|
53
53
|
/**
|
|
54
54
|
* Create a timer that will call callback after durationMs has passed.
|
|
55
55
|
*/
|
|
56
|
-
getTimer(
|
|
57
|
-
|
|
56
|
+
getTimer(_name: string, _duration: Duration, _callback: Timer.Callback): Timer {
|
|
57
|
+
throw new NoProviderError();
|
|
58
58
|
}
|
|
59
59
|
static readonly getTimer = (name: string, duration: Duration, callback: Timer.Callback): Timer =>
|
|
60
60
|
Time.default.getTimer(name, duration, callback);
|
|
@@ -62,8 +62,8 @@ export class Time {
|
|
|
62
62
|
/**
|
|
63
63
|
* Create a timer that will periodically call callback at intervalMs intervals.
|
|
64
64
|
*/
|
|
65
|
-
getPeriodicTimer(
|
|
66
|
-
|
|
65
|
+
getPeriodicTimer(_name: string, _duration: Duration, _callback: Timer.Callback): Timer {
|
|
66
|
+
throw new NoProviderError();
|
|
67
67
|
}
|
|
68
68
|
static readonly getPeriodicTimer = (name: string, duration: Duration, callback: Timer.Callback): Timer =>
|
|
69
69
|
Time.default.getPeriodicTimer(name, duration, callback);
|
|
@@ -77,7 +77,7 @@ export class Time {
|
|
|
77
77
|
return new CancelablePromise(
|
|
78
78
|
resolve => {
|
|
79
79
|
resolver = resolve;
|
|
80
|
-
timer = Time.getTimer(name, duration, resolve);
|
|
80
|
+
timer = Time.getTimer(name, duration, () => resolve());
|
|
81
81
|
timer.start();
|
|
82
82
|
},
|
|
83
83
|
|
|
@@ -144,113 +144,21 @@ export interface Timer {
|
|
|
144
144
|
}
|
|
145
145
|
|
|
146
146
|
export namespace Timer {
|
|
147
|
-
export type Callback = () => any;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
export class StandardTimer implements Timer {
|
|
151
|
-
#timerId: unknown;
|
|
152
|
-
#utility = false;
|
|
153
|
-
#interval = Instant; // Real value installed in constructor
|
|
154
|
-
isRunning = false;
|
|
155
|
-
|
|
156
|
-
get systemId() {
|
|
157
|
-
return Number(this.#timerId);
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
constructor(
|
|
161
|
-
readonly name: string,
|
|
162
|
-
duration: Duration,
|
|
163
|
-
private readonly callback: Timer.Callback,
|
|
164
|
-
readonly isPeriodic: boolean,
|
|
165
|
-
) {
|
|
166
|
-
this.interval = duration;
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
/**
|
|
170
|
-
* The timer's interval.
|
|
171
|
-
*
|
|
172
|
-
* You can change this value but changes have no effect until the timer restarts.
|
|
173
|
-
*/
|
|
174
|
-
set interval(interval: Duration) {
|
|
175
|
-
if (interval < 0 || interval > 2147483647) {
|
|
176
|
-
throw new ImplementationError(
|
|
177
|
-
`Invalid intervalMs: ${interval}. The value must be between 0 and 32-bit maximum value (2147483647)`,
|
|
178
|
-
);
|
|
179
|
-
}
|
|
180
|
-
this.#interval = interval;
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
get interval() {
|
|
184
|
-
return this.#interval;
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
get utility() {
|
|
188
|
-
return this.#utility;
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
set utility(utility: boolean) {
|
|
192
|
-
if (utility === this.#utility) {
|
|
193
|
-
return;
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
// Support node.js-style environments to control whether the timer blocks process exit
|
|
197
|
-
if (this.#timerId !== undefined) {
|
|
198
|
-
const timerId = this.#timerId as { ref?: () => void; unref?: () => void };
|
|
199
|
-
if (utility) {
|
|
200
|
-
timerId.unref?.();
|
|
201
|
-
} else {
|
|
202
|
-
timerId.ref?.();
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
this.#utility = utility;
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
start() {
|
|
210
|
-
if (this.isRunning) this.stop();
|
|
211
|
-
Time.register(this);
|
|
212
|
-
this.isRunning = true;
|
|
213
|
-
this.#timerId = (this.isPeriodic ? setInterval : setTimeout)(() => {
|
|
214
|
-
if (!this.isPeriodic) {
|
|
215
|
-
Time.unregister(this);
|
|
216
|
-
this.isRunning = false;
|
|
217
|
-
}
|
|
218
|
-
this.callback();
|
|
219
|
-
}, this.interval);
|
|
220
|
-
return this;
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
stop() {
|
|
224
|
-
(this.isPeriodic ? clearInterval : clearTimeout)(this.#timerId as ReturnType<typeof setTimeout>);
|
|
225
|
-
Time.unregister(this);
|
|
226
|
-
this.isRunning = false;
|
|
227
|
-
return this;
|
|
228
|
-
}
|
|
147
|
+
export type Callback = (lifetime: Lifetime) => any;
|
|
229
148
|
}
|
|
230
149
|
|
|
231
150
|
DiagnosticSource.add({
|
|
232
|
-
get [
|
|
151
|
+
get [DiagnosticPresentation.value]() {
|
|
233
152
|
return Diagnostic.node("⏱", "Timers", {
|
|
234
153
|
children: [...registry].map(timer => [
|
|
235
154
|
timer.name,
|
|
236
155
|
Diagnostic.dict({
|
|
237
156
|
periodic: timer.isPeriodic,
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
157
|
+
up: timer.elapsed,
|
|
158
|
+
interval: Duration.format(timer.interval),
|
|
159
|
+
"system#": timer.systemId,
|
|
241
160
|
}),
|
|
242
161
|
]),
|
|
243
162
|
});
|
|
244
163
|
},
|
|
245
164
|
});
|
|
246
|
-
|
|
247
|
-
Boot.init(() => {
|
|
248
|
-
Time.default = new Time();
|
|
249
|
-
|
|
250
|
-
Time.startup.systemMs = Time.startup.processMs = Time.nowMs;
|
|
251
|
-
|
|
252
|
-
// Hook for testing frameworks
|
|
253
|
-
if (typeof MatterHooks !== "undefined") {
|
|
254
|
-
MatterHooks?.timeSetup?.(Time);
|
|
255
|
-
}
|
|
256
|
-
});
|
package/src/time/Timestamp.ts
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
import { UnexpectedDataError } from "#MatterError.js";
|
|
8
8
|
import { Branded } from "#util/Type.js";
|
|
9
|
+
import type { Duration } from "./Duration.js";
|
|
9
10
|
import { Time } from "./Time.js";
|
|
10
11
|
|
|
11
12
|
/**
|
|
@@ -91,4 +92,11 @@ export namespace Timestamp {
|
|
|
91
92
|
export function dateOf(timestamp: Timestamp) {
|
|
92
93
|
return new Date(timestamp);
|
|
93
94
|
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Compute the duration between two timestamps.
|
|
98
|
+
*/
|
|
99
|
+
export function delta(from: Timestamp, to: Timestamp) {
|
|
100
|
+
return (to - from) as Duration;
|
|
101
|
+
}
|
|
94
102
|
}
|
package/src/time/index.ts
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
+
import { Lifetime } from "#util/Lifetime.js";
|
|
7
8
|
import { MaybePromise } from "#util/Promises.js";
|
|
8
9
|
import { Participant } from "./Participant.js";
|
|
9
10
|
import { Resource } from "./Resource.js";
|
|
@@ -27,7 +28,7 @@ import { open } from "./Tx.js";
|
|
|
27
28
|
*
|
|
28
29
|
* TODO - does prevent deadlock but we should probably add a timeout for resource locking
|
|
29
30
|
*/
|
|
30
|
-
export interface Transaction {
|
|
31
|
+
export interface Transaction extends Lifetime.Owner {
|
|
31
32
|
/**
|
|
32
33
|
* Diagnostic description of the transaction's source.
|
|
33
34
|
*/
|
|
@@ -144,6 +145,14 @@ export interface Transaction {
|
|
|
144
145
|
*/
|
|
145
146
|
rollback(): MaybePromise;
|
|
146
147
|
|
|
148
|
+
/**
|
|
149
|
+
* Destroy the transaction without proper commit or rollback.
|
|
150
|
+
*
|
|
151
|
+
* This guarantees a synchronous resolution but will result in an error if {@link Transaction#status} is not shared,
|
|
152
|
+
* read-only or destroyed.
|
|
153
|
+
*/
|
|
154
|
+
[Symbol.dispose](): void;
|
|
155
|
+
|
|
147
156
|
/**
|
|
148
157
|
* Wait for a set of transactions to complete.
|
|
149
158
|
*
|
|
@@ -168,8 +177,12 @@ export const Transaction = {
|
|
|
168
177
|
* The transaction is destroyed when {@link act} returns. You will receive an error if you access it after it is
|
|
169
178
|
* destroyed.
|
|
170
179
|
*/
|
|
171
|
-
act<T>(
|
|
172
|
-
|
|
180
|
+
act<T>(
|
|
181
|
+
via: string,
|
|
182
|
+
lifetime: Lifetime.Owner,
|
|
183
|
+
actor: (transaction: Transaction) => MaybePromise<T>,
|
|
184
|
+
): MaybePromise<T> {
|
|
185
|
+
const tx = open(via, lifetime);
|
|
173
186
|
|
|
174
187
|
let result;
|
|
175
188
|
try {
|
|
@@ -188,9 +201,9 @@ export const Transaction = {
|
|
|
188
201
|
*
|
|
189
202
|
* When closed the transaction commits automatically if exclusive.
|
|
190
203
|
*/
|
|
191
|
-
open(via: string, isolation: Transaction.IsolationLevel = "rw") {
|
|
204
|
+
open(via: string, lifetime: Lifetime.Owner, isolation: Transaction.IsolationLevel = "rw") {
|
|
192
205
|
// This function is replaced below so do not edit
|
|
193
|
-
return open(via, isolation);
|
|
206
|
+
return open(via, lifetime, isolation);
|
|
194
207
|
},
|
|
195
208
|
|
|
196
209
|
Status,
|
|
@@ -218,7 +231,7 @@ export namespace Transaction {
|
|
|
218
231
|
|
|
219
232
|
export interface Finalization {
|
|
220
233
|
/**
|
|
221
|
-
* Finish the transaction. If {@link result} is a promise this may result
|
|
234
|
+
* Finish the transaction. If {@link result} is a promise this may result in commit or rollback.
|
|
222
235
|
*/
|
|
223
236
|
resolve<T>(result: T): MaybePromise<Awaited<T>>;
|
|
224
237
|
|
package/src/transaction/Tx.ts
CHANGED
|
@@ -11,6 +11,7 @@ import { Time, Timer } from "#time/Time.js";
|
|
|
11
11
|
import { Timestamp } from "#time/Timestamp.js";
|
|
12
12
|
import { Millis } from "#time/TimeUnit.js";
|
|
13
13
|
import { asError } from "#util/Error.js";
|
|
14
|
+
import { Lifetime } from "#util/Lifetime.js";
|
|
14
15
|
import { Observable } from "#util/Observable.js";
|
|
15
16
|
import { MaybePromise } from "#util/Promises.js";
|
|
16
17
|
import { describeList } from "#util/String.js";
|
|
@@ -34,9 +35,10 @@ const MAX_CHAINED_COMMITS = 5;
|
|
|
34
35
|
*/
|
|
35
36
|
export function open(
|
|
36
37
|
via: string,
|
|
38
|
+
lifetime: Lifetime.Owner,
|
|
37
39
|
isolation: Transaction.IsolationLevel = "rw",
|
|
38
40
|
): Transaction & Transaction.Finalization {
|
|
39
|
-
return new Tx(via, isolation);
|
|
41
|
+
return new Tx(via, lifetime, isolation);
|
|
40
42
|
}
|
|
41
43
|
|
|
42
44
|
/**
|
|
@@ -50,14 +52,35 @@ class Tx implements Transaction, Transaction.Finalization {
|
|
|
50
52
|
#status;
|
|
51
53
|
#waitingOn?: Iterable<Transaction>;
|
|
52
54
|
#via: string;
|
|
55
|
+
#lifetime: Lifetime;
|
|
53
56
|
#shared?: Observable<[]>;
|
|
54
57
|
#closed?: Observable<[]>;
|
|
55
58
|
#isAsync = false;
|
|
56
59
|
#reportingLocks = false;
|
|
57
60
|
|
|
58
|
-
constructor(via: string, isolation: Transaction.IsolationLevel) {
|
|
61
|
+
constructor(via: string, lifetime: Lifetime.Owner, isolation: Transaction.IsolationLevel) {
|
|
59
62
|
this.#via = Diagnostic.via(via);
|
|
63
|
+
|
|
64
|
+
this.#lifetime = lifetime.join("tx", via);
|
|
65
|
+
Object.defineProperties(this.#lifetime.details, {
|
|
66
|
+
status: {
|
|
67
|
+
get: () => this.#status,
|
|
68
|
+
enumerable: true,
|
|
69
|
+
},
|
|
70
|
+
|
|
71
|
+
resources: {
|
|
72
|
+
get: () => {
|
|
73
|
+
if (!this.#resources.size) {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return [...this.#resources].join("+");
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
});
|
|
81
|
+
|
|
60
82
|
this.#isolation = isolation;
|
|
83
|
+
|
|
61
84
|
if (isolation === "rw") {
|
|
62
85
|
this.#status = Status.Shared;
|
|
63
86
|
} else {
|
|
@@ -66,6 +89,18 @@ class Tx implements Transaction, Transaction.Finalization {
|
|
|
66
89
|
}
|
|
67
90
|
|
|
68
91
|
[Symbol.dispose]() {
|
|
92
|
+
switch (this.status) {
|
|
93
|
+
case Status.ReadOnly:
|
|
94
|
+
case Status.Shared:
|
|
95
|
+
case Status.Destroyed:
|
|
96
|
+
break;
|
|
97
|
+
|
|
98
|
+
default:
|
|
99
|
+
logger.error(this.via, "Disposed", this.via, "while", this.status);
|
|
100
|
+
break;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
using _closing = this.#lifetime.closing();
|
|
69
104
|
this.#reset("dropped");
|
|
70
105
|
this.#status = Status.Destroyed;
|
|
71
106
|
this.#closed?.emit();
|
|
@@ -253,6 +288,8 @@ class Tx implements Transaction, Transaction.Finalization {
|
|
|
253
288
|
}
|
|
254
289
|
|
|
255
290
|
resolve<T>(result: T): MaybePromise<Awaited<T>> {
|
|
291
|
+
this.#lifetime.closing();
|
|
292
|
+
|
|
256
293
|
// If result is a promise, we wait for resolution and then commit (success) or roll back (error)
|
|
257
294
|
if (MaybePromise.is(result)) {
|
|
258
295
|
this.isAsync = true;
|
|
@@ -292,6 +329,8 @@ class Tx implements Transaction, Transaction.Finalization {
|
|
|
292
329
|
}
|
|
293
330
|
|
|
294
331
|
reject(cause: unknown): MaybePromise<never> {
|
|
332
|
+
this.#lifetime.closing();
|
|
333
|
+
|
|
295
334
|
if (this.#status === Status.Shared) {
|
|
296
335
|
try {
|
|
297
336
|
this.#reset("released");
|
|
@@ -331,6 +370,14 @@ class Tx implements Transaction, Transaction.Finalization {
|
|
|
331
370
|
throw cause;
|
|
332
371
|
}
|
|
333
372
|
|
|
373
|
+
join(...name: unknown[]) {
|
|
374
|
+
if (this.#isolation === "ro") {
|
|
375
|
+
throw new ReadOnlyError();
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
return this.#lifetime.join(...name);
|
|
379
|
+
}
|
|
380
|
+
|
|
334
381
|
/**
|
|
335
382
|
* Execute commit logic for a single commit cycle.
|
|
336
383
|
*
|