zwave-js 8.7.7 → 8.8.1
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/build/CommandClass.js +1 -0
- package/build/CommandClass.js.map +1 -1
- package/build/Controller.d.ts +1 -0
- package/build/Controller.d.ts.map +1 -1
- package/build/Controller.js +4 -1
- package/build/Controller.js.map +1 -1
- package/build/Node.d.ts +1 -1
- package/build/Node.d.ts.map +1 -1
- package/build/Node.js.map +1 -1
- package/build/Utils.d.ts +1 -0
- package/build/Utils.d.ts.map +1 -1
- package/build/Utils.js +7 -1
- package/build/Utils.js.map +1 -1
- package/build/lib/commandclass/API.d.ts +15 -3
- package/build/lib/commandclass/API.d.ts.map +1 -1
- package/build/lib/commandclass/API.js +50 -0
- package/build/lib/commandclass/API.js.map +1 -1
- package/build/lib/commandclass/CommandClass.d.ts +0 -6
- package/build/lib/commandclass/CommandClass.d.ts.map +1 -1
- package/build/lib/commandclass/CommandClass.js +0 -12
- package/build/lib/commandclass/CommandClass.js.map +1 -1
- package/build/lib/commandclass/Security2CC.d.ts +1 -10
- package/build/lib/commandclass/Security2CC.d.ts.map +1 -1
- package/build/lib/commandclass/Security2CC.js +16 -48
- package/build/lib/commandclass/Security2CC.js.map +1 -1
- package/build/lib/commandclass/SecurityCC.d.ts +2 -9
- package/build/lib/commandclass/SecurityCC.d.ts.map +1 -1
- package/build/lib/commandclass/SecurityCC.js +9 -53
- package/build/lib/commandclass/SecurityCC.js.map +1 -1
- package/build/lib/commandclass/WakeUpCC.d.ts.map +1 -1
- package/build/lib/commandclass/WakeUpCC.js +1 -0
- package/build/lib/commandclass/WakeUpCC.js.map +1 -1
- package/build/lib/controller/BridgeApplicationCommandRequest.d.ts +2 -6
- package/build/lib/controller/BridgeApplicationCommandRequest.d.ts.map +1 -1
- package/build/lib/controller/BridgeApplicationCommandRequest.js +9 -19
- package/build/lib/controller/BridgeApplicationCommandRequest.js.map +1 -1
- package/build/lib/controller/Controller.d.ts +12 -2
- package/build/lib/controller/Controller.d.ts.map +1 -1
- package/build/lib/controller/Controller.js +14 -6
- package/build/lib/controller/Controller.js.map +1 -1
- package/build/lib/controller/Inclusion.d.ts +1 -1
- package/build/lib/controller/SendDataBridgeMessages.d.ts +5 -3
- package/build/lib/controller/SendDataBridgeMessages.d.ts.map +1 -1
- package/build/lib/controller/SendDataBridgeMessages.js +21 -8
- package/build/lib/controller/SendDataBridgeMessages.js.map +1 -1
- package/build/lib/controller/SendDataMessages.d.ts +5 -3
- package/build/lib/controller/SendDataMessages.d.ts.map +1 -1
- package/build/lib/controller/SendDataMessages.js +21 -9
- package/build/lib/controller/SendDataMessages.js.map +1 -1
- package/build/lib/controller/SendDataShared.d.ts +72 -2
- package/build/lib/controller/SendDataShared.d.ts.map +1 -1
- package/build/lib/controller/SendDataShared.js +195 -1
- package/build/lib/controller/SendDataShared.js.map +1 -1
- package/build/lib/driver/CommandQueueMachine.d.ts +7 -3
- package/build/lib/driver/CommandQueueMachine.d.ts.map +1 -1
- package/build/lib/driver/CommandQueueMachine.js +66 -29
- package/build/lib/driver/CommandQueueMachine.js.map +1 -1
- package/build/lib/driver/Driver.d.ts +16 -12
- package/build/lib/driver/Driver.d.ts.map +1 -1
- package/build/lib/driver/Driver.js +178 -163
- package/build/lib/driver/Driver.js.map +1 -1
- package/build/lib/driver/MessageGenerators.d.ts +26 -0
- package/build/lib/driver/MessageGenerators.d.ts.map +1 -0
- package/build/lib/driver/MessageGenerators.js +242 -0
- package/build/lib/driver/MessageGenerators.js.map +1 -0
- package/build/lib/driver/SendThreadMachine.d.ts +24 -53
- package/build/lib/driver/SendThreadMachine.d.ts.map +1 -1
- package/build/lib/driver/SendThreadMachine.js +160 -618
- package/build/lib/driver/SendThreadMachine.js.map +1 -1
- package/build/lib/driver/StateMachineShared.d.ts +2 -0
- package/build/lib/driver/StateMachineShared.d.ts.map +1 -1
- package/build/lib/driver/StateMachineShared.js +21 -10
- package/build/lib/driver/StateMachineShared.js.map +1 -1
- package/build/lib/driver/Transaction.d.ts +35 -3
- package/build/lib/driver/Transaction.d.ts.map +1 -1
- package/build/lib/driver/Transaction.js +20 -15
- package/build/lib/driver/Transaction.js.map +1 -1
- package/build/lib/driver/TransactionMachine.d.ts +30 -0
- package/build/lib/driver/TransactionMachine.d.ts.map +1 -0
- package/build/lib/driver/TransactionMachine.js +247 -0
- package/build/lib/driver/TransactionMachine.js.map +1 -0
- package/build/lib/driver/ZWaveOptions.d.ts +0 -2
- package/build/lib/driver/ZWaveOptions.d.ts.map +1 -1
- package/build/lib/message/Constants.d.ts +8 -9
- package/build/lib/message/Constants.d.ts.map +1 -1
- package/build/lib/message/Constants.js +9 -12
- package/build/lib/message/Constants.js.map +1 -1
- package/build/lib/message/Message.d.ts +5 -1
- package/build/lib/message/Message.d.ts.map +1 -1
- package/build/lib/message/Message.js +11 -0
- package/build/lib/message/Message.js.map +1 -1
- package/build/lib/node/HealthCheck.d.ts +8 -0
- package/build/lib/node/HealthCheck.d.ts.map +1 -0
- package/build/lib/node/HealthCheck.js +83 -0
- package/build/lib/node/HealthCheck.js.map +1 -0
- package/build/lib/node/Node.d.ts +11 -3
- package/build/lib/node/Node.d.ts.map +1 -1
- package/build/lib/node/Node.js +305 -21
- package/build/lib/node/Node.js.map +1 -1
- package/build/lib/node/Types.d.ts +133 -2
- package/build/lib/node/Types.d.ts.map +1 -1
- package/build/lib/node/Types.js.map +1 -1
- package/build/lib/serialapi/misc/GetBackgroundRSSIMessages.d.ts +14 -0
- package/build/lib/serialapi/misc/GetBackgroundRSSIMessages.d.ts.map +1 -0
- package/build/lib/serialapi/misc/GetBackgroundRSSIMessages.js +46 -0
- package/build/lib/serialapi/misc/GetBackgroundRSSIMessages.js.map +1 -0
- package/package.json +14 -14
|
@@ -5,71 +5,25 @@ const core_1 = require("@zwave-js/core");
|
|
|
5
5
|
const sorted_list_1 = require("alcalzone-shared/sorted-list");
|
|
6
6
|
const xstate_1 = require("xstate");
|
|
7
7
|
const actions_1 = require("xstate/lib/actions");
|
|
8
|
-
const ICommandClassContainer_1 = require("../commandclass/ICommandClassContainer");
|
|
9
8
|
const NoOperationCC_1 = require("../commandclass/NoOperationCC");
|
|
10
|
-
const ApplicationCommandRequest_1 = require("../controller/ApplicationCommandRequest");
|
|
11
|
-
const BridgeApplicationCommandRequest_1 = require("../controller/BridgeApplicationCommandRequest");
|
|
12
|
-
const SendDataBridgeMessages_1 = require("../controller/SendDataBridgeMessages");
|
|
13
|
-
const SendDataMessages_1 = require("../controller/SendDataMessages");
|
|
14
|
-
const SendDataShared_1 = require("../controller/SendDataShared");
|
|
15
9
|
const Constants_1 = require("../message/Constants");
|
|
16
10
|
const Types_1 = require("../node/Types");
|
|
17
11
|
const CommandQueueMachine_1 = require("./CommandQueueMachine");
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
}));
|
|
33
|
-
const deleteHandshakeTransaction = (0, xstate_1.assign)((ctx) => ({
|
|
34
|
-
...ctx,
|
|
35
|
-
handshakeTransaction: undefined,
|
|
36
|
-
}));
|
|
37
|
-
const resetSendDataAttempts = (0, xstate_1.assign)({
|
|
38
|
-
sendDataAttempts: (_) => 0,
|
|
39
|
-
});
|
|
40
|
-
const incrementSendDataAttempts = (0, xstate_1.assign)({
|
|
41
|
-
sendDataAttempts: (ctx) => ctx.sendDataAttempts + 1,
|
|
42
|
-
});
|
|
12
|
+
const TransactionMachine_1 = require("./TransactionMachine");
|
|
13
|
+
const finalizeTransaction = (0, actions_1.pure)((ctx, evt) => [
|
|
14
|
+
(0, actions_1.stop)(evt.id),
|
|
15
|
+
(0, xstate_1.assign)((ctx) => {
|
|
16
|
+
var _a;
|
|
17
|
+
// Pause the send thread if necessary
|
|
18
|
+
const transaction = (_a = ctx.activeTransactions.get(evt.id)) === null || _a === void 0 ? void 0 : _a.transaction;
|
|
19
|
+
if (transaction === null || transaction === void 0 ? void 0 : transaction.pauseSendThread)
|
|
20
|
+
ctx.paused = true;
|
|
21
|
+
// Remove the last reference to the actor
|
|
22
|
+
ctx.activeTransactions.delete(evt.id);
|
|
23
|
+
return ctx;
|
|
24
|
+
}),
|
|
25
|
+
]);
|
|
43
26
|
const forwardToCommandQueue = (0, xstate_1.forwardTo)((ctx) => ctx.commandQueue);
|
|
44
|
-
const currentTransactionIsSendData = (ctx) => { var _a; return (0, SendDataShared_1.isSendData)((_a = ctx.currentTransaction) === null || _a === void 0 ? void 0 : _a.message); };
|
|
45
|
-
const forwardNodeUpdate = (0, actions_1.pure)((ctx, evt) => {
|
|
46
|
-
return (0, actions_1.raise)({
|
|
47
|
-
type: "nodeUpdate",
|
|
48
|
-
result: evt.message,
|
|
49
|
-
});
|
|
50
|
-
});
|
|
51
|
-
const forwardHandshakeResponse = (0, actions_1.pure)((ctx, evt) => {
|
|
52
|
-
return (0, actions_1.raise)({
|
|
53
|
-
type: "handshakeResponse",
|
|
54
|
-
result: evt.message,
|
|
55
|
-
});
|
|
56
|
-
});
|
|
57
|
-
const forwardActiveCommandSuccess = (0, actions_1.pure)((ctx, evt) => {
|
|
58
|
-
return (0, actions_1.raise)({ ...evt, type: "active_command_success" });
|
|
59
|
-
});
|
|
60
|
-
const forwardActiveCommandFailure = (0, actions_1.pure)((ctx, evt) => {
|
|
61
|
-
return (0, actions_1.raise)({ ...evt, type: "active_command_failure" });
|
|
62
|
-
});
|
|
63
|
-
const forwardActiveCommandError = (0, actions_1.pure)((ctx, evt) => {
|
|
64
|
-
return (0, actions_1.raise)({ ...evt, type: "active_command_error" });
|
|
65
|
-
});
|
|
66
|
-
const sendCurrentTransactionToCommandQueue = (0, actions_1.send)((ctx) => ({
|
|
67
|
-
type: "add",
|
|
68
|
-
transaction: ctx.currentTransaction,
|
|
69
|
-
}), { to: (ctx) => ctx.commandQueue });
|
|
70
|
-
const resetCommandQueue = (0, actions_1.send)("reset", {
|
|
71
|
-
to: (ctx) => ctx.commandQueue,
|
|
72
|
-
});
|
|
73
27
|
const sortQueue = (0, xstate_1.assign)({
|
|
74
28
|
queue: (ctx) => {
|
|
75
29
|
const queue = ctx.queue;
|
|
@@ -80,12 +34,8 @@ const sortQueue = (0, xstate_1.assign)({
|
|
|
80
34
|
return queue;
|
|
81
35
|
},
|
|
82
36
|
});
|
|
83
|
-
const every = (...guards) => ({
|
|
84
|
-
type: "every",
|
|
85
|
-
guards,
|
|
86
|
-
});
|
|
87
37
|
const guards = {
|
|
88
|
-
|
|
38
|
+
mayStartTransaction: (ctx, evt, meta) => {
|
|
89
39
|
// We may not send anything if the send thread is paused
|
|
90
40
|
if (ctx.paused)
|
|
91
41
|
return false;
|
|
@@ -102,243 +52,96 @@ const guards = {
|
|
|
102
52
|
// If we don't send them, they block the send queue
|
|
103
53
|
// 3. Nodes that can sleep but do not support wakeup: https://github.com/zwave-js/node-zwave-js/discussions/1537
|
|
104
54
|
// We need to try and send messages to them even if they are asleep, because we might never hear from them
|
|
55
|
+
// 3.
|
|
56
|
+
if (nextTransaction.priority === Constants_1.MessagePriority.Handshake)
|
|
57
|
+
return true;
|
|
58
|
+
// We may not start any non-handshake transaction while the queue is busy
|
|
59
|
+
if (meta.state.matches("busy"))
|
|
60
|
+
return false;
|
|
61
|
+
// 1./2.
|
|
105
62
|
return (!targetNode ||
|
|
106
63
|
targetNode.status !== Types_1.NodeStatus.Asleep ||
|
|
107
64
|
(!targetNode.supportsCC(core_1.CommandClasses["Wake Up"]) &&
|
|
108
65
|
targetNode.interviewStage >= Types_1.InterviewStage.NodeInfo) ||
|
|
109
|
-
(0, NoOperationCC_1.messageIsPing)(message)
|
|
110
|
-
nextTransaction.priority === Constants_1.MessagePriority.Handshake);
|
|
111
|
-
},
|
|
112
|
-
requiresNoHandshake: (ctx) => {
|
|
113
|
-
var _a;
|
|
114
|
-
const msg = (_a = ctx.currentTransaction) === null || _a === void 0 ? void 0 : _a.message;
|
|
115
|
-
if (msg instanceof SendDataMessages_1.SendDataRequest ||
|
|
116
|
-
msg instanceof SendDataBridgeMessages_1.SendDataBridgeRequest) {
|
|
117
|
-
return !msg.command.requiresPreTransmitHandshake();
|
|
118
|
-
}
|
|
119
|
-
return true;
|
|
120
|
-
},
|
|
121
|
-
isForActiveTransaction: (ctx, evt, meta) => {
|
|
122
|
-
return (((meta.state.matches("sending.handshake") ||
|
|
123
|
-
!!ctx.handshakeTransaction) &&
|
|
124
|
-
evt.transaction === ctx.handshakeTransaction) ||
|
|
125
|
-
((meta.state.matches("sending.execute") ||
|
|
126
|
-
meta.state.matches("sending.waitForUpdate") ||
|
|
127
|
-
!!ctx.currentTransaction) &&
|
|
128
|
-
evt.transaction === ctx.currentTransaction));
|
|
129
|
-
},
|
|
130
|
-
expectsNodeUpdate: (ctx) => {
|
|
131
|
-
var _a;
|
|
132
|
-
const msg = (_a = ctx.currentTransaction) === null || _a === void 0 ? void 0 : _a.message;
|
|
133
|
-
if (msg instanceof SendDataMessages_1.SendDataRequest ||
|
|
134
|
-
msg instanceof SendDataBridgeMessages_1.SendDataBridgeRequest) {
|
|
135
|
-
return msg.command.expectsCCResponse();
|
|
136
|
-
}
|
|
137
|
-
return false;
|
|
138
|
-
},
|
|
139
|
-
isExpectedUpdate: (ctx, evt, meta) => {
|
|
140
|
-
if (!meta.state.matches("sending.waitForUpdate"))
|
|
141
|
-
return false;
|
|
142
|
-
const sentMsg = ctx.currentTransaction.message;
|
|
143
|
-
const receivedMsg = evt.message;
|
|
144
|
-
return ((receivedMsg instanceof ApplicationCommandRequest_1.ApplicationCommandRequest ||
|
|
145
|
-
receivedMsg instanceof BridgeApplicationCommandRequest_1.BridgeApplicationCommandRequest) &&
|
|
146
|
-
sentMsg.command.isExpectedCCResponse(receivedMsg.command));
|
|
147
|
-
},
|
|
148
|
-
currentTransactionIsSendData,
|
|
149
|
-
mayRetry: (ctx, evt) => {
|
|
150
|
-
const msg = ctx.currentTransaction.message;
|
|
151
|
-
if (!(0, SendDataShared_1.isSendData)(msg))
|
|
152
|
-
return false;
|
|
153
|
-
if (msg instanceof SendDataMessages_1.SendDataMulticastRequest ||
|
|
154
|
-
msg instanceof SendDataBridgeMessages_1.SendDataMulticastBridgeRequest) {
|
|
155
|
-
// Don't try to resend multicast messages if they were already transmitted.
|
|
156
|
-
// One or more nodes might have already reacted
|
|
157
|
-
if (evt.reason === "callback NOK") {
|
|
158
|
-
return false;
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
return msg.maxSendAttempts > ctx.sendDataAttempts;
|
|
162
|
-
},
|
|
163
|
-
/** Whether the message is an outgoing pre-transmit handshake */
|
|
164
|
-
isPreTransmitHandshakeForCurrentTransaction: (ctx, evt, meta) => {
|
|
165
|
-
if (!meta.state.matches("sending.handshake"))
|
|
166
|
-
return false;
|
|
167
|
-
// Ensure that the current transaction is SendData
|
|
168
|
-
if (!currentTransactionIsSendData(ctx))
|
|
169
|
-
return false;
|
|
170
|
-
const transaction = evt.transaction;
|
|
171
|
-
if (transaction.priority !== Constants_1.MessagePriority.PreTransmitHandshake)
|
|
172
|
-
return false;
|
|
173
|
-
if (transaction.message instanceof SendDataMessages_1.SendDataRequest ||
|
|
174
|
-
transaction.message instanceof SendDataBridgeMessages_1.SendDataBridgeRequest) {
|
|
175
|
-
// require the handshake to be for the same node
|
|
176
|
-
return (transaction.message.command.nodeId ===
|
|
177
|
-
ctx.currentTransaction.message.command.nodeId);
|
|
178
|
-
}
|
|
179
|
-
return false;
|
|
180
|
-
},
|
|
181
|
-
isExpectedHandshakeResponse: (ctx, evt, meta) => {
|
|
182
|
-
if (!ctx.handshakeTransaction)
|
|
183
|
-
return false;
|
|
184
|
-
if (!meta.state.matches("sending.handshake.waitForHandshakeResponse"))
|
|
185
|
-
return false;
|
|
186
|
-
const sentMsg = ctx.handshakeTransaction.message;
|
|
187
|
-
const receivedMsg = evt.message;
|
|
188
|
-
if (!(0, ICommandClassContainer_1.isCommandClassContainer)(receivedMsg))
|
|
189
|
-
return false;
|
|
190
|
-
return ((receivedMsg instanceof ApplicationCommandRequest_1.ApplicationCommandRequest ||
|
|
191
|
-
receivedMsg instanceof BridgeApplicationCommandRequest_1.BridgeApplicationCommandRequest) &&
|
|
192
|
-
sentMsg.command.isExpectedCCResponse(receivedMsg.command));
|
|
193
|
-
},
|
|
194
|
-
/** Whether the message is an outgoing handshake response to the current node*/
|
|
195
|
-
isHandshakeForCurrentTransaction: (ctx, evt) => {
|
|
196
|
-
// First ensure that the current transaction is SendData
|
|
197
|
-
if (!currentTransactionIsSendData(ctx))
|
|
198
|
-
return false;
|
|
199
|
-
// Then ensure that the event transaction is also SendData
|
|
200
|
-
const transaction = evt.transaction;
|
|
201
|
-
if (transaction.priority !== Constants_1.MessagePriority.Handshake)
|
|
202
|
-
return false;
|
|
203
|
-
if (transaction.message instanceof SendDataMessages_1.SendDataRequest ||
|
|
204
|
-
transaction.message instanceof SendDataBridgeMessages_1.SendDataBridgeRequest) {
|
|
205
|
-
// require the handshake to be for the same node
|
|
206
|
-
return (transaction.message.command.nodeId ===
|
|
207
|
-
ctx.currentTransaction.message.command.nodeId);
|
|
208
|
-
}
|
|
209
|
-
return false;
|
|
210
|
-
},
|
|
211
|
-
shouldNotKeepCurrentTransaction: (ctx, evt) => {
|
|
212
|
-
const reducer = evt.reducer;
|
|
213
|
-
return reducer(ctx.currentTransaction, "current").type !== "keep";
|
|
214
|
-
},
|
|
215
|
-
currentTransactionIsPingForNode: (ctx, evt) => {
|
|
216
|
-
var _a;
|
|
217
|
-
const msg = (_a = ctx.currentTransaction) === null || _a === void 0 ? void 0 : _a.message;
|
|
218
|
-
return (!!msg &&
|
|
219
|
-
(0, NoOperationCC_1.messageIsPing)(msg) &&
|
|
220
|
-
msg.getNodeId() === evt.nodeId);
|
|
66
|
+
(0, NoOperationCC_1.messageIsPing)(message));
|
|
221
67
|
},
|
|
68
|
+
hasNoActiveTransactions: (ctx) => ctx.activeTransactions.size === 0,
|
|
222
69
|
};
|
|
223
|
-
function createMessageDroppedUnexpectedError(original) {
|
|
224
|
-
const ret = new core_1.ZWaveError(`Message dropped because of an unexpected error: ${original.message}`, core_1.ZWaveErrorCodes.Controller_MessageDropped);
|
|
225
|
-
if (original.stack)
|
|
226
|
-
ret.stack = original.stack;
|
|
227
|
-
return ret;
|
|
228
|
-
}
|
|
229
70
|
function createSendThreadMachine(implementations, params) {
|
|
230
|
-
const resolveCurrentTransaction = (0, xstate_1.assign)((ctx, evt) => {
|
|
231
|
-
if (ctx.currentTransaction.pauseSendThread) {
|
|
232
|
-
ctx.paused = true;
|
|
233
|
-
}
|
|
234
|
-
implementations.resolveTransaction(ctx.currentTransaction, evt.result);
|
|
235
|
-
return ctx;
|
|
236
|
-
});
|
|
237
|
-
const resolveCurrentTransactionWithoutMessage = (0, xstate_1.assign)((ctx) => {
|
|
238
|
-
if (ctx.currentTransaction.pauseSendThread) {
|
|
239
|
-
ctx.paused = true;
|
|
240
|
-
}
|
|
241
|
-
implementations.resolveTransaction(ctx.currentTransaction, undefined);
|
|
242
|
-
return ctx;
|
|
243
|
-
});
|
|
244
|
-
const rejectCurrentTransaction = (0, xstate_1.assign)((ctx, evt) => {
|
|
245
|
-
implementations.rejectTransaction(ctx.currentTransaction, (0, StateMachineShared_1.sendDataErrorToZWaveError)(evt.reason, ctx.currentTransaction, evt.result));
|
|
246
|
-
return ctx;
|
|
247
|
-
});
|
|
248
|
-
const rejectCurrentTransactionWithError = (0, xstate_1.assign)((ctx, evt) => {
|
|
249
|
-
implementations.rejectTransaction(ctx.currentTransaction, createMessageDroppedUnexpectedError(evt.error));
|
|
250
|
-
return ctx;
|
|
251
|
-
});
|
|
252
|
-
const rejectCurrentTransactionWithNodeTimeout = (0, xstate_1.assign)((ctx) => {
|
|
253
|
-
implementations.rejectTransaction(ctx.currentTransaction, (0, StateMachineShared_1.sendDataErrorToZWaveError)("node timeout", ctx.currentTransaction, undefined));
|
|
254
|
-
return ctx;
|
|
255
|
-
});
|
|
256
|
-
const resolveHandshakeTransaction = (0, xstate_1.assign)((ctx, evt) => {
|
|
257
|
-
implementations.resolveTransaction(ctx.handshakeTransaction, evt.result);
|
|
258
|
-
return ctx;
|
|
259
|
-
});
|
|
260
|
-
const rejectHandshakeTransaction = (0, xstate_1.assign)((ctx, evt) => {
|
|
261
|
-
implementations.rejectTransaction(ctx.handshakeTransaction, (0, StateMachineShared_1.sendDataErrorToZWaveError)(evt.reason, ctx.handshakeTransaction, evt.result));
|
|
262
|
-
return ctx;
|
|
263
|
-
});
|
|
264
|
-
const rejectHandshakeTransactionWithError = (0, xstate_1.assign)((ctx, evt) => {
|
|
265
|
-
implementations.rejectTransaction(ctx.handshakeTransaction, createMessageDroppedUnexpectedError(evt.error));
|
|
266
|
-
return ctx;
|
|
267
|
-
});
|
|
268
|
-
const rejectHandshakeTransactionWithNodeTimeout = (0, xstate_1.assign)((ctx) => {
|
|
269
|
-
const hsTransaction = ctx.handshakeTransaction;
|
|
270
|
-
if (hsTransaction) {
|
|
271
|
-
implementations.rejectTransaction(hsTransaction, (0, StateMachineShared_1.sendDataErrorToZWaveError)("node timeout", hsTransaction, undefined));
|
|
272
|
-
}
|
|
273
|
-
return ctx;
|
|
274
|
-
});
|
|
275
|
-
const resolveEventTransaction = (0, xstate_1.assign)((ctx, evt) => {
|
|
276
|
-
if (evt.transaction.pauseSendThread) {
|
|
277
|
-
ctx.paused = true;
|
|
278
|
-
}
|
|
279
|
-
implementations.resolveTransaction(evt.transaction, evt.result);
|
|
280
|
-
return ctx;
|
|
281
|
-
});
|
|
282
|
-
const rejectEventTransaction = (0, xstate_1.assign)((ctx, evt) => {
|
|
283
|
-
implementations.rejectTransaction(evt.transaction, (0, StateMachineShared_1.sendDataErrorToZWaveError)(evt.reason, evt.transaction.message, evt.result));
|
|
284
|
-
return ctx;
|
|
285
|
-
});
|
|
286
|
-
const rejectEventTransactionWithError = (0, xstate_1.assign)((ctx, evt) => {
|
|
287
|
-
implementations.rejectTransaction(evt.transaction, createMessageDroppedUnexpectedError(evt.error));
|
|
288
|
-
return ctx;
|
|
289
|
-
});
|
|
290
71
|
const notifyUnsolicited = (_, evt) => {
|
|
291
72
|
implementations.notifyUnsolicited(evt.message);
|
|
292
73
|
};
|
|
293
|
-
const reduce = (0,
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
const
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
};
|
|
323
|
-
for (const transaction of queue) {
|
|
324
|
-
reduceTransaction(transaction, "queue");
|
|
74
|
+
const reduce = (0, actions_1.pure)((ctx, evt) => {
|
|
75
|
+
const dropQueued = [];
|
|
76
|
+
const stopActive = [];
|
|
77
|
+
const requeue = [];
|
|
78
|
+
const reduceTransaction = (transaction, source) => {
|
|
79
|
+
const reducerResult = evt.reducer(transaction, source);
|
|
80
|
+
switch (reducerResult.type) {
|
|
81
|
+
case "drop":
|
|
82
|
+
(source === "queue" ? dropQueued : stopActive).push(transaction);
|
|
83
|
+
break;
|
|
84
|
+
case "requeue":
|
|
85
|
+
if (reducerResult.priority != undefined) {
|
|
86
|
+
transaction.priority = reducerResult.priority;
|
|
87
|
+
}
|
|
88
|
+
if (reducerResult.tag != undefined) {
|
|
89
|
+
transaction.tag = reducerResult.tag;
|
|
90
|
+
}
|
|
91
|
+
if (source === "active")
|
|
92
|
+
stopActive.push(transaction);
|
|
93
|
+
requeue.push(transaction);
|
|
94
|
+
break;
|
|
95
|
+
case "resolve":
|
|
96
|
+
implementations.resolveTransaction(transaction, reducerResult.message);
|
|
97
|
+
(source === "queue" ? dropQueued : stopActive).push(transaction);
|
|
98
|
+
break;
|
|
99
|
+
case "reject":
|
|
100
|
+
implementations.rejectTransaction(transaction, new core_1.ZWaveError(reducerResult.message, reducerResult.code, undefined, transaction.stack));
|
|
101
|
+
(source === "queue" ? dropQueued : stopActive).push(transaction);
|
|
102
|
+
break;
|
|
325
103
|
}
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
}
|
|
104
|
+
};
|
|
105
|
+
const { queue, activeTransactions } = ctx;
|
|
106
|
+
for (const transaction of queue) {
|
|
107
|
+
reduceTransaction(transaction, "queue");
|
|
108
|
+
}
|
|
109
|
+
for (const { transaction } of activeTransactions.values()) {
|
|
110
|
+
reduceTransaction(transaction, "active");
|
|
111
|
+
}
|
|
112
|
+
// Now we know what to do with the transactions
|
|
113
|
+
queue.remove(...dropQueued, ...requeue);
|
|
114
|
+
queue.add(...requeue);
|
|
115
|
+
return [
|
|
116
|
+
(0, xstate_1.assign)((ctx) => ({
|
|
117
|
+
...ctx,
|
|
118
|
+
queue,
|
|
119
|
+
})),
|
|
120
|
+
...stopActive.map((t) => (0, actions_1.send)({ type: "remove", transaction: t }, { to: ctx.commandQueue })),
|
|
121
|
+
];
|
|
122
|
+
});
|
|
123
|
+
const spawnTransaction = (0, xstate_1.assign)((ctx) => {
|
|
124
|
+
const newCounter = (ctx.counter + 1) % 0xffffffff;
|
|
125
|
+
const id = "T" + newCounter.toString(16).padStart(8, "0");
|
|
126
|
+
const transaction = ctx.queue.shift();
|
|
127
|
+
const machine = (0, xstate_1.spawn)((0, TransactionMachine_1.createTransactionMachine)(id, transaction, implementations), {
|
|
128
|
+
name: id,
|
|
129
|
+
});
|
|
130
|
+
ctx.activeTransactions.set(id, { machine, transaction });
|
|
131
|
+
return {
|
|
132
|
+
...ctx,
|
|
133
|
+
counter: newCounter,
|
|
134
|
+
};
|
|
334
135
|
});
|
|
335
|
-
const ret = (0, xstate_1.
|
|
136
|
+
const ret = (0, xstate_1.createMachine)({
|
|
336
137
|
id: "SendThread",
|
|
337
138
|
initial: "init",
|
|
139
|
+
preserveActionOrder: true,
|
|
338
140
|
context: {
|
|
339
141
|
commandQueue: undefined,
|
|
340
142
|
queue: new sorted_list_1.SortedList(),
|
|
341
|
-
|
|
143
|
+
activeTransactions: new Map(),
|
|
144
|
+
counter: 0,
|
|
342
145
|
paused: false,
|
|
343
146
|
},
|
|
344
147
|
on: {
|
|
@@ -349,83 +152,43 @@ function createSendThreadMachine(implementations, params) {
|
|
|
349
152
|
// messages may come back as "unsolicited", these might be expected updates
|
|
350
153
|
// we need to run them through the serial API machine to avoid mismatches
|
|
351
154
|
message: { actions: forwardToCommandQueue },
|
|
352
|
-
//
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
// If this notification belongs to an active command, forward it
|
|
366
|
-
{
|
|
367
|
-
cond: "isForActiveTransaction",
|
|
368
|
-
actions: forwardActiveCommandFailure,
|
|
369
|
-
},
|
|
370
|
-
// otherwise just reject it
|
|
371
|
-
{
|
|
372
|
-
actions: rejectEventTransaction,
|
|
373
|
-
},
|
|
374
|
-
],
|
|
375
|
-
command_error: [
|
|
376
|
-
// If this notification belongs to an active command, forward it
|
|
377
|
-
{
|
|
378
|
-
cond: "isForActiveTransaction",
|
|
379
|
-
actions: forwardActiveCommandError,
|
|
380
|
-
},
|
|
381
|
-
// otherwise just reject it
|
|
382
|
-
{
|
|
383
|
-
actions: rejectEventTransactionWithError,
|
|
384
|
-
},
|
|
385
|
-
],
|
|
386
|
-
// handle newly added messages
|
|
387
|
-
add: [
|
|
388
|
-
// Trigger outgoing handshakes immediately without queueing
|
|
389
|
-
{
|
|
390
|
-
cond: "isPreTransmitHandshakeForCurrentTransaction",
|
|
391
|
-
actions: [
|
|
392
|
-
forwardToCommandQueue,
|
|
393
|
-
// and inform the state machine when it is the one we've waited for
|
|
394
|
-
(0, xstate_1.assign)({
|
|
395
|
-
handshakeTransaction: (_, evt) => evt.transaction,
|
|
396
|
-
}),
|
|
397
|
-
],
|
|
398
|
-
},
|
|
399
|
-
// Forward all handshake messages that could have to do with the current transaction
|
|
400
|
-
{
|
|
401
|
-
cond: "isHandshakeForCurrentTransaction",
|
|
402
|
-
actions: forwardToCommandQueue,
|
|
403
|
-
},
|
|
404
|
-
{
|
|
405
|
-
actions: [
|
|
406
|
-
(0, xstate_1.assign)({
|
|
407
|
-
queue: (ctx, evt) => {
|
|
408
|
-
ctx.queue.add(evt.transaction);
|
|
409
|
-
return ctx.queue;
|
|
410
|
-
},
|
|
411
|
-
}),
|
|
155
|
+
// Forward NIFs to each transaction machine to resolve potential waiting pings
|
|
156
|
+
NIF: {
|
|
157
|
+
actions: (0, actions_1.pure)((ctx, evt) => {
|
|
158
|
+
const activeTransactionMachinesForNode = [
|
|
159
|
+
...ctx.activeTransactions.values(),
|
|
160
|
+
]
|
|
161
|
+
.filter(({ transaction }) => transaction.message.getNodeId() ===
|
|
162
|
+
evt.nodeId)
|
|
163
|
+
.map((a) => a.machine.id);
|
|
164
|
+
return [
|
|
165
|
+
...activeTransactionMachinesForNode.map((id) => (0, actions_1.send)(evt, { to: id })),
|
|
166
|
+
// Sort the send queue and evaluate again whether the next message may be sent
|
|
167
|
+
sortQueue,
|
|
412
168
|
(0, actions_1.raise)("trigger"),
|
|
413
|
-
]
|
|
414
|
-
},
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
169
|
+
];
|
|
170
|
+
}),
|
|
171
|
+
},
|
|
172
|
+
// handle newly added messages
|
|
173
|
+
add: {
|
|
174
|
+
actions: [
|
|
175
|
+
(0, xstate_1.assign)({
|
|
176
|
+
queue: (ctx, evt) => {
|
|
177
|
+
ctx.queue.add(evt.transaction);
|
|
178
|
+
return ctx.queue;
|
|
179
|
+
},
|
|
180
|
+
}),
|
|
181
|
+
(0, actions_1.raise)("trigger"),
|
|
182
|
+
],
|
|
183
|
+
},
|
|
184
|
+
reduce: {
|
|
185
|
+
// Reducing may reorder the queue, so raise a trigger afterwards
|
|
186
|
+
actions: [reduce, (0, actions_1.raise)("trigger")],
|
|
187
|
+
},
|
|
188
|
+
// Return unsolicited messages to the driver
|
|
189
|
+
unsolicited: {
|
|
190
|
+
actions: notifyUnsolicited,
|
|
191
|
+
},
|
|
429
192
|
// Accept external commands to sort the queue
|
|
430
193
|
sortQueue: {
|
|
431
194
|
actions: [sortQueue, (0, actions_1.raise)("trigger")],
|
|
@@ -440,281 +203,63 @@ function createSendThreadMachine(implementations, params) {
|
|
|
440
203
|
(0, actions_1.raise)("trigger"),
|
|
441
204
|
],
|
|
442
205
|
},
|
|
206
|
+
// forward events between child machinies
|
|
207
|
+
forward: {
|
|
208
|
+
actions: (0, actions_1.send)((_, evt) => ({ ...evt.payload, from: evt.from }), {
|
|
209
|
+
to: (_, evt) => evt.to,
|
|
210
|
+
}),
|
|
211
|
+
},
|
|
212
|
+
// Stop transactions when they are done
|
|
213
|
+
transaction_done: {
|
|
214
|
+
actions: [finalizeTransaction, (0, actions_1.raise)("trigger")],
|
|
215
|
+
},
|
|
443
216
|
},
|
|
444
217
|
states: {
|
|
445
218
|
init: {
|
|
446
219
|
entry: (0, xstate_1.assign)({
|
|
447
220
|
commandQueue: () => (0, xstate_1.spawn)((0, CommandQueueMachine_1.createCommandQueueMachine)(implementations, params), {
|
|
448
|
-
name: "
|
|
221
|
+
name: "QUEUE",
|
|
449
222
|
}),
|
|
450
223
|
}),
|
|
451
224
|
// Spawn the command queue when starting the send thread
|
|
452
225
|
always: "idle",
|
|
453
226
|
},
|
|
227
|
+
// While idle, any transaction may be started
|
|
454
228
|
idle: {
|
|
455
229
|
id: "idle",
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
trigger: [
|
|
462
|
-
{
|
|
463
|
-
cond: "maySendFirstMessage",
|
|
464
|
-
target: "sending",
|
|
465
|
-
},
|
|
466
|
-
],
|
|
467
|
-
reduce: {
|
|
468
|
-
// Reducing may reorder the queue, so raise a trigger afterwards
|
|
469
|
-
actions: [reduce, (0, actions_1.raise)("trigger")],
|
|
470
|
-
},
|
|
230
|
+
always: {
|
|
231
|
+
cond: "mayStartTransaction",
|
|
232
|
+
// Use the first transaction in the queue as the current one
|
|
233
|
+
actions: spawnTransaction,
|
|
234
|
+
target: "busy",
|
|
471
235
|
},
|
|
472
|
-
},
|
|
473
|
-
sending: {
|
|
474
|
-
id: "sending",
|
|
475
|
-
// Use the first transaction in the queue as the current one
|
|
476
|
-
entry: setCurrentTransaction,
|
|
477
|
-
initial: "beforeSend",
|
|
478
236
|
on: {
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
// Therefore resolve pending pings so the communication may proceed immediately
|
|
482
|
-
cond: "currentTransactionIsPingForNode",
|
|
483
|
-
actions: [
|
|
484
|
-
resolveCurrentTransactionWithoutMessage,
|
|
485
|
-
// TODO:
|
|
486
|
-
// this.driver.controllerLog.logNode(
|
|
487
|
-
// node.id,
|
|
488
|
-
// `Treating the node info as a successful ping...`,
|
|
489
|
-
// );
|
|
490
|
-
],
|
|
491
|
-
target: "sending.done",
|
|
492
|
-
internal: true,
|
|
493
|
-
},
|
|
494
|
-
reduce: [
|
|
495
|
-
// If the current transaction should not be kept, tell the send queue to abort it and go back to idle
|
|
496
|
-
{
|
|
497
|
-
cond: "shouldNotKeepCurrentTransaction",
|
|
498
|
-
actions: [resetCommandQueue, reduce],
|
|
499
|
-
target: "sending.done",
|
|
500
|
-
internal: true,
|
|
501
|
-
},
|
|
502
|
-
{ actions: reduce },
|
|
503
|
-
],
|
|
237
|
+
// On trigger, re-evaluate the conditions to enter "busy"
|
|
238
|
+
trigger: { target: "idle" },
|
|
504
239
|
},
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
always: [
|
|
514
|
-
// Skip this step if no handshake is required
|
|
515
|
-
{
|
|
516
|
-
cond: "requiresNoHandshake",
|
|
517
|
-
target: "execute",
|
|
518
|
-
},
|
|
519
|
-
// else begin the handshake process
|
|
520
|
-
{
|
|
521
|
-
target: "handshake",
|
|
522
|
-
},
|
|
523
|
-
],
|
|
524
|
-
},
|
|
525
|
-
handshake: {
|
|
526
|
-
// Just send the handshake as a side effect
|
|
527
|
-
invoke: {
|
|
528
|
-
id: "preTransmitHandshake",
|
|
529
|
-
src: "preTransmitHandshake",
|
|
530
|
-
onDone: "#sending.execute",
|
|
531
|
-
},
|
|
532
|
-
initial: "waitForCommandResult",
|
|
533
|
-
on: {
|
|
534
|
-
handshakeResponse: {
|
|
535
|
-
actions: resolveHandshakeTransaction,
|
|
536
|
-
},
|
|
537
|
-
},
|
|
538
|
-
states: {
|
|
539
|
-
// After kicking off the command, wait until it is completed
|
|
540
|
-
waitForCommandResult: {
|
|
541
|
-
on: {
|
|
542
|
-
// On success, start waiting for the handshake response
|
|
543
|
-
active_command_success: "waitForHandshakeResponse",
|
|
544
|
-
active_command_failure: [
|
|
545
|
-
// On failure, retry SendData commands if possible
|
|
546
|
-
{
|
|
547
|
-
cond: "mayRetry",
|
|
548
|
-
actions: rejectHandshakeTransaction,
|
|
549
|
-
target: "#sending.retryWait",
|
|
550
|
-
},
|
|
551
|
-
// Otherwise reject the transaction
|
|
552
|
-
{
|
|
553
|
-
actions: [
|
|
554
|
-
rejectHandshakeTransaction,
|
|
555
|
-
rejectCurrentTransaction,
|
|
556
|
-
],
|
|
557
|
-
target: "#sending.done",
|
|
558
|
-
},
|
|
559
|
-
],
|
|
560
|
-
active_command_error: [
|
|
561
|
-
// On failure, retry SendData commands if possible
|
|
562
|
-
{
|
|
563
|
-
cond: "mayRetry",
|
|
564
|
-
actions: rejectHandshakeTransactionWithError,
|
|
565
|
-
target: "#sending.retryWait",
|
|
566
|
-
},
|
|
567
|
-
// Otherwise reject the transaction
|
|
568
|
-
{
|
|
569
|
-
actions: [
|
|
570
|
-
rejectHandshakeTransactionWithError,
|
|
571
|
-
rejectCurrentTransactionWithError,
|
|
572
|
-
],
|
|
573
|
-
target: "#sending.done",
|
|
574
|
-
},
|
|
575
|
-
],
|
|
576
|
-
},
|
|
577
|
-
},
|
|
578
|
-
waitForHandshakeResponse: {
|
|
579
|
-
after: {
|
|
580
|
-
// If an update times out, retry if possible - otherwise reject the entire transaction
|
|
581
|
-
REPORT_TIMEOUT: [
|
|
582
|
-
// only retry on timeout when configured
|
|
583
|
-
...(params.attempts
|
|
584
|
-
.retryAfterTransmitReport
|
|
585
|
-
? [
|
|
586
|
-
{
|
|
587
|
-
cond: "mayRetry",
|
|
588
|
-
target: "#sending.retryWait",
|
|
589
|
-
actions: rejectHandshakeTransactionWithNodeTimeout,
|
|
590
|
-
},
|
|
591
|
-
]
|
|
592
|
-
: []),
|
|
593
|
-
{
|
|
594
|
-
actions: [
|
|
595
|
-
rejectHandshakeTransactionWithNodeTimeout,
|
|
596
|
-
rejectCurrentTransactionWithNodeTimeout,
|
|
597
|
-
],
|
|
598
|
-
target: "#sending.done",
|
|
599
|
-
},
|
|
600
|
-
],
|
|
601
|
-
},
|
|
602
|
-
},
|
|
603
|
-
},
|
|
604
|
-
},
|
|
605
|
-
execute: {
|
|
606
|
-
entry: [
|
|
607
|
-
deleteHandshakeTransaction,
|
|
608
|
-
sendCurrentTransactionToCommandQueue,
|
|
609
|
-
],
|
|
610
|
-
on: {
|
|
611
|
-
active_command_success: [
|
|
612
|
-
// On success, start waiting for an update
|
|
613
|
-
{
|
|
614
|
-
cond: "expectsNodeUpdate",
|
|
615
|
-
target: "waitForUpdate",
|
|
616
|
-
},
|
|
617
|
-
// or resolve the current transaction if none is required
|
|
618
|
-
{
|
|
619
|
-
actions: resolveCurrentTransaction,
|
|
620
|
-
target: "done",
|
|
621
|
-
},
|
|
622
|
-
],
|
|
623
|
-
active_command_failure: [
|
|
624
|
-
// On failure, retry SendData commands if possible
|
|
625
|
-
{
|
|
626
|
-
cond: every("currentTransactionIsSendData", "mayRetry"),
|
|
627
|
-
target: "retryWait",
|
|
628
|
-
},
|
|
629
|
-
// Otherwise reject the transaction
|
|
630
|
-
{
|
|
631
|
-
actions: rejectCurrentTransaction,
|
|
632
|
-
target: "done",
|
|
633
|
-
},
|
|
634
|
-
],
|
|
635
|
-
active_command_error: [
|
|
636
|
-
// On failure, retry SendData commands if possible
|
|
637
|
-
{
|
|
638
|
-
cond: every("currentTransactionIsSendData", "mayRetry"),
|
|
639
|
-
target: "retryWait",
|
|
640
|
-
},
|
|
641
|
-
// Otherwise reject the transaction
|
|
642
|
-
{
|
|
643
|
-
actions: rejectCurrentTransactionWithError,
|
|
644
|
-
target: "done",
|
|
645
|
-
},
|
|
646
|
-
],
|
|
647
|
-
},
|
|
648
|
-
},
|
|
649
|
-
waitForUpdate: {
|
|
650
|
-
on: {
|
|
651
|
-
nodeUpdate: {
|
|
652
|
-
actions: resolveCurrentTransaction,
|
|
653
|
-
target: "done",
|
|
654
|
-
},
|
|
655
|
-
resend: {
|
|
656
|
-
// We were asked to resend the pending transaction immediately
|
|
657
|
-
// without increasing the retry counter
|
|
658
|
-
target: "execute",
|
|
659
|
-
},
|
|
660
|
-
},
|
|
661
|
-
after: {
|
|
662
|
-
// If an update times out, retry if possible - otherwise reject the transaction
|
|
663
|
-
REPORT_TIMEOUT: [
|
|
664
|
-
// only retry on timeout when configured
|
|
665
|
-
...(params.attempts.retryAfterTransmitReport
|
|
666
|
-
? [
|
|
667
|
-
{
|
|
668
|
-
cond: "mayRetry",
|
|
669
|
-
target: "retryWait",
|
|
670
|
-
},
|
|
671
|
-
]
|
|
672
|
-
: []),
|
|
673
|
-
{
|
|
674
|
-
actions: rejectCurrentTransactionWithNodeTimeout,
|
|
675
|
-
target: "done",
|
|
676
|
-
},
|
|
677
|
-
],
|
|
678
|
-
},
|
|
679
|
-
},
|
|
680
|
-
retryWait: {
|
|
681
|
-
invoke: {
|
|
682
|
-
id: "notify",
|
|
683
|
-
src: "notifyRetry",
|
|
684
|
-
},
|
|
685
|
-
after: {
|
|
686
|
-
500: "beforeSend",
|
|
687
|
-
},
|
|
240
|
+
},
|
|
241
|
+
// While busy, only handshake responses may be sent
|
|
242
|
+
busy: {
|
|
243
|
+
id: "busy",
|
|
244
|
+
always: [
|
|
245
|
+
{
|
|
246
|
+
cond: "hasNoActiveTransactions",
|
|
247
|
+
target: "idle",
|
|
688
248
|
},
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
deleteCurrentTransaction,
|
|
695
|
-
deleteHandshakeTransaction,
|
|
696
|
-
resetSendDataAttempts,
|
|
697
|
-
],
|
|
698
|
-
},
|
|
249
|
+
{
|
|
250
|
+
cond: "mayStartTransaction",
|
|
251
|
+
// Use the first transaction in the queue as the current one
|
|
252
|
+
actions: spawnTransaction,
|
|
253
|
+
target: "busy",
|
|
699
254
|
},
|
|
255
|
+
],
|
|
256
|
+
on: {
|
|
257
|
+
// On trigger, re-evaluate the conditions to go spawn transactions or back to idle
|
|
258
|
+
trigger: { target: "busy" },
|
|
700
259
|
},
|
|
701
260
|
},
|
|
702
261
|
},
|
|
703
262
|
}, {
|
|
704
|
-
services: {
|
|
705
|
-
preTransmitHandshake: async (ctx) => {
|
|
706
|
-
// Execute the pre transmit handshake and swallow all errors
|
|
707
|
-
try {
|
|
708
|
-
await ctx.currentTransaction.message.command.preTransmitHandshake();
|
|
709
|
-
}
|
|
710
|
-
catch (e) { }
|
|
711
|
-
},
|
|
712
|
-
notifyRetry: (ctx) => {
|
|
713
|
-
var _a;
|
|
714
|
-
(_a = implementations.notifyRetry) === null || _a === void 0 ? void 0 : _a.call(implementations, "SendData", undefined, ctx.currentTransaction.message, ctx.sendDataAttempts, ctx.currentTransaction.message.maxSendAttempts, 500);
|
|
715
|
-
return Promise.resolve();
|
|
716
|
-
},
|
|
717
|
-
},
|
|
718
263
|
guards: {
|
|
719
264
|
...guards,
|
|
720
265
|
every: (ctx, event, { cond }) => {
|
|
@@ -722,9 +267,6 @@ function createSendThreadMachine(implementations, params) {
|
|
|
722
267
|
return keys.every((guardKey) => guards[guardKey](ctx, event, undefined));
|
|
723
268
|
},
|
|
724
269
|
},
|
|
725
|
-
delays: {
|
|
726
|
-
REPORT_TIMEOUT: params.timeouts.report,
|
|
727
|
-
},
|
|
728
270
|
});
|
|
729
271
|
return ret;
|
|
730
272
|
}
|