@mega-yfue/eufy-sdk 0.2.0-beta.1 → 0.2.0-beta.3
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/core/contracts.d.ts +55 -0
- package/dist/index.js +109 -24
- package/dist/index.js.map +2 -2
- package/dist/model/capabilities/arming.d.ts +44 -16
- package/dist/model/capabilities/index.d.ts +2 -2
- package/dist/transport/p2p/command-router.d.ts +23 -0
- package/dist/transport/p2p/index.d.ts +1 -0
- package/dist/transport/p2p/live-trace.d.ts +84 -6
- package/dist/transport/p2p/p2p-session.d.ts +4 -0
- package/package.json +1 -1
package/dist/core/contracts.d.ts
CHANGED
|
@@ -74,6 +74,61 @@ export declare class CameraDisabledError extends Error {
|
|
|
74
74
|
cause?: unknown;
|
|
75
75
|
});
|
|
76
76
|
}
|
|
77
|
+
/**
|
|
78
|
+
* Work on a station was refused: the station did not provide the session key that work requires.
|
|
79
|
+
*
|
|
80
|
+
* A station reached over its HomeBase encrypts what it is sent under a key negotiated once per connection, and
|
|
81
|
+
* a media start for an attached camera has no unencrypted form at all — so without that key there is nothing
|
|
82
|
+
* to send, however reachable the station is. Naming this apart from a source that failed is what separates an
|
|
83
|
+
* account whose cipher material could not be resolved from a camera that is off, a station that is busy, or a
|
|
84
|
+
* stream that produced nothing: they share no next step.
|
|
85
|
+
*
|
|
86
|
+
* The `level2-unavailable` trace states WHY the key is not coming. This states only that it is not, because
|
|
87
|
+
* that is what the refusal itself knows.
|
|
88
|
+
*
|
|
89
|
+
* `stationSn` is the station that owed the key, which is the parent for an attached camera and therefore not
|
|
90
|
+
* the serial the refused call was made about: several cameras refused at once are one station's outcome, and
|
|
91
|
+
* nothing else in the refusal says so.
|
|
92
|
+
*/
|
|
93
|
+
export declare class StationKeyUnavailableError extends Error {
|
|
94
|
+
/** The station whose session key did not arrive. */
|
|
95
|
+
readonly stationSn: string;
|
|
96
|
+
/** Always true: the negotiation is per connection, so a later one may still produce a key. */
|
|
97
|
+
readonly retryable = true;
|
|
98
|
+
constructor(
|
|
99
|
+
/** The station whose session key did not arrive. */
|
|
100
|
+
stationSn: string, options?: {
|
|
101
|
+
cause?: unknown;
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Work on a station was refused: its session did not connect within the wait it was given.
|
|
106
|
+
*
|
|
107
|
+
* A station is reached over its own session, and nothing addressed to it — a media start, a property read, a
|
|
108
|
+
* still — can be attempted before that session is up. Naming this apart from every other failure is what tells
|
|
109
|
+
* a station that could not be reached at all from one that answered and then refused, or one that served media
|
|
110
|
+
* a caller could not use: those call for opposite next steps, and a caller cannot infer which it had from a
|
|
111
|
+
* message.
|
|
112
|
+
*
|
|
113
|
+
* `waitedMs` is how long was actually waited, which a caller compares against its own deadline to know whether
|
|
114
|
+
* this SDK concluded or its own bound expired first. `stationSn` is the station that could not be reached —
|
|
115
|
+
* the parent for an attached camera, so it is not derivable from the serial the call was made about.
|
|
116
|
+
*/
|
|
117
|
+
export declare class StationUnreachableError extends Error {
|
|
118
|
+
/** The station whose session did not connect. */
|
|
119
|
+
readonly stationSn: string;
|
|
120
|
+
/** How long the session was waited on before this was raised. */
|
|
121
|
+
readonly waitedMs: number;
|
|
122
|
+
/** Always true: a station unreachable now may answer on a later attempt. */
|
|
123
|
+
readonly retryable = true;
|
|
124
|
+
constructor(
|
|
125
|
+
/** The station whose session did not connect. */
|
|
126
|
+
stationSn: string,
|
|
127
|
+
/** How long the session was waited on before this was raised. */
|
|
128
|
+
waitedMs: number, options?: {
|
|
129
|
+
cause?: unknown;
|
|
130
|
+
});
|
|
131
|
+
}
|
|
77
132
|
/**
|
|
78
133
|
* A live stream was refused: the station is already serving another of its cameras to a viewer.
|
|
79
134
|
*
|
package/dist/index.js
CHANGED
|
@@ -2556,6 +2556,28 @@ var CameraDisabledError = class extends Error {
|
|
|
2556
2556
|
this.name = "CameraDisabledError";
|
|
2557
2557
|
}
|
|
2558
2558
|
};
|
|
2559
|
+
var StationKeyUnavailableError = class extends Error {
|
|
2560
|
+
stationSn;
|
|
2561
|
+
/** Always true: the negotiation is per connection, so a later one may still produce a key. */
|
|
2562
|
+
retryable = true;
|
|
2563
|
+
constructor(stationSn, options) {
|
|
2564
|
+
super(`station ${stationSn} did not provide its session key, so nothing that requires one could be sent`, options);
|
|
2565
|
+
this.stationSn = stationSn;
|
|
2566
|
+
this.name = "StationKeyUnavailableError";
|
|
2567
|
+
}
|
|
2568
|
+
};
|
|
2569
|
+
var StationUnreachableError = class extends Error {
|
|
2570
|
+
stationSn;
|
|
2571
|
+
waitedMs;
|
|
2572
|
+
/** Always true: a station unreachable now may answer on a later attempt. */
|
|
2573
|
+
retryable = true;
|
|
2574
|
+
constructor(stationSn, waitedMs, options) {
|
|
2575
|
+
super(`station ${stationSn}'s P2P session did not connect within ${waitedMs}ms, so nothing could be sent to it`, options);
|
|
2576
|
+
this.stationSn = stationSn;
|
|
2577
|
+
this.waitedMs = waitedMs;
|
|
2578
|
+
this.name = "StationUnreachableError";
|
|
2579
|
+
}
|
|
2580
|
+
};
|
|
2559
2581
|
var StationBusyError = class extends Error {
|
|
2560
2582
|
servingChannel;
|
|
2561
2583
|
/** Always true: the station is busy now, and stops being busy when the other stream is released. */
|
|
@@ -6890,6 +6912,16 @@ var KEYPAD = {
|
|
|
6890
6912
|
// dist/model/capabilities/arming.js
|
|
6891
6913
|
var STATION_CHANNEL2 = 255;
|
|
6892
6914
|
var ArmingMode = {
|
|
6915
|
+
/** Armed — full protection, nobody home (wire value 0). */
|
|
6916
|
+
away: "away",
|
|
6917
|
+
/** Armed for occupancy — reduced/perimeter protection while home (wire value 1). */
|
|
6918
|
+
home: "home",
|
|
6919
|
+
/** Custom 1 — a user-defined posture configured in the app (wire value 3). */
|
|
6920
|
+
custom1: "custom1",
|
|
6921
|
+
/** Disarmed — no alarms; sensors still report state (wire value 63). */
|
|
6922
|
+
disarmed: "disarmed"
|
|
6923
|
+
};
|
|
6924
|
+
var AlarmDelayMode = {
|
|
6893
6925
|
/** Armed — full protection, nobody home (wire value 0). */
|
|
6894
6926
|
away: "away",
|
|
6895
6927
|
/** Armed for occupancy — reduced/perimeter protection while home (wire value 1). */
|
|
@@ -6905,10 +6937,11 @@ var ARMING_CMD = {
|
|
|
6905
6937
|
* mValue3:0, `payload:{mode_type:<int>, user_name:<string>}`.
|
|
6906
6938
|
*
|
|
6907
6939
|
* ⚠️ Only 3 of the 9 modes were exercised in that capture — `mode_type` 0 (away), 63 (disarmed), 1
|
|
6908
|
-
* (home), all confirmed byte-exact
|
|
6909
|
-
*
|
|
6910
|
-
*
|
|
6911
|
-
* them. See `ARMING_MODE_WIRE` for the
|
|
6940
|
+
* (home), all confirmed byte-exact. Re-confirmed live 2026-08-05: each reported its own MODE_SWITCH push
|
|
6941
|
+
* within ~5s of the write. `custom1` 3 joined {@link ArmingMode} on a live confirmation rather than a
|
|
6942
|
+
* capture, making four settable in total. The remaining five are named by the app but never observed
|
|
6943
|
+
* leaving it, so this capability reads them and refuses to send them. See `ARMING_MODE_WIRE` for the
|
|
6944
|
+
* per-value breakdown.
|
|
6912
6945
|
*/
|
|
6913
6946
|
SET_ARMING: 1224,
|
|
6914
6947
|
/**
|
|
@@ -6944,7 +6977,6 @@ var ARMING_MODE_WIRE = {
|
|
|
6944
6977
|
schedule: 2,
|
|
6945
6978
|
// ⚠️ reportable, NOT settable — see the doc comment above
|
|
6946
6979
|
custom1: 3,
|
|
6947
|
-
// ⚠️ reportable, NOT settable — see the doc comment above
|
|
6948
6980
|
custom2: 4,
|
|
6949
6981
|
// ⚠️ reportable, NOT settable — see the doc comment above
|
|
6950
6982
|
custom3: 5,
|
|
@@ -6987,9 +7019,9 @@ function alarmDelayCommand(mode, config, ctx) {
|
|
|
6987
7019
|
var ARMING_MEMBERS = {
|
|
6988
7020
|
/**
|
|
6989
7021
|
* The one member whose write domain is NARROWER than its read: `enumValues` names all nine modes a
|
|
6990
|
-
* station can report, and the argument's `values` publishes only the
|
|
6991
|
-
* argument IS the domain the derived setter enforces and the refusal names, so an
|
|
6992
|
-
* refused by naming the
|
|
7022
|
+
* station can report, and the argument's `values` publishes only the four whose write is confirmed. That
|
|
7023
|
+
* argument IS the domain the derived setter enforces and the refusal names, so an unconfirmed mode is
|
|
7024
|
+
* refused by naming the four that work — nine labels for the read and four for the write, off one
|
|
6993
7025
|
* declaration.
|
|
6994
7026
|
*
|
|
6995
7027
|
* `armingCommand` may also throw synchronously (missing account identity) and `bindMembers` turns that
|
|
@@ -7010,7 +7042,7 @@ var ARMING_MEMBERS = {
|
|
|
7010
7042
|
enumValues: ARMING_MODE_LABELS,
|
|
7011
7043
|
provenance: "verified",
|
|
7012
7044
|
args: [{ name: "mode", kind: "enum", values: SETTABLE_MODES }],
|
|
7013
|
-
description: "Guard mode (verified: param 1224 = GUARD_MODE, read/write mechanism confirmed). Reads all 9 modes the app defines; SETS only the
|
|
7045
|
+
description: "Guard mode (verified: param 1224 = GUARD_MODE, read/write mechanism confirmed). Reads all 9 modes the app defines; SETS only the 4 whose write is confirmed (away/home/custom1/disarmed) \u2014 schedule/custom2/custom3/off/geo are named by the app but no capture shows one being sent, so they are refused rather than guessed; see ARMING_MODE_WIRE in arming.ts for the breakdown.",
|
|
7014
7046
|
observation: {
|
|
7015
7047
|
event: "armingModeChanged",
|
|
7016
7048
|
reflects: (value) => ({ param: ARMING_CMD.SET_ARMING, expected: ARMING_MODE_WIRE[armingModeOf(value)] }),
|
|
@@ -7031,9 +7063,10 @@ var ARMING_MEMBERS = {
|
|
|
7031
7063
|
* this mode — there is no known GET to fetch it automatically, and a wrong guess here can silently
|
|
7032
7064
|
* misconfigure which sensors arm/trigger for real.
|
|
7033
7065
|
*
|
|
7034
|
-
* Takes {@link
|
|
7035
|
-
* captured
|
|
7036
|
-
* `
|
|
7066
|
+
* Takes {@link AlarmDelayMode}, not {@link ArmingMode}: a delay is configurable only for a mode whose
|
|
7067
|
+
* integer is captured on THIS command, and `custom1` is confirmed on cmd 1224 only. The frame carries
|
|
7068
|
+
* that integer in `mode_id` with no runtime validation and no readback, so a mode outside this union
|
|
7069
|
+
* would be the same unverified guess `setMode` refuses.
|
|
7037
7070
|
*/
|
|
7038
7071
|
setAlarmDelayConfig: method(({ ctx, sink }) => (mode, config) => {
|
|
7039
7072
|
try {
|
|
@@ -14190,19 +14223,27 @@ var P2PSession = class _P2PSession extends EventEmitter2 {
|
|
|
14190
14223
|
* cameras from that second group streamed normally at level-1 — including one of the same firmware as an
|
|
14191
14224
|
* own-session camera that delivered no video at all for a reason of its own. An expired grace therefore
|
|
14192
14225
|
* separates nothing on this path, and a start failure on such a session is not evidence about it.
|
|
14226
|
+
*
|
|
14227
|
+
* Every `false` answer carries a `level2-unavailable` trace naming its reason, wherever the wait ended: a
|
|
14228
|
+
* `terminal` outcome is the one already stated where the negotiation concluded, since that is where the
|
|
14229
|
+
* cipher and the cause are known, and re-stating it here would double every settled negotiation.
|
|
14193
14230
|
*/
|
|
14194
14231
|
async awaitLevel2Key(graceMs, graceFrom = "call") {
|
|
14195
|
-
if (this.closed)
|
|
14232
|
+
if (this.closed) {
|
|
14233
|
+
this.trace({ phase: "level2-unavailable", reason: "session-closed" });
|
|
14196
14234
|
return false;
|
|
14235
|
+
}
|
|
14197
14236
|
if (this.level2Key)
|
|
14198
14237
|
return true;
|
|
14199
|
-
if (!this.level2Pending)
|
|
14238
|
+
if (!this.level2Pending) {
|
|
14239
|
+
this.trace({ phase: "level2-unavailable", reason: "not-negotiating" });
|
|
14200
14240
|
return false;
|
|
14241
|
+
}
|
|
14201
14242
|
const since = graceFrom === "call" ? Date.now() : this.connectedAtMs ?? Date.now();
|
|
14202
14243
|
const remaining = graceMs - (Date.now() - since);
|
|
14203
14244
|
if (remaining <= 0) {
|
|
14204
14245
|
this.logger.debug(`[p2p] ${this.cfg.stationSn} no level-2 key and its ${graceMs}ms grace has elapsed`);
|
|
14205
|
-
this.trace({ phase: "level2-
|
|
14246
|
+
this.trace({ phase: "level2-unavailable", reason: "grace-elapsed", waitedMs: graceMs });
|
|
14206
14247
|
return false;
|
|
14207
14248
|
}
|
|
14208
14249
|
this.logger.debug(`[p2p] ${this.cfg.stationSn} waiting up to ${remaining}ms for the level-2 key`);
|
|
@@ -14228,10 +14269,12 @@ var P2PSession = class _P2PSession extends EventEmitter2 {
|
|
|
14228
14269
|
});
|
|
14229
14270
|
if (outcome === "timeout") {
|
|
14230
14271
|
this.logger.debug(`[p2p] ${this.cfg.stationSn} level-2 key did not arrive within its grace`);
|
|
14272
|
+
this.trace({ phase: "level2-unavailable", reason: "grace-elapsed", waitedMs: remaining });
|
|
14231
14273
|
} else if (outcome === "terminal") {
|
|
14232
14274
|
this.logger.debug(`[p2p] ${this.cfg.stationSn} level-2 negotiation concluded without a key`);
|
|
14233
14275
|
} else if (outcome === "closed") {
|
|
14234
14276
|
this.logger.debug(`[p2p] ${this.cfg.stationSn} session closed before the level-2 key arrived`);
|
|
14277
|
+
this.trace({ phase: "level2-unavailable", reason: "session-closed" });
|
|
14235
14278
|
}
|
|
14236
14279
|
return outcome === "key";
|
|
14237
14280
|
}
|
|
@@ -14282,6 +14325,7 @@ var P2PSession = class _P2PSession extends EventEmitter2 {
|
|
|
14282
14325
|
this.level2Negotiating = true;
|
|
14283
14326
|
const generation = this.connectionGeneration;
|
|
14284
14327
|
const cipherId = gatewayInfoCipherId(gwPayload);
|
|
14328
|
+
this.trace({ phase: "level2-negotiating", cipherId });
|
|
14285
14329
|
void (async () => {
|
|
14286
14330
|
try {
|
|
14287
14331
|
const eccPrivHex = await this.cfg.resolveCipherKey?.(cipherId);
|
|
@@ -14289,11 +14333,13 @@ var P2PSession = class _P2PSession extends EventEmitter2 {
|
|
|
14289
14333
|
return;
|
|
14290
14334
|
if (!eccPrivHex) {
|
|
14291
14335
|
this.logger.debug(`[p2p] ${this.cfg.stationSn} no ECC key for cipher_id ${cipherId}`);
|
|
14336
|
+
this.trace({ phase: "level2-unavailable", reason: "no-cipher-key", cipherId });
|
|
14292
14337
|
this.settleLevel2();
|
|
14293
14338
|
return;
|
|
14294
14339
|
}
|
|
14295
14340
|
const key = deriveLevel2KeyFromGatewayInfo(gwPayload, eccPrivHex);
|
|
14296
14341
|
if (!key) {
|
|
14342
|
+
this.trace({ phase: "level2-unavailable", reason: "derivation-failed", cipherId });
|
|
14297
14343
|
this.settleLevel2();
|
|
14298
14344
|
this.emit("error", new Error(`level-2 key derivation failed (cipher_id ${cipherId})`));
|
|
14299
14345
|
return;
|
|
@@ -14305,6 +14351,7 @@ var P2PSession = class _P2PSession extends EventEmitter2 {
|
|
|
14305
14351
|
} catch (e) {
|
|
14306
14352
|
if (this.closed || generation !== this.connectionGeneration)
|
|
14307
14353
|
return;
|
|
14354
|
+
this.trace({ phase: "level2-unavailable", reason: "derivation-failed", cipherId });
|
|
14308
14355
|
this.settleLevel2();
|
|
14309
14356
|
this.emit("error", e instanceof Error ? e : new Error(String(e)));
|
|
14310
14357
|
}
|
|
@@ -18858,6 +18905,11 @@ function abortable(work, signal) {
|
|
|
18858
18905
|
}
|
|
18859
18906
|
var LEVEL2_GRACE_MS = 25e3;
|
|
18860
18907
|
var LEVEL2_SETTLE_MS = 8e3;
|
|
18908
|
+
var P2P_STATION_WAITS = {
|
|
18909
|
+
connect: CONNECT_WAIT_MS,
|
|
18910
|
+
level2Grace: LEVEL2_GRACE_MS,
|
|
18911
|
+
level2Settle: LEVEL2_SETTLE_MS
|
|
18912
|
+
};
|
|
18861
18913
|
var RTSP_URL_READ_TIMEOUT_MS = 12e3;
|
|
18862
18914
|
var SHARED_LIVE_OPT_KEYS = [
|
|
18863
18915
|
"eccPrivateKey",
|
|
@@ -18909,6 +18961,14 @@ var P2PCommandRouter = class _P2PCommandRouter {
|
|
|
18909
18961
|
}
|
|
18910
18962
|
return normalized;
|
|
18911
18963
|
}
|
|
18964
|
+
/**
|
|
18965
|
+
* Emit a live trace under a station session's handle, for work this router does ON that session before
|
|
18966
|
+
* the session itself records anything — reaching the station, and resolving what a device is on it. Same
|
|
18967
|
+
* handle as everything the session goes on to trace, which is what groups one attempt.
|
|
18968
|
+
*/
|
|
18969
|
+
traceOnStation(session, trace) {
|
|
18970
|
+
traceLiveStart(this.deps.logger ?? noopLogger, trace, session.traceId);
|
|
18971
|
+
}
|
|
18912
18972
|
/**
|
|
18913
18973
|
* Whether this transport stack drives `dev`'s `ff09-*` commands — true when the device has its own
|
|
18914
18974
|
* usable P2P endpoint (a non-empty `p2p_did`). The command sink asks each stack this to route a
|
|
@@ -19049,7 +19109,15 @@ var P2PCommandRouter = class _P2PCommandRouter {
|
|
|
19049
19109
|
let ecc;
|
|
19050
19110
|
try {
|
|
19051
19111
|
const ciphers = await this.deps.mega.getCiphers([cipherId], adminUserId, stationSn);
|
|
19052
|
-
ecc = ciphers.find((c) => Number(c.cipher_id) === cipherId)?.ecc_private_key
|
|
19112
|
+
ecc = ciphers.find((c) => Number(c.cipher_id) === cipherId)?.ecc_private_key;
|
|
19113
|
+
if (ecc === void 0 && ciphers[0]?.ecc_private_key !== void 0) {
|
|
19114
|
+
ecc = ciphers[0].ecc_private_key;
|
|
19115
|
+
this.traceOnStation(session, {
|
|
19116
|
+
phase: "cipher-fallback",
|
|
19117
|
+
cipherId,
|
|
19118
|
+
answeredCipherId: Number(ciphers[0].cipher_id)
|
|
19119
|
+
});
|
|
19120
|
+
}
|
|
19053
19121
|
} catch (e) {
|
|
19054
19122
|
this.deps.onError(e instanceof Error ? e : new Error(String(e)));
|
|
19055
19123
|
}
|
|
@@ -19680,9 +19748,9 @@ var P2PCommandRouter = class _P2PCommandRouter {
|
|
|
19680
19748
|
s.sendStringPayloadCommand(P2P_ENVELOPE.CONTROL_PAYLOAD, json, ch);
|
|
19681
19749
|
return Promise.resolve();
|
|
19682
19750
|
},
|
|
19683
|
-
l2: async ({ session: s, channel: ch }) => {
|
|
19751
|
+
l2: async ({ session: s, channel: ch, parentSn }) => {
|
|
19684
19752
|
if (!await s.awaitLevel2Key(LEVEL2_GRACE_MS, "call")) {
|
|
19685
|
-
throw new
|
|
19753
|
+
throw new StationKeyUnavailableError(parentSn);
|
|
19686
19754
|
}
|
|
19687
19755
|
s.sendRawLevel2(json, ch, P2P_ENVELOPE.CONTROL_PAYLOAD);
|
|
19688
19756
|
}
|
|
@@ -19849,15 +19917,28 @@ var P2PCommandRouter = class _P2PCommandRouter {
|
|
|
19849
19917
|
}
|
|
19850
19918
|
this.manager.bumpCommand(parentSn);
|
|
19851
19919
|
const channel = typeof raw.device_channel === "number" ? raw.device_channel : 0;
|
|
19852
|
-
const
|
|
19920
|
+
const stationAdminId = raw.member?.admin_user_id;
|
|
19921
|
+
const accountId = stationAdminId ?? this.deps.mega.auth?.userId ?? "";
|
|
19853
19922
|
const t0 = Date.now();
|
|
19854
|
-
|
|
19855
|
-
|
|
19856
|
-
|
|
19923
|
+
let waitedMs = 0;
|
|
19924
|
+
if (!session.isConnected) {
|
|
19925
|
+
this.traceOnStation(session, { phase: "session-connect-wait", waitMs: CONNECT_WAIT_MS });
|
|
19926
|
+
while (!session.isConnected && Date.now() - t0 < CONNECT_WAIT_MS) {
|
|
19927
|
+
opts.signal?.throwIfAborted();
|
|
19928
|
+
await sleep2(200);
|
|
19929
|
+
}
|
|
19930
|
+
waitedMs = Date.now() - t0;
|
|
19931
|
+
this.traceOnStation(session, session.isConnected ? { phase: "session-connected", waitedMs } : { phase: "session-unreachable", waitedMs });
|
|
19857
19932
|
}
|
|
19858
19933
|
opts.signal?.throwIfAborted();
|
|
19859
19934
|
if (!session.isConnected)
|
|
19860
|
-
throw new
|
|
19935
|
+
throw new StationUnreachableError(parentSn, waitedMs);
|
|
19936
|
+
this.traceOnStation(session, {
|
|
19937
|
+
phase: "station-resolved",
|
|
19938
|
+
topology: homeBaseAttached ? "attached" : "own",
|
|
19939
|
+
channel,
|
|
19940
|
+
stationAdmin: typeof stationAdminId !== "string" ? "unstated" : stationAdminId === this.deps.mega.auth?.userId ? "self" : "other"
|
|
19941
|
+
});
|
|
19861
19942
|
if (opts.waitLevel2) {
|
|
19862
19943
|
if (opts.waitLevel2 === "settle") {
|
|
19863
19944
|
await abortable(session.awaitLevel2Key(LEVEL2_SETTLE_MS, "session"), opts.signal);
|
|
@@ -19871,7 +19952,7 @@ var P2PCommandRouter = class _P2PCommandRouter {
|
|
|
19871
19952
|
ready = await abortable(session.awaitLevel2Key(LEVEL2_GRACE_MS, "call"), opts.signal);
|
|
19872
19953
|
}
|
|
19873
19954
|
if (!ready)
|
|
19874
|
-
throw new
|
|
19955
|
+
throw new StationKeyUnavailableError(parentSn);
|
|
19875
19956
|
}
|
|
19876
19957
|
return { session, parentSn, channel, accountId, homeBaseAttached };
|
|
19877
19958
|
}
|
|
@@ -25312,6 +25393,7 @@ export {
|
|
|
25312
25393
|
AUDIO_MEMBERS,
|
|
25313
25394
|
AccessUnitAssembler,
|
|
25314
25395
|
AiDetectType,
|
|
25396
|
+
AlarmDelayMode,
|
|
25315
25397
|
ArmingMode,
|
|
25316
25398
|
BATTERY_MEMBERS,
|
|
25317
25399
|
BIZ_CHANNEL,
|
|
@@ -25385,6 +25467,7 @@ export {
|
|
|
25385
25467
|
P256,
|
|
25386
25468
|
P2PSession,
|
|
25387
25469
|
P2P_ENVELOPE,
|
|
25470
|
+
P2P_STATION_WAITS,
|
|
25388
25471
|
PRINTER_CATEGORY_RE,
|
|
25389
25472
|
PTZ_MEMBERS,
|
|
25390
25473
|
PowerSource,
|
|
@@ -25418,6 +25501,8 @@ export {
|
|
|
25418
25501
|
SmartDropPushEvent,
|
|
25419
25502
|
StateConvergenceError,
|
|
25420
25503
|
StationBusyError,
|
|
25504
|
+
StationKeyUnavailableError,
|
|
25505
|
+
StationUnreachableError,
|
|
25421
25506
|
StoredSnapshotUnavailableError,
|
|
25422
25507
|
StreamingQuality,
|
|
25423
25508
|
SuctionLevel,
|