amule-ec-client 0.7.0 → 0.7.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.
Files changed (40) hide show
  1. package/dist/{AddLinkRequest-DEKGy-R2.js → AddLinkRequest-CGv1H3PC.js} +2 -2
  2. package/dist/{ClientQueueRequest-DrLXSxtp.js → ClientQueueRequest-mklt-KLi.js} +2 -2
  3. package/dist/{ClientQueueResponse-CXxY_9wU.js → ClientQueueResponse-RfXh2JGa.js} +3 -2
  4. package/dist/{CreateCategoryRequest-COulF12x.js → CreateCategoryRequest-Cyp9G7jU.js} +2 -2
  5. package/dist/{DeleteCategoryRequest-D-mljaNV.js → DeleteCategoryRequest-DbLJ4mvi.js} +2 -2
  6. package/dist/{DownloadCommandRequest-Bf1Ez8Da.js → DownloadCommandRequest-DLU7RtYs.js} +2 -2
  7. package/dist/{DownloadFileRequest-WfOIV07R.js → DownloadFileRequest-Db7oijyu.js} +2 -2
  8. package/dist/{DownloadQueueRequest-Br-pgrRt.js → DownloadQueueRequest-DdHRjl4L.js} +2 -2
  9. package/dist/{GetPreferencesRequest-BE3RbRRn.js → GetPreferencesRequest-BlWGYNCP.js} +2 -2
  10. package/dist/{PreferencesDetailsResponse-D8lBd8Ot.js → PreferencesDetailsResponse-BX6qUoga.js} +1 -1
  11. package/dist/{PreferencesResponse-BmGTQM30.js → PreferencesResponse-migFtIG7.js} +1 -1
  12. package/dist/{ReloadSharedFilesRequest-BbDUeGcq.js → ReloadSharedFilesRequest-WD9iYLje.js} +2 -2
  13. package/dist/{Request-BvScDpeu.js → Request-YQ0nIM6b.js} +1 -1
  14. package/dist/{SearchProgressResponse-BQPliUup.js → SearchProgressResponse-CkEgZGFE.js} +1 -1
  15. package/dist/{SearchRequest-DOakj8fA.js → SearchRequest-DaAKS4IO.js} +2 -2
  16. package/dist/{SearchResultsRequest-oZBs5KKm.js → SearchResultsRequest-B53jwjRH.js} +2 -2
  17. package/dist/{SearchResultsResponse-C9I9x035.js → SearchResultsResponse-C1l-bBja.js} +1 -1
  18. package/dist/{SearchStatusRequest-B1ZzSQlE.js → SearchStatusRequest-DuEa5ZYu.js} +2 -2
  19. package/dist/{SearchStopRequest-FfXf_DCn.js → SearchStopRequest-B5TZdMiB.js} +2 -2
  20. package/dist/{ServerConnectRequest-Cdiw-KWu.js → ServerConnectRequest-BeB8RSBN.js} +2 -2
  21. package/dist/{ServerDisconnectRequest-BVXSumxX.js → ServerDisconnectRequest-CSkUHETP.js} +2 -2
  22. package/dist/{ServerListRequest-3yMrgZID.js → ServerListRequest-B82686jD.js} +2 -2
  23. package/dist/{ServerListResponse-Do3iRai0.js → ServerListResponse-M3C2OcfZ.js} +1 -1
  24. package/dist/{ServerUpdateFromUrlRequest-DpxBII5W.js → ServerUpdateFromUrlRequest-BcvhRKgH.js} +2 -2
  25. package/dist/{SetFileCategoryRequest-CFgkJB-H.js → SetFileCategoryRequest-C1jWsYO5.js} +2 -2
  26. package/dist/{SetPreferencesRequest-BdZ40Ao_.js → SetPreferencesRequest-CNJVmeQl.js} +2 -2
  27. package/dist/{SharedFilePriorityRequest-BMNmaL06.js → SharedFilePriorityRequest-CBqkaXaK.js} +2 -2
  28. package/dist/{SharedFilesRequest-BZKz0oyn.js → SharedFilesRequest-5mKKjzgt.js} +2 -2
  29. package/dist/{SharedFilesResponse-DE0cd1DT.js → SharedFilesResponse-CFl0NuO-.js} +1 -1
  30. package/dist/{StatsRequest-DVwx5wk1.js → StatsRequest-C9gBUvSq.js} +2 -2
  31. package/dist/{StatsResponse-CP2F2zt0.js → StatsResponse-KOk-xT6_.js} +1 -1
  32. package/dist/{Tag-B5gWV2XF.js → Tag-D_Ybe5RQ.js} +17 -5
  33. package/dist/{UpdateCategoryRequest-Bu22YjOm.js → UpdateCategoryRequest-BOYfb6Vn.js} +2 -2
  34. package/dist/{UpdateRequest-CaQ867p8.js → UpdateRequest-csLQz7JO.js} +2 -2
  35. package/dist/UpdateState-LhdtiATk.js +443 -0
  36. package/dist/index.d.ts +24 -2
  37. package/dist/index.js +63 -44
  38. package/package.json +1 -1
  39. package/dist/DownloadQueueResponse-C-5d4teB.js +0 -241
  40. package/dist/UpdateState-Dn-SuAsj.js +0 -173
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
- import { n as Packet, r as Flags, t as Request } from "./Request-BvScDpeu.js";
2
- import { _ as ECSearchType, a as StringTag, b as ProtocolVersion, c as UInt128Tag, d as UShortTag, f as findNumericTag, g as ECSearchFileDownloadStatus, h as ECOpCode, i as Ipv4Tag, l as UIntTag, m as ECDetailLevel, n as DoubleTag, o as Tag, p as findTag, r as Hash16Tag, s as UByteTag, t as CustomTag, u as ULongTag, v as ECTagName, y as EcPrefs } from "./Tag-B5gWV2XF.js";
1
+ import { n as Packet, r as Flags, t as Request } from "./Request-YQ0nIM6b.js";
2
+ import { _ as ECSearchType, a as StringTag, b as ProtocolVersion, c as UInt128Tag, d as UShortTag, f as findNumericTag, g as ECSearchFileDownloadStatus, h as ECOpCode, i as Ipv4Tag, l as UIntTag, m as ECDetailLevel, n as DoubleTag, o as Tag, p as findTag, r as Hash16Tag, s as UByteTag, t as CustomTag, u as ULongTag, v as ECTagName, y as EcPrefs } from "./Tag-D_Ybe5RQ.js";
3
3
  import { n as PARTSIZE, t as ChunkStatus } from "./download-details-OM0FJUhZ.js";
4
4
  import * as net from "net";
5
5
  import * as zlib from "zlib";
@@ -182,7 +182,11 @@ var TagParser = class {
182
182
  case 5: return new ULongTag(name, value.length >= 8 ? value.readBigUInt64BE(0) : 0n);
183
183
  case 10: return new UInt128Tag(name, value.length >= 16 ? this.parseUInt128(value) : 0n);
184
184
  case 6: return new StringTag(name, value[value.length - 1] === 0 ? value.toString("utf-8", 0, value.length - 1) : value.toString("utf-8"));
185
- case 7: return new DoubleTag(name, value.length >= 8 ? value.readDoubleBE(0) : 0);
185
+ case 7: {
186
+ const tag = new DoubleTag(name);
187
+ tag.parseValue(value);
188
+ return tag;
189
+ }
186
190
  case 8: {
187
191
  if (value.length !== 6) throw new InvalidECException(`Ipv4Tag value must be 6 bytes long, got ${value.length}`);
188
192
  const address = `${value[0]}.${value[1]}.${value[2]}.${value[3]}`;
@@ -334,7 +338,7 @@ var TagEncoder = class {
334
338
  case 4: return 4;
335
339
  case 5: return 8;
336
340
  case 10: return 16;
337
- case 7: return 8;
341
+ case 7: return encoded.length;
338
342
  case 8: return 6;
339
343
  case 9: return 16;
340
344
  default: return 0;
@@ -838,13 +842,26 @@ var AmuleClient = class {
838
842
  * Get server statistics
839
843
  */
840
844
  async getStats() {
841
- const { StatsRequest } = await import("./StatsRequest-DVwx5wk1.js");
842
- const { StatsResponseParser } = await import("./StatsResponse-CP2F2zt0.js");
845
+ const { StatsRequest } = await import("./StatsRequest-C9gBUvSq.js");
846
+ const { StatsResponseParser } = await import("./StatsResponse-KOk-xT6_.js");
843
847
  const request = new StatsRequest();
844
848
  const packet = await this.connection.sendRequest(request);
845
849
  return StatsResponseParser.fromPacket(packet);
846
850
  }
847
851
  /**
852
+ * Per-connection file-detail state (diff baselines, source names, merged snapshots).
853
+ * The daemon diffs per connection and shares the diff state between the update,
854
+ * download-queue and shared-files requests, so this state must be fed by all of
855
+ * them (see UpdateState). Call only after sendRequest: connecting may have started
856
+ * a new session, which invalidates the previous state.
857
+ */
858
+ async getFileState() {
859
+ const { UpdateState } = await import("./UpdateState-LhdtiATk.js");
860
+ const generation = this.connection.getSessionGeneration();
861
+ if (!this.updateState || this.updateState.sessionGeneration !== generation) this.updateState = new UpdateState(generation);
862
+ return this.updateState;
863
+ }
864
+ /**
848
865
  * Get updates for files, clients, servers, and friends.
849
866
  *
850
867
  * The underlying EC_OP_GET_UPDATE request is incremental per connection: the daemon
@@ -854,13 +871,10 @@ var AmuleClient = class {
854
871
  * and file ecid). The cache is reset whenever the connection is re-established.
855
872
  */
856
873
  async getUpdate(detailLevel = 4) {
857
- const { UpdateRequest } = await import("./UpdateRequest-CaQ867p8.js");
858
- const { UpdateState } = await import("./UpdateState-Dn-SuAsj.js");
874
+ const { UpdateRequest } = await import("./UpdateRequest-csLQz7JO.js");
859
875
  const request = new UpdateRequest(detailLevel);
860
876
  const packet = await this.connection.sendRequest(request);
861
- const generation = this.connection.getSessionGeneration();
862
- if (!this.updateState || this.updateState.sessionGeneration !== generation) this.updateState = new UpdateState(generation);
863
- return this.updateState.apply(packet);
877
+ return (await this.getFileState()).apply(packet);
864
878
  }
865
879
  /**
866
880
  * Get the download queue including per-peer source details.
@@ -877,7 +891,7 @@ var AmuleClient = class {
877
891
  * Start an asynchronous search
878
892
  */
879
893
  async searchAsync(query, searchType, filters) {
880
- const { SearchRequest } = await import("./SearchRequest-DOakj8fA.js");
894
+ const { SearchRequest } = await import("./SearchRequest-DaAKS4IO.js");
881
895
  const request = new SearchRequest(query, searchType, filters);
882
896
  await this.connection.sendRequest(request);
883
897
  return query;
@@ -886,8 +900,8 @@ var AmuleClient = class {
886
900
  * Get search status (0-1)
887
901
  */
888
902
  async searchStatus() {
889
- const { SearchStatusRequest } = await import("./SearchStatusRequest-B1ZzSQlE.js");
890
- const { SearchProgressResponse } = await import("./SearchProgressResponse-BQPliUup.js");
903
+ const { SearchStatusRequest } = await import("./SearchStatusRequest-DuEa5ZYu.js");
904
+ const { SearchProgressResponse } = await import("./SearchProgressResponse-CkEgZGFE.js");
891
905
  const request = new SearchStatusRequest();
892
906
  const packet = await this.connection.sendRequest(request);
893
907
  return SearchProgressResponse.fromPacket(packet).progress;
@@ -896,8 +910,8 @@ var AmuleClient = class {
896
910
  * Get search results
897
911
  */
898
912
  async searchResults() {
899
- const { SearchResultsRequest } = await import("./SearchResultsRequest-oZBs5KKm.js");
900
- const { SearchResultsResponseParser } = await import("./SearchResultsResponse-C9I9x035.js");
913
+ const { SearchResultsRequest } = await import("./SearchResultsRequest-B53jwjRH.js");
914
+ const { SearchResultsResponseParser } = await import("./SearchResultsResponse-C1l-bBja.js");
901
915
  const request = new SearchResultsRequest();
902
916
  const packet = await this.connection.sendRequest(request);
903
917
  return SearchResultsResponseParser.fromPacket(packet);
@@ -918,7 +932,7 @@ var AmuleClient = class {
918
932
  * Stop current search
919
933
  */
920
934
  async searchStop() {
921
- const { SearchStopRequest } = await import("./SearchStopRequest-FfXf_DCn.js");
935
+ const { SearchStopRequest } = await import("./SearchStopRequest-B5TZdMiB.js");
922
936
  const request = new SearchStopRequest();
923
937
  await this.connection.sendRequest(request);
924
938
  }
@@ -926,7 +940,7 @@ var AmuleClient = class {
926
940
  * Download a file from search results
927
941
  */
928
942
  async downloadSearchResult(hash) {
929
- const { DownloadFileRequest } = await import("./DownloadFileRequest-WfOIV07R.js");
943
+ const { DownloadFileRequest } = await import("./DownloadFileRequest-Db7oijyu.js");
930
944
  const request = new DownloadFileRequest(hash);
931
945
  await this.connection.sendRequest(request);
932
946
  }
@@ -934,35 +948,40 @@ var AmuleClient = class {
934
948
  * Download from an ed2k link
935
949
  */
936
950
  async downloadEd2kLink(link) {
937
- const { AddLinkRequest } = await import("./AddLinkRequest-DEKGy-R2.js");
951
+ const { AddLinkRequest } = await import("./AddLinkRequest-CGv1H3PC.js");
938
952
  const request = new AddLinkRequest(link);
939
953
  await this.connection.sendRequest(request);
940
954
  }
941
955
  /**
942
- * Get download queue
956
+ * Get download queue (EC_OP_GET_DLOAD_QUEUE, full detail).
957
+ *
958
+ * The response rebases the per-connection diff state the daemon shares with
959
+ * getUpdate()/getDownloadQueueWithSources(), so it is fed into the same
960
+ * client-side state: both methods stay consistent however they are interleaved,
961
+ * and chunkInfo/sourceNames are correct across repeated calls.
943
962
  */
944
963
  async getDownloadQueue() {
945
- const { DownloadQueueRequest } = await import("./DownloadQueueRequest-Br-pgrRt.js");
946
- const { DownloadQueueResponseParser } = await import("./DownloadQueueResponse-C-5d4teB.js").then((n) => n.n);
964
+ const { DownloadQueueRequest } = await import("./DownloadQueueRequest-DdHRjl4L.js");
947
965
  const request = new DownloadQueueRequest();
948
966
  const packet = await this.connection.sendRequest(request);
949
- return DownloadQueueResponseParser.fromPacket(packet).files;
967
+ return (await this.getFileState()).applyDownloadQueue(packet);
950
968
  }
951
969
  /**
952
970
  * Get shared files
953
971
  */
954
972
  async getSharedFiles() {
955
- const { SharedFilesRequest } = await import("./SharedFilesRequest-BZKz0oyn.js");
956
- const { SharedFilesResponseParser } = await import("./SharedFilesResponse-DE0cd1DT.js").then((n) => n.n);
973
+ const { SharedFilesRequest } = await import("./SharedFilesRequest-5mKKjzgt.js");
974
+ const { SharedFilesResponseParser } = await import("./SharedFilesResponse-CFl0NuO-.js").then((n) => n.n);
957
975
  const request = new SharedFilesRequest();
958
976
  const packet = await this.connection.sendRequest(request);
977
+ (await this.getFileState()).applySharedFiles(packet);
959
978
  return SharedFilesResponseParser.fromPacket(packet).files;
960
979
  }
961
980
  /**
962
981
  * Reload shared files list
963
982
  */
964
983
  async reloadSharedFiles() {
965
- const { ReloadSharedFilesRequest } = await import("./ReloadSharedFilesRequest-BbDUeGcq.js");
984
+ const { ReloadSharedFilesRequest } = await import("./ReloadSharedFilesRequest-WD9iYLje.js");
966
985
  const request = new ReloadSharedFilesRequest();
967
986
  await this.connection.sendRequest(request);
968
987
  }
@@ -971,8 +990,8 @@ var AmuleClient = class {
971
990
  * (EC_OP_GET_ULOAD_QUEUE). For download sources use getDownloadQueueWithSources().
972
991
  */
973
992
  async getClientQueue() {
974
- const { ClientQueueRequest } = await import("./ClientQueueRequest-DrLXSxtp.js");
975
- const { ClientQueueResponseParser } = await import("./ClientQueueResponse-CXxY_9wU.js").then((n) => n.n);
993
+ const { ClientQueueRequest } = await import("./ClientQueueRequest-mklt-KLi.js");
994
+ const { ClientQueueResponseParser } = await import("./ClientQueueResponse-RfXh2JGa.js").then((n) => n.n);
976
995
  const request = new ClientQueueRequest();
977
996
  const packet = await this.connection.sendRequest(request);
978
997
  return ClientQueueResponseParser.fromPacket(packet).clients;
@@ -981,8 +1000,8 @@ var AmuleClient = class {
981
1000
  * Get the list of servers
982
1001
  */
983
1002
  async getServerList() {
984
- const { ServerListRequest } = await import("./ServerListRequest-3yMrgZID.js");
985
- const { ServerListResponseParser } = await import("./ServerListResponse-Do3iRai0.js").then((n) => n.n);
1003
+ const { ServerListRequest } = await import("./ServerListRequest-B82686jD.js");
1004
+ const { ServerListResponseParser } = await import("./ServerListResponse-M3C2OcfZ.js").then((n) => n.n);
986
1005
  const request = new ServerListRequest();
987
1006
  const packet = await this.connection.sendRequest(request);
988
1007
  return ServerListResponseParser.fromPacket(packet).servers;
@@ -991,7 +1010,7 @@ var AmuleClient = class {
991
1010
  * Connect to a specific server
992
1011
  */
993
1012
  async connectToServer(ip, port) {
994
- const { ServerConnectRequest } = await import("./ServerConnectRequest-Cdiw-KWu.js");
1013
+ const { ServerConnectRequest } = await import("./ServerConnectRequest-BeB8RSBN.js");
995
1014
  const request = new ServerConnectRequest(ip, port);
996
1015
  await this.connection.sendRequest(request);
997
1016
  }
@@ -999,7 +1018,7 @@ var AmuleClient = class {
999
1018
  * Disconnect from the current server
1000
1019
  */
1001
1020
  async disconnectFromServer() {
1002
- const { ServerDisconnectRequest } = await import("./ServerDisconnectRequest-BVXSumxX.js");
1021
+ const { ServerDisconnectRequest } = await import("./ServerDisconnectRequest-CSkUHETP.js");
1003
1022
  const request = new ServerDisconnectRequest();
1004
1023
  await this.connection.sendRequest(request);
1005
1024
  }
@@ -1007,7 +1026,7 @@ var AmuleClient = class {
1007
1026
  * Create a category
1008
1027
  */
1009
1028
  async createCategory(category) {
1010
- const { CreateCategoryRequest } = await import("./CreateCategoryRequest-COulF12x.js");
1029
+ const { CreateCategoryRequest } = await import("./CreateCategoryRequest-Cyp9G7jU.js");
1011
1030
  const request = new CreateCategoryRequest(category);
1012
1031
  await this.connection.sendRequest(request);
1013
1032
  }
@@ -1015,7 +1034,7 @@ var AmuleClient = class {
1015
1034
  * Update a category
1016
1035
  */
1017
1036
  async updateCategory(id, category) {
1018
- const { UpdateCategoryRequest } = await import("./UpdateCategoryRequest-Bu22YjOm.js");
1037
+ const { UpdateCategoryRequest } = await import("./UpdateCategoryRequest-BOYfb6Vn.js");
1019
1038
  const request = new UpdateCategoryRequest(id, category);
1020
1039
  await this.connection.sendRequest(request);
1021
1040
  }
@@ -1023,7 +1042,7 @@ var AmuleClient = class {
1023
1042
  * Delete a category
1024
1043
  */
1025
1044
  async deleteCategory(id) {
1026
- const { DeleteCategoryRequest } = await import("./DeleteCategoryRequest-D-mljaNV.js");
1045
+ const { DeleteCategoryRequest } = await import("./DeleteCategoryRequest-DbLJ4mvi.js");
1027
1046
  const request = new DeleteCategoryRequest(id);
1028
1047
  await this.connection.sendRequest(request);
1029
1048
  }
@@ -1031,8 +1050,8 @@ var AmuleClient = class {
1031
1050
  * Get all categories
1032
1051
  */
1033
1052
  async getCategories() {
1034
- const { GetPreferencesRequest } = await import("./GetPreferencesRequest-BE3RbRRn.js");
1035
- const { PreferencesResponseParser } = await import("./PreferencesResponse-BmGTQM30.js");
1053
+ const { GetPreferencesRequest } = await import("./GetPreferencesRequest-BlWGYNCP.js");
1054
+ const { PreferencesResponseParser } = await import("./PreferencesResponse-migFtIG7.js");
1036
1055
  const request = new GetPreferencesRequest(1);
1037
1056
  const packet = await this.connection.sendRequest(request);
1038
1057
  return PreferencesResponseParser.fromPacket(packet).categories;
@@ -1041,7 +1060,7 @@ var AmuleClient = class {
1041
1060
  * Set file category
1042
1061
  */
1043
1062
  async setFileCategory(hash, categoryId) {
1044
- const { SetFileCategoryRequest } = await import("./SetFileCategoryRequest-CFgkJB-H.js");
1063
+ const { SetFileCategoryRequest } = await import("./SetFileCategoryRequest-C1jWsYO5.js");
1045
1064
  const request = new SetFileCategoryRequest(hash, categoryId);
1046
1065
  await this.connection.sendRequest(request);
1047
1066
  }
@@ -1049,7 +1068,7 @@ var AmuleClient = class {
1049
1068
  * Send a download command (PAUSE, RESUME, STOP, DELETE, etc.)
1050
1069
  */
1051
1070
  async sendDownloadCommand(hash, command) {
1052
- const { DownloadCommandRequest } = await import("./DownloadCommandRequest-Bf1Ez8Da.js");
1071
+ const { DownloadCommandRequest } = await import("./DownloadCommandRequest-DLU7RtYs.js");
1053
1072
  const request = new DownloadCommandRequest(hash, command);
1054
1073
  await this.connection.sendRequest(request);
1055
1074
  }
@@ -1081,7 +1100,7 @@ var AmuleClient = class {
1081
1100
  * Trigger a server list update from an URL.
1082
1101
  */
1083
1102
  async updateServerListFromUrl(url) {
1084
- const { ServerUpdateFromUrlRequest } = await import("./ServerUpdateFromUrlRequest-DpxBII5W.js");
1103
+ const { ServerUpdateFromUrlRequest } = await import("./ServerUpdateFromUrlRequest-BcvhRKgH.js");
1085
1104
  const request = new ServerUpdateFromUrlRequest(url);
1086
1105
  await this.connection.sendRequest(request);
1087
1106
  }
@@ -1089,7 +1108,7 @@ var AmuleClient = class {
1089
1108
  * Set upload priority for a shared file.
1090
1109
  */
1091
1110
  async setSharedFilePriority(hash, priority) {
1092
- const { SharedFilePriorityRequest } = await import("./SharedFilePriorityRequest-BMNmaL06.js");
1111
+ const { SharedFilePriorityRequest } = await import("./SharedFilePriorityRequest-CBqkaXaK.js");
1093
1112
  const request = new SharedFilePriorityRequest(hash, priority);
1094
1113
  await this.connection.sendRequest(request);
1095
1114
  }
@@ -1097,8 +1116,8 @@ var AmuleClient = class {
1097
1116
  * Get daemon preferences for general/connection/servers/security sections.
1098
1117
  */
1099
1118
  async getPreferences() {
1100
- const { GetPreferencesRequest } = await import("./GetPreferencesRequest-BE3RbRRn.js");
1101
- const { PreferencesDetailsResponseParser } = await import("./PreferencesDetailsResponse-D8lBd8Ot.js");
1119
+ const { GetPreferencesRequest } = await import("./GetPreferencesRequest-BlWGYNCP.js");
1120
+ const { PreferencesDetailsResponseParser } = await import("./PreferencesDetailsResponse-BX6qUoga.js");
1102
1121
  const request = new GetPreferencesRequest(2118);
1103
1122
  const packet = await this.connection.sendRequest(request);
1104
1123
  return PreferencesDetailsResponseParser.fromPacket(packet).preferences;
@@ -1108,7 +1127,7 @@ var AmuleClient = class {
1108
1127
  */
1109
1128
  async setPreferences(preferences) {
1110
1129
  if (!preferences.general && !preferences.connection && !preferences.servers && !preferences.security) return;
1111
- const { SetPreferencesRequest } = await import("./SetPreferencesRequest-BdZ40Ao_.js");
1130
+ const { SetPreferencesRequest } = await import("./SetPreferencesRequest-CNJVmeQl.js");
1112
1131
  const request = new SetPreferencesRequest(preferences);
1113
1132
  await this.connection.sendRequest(request);
1114
1133
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "amule-ec-client",
3
- "version": "0.7.0",
3
+ "version": "0.7.1",
4
4
  "description": "A TypeScript client for Amule EC API.",
5
5
  "author": "José Carlos HR <joecarlhr@gmail.com>",
6
6
  "license": "MIT",
@@ -1,241 +0,0 @@
1
- import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
2
- import { f as findNumericTag, p as findTag } from "./Tag-B5gWV2XF.js";
3
- import { n as PARTSIZE, t as ChunkStatus } from "./download-details-OM0FJUhZ.js";
4
- import { a as toOptionalNumber, n as tagOwnNumericValue, r as toOptionalBool } from "./utils-CNoUroOI.js";
5
- import { r as parseKnownFileFields } from "./SharedFilesResponse-DE0cd1DT.js";
6
- //#region src/response/DownloadDetailsResponse.ts
7
- /**
8
- * Decode an aMule EC RLE-compressed buffer.
9
- * Format: [value, value, count] repeats value count times; other bytes pass through.
10
- */
11
- function rleDecode(buf) {
12
- let size = 0;
13
- let index = 0;
14
- while (index < buf.length) if (index < buf.length - 2 && buf[index + 1] === buf[index]) {
15
- size += buf[index + 2];
16
- index += 3;
17
- } else {
18
- size += 1;
19
- index += 1;
20
- }
21
- const output = Buffer.alloc(size);
22
- let outIndex = 0;
23
- index = 0;
24
- while (index < buf.length) if (index < buf.length - 2 && buf[index + 1] === buf[index]) {
25
- const count = buf[index + 2];
26
- output.fill(buf[index], outIndex, outIndex + count);
27
- outIndex += count;
28
- index += 3;
29
- } else {
30
- output[outIndex++] = buf[index];
31
- index += 1;
32
- }
33
- return output;
34
- }
35
- /**
36
- * Reconstruct the current state from the previous state and an RLE-decoded XOR diff,
37
- * mirroring aMule's RLE_Data: resize previous buffer to the diff size (zero-extend on
38
- * grow, truncate on shrink), then XOR byte-wise.
39
- */
40
- function xorReconstruct(previous, decodedDiff) {
41
- const result = Buffer.alloc(decodedDiff.length, 0);
42
- previous.copy(result, 0, 0, Math.min(previous.length, decodedDiff.length));
43
- for (let i = 0; i < decodedDiff.length; i++) result[i] ^= decodedDiff[i];
44
- return result;
45
- }
46
- /**
47
- * Decode an RLE-decoded buffer of byte-interleaved (column-major) little-endian uint64 values.
48
- */
49
- function decodeInterleavedUint64(decoded) {
50
- if (decoded.length === 0 || decoded.length % 8 !== 0) return [];
51
- const valueCount = decoded.length / 8;
52
- const values = new Array(valueCount);
53
- for (let i = 0; i < valueCount; i++) {
54
- let value = 0;
55
- for (let byte = 7; byte >= 0; byte--) value = value * 256 + decoded[i + byte * valueCount];
56
- values[i] = value;
57
- }
58
- return values;
59
- }
60
- function stringValue(tag) {
61
- if (!tag) return "";
62
- const value = tag.getValue();
63
- return typeof value === "string" ? value : "";
64
- }
65
- function bufferValue(tag) {
66
- if (!tag) return;
67
- const value = tag.getValue();
68
- return Buffer.isBuffer(value) ? value : void 0;
69
- }
70
- function nestedTag(parent, tagName) {
71
- return parent.nestedTags ? findTag(parent.nestedTags, tagName) : void 0;
72
- }
73
- function nestedNumeric(parent, tagName) {
74
- if (!parent.nestedTags) return 0;
75
- const numeric = findNumericTag(parent.nestedTags, tagName);
76
- if (numeric) return Number(numeric.getValue());
77
- return tagOwnNumericValue(findTag(parent.nestedTags, tagName)) ?? 0;
78
- }
79
- /**
80
- * Extract the raw (RLE-encoded) part/gap/req status buffers of a partfile tag.
81
- */
82
- function extractPartFileStatusBuffers(fileTag) {
83
- return {
84
- partStatus: bufferValue(nestedTag(fileTag, 786)),
85
- gapStatus: bufferValue(nestedTag(fileTag, 787)),
86
- reqStatus: bufferValue(nestedTag(fileTag, 788))
87
- };
88
- }
89
- /**
90
- * Compute per-chunk status from RLE-decoded part/gap/req status buffers.
91
- */
92
- function computeChunkInfo(sizeFull, buffers) {
93
- const partCount = sizeFull > 0 ? Math.ceil(sizeFull / PARTSIZE) : 0;
94
- const availability = new Array(partCount).fill(0);
95
- if (buffers.partStatus && buffers.partStatus.length > 0) for (let i = 0; i < Math.min(buffers.partStatus.length, partCount); i++) availability[i] = buffers.partStatus[i];
96
- const chunks = new Array(partCount).fill(ChunkStatus.COMPLETE);
97
- if (partCount > 0 && buffers.gapStatus && buffers.gapStatus.length > 0) {
98
- const gapValues = decodeInterleavedUint64(buffers.gapStatus);
99
- for (let i = 0; i + 1 < gapValues.length; i += 2) {
100
- const gapStart = gapValues[i];
101
- const gapEnd = gapValues[i + 1];
102
- if (gapStart > sizeFull || gapEnd > sizeFull || gapStart >= gapEnd) continue;
103
- const startPart = Math.floor(gapStart / PARTSIZE);
104
- const endPart = Math.min(Math.floor(gapEnd / PARTSIZE) + 1, partCount);
105
- for (let part = startPart; part < endPart; part++) {
106
- const chunkStart = part * PARTSIZE;
107
- if (gapStart < Math.min((part + 1) * 9728e3, sizeFull) && gapEnd > chunkStart) chunks[part] = availability[part] > 0 ? ChunkStatus.AVAILABLE : ChunkStatus.UNAVAILABLE;
108
- }
109
- }
110
- }
111
- if (partCount > 0 && buffers.reqStatus && buffers.reqStatus.length > 0) {
112
- const reqValues = decodeInterleavedUint64(buffers.reqStatus);
113
- for (let i = 0; i + 1 < reqValues.length; i += 2) {
114
- const reqStart = reqValues[i];
115
- const reqEnd = reqValues[i + 1];
116
- if (reqStart > sizeFull || reqEnd > sizeFull || reqStart >= reqEnd) continue;
117
- const startPart = Math.floor(reqStart / PARTSIZE);
118
- const endPart = Math.min(Math.floor(reqEnd / PARTSIZE) + 1, partCount);
119
- for (let part = startPart; part < endPart; part++) {
120
- if (chunks[part] === ChunkStatus.COMPLETE) continue;
121
- const chunkStart = part * PARTSIZE;
122
- if (reqStart < Math.min((part + 1) * 9728e3, sizeFull) && reqEnd > chunkStart) chunks[part] = ChunkStatus.DOWNLOADING;
123
- }
124
- }
125
- }
126
- return {
127
- chunks,
128
- availability,
129
- partCount,
130
- sizeFull
131
- };
132
- }
133
- /**
134
- * Chunk details of a partfile tag from a full (non-incremental) download queue packet.
135
- * Only valid for EC_OP_GET_DLOAD_QUEUE responses: incremental updates (EC_OP_GET_UPDATE)
136
- * send XOR diffs for the status buffers and must be reconstructed statefully instead.
137
- */
138
- function chunkInfoFromPartFileTag(fileTag) {
139
- const sizeFull = nestedNumeric(fileTag, 771);
140
- const raw = extractPartFileStatusBuffers(fileTag);
141
- return computeChunkInfo(sizeFull, {
142
- partStatus: raw.partStatus ? rleDecode(raw.partStatus) : void 0,
143
- gapStatus: raw.gapStatus ? rleDecode(raw.gapStatus) : void 0,
144
- reqStatus: raw.reqStatus ? rleDecode(raw.reqStatus) : void 0
145
- });
146
- }
147
- /**
148
- * Raw diff entries of the source-names map of a partfile tag, or undefined when the
149
- * packet carries no source-names changes for this file.
150
- *
151
- * The daemon sends source names (the filenames under which the sources share the file)
152
- * as a per-connection incremental map (see CPartFile_Encoder::Encode in aMule's
153
- * ExternalConn.cpp): an EC_TAG_PARTFILE_SOURCE_NAMES container whose children are
154
- * integer-valued EC_TAG_PARTFILE_SOURCE_NAMES tags (the map key), each carrying a
155
- * nested count (0 removes the entry) and, only when the entry is new, a nested name
156
- * string. The map is never reset while the connection lives, not even for
157
- * EC_DETAIL_FULL requests.
158
- */
159
- function sourceNameEntriesFromFileTag(fileTag) {
160
- const container = nestedTag(fileTag, 789);
161
- if (!container) return;
162
- const entries = [];
163
- for (const child of container.nestedTags || []) {
164
- if (child.name !== 789) continue;
165
- const id = tagOwnNumericValue(child);
166
- if (id === void 0) continue;
167
- const name = stringValue(nestedTag(child, 789)) || void 0;
168
- const count = nestedNumeric(child, 796);
169
- entries.push({
170
- id,
171
- name,
172
- count
173
- });
174
- }
175
- return entries;
176
- }
177
- /**
178
- * Stateless view of source-name diff entries: only entries whose name is present in
179
- * this very packet (i.e. new for the connection). Complete on the first request of a
180
- * connection; later requests only carry changes, so prefer the stateful update path
181
- * for polling.
182
- */
183
- function sourceNameCountsFromEntries(entries) {
184
- return entries.filter((entry) => entry.name !== void 0 && entry.count > 0).map((entry) => ({
185
- name: entry.name,
186
- count: entry.count
187
- }));
188
- }
189
- //#endregion
190
- //#region src/response/DownloadQueueResponse.ts
191
- var DownloadQueueResponse_exports = /* @__PURE__ */ __exportAll({ DownloadQueueResponseParser: () => DownloadQueueResponseParser });
192
- var DownloadQueueResponseParser = class {
193
- static fromPacket(packet) {
194
- const files = [];
195
- const partfileTags = packet.tags.filter((tag) => tag.name === 768);
196
- for (const fileTag of partfileTags) {
197
- const tags = fileTag.nestedTags || [];
198
- let a4afSources = void 0;
199
- const a4afSourcesTag = findTag(tags, 802);
200
- if (a4afSourcesTag) {
201
- a4afSources = [];
202
- a4afSourcesTag.nestedTags = a4afSourcesTag.nestedTags || [];
203
- for (const sourceTag of a4afSourcesTag.nestedTags) if (sourceTag.name === 15) a4afSources.push(sourceTag.getValue());
204
- }
205
- const file = {
206
- ...parseKnownFileFields(fileTag),
207
- partMetID: findNumericTag(tags, 770)?.getShort(),
208
- sizeXfer: toOptionalNumber(findNumericTag(tags, 772)?.getLong()),
209
- sizeDone: toOptionalNumber(findNumericTag(tags, 774)?.getLong()),
210
- fileStatus: findNumericTag(tags, 776)?.getInt(),
211
- stopped: toOptionalBool(findNumericTag(tags, 791)?.getInt()),
212
- sourceCount: findNumericTag(tags, 778)?.getShort(),
213
- sourceNotCurrCount: findNumericTag(tags, 780)?.getShort(),
214
- sourceXferCount: findNumericTag(tags, 781)?.getShort(),
215
- sourceCountA4AF: findNumericTag(tags, 779)?.getShort(),
216
- speed: toOptionalNumber(findNumericTag(tags, 775)?.getLong()),
217
- downPrio: findNumericTag(tags, 777)?.getInt(),
218
- fileCat: toOptionalNumber(findNumericTag(tags, 783)?.getLong()),
219
- lastSeenComplete: toOptionalNumber(findNumericTag(tags, 785)?.getLong()),
220
- lastDateChanged: toOptionalNumber(findNumericTag(tags, 784)?.getLong()),
221
- downloadActiveTime: findNumericTag(tags, 792)?.getInt(),
222
- availablePartCount: findNumericTag(tags, 797)?.getShort(),
223
- a4AFAuto: toOptionalBool(findNumericTag(tags, 801)?.getInt()),
224
- hashedPartCount: findNumericTag(tags, 800)?.getInt(),
225
- getLostDueToCorruption: toOptionalNumber(findNumericTag(tags, 793)?.getLong()),
226
- getGainDueToCompression: toOptionalNumber(findNumericTag(tags, 794)?.getLong()),
227
- totalPacketsSavedDueToICH: findNumericTag(tags, 795)?.getInt(),
228
- a4afSources
229
- };
230
- if (file.fileHashHexString) {
231
- file.chunkInfo = chunkInfoFromPartFileTag(fileTag);
232
- const sourceNameEntries = sourceNameEntriesFromFileTag(fileTag);
233
- if (sourceNameEntries) file.sourceNames = sourceNameCountsFromEntries(sourceNameEntries);
234
- }
235
- files.push(file);
236
- }
237
- return { files };
238
- }
239
- };
240
- //#endregion
241
- export { rleDecode as a, extractPartFileStatusBuffers as i, DownloadQueueResponse_exports as n, sourceNameEntriesFromFileTag as o, computeChunkInfo as r, xorReconstruct as s, DownloadQueueResponseParser as t };