@mega-yfue/eufy-sdk 0.6.0-beta.5 → 0.6.0-beta.7

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/index.js CHANGED
@@ -16201,6 +16201,9 @@ function traceLiveStart(logger, trace, source) {
16201
16201
  logger.debug(LIVE_TRACE_MESSAGE, source === void 0 ? trace : { ...trace, source });
16202
16202
  }
16203
16203
 
16204
+ // dist/transport/p2p/level2-settle.js
16205
+ var LEVEL2_SETTLE_MS = 8e3;
16206
+
16204
16207
  // dist/transport/p2p/p2p-session.js
16205
16208
  var LOCAL_LOOKUP_PORT = 32108;
16206
16209
  var HEARTBEAT_MS = 5e3;
@@ -17777,7 +17780,7 @@ var P2PSession = class _P2PSession extends EventEmitter2 {
17777
17780
  });
17778
17781
  const body = Buffer.concat([
17779
17782
  buildCommandHeader(this.seqNumber, CMD_SET_PAYLOAD),
17780
- buildStringCommandPayload(value, channel, this.level1Key, 1)
17783
+ this.databasePayload(value, channel)
17781
17784
  ]);
17782
17785
  this.seqNumber = this.seqNumber + 1 & 65535;
17783
17786
  this.logger.debug(`[p2p] ${this.cfg.stationSn} requestImage ${filePath}`);
@@ -17815,12 +17818,20 @@ var P2PSession = class _P2PSession extends EventEmitter2 {
17815
17818
  });
17816
17819
  const body = Buffer.concat([
17817
17820
  buildCommandHeader(this.seqNumber, CMD_SET_PAYLOAD),
17818
- buildStringCommandPayload(value, channel, this.level1Key, 1)
17821
+ this.databasePayload(value, channel)
17819
17822
  ]);
17820
17823
  this.seqNumber = this.seqNumber + 1 & 65535;
17821
17824
  this.logger.debug(`[p2p] ${this.cfg.stationSn} queryDatabase ${table} ch=${channel}`);
17822
17825
  this.send(this.connectAddress, RequestMessageType.DATA, body);
17823
17826
  }
17827
+ /**
17828
+ * The `CMD_SET_PAYLOAD` payload of a database read or stored-image request: the JSON level-1 encrypted, or
17829
+ * in the clear with header bytes from {@link nextClearCommandBytes} on a session that {@link sendsInTheClear}
17830
+ * and holds no level-2 key.
17831
+ */
17832
+ databasePayload(value, channel) {
17833
+ return !this.level2Key && this.sendsInTheClear() ? buildRawCommandPayload(Buffer.from(value, "utf-8"), channel, 0, this.nextClearCommandBytes(), 0) : buildStringCommandPayload(value, channel, this.level1Key, 1);
17834
+ }
17824
17835
  /**
17825
17836
  * Standard "give me the whole table" query params the eufy app uses for a direct
17826
17837
  * `CMD_DATABASE` read (inner `cmd 10000`). `count` bounds the row count.
@@ -17893,10 +17904,15 @@ var P2PSession = class _P2PSession extends EventEmitter2 {
17893
17904
  *
17894
17905
  * One read at a time per session: while one is accumulating, every {@link queryDatabase} on the
17895
17906
  * session throws, so a second reply cannot land in this buffer.
17907
+ *
17908
+ * The query's framing follows the cipher the gateway-info reply names, so on a session still negotiating
17909
+ * its level-2 key the query waits for that to settle, up to {@link LEVEL2_SETTLE_MS} from connect.
17896
17910
  */
17897
17911
  async readDatabase(table, opts = {}) {
17898
17912
  if (opts.signal?.aborted)
17899
17913
  throw new Error("readDatabase: aborted");
17914
+ if (this.level2Pending)
17915
+ await abortable(this.awaitLevel2Key(LEVEL2_SETTLE_MS, "session"), opts.signal);
17900
17916
  this.queryDatabase(table, {
17901
17917
  accountId: opts.accountId,
17902
17918
  innerCmd: opts.innerCmd,
@@ -18199,6 +18215,8 @@ var P2PSession = class _P2PSession extends EventEmitter2 {
18199
18215
  } catch {
18200
18216
  }
18201
18217
  }
18218
+ } else if (header.commandId === CMD_DATABASE && this.sendsInTheClear()) {
18219
+ this.emit("dbChunk", { stationSn: this.cfg.stationSn, text: payload.toString("latin1") });
18202
18220
  }
18203
18221
  const frame = {
18204
18222
  ...header,
@@ -20550,14 +20568,20 @@ var SharedLiveSource = class {
20550
20568
  }
20551
20569
  /**
20552
20570
  * Handle a consumer leaving. When the last one detaches (1→0), release the station-session user via
20553
- * {@link SharedLiveSourceOptions.onIdle} (its own longer idle timer then arms) and arm the stream's
20554
- * linger teardown.
20571
+ * {@link SharedLiveSourceOptions.onIdle} (its own longer idle timer then arms) and, while a stream is
20572
+ * still running, arm its linger teardown.
20573
+ *
20574
+ * A source that ended its own stream ends its consumers before tearing down, and a Readable consumer
20575
+ * detaches only once it has reached EOF — after that teardown. The source is then already `stopped`,
20576
+ * with its session claim released, and stays so: lingering would make the owner hand it out again
20577
+ * instead of building a source that holds a session.
20555
20578
  */
20556
20579
  onDetach(consumer) {
20557
20580
  this.consumers.delete(consumer);
20558
20581
  if (this.consumers.size === 0 && !this.disposed) {
20559
20582
  this.opts.onIdle?.();
20560
- this.arm();
20583
+ if (this.stream)
20584
+ this.arm();
20561
20585
  }
20562
20586
  }
20563
20587
  /** Refcount hit zero — arm the linger teardown. A new attach in the window cancels it. */
@@ -22030,7 +22054,6 @@ function stationChannels(devices) {
22030
22054
  // dist/transport/p2p/command-router.js
22031
22055
  var DIRECT_CMD_SENDS = 5;
22032
22056
  var LEVEL2_GRACE_MS = 25e3;
22033
- var LEVEL2_SETTLE_MS = 8e3;
22034
22057
  var KEEP_LEVEL1_SESSION_MODELS = /* @__PURE__ */ new Set(["T8423"]);
22035
22058
  var P2P_STATION_WAITS = {
22036
22059
  connect: CONNECT_TIMEOUT_MS,