@mega-yfue/eufy-sdk 0.5.0-beta.41 → 0.5.0-beta.43

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.
@@ -297,6 +297,8 @@ export declare class EufyMega extends EventEmitter {
297
297
  * manager's own log, since by then nothing is waiting to receive it.
298
298
  */
299
299
  private recycleStandaloneSession;
300
+ /** Reopen a wired station that {@link recycleStandaloneSession} closed, while the generation that warmed it is current. */
301
+ private reopenWiredStation;
300
302
  /**
301
303
  * Whether the DECODED property now reads what the write asked for.
302
304
  *
package/dist/index.js CHANGED
@@ -24277,12 +24277,17 @@ async function probeBrokerInstance(ip, creds, opts) {
24277
24277
  });
24278
24278
  const timer = setTimeout(() => finish({ granted: false, error: "timeout" }), timeoutMs);
24279
24279
  client.on("connect", () => {
24280
- client.subscribe(opts.topic, { qos: 1 }, (err, granted) => {
24281
- if (err)
24282
- return finish({ granted: false, error: err.message });
24280
+ client.subscribe(opts.topic, { qos: 1 }, (err, granted, packet) => {
24281
+ if (err) {
24282
+ const code = packet?.granted?.[0];
24283
+ return finish({
24284
+ granted: false,
24285
+ grantedQos: typeof code === "number" ? code : void 0,
24286
+ error: err.message
24287
+ });
24288
+ }
24283
24289
  const g = granted?.[0];
24284
- const denied = !g || g.qos === 128;
24285
- finish({ granted: !denied, grantedQos: g?.qos });
24290
+ finish({ granted: !!g, grantedQos: g?.qos });
24286
24291
  });
24287
24292
  });
24288
24293
  client.on("error", (err) => finish({ granted: false, error: err.message }));
@@ -24708,8 +24713,9 @@ var MqttCommandRouter = class _MqttCommandRouter {
24708
24713
  * One exception is known: a single garage unit whose own-cert SUBSCRIBE was denied on every candidate
24709
24714
  * while a phone-extracted cert granted on the same one, with a sibling of the same model on the same
24710
24715
  * account granting fine. That is a per-device authorization gap on the vendor's backend, not a
24711
- * broker-instance problem and not something this SDK works around — such a device reports as offline
24712
- * (the throw below) until the backend grants the account's own credentials.
24716
+ * broker-instance problem and not something this SDK works around — the throw below names each
24717
+ * candidate's outcome (its SUBACK deny code, a timeout or a connection error) until the backend grants
24718
+ * the account's own credentials.
24713
24719
  *
24714
24720
  * One fresh, explicitly non-reconnecting (`reconnectPeriod: 0`) connection per call — it repays the
24715
24721
  * full mTLS handshake every command and tears the socket down right after (see
@@ -24738,7 +24744,7 @@ var MqttCommandRouter = class _MqttCommandRouter {
24738
24744
  });
24739
24745
  const winner = results.find((res) => res.granted);
24740
24746
  if (!winner) {
24741
- throw new Error(`ensureSecurityMqttFor(${dev.sn}): no broker instance currently holds this device's session (probed ${results.length} candidate IPs, all denied/unreachable) \u2014 the device may be offline.`);
24747
+ throw new Error(`ensureSecurityMqttFor(${dev.sn}): no broker instance currently holds this device's session (probed ${results.length} candidate IPs: ` + results.map((r) => `${r.ip} ${r.grantedQos === void 0 ? "" : `SUBACK 0x${r.grantedQos.toString(16)} `}${r.error ?? "denied"}`).join("; ") + `).`);
24742
24748
  }
24743
24749
  const m = new SecureMqtt({
24744
24750
  credentials: creds,
@@ -28063,10 +28069,24 @@ var EufyMega = class extends EventEmitter13 {
28063
28069
  recycleStandaloneSession(sn) {
28064
28070
  const releaseWrite = new Promise((resolve) => void setTimeout(resolve, SESSION_RECYCLE_WAIT_MS).unref?.());
28065
28071
  return Promise.race([
28066
- this.p2p.resetStandaloneSession(sn),
28072
+ this.p2p.resetStandaloneSession(sn).finally(() => this.reopenWiredStation(sn)),
28067
28073
  releaseWrite.then(() => this.opts.logger?.debug(`[session ${sn}] recycle still waiting on an attached viewer \u2014 releasing the write that asked for it`))
28068
28074
  ]);
28069
28075
  }
28076
+ /** Reopen a wired station that {@link recycleStandaloneSession} closed, while the generation that warmed it is current. */
28077
+ reopenWiredStation(sn) {
28078
+ const generation = this.realtimeGeneration;
28079
+ if (generation?.epoch !== this.realtimeEpoch)
28080
+ return;
28081
+ if (this.p2p.stationKeyOf(sn) !== sn || !this.registry.p2pDevices().some((d) => d.sn === sn))
28082
+ return;
28083
+ if (this.stationPower(sn) !== "wired")
28084
+ return;
28085
+ void this.p2p.ensureStation(sn, generation.abort.signal).catch((error) => {
28086
+ if (!generation.abort.signal.aborted)
28087
+ this.reportError(error);
28088
+ });
28089
+ }
28070
28090
  /**
28071
28091
  * Whether the DECODED property now reads what the write asked for.
28072
28092
  *