@mega-yfue/eufy-sdk 0.4.0-beta.0 → 0.4.0-beta.10
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/client/eufy-mega.d.ts +4 -1
- package/dist/core/contracts.d.ts +2 -2
- package/dist/index.js +106 -42
- package/dist/index.js.map +2 -2
- package/dist/transport/mqtt/secure-mqtt.d.ts +20 -13
- package/dist/transport/p2p/p2p-session.d.ts +21 -2
- package/dist/transport/p2p/shared-live-source.d.ts +1 -1
- package/package.json +3 -3
|
@@ -99,28 +99,35 @@ export declare class SecureMqtt extends EventEmitter implements RealtimeTranspor
|
|
|
99
99
|
private open;
|
|
100
100
|
/**
|
|
101
101
|
* Subscribe every inbound leg this device's line uses (see `topics.ts` — one `/res` for most lines,
|
|
102
|
-
* four topics for `eufy_life`).
|
|
102
|
+
* four topics for `eufy_life` and the clean line).
|
|
103
103
|
*
|
|
104
|
-
* The grants are INSPECTED, not assumed: AWS IoT
|
|
105
|
-
* SUBACK_FAILURE
|
|
106
|
-
*
|
|
107
|
-
*
|
|
108
|
-
* line that grants its state channel but refuses (say) the OTA leg still works.
|
|
104
|
+
* The grants are INSPECTED, not assumed: AWS IoT refuses a policy-denied filter with a
|
|
105
|
+
* {@link SUBACK_FAILURE} grant rather than failing the connection. A denied topic is reported via
|
|
106
|
+
* `error` naming the credential scope; only an all-denied device throws, so a line that grants its
|
|
107
|
+
* state channel but refuses (say) a business leg still works.
|
|
109
108
|
*/
|
|
110
109
|
subscribeDevice(device: EufyDevice): Promise<void>;
|
|
111
110
|
/**
|
|
112
111
|
* Subscribe to explicit topic filters, returning the topics that were granted. A scope-denied filter
|
|
113
|
-
*
|
|
114
|
-
*
|
|
115
|
-
*
|
|
112
|
+
* is dropped from the result instead of throwing — callers that need every leg check the returned
|
|
113
|
+
* list. Used by lines whose topic vocabulary isn't the eufy `subscribeTopics` shape (e.g. Anker Solix
|
|
114
|
+
* `dt/{app}/{pn}/{sn}`).
|
|
116
115
|
*/
|
|
117
116
|
subscribe(topics: string[]): Promise<string[]>;
|
|
118
117
|
/**
|
|
119
|
-
*
|
|
120
|
-
*
|
|
121
|
-
*
|
|
118
|
+
* Subscribe each filter in a SUBSCRIBE of its own and split the outcome into granted vs refused.
|
|
119
|
+
*
|
|
120
|
+
* One request per filter because the MQTT engine treats a SUBACK as all-or-nothing: one refused grant
|
|
121
|
+
* rejects the whole request, and it forgets EVERY filter of that request for resubscription after a
|
|
122
|
+
* reconnect — so a batch holding one denied leg would lose the granted legs on the next drop. Alone,
|
|
123
|
+
* a refused filter costs only itself. A rejection that carries no SUBACK is a transport failure and
|
|
124
|
+
* is thrown.
|
|
125
|
+
*
|
|
126
|
+
* The cost is one SUBSCRIBE and one SUBACK per filter instead of one per device — four for a
|
|
127
|
+
* four-leg line. They are sent concurrently, so the wall-clock cost is one round trip. Folding them
|
|
128
|
+
* back into one request brings back the lost resubscription.
|
|
122
129
|
*/
|
|
123
|
-
private
|
|
130
|
+
private subscribeEach;
|
|
124
131
|
/**
|
|
125
132
|
* Publish a raw payload to an MQTT topic (the command leg — `cmd/{app}/{pn}/{sn}/req`). The `body`
|
|
126
133
|
* is a pre-built envelope the caller supplies (the command router builds it). QoS 1 by default (the
|
|
@@ -95,6 +95,8 @@ export declare class P2PSession extends EventEmitter {
|
|
|
95
95
|
private connected;
|
|
96
96
|
private connecting;
|
|
97
97
|
private closed;
|
|
98
|
+
/** Whether a short receive buffer has been reported, so a reconnect does not repeat the same warning. */
|
|
99
|
+
private receiveBufferReported;
|
|
98
100
|
private connectAddress?;
|
|
99
101
|
private seqNumber;
|
|
100
102
|
/**
|
|
@@ -134,7 +136,10 @@ export declare class P2PSession extends EventEmitter {
|
|
|
134
136
|
private cloudLookup?;
|
|
135
137
|
/** Local outbound IPv4 reported inside LOOKUP_WITH_KEY requests. */
|
|
136
138
|
private selfHost?;
|
|
137
|
-
/**
|
|
139
|
+
/**
|
|
140
|
+
* In-flight multi-datagram frame per data channel (see reassemble): the payload gathered so far under its
|
|
141
|
+
* parsed header, or, without a header, the start of a frame header cut by the datagram boundary.
|
|
142
|
+
*/
|
|
138
143
|
private readonly pendingByDataType;
|
|
139
144
|
/** Last delivered datagram sequence number per data type. */
|
|
140
145
|
private readonly lastSeqByType;
|
|
@@ -271,6 +276,14 @@ export declare class P2PSession extends EventEmitter {
|
|
|
271
276
|
*/
|
|
272
277
|
private decryptLevel2;
|
|
273
278
|
get isConnected(): boolean;
|
|
279
|
+
/**
|
|
280
|
+
* Ask the OS for {@link RECEIVE_BUFFER_BYTES} on a bound socket, and warn once per session when it grants
|
|
281
|
+
* less or refuses.
|
|
282
|
+
*
|
|
283
|
+
* The request is made here rather than through `createSocket`'s `recvBufferSize`: Node applies that option
|
|
284
|
+
* inside the bind callback, where a refusal is thrown out of reach of this session and ends the process.
|
|
285
|
+
*/
|
|
286
|
+
private requestReceiveBuffer;
|
|
274
287
|
/** Open the socket and start the lookup → hole-punch handshake. */
|
|
275
288
|
connect(): Promise<void>;
|
|
276
289
|
/** Cached across every `P2PSession` in this process — the local outbound IPv4 doesn't vary by
|
|
@@ -643,7 +656,13 @@ export declare class P2PSession extends EventEmitter {
|
|
|
643
656
|
*/
|
|
644
657
|
private abandonHole;
|
|
645
658
|
private clearReorderTimer;
|
|
646
|
-
/**
|
|
659
|
+
/**
|
|
660
|
+
* Reassemble one in-sequence datagram body into logical frames.
|
|
661
|
+
*
|
|
662
|
+
* Frames are packed back to back, so a frame header can itself be cut by a datagram boundary. The start
|
|
663
|
+
* of a header left at the end of a datagram is carried into the next one rather than discarded; dropping
|
|
664
|
+
* it would lose that frame and every frame after it until a datagram happened to begin on a header.
|
|
665
|
+
*/
|
|
647
666
|
private reassemble;
|
|
648
667
|
/**
|
|
649
668
|
* Forget where each data type's sequence numbering had reached, and drop any half-reassembled frame.
|
|
@@ -16,7 +16,7 @@ export interface SharedLiveSourceOptions {
|
|
|
16
16
|
makeStream: (ctx: {
|
|
17
17
|
reassertWanted: () => boolean;
|
|
18
18
|
}) => LiveStreamHandle;
|
|
19
|
-
/** No-consumer grace before teardown (default 8000ms). Distinct from the stream's keepalive. */
|
|
19
|
+
/** No-consumer grace before teardown (default 8000ms; 0 schedules teardown next tick). Distinct from the stream's keepalive. */
|
|
20
20
|
lingerMs?: number;
|
|
21
21
|
/** Per-consumer bounded queue depth; overflow → drop-to-keyframe (default 900 ≈ 30s @ 30fps). */
|
|
22
22
|
maxQueue?: number;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mega-yfue/eufy-sdk",
|
|
3
|
-
"version": "0.4.0-beta.
|
|
3
|
+
"version": "0.4.0-beta.10",
|
|
4
4
|
"description": "One typed TypeScript client for the Anker eufy v6 cloud — capability-driven devices, realtime events over P2P/MQTT/push, and live media",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "mega-yfue",
|
|
@@ -77,10 +77,10 @@
|
|
|
77
77
|
"protobufjs": "^8.8.0"
|
|
78
78
|
},
|
|
79
79
|
"devDependencies": {
|
|
80
|
-
"@types/node": "^26.6.
|
|
80
|
+
"@types/node": "^26.6.3",
|
|
81
81
|
"esbuild": "^0.28.2",
|
|
82
82
|
"prettier": "^3.9.9",
|
|
83
83
|
"typescript": "^7.0.2",
|
|
84
|
-
"vitest": "^5.0.
|
|
84
|
+
"vitest": "^5.0.2"
|
|
85
85
|
}
|
|
86
86
|
}
|