@nerimity/nerimity.js 1.18.0 → 1.20.0

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 (41) hide show
  1. package/build/AsyncFunctionQueue.d.ts +43 -0
  2. package/build/AsyncFunctionQueue.d.ts.map +1 -0
  3. package/build/AsyncFunctionQueue.js +105 -0
  4. package/build/AsyncFunctionQueue.js.map +1 -0
  5. package/build/classes/Channel.d.ts +2 -0
  6. package/build/classes/Channel.d.ts.map +1 -1
  7. package/build/classes/Channel.js +16 -12
  8. package/build/classes/Channel.js.map +1 -1
  9. package/build/classes/Client.js +10 -2
  10. package/build/classes/Client.js.map +1 -1
  11. package/build/classes/Message.d.ts +1 -0
  12. package/build/classes/Message.d.ts.map +1 -1
  13. package/build/classes/Message.js +1 -0
  14. package/build/classes/Message.js.map +1 -1
  15. package/build/classes/Server.d.ts +2 -0
  16. package/build/classes/Server.d.ts.map +1 -1
  17. package/build/classes/Server.js +1 -0
  18. package/build/classes/Server.js.map +1 -1
  19. package/build/classes/Webhooks.d.ts.map +1 -1
  20. package/build/classes/Webhooks.js +6 -1
  21. package/build/classes/Webhooks.js.map +1 -1
  22. package/build/services/MessageService.d.ts +1 -0
  23. package/build/services/MessageService.d.ts.map +1 -1
  24. package/build/services/MessageService.js +18 -24
  25. package/build/services/MessageService.js.map +1 -1
  26. package/build/services/PostsService.d.ts.map +1 -1
  27. package/build/services/PostsService.js +0 -8
  28. package/build/services/PostsService.js.map +1 -1
  29. package/build/services/ServerService.d.ts.map +1 -1
  30. package/build/services/ServerService.js +0 -6
  31. package/build/services/ServerService.js.map +1 -1
  32. package/package.json +38 -38
  33. package/src/AsyncFunctionQueue.ts +115 -0
  34. package/src/classes/Channel.ts +17 -12
  35. package/src/classes/Client.ts +12 -2
  36. package/src/classes/Message.ts +2 -0
  37. package/src/classes/Server.ts +2 -0
  38. package/src/classes/Webhooks.ts +8 -1
  39. package/src/services/MessageService.ts +19 -24
  40. package/src/services/PostsService.ts +0 -8
  41. package/src/services/ServerService.ts +0 -6
@@ -1 +1 @@
1
- {"version":3,"file":"PostsService.d.ts","sourceRoot":"","sources":["../../src/services/PostsService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC3C,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAIrC,UAAU,YAAY;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,IAAI,CAAC,EAAE;QACL,OAAO,EAAE,MAAM,EAAE,CAAC;KACnB,CAAC;CACH;AAED,UAAU,YAAY;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,UAAU,cAAc;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wBAAsB,QAAQ,CAAC,MAAM,EAAE,MAAM,sBAS5C;AAED,wBAAsB,QAAQ,CAAC,IAAI,EAAE,YAAY,oBAchD;AAED,wBAAsB,QAAQ,CAAC,IAAI,EAAE,YAAY,oBAUhD;AAED,wBAAsB,UAAU,CAAC,IAAI,EAAE,cAAc,oBASpD"}
1
+ {"version":3,"file":"PostsService.d.ts","sourceRoot":"","sources":["../../src/services/PostsService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC3C,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAIrC,UAAU,YAAY;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,IAAI,CAAC,EAAE;QACL,OAAO,EAAE,MAAM,EAAE,CAAC;KACnB,CAAC;CACH;AAED,UAAU,YAAY;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,UAAU,cAAc;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wBAAsB,QAAQ,CAAC,MAAM,EAAE,MAAM,sBAO5C;AAED,wBAAsB,QAAQ,CAAC,IAAI,EAAE,YAAY,oBAYhD;AAED,wBAAsB,QAAQ,CAAC,IAAI,EAAE,YAAY,oBAQhD;AAED,wBAAsB,UAAU,CAAC,IAAI,EAAE,cAAc,oBAOpD"}
@@ -12,8 +12,6 @@ async function getPosts(client) {
12
12
  url: serviceEndpoints_1.ServiceEndpoints.GetPosts(),
13
13
  method: "GET",
14
14
  useToken: true,
15
- }).catch((err) => {
16
- throw new Error(`Failed to get posts. ${err.message}`);
17
15
  });
18
16
  }
19
17
  async function postPost(opts) {
@@ -27,8 +25,6 @@ async function postPost(opts) {
27
25
  poll: opts.poll,
28
26
  },
29
27
  useToken: true,
30
- }).catch((err) => {
31
- throw new Error(`Failed to send post. ${err.message}`);
32
28
  });
33
29
  }
34
30
  async function editPost(opts) {
@@ -38,8 +34,6 @@ async function editPost(opts) {
38
34
  method: "PATCH",
39
35
  body: { content: opts.content },
40
36
  useToken: true,
41
- }).catch((err) => {
42
- throw new Error(`Failed to edit post. ${err.message}`);
43
37
  });
44
38
  }
45
39
  async function deletePost(opts) {
@@ -48,8 +42,6 @@ async function deletePost(opts) {
48
42
  url: serviceEndpoints_1.ServiceEndpoints.DeletePost(opts.postId),
49
43
  method: "DELETE",
50
44
  useToken: true,
51
- }).catch((err) => {
52
- throw new Error(`Failed to delete post. ${err.message}`);
53
45
  });
54
46
  }
55
47
  //# sourceMappingURL=PostsService.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"PostsService.js","sourceRoot":"","sources":["../../src/services/PostsService.ts"],"names":[],"mappings":";;AA0BA,4BASC;AAED,4BAcC;AAED,4BAUC;AAED,gCASC;AAxED,qDAA2C;AAC3C,yDAAsD;AAuB/C,KAAK,UAAU,QAAQ,CAAC,MAAc;IAC3C,OAAO,MAAM,IAAA,wBAAO,EAAY;QAC9B,MAAM,EAAE,MAAM;QACd,GAAG,EAAE,mCAAgB,CAAC,QAAQ,EAAE;QAChC,MAAM,EAAE,KAAK;QACb,QAAQ,EAAE,IAAI;KACf,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;QACf,MAAM,IAAI,KAAK,CAAC,wBAAwB,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;AACL,CAAC;AAEM,KAAK,UAAU,QAAQ,CAAC,IAAkB;IAC/C,OAAO,MAAM,IAAA,wBAAO,EAAU;QAC5B,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,GAAG,EAAE,mCAAgB,CAAC,QAAQ,EAAE;QAChC,MAAM,EAAE,MAAM;QACd,IAAI,EAAE;YACJ,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,iBAAiB,EAAE,IAAI,CAAC,iBAAiB;YACzC,IAAI,EAAE,IAAI,CAAC,IAAI;SAChB;QACD,QAAQ,EAAE,IAAI;KACf,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;QACf,MAAM,IAAI,KAAK,CAAC,wBAAwB,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;AACL,CAAC;AAEM,KAAK,UAAU,QAAQ,CAAC,IAAkB;IAC/C,OAAO,MAAM,IAAA,wBAAO,EAAU;QAC5B,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,GAAG,EAAE,mCAAgB,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC;QAC3C,MAAM,EAAE,OAAO;QACf,IAAI,EAAE,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE;QAC/B,QAAQ,EAAE,IAAI;KACf,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;QACf,MAAM,IAAI,KAAK,CAAC,wBAAwB,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;AACL,CAAC;AAEM,KAAK,UAAU,UAAU,CAAC,IAAoB;IACnD,OAAO,MAAM,IAAA,wBAAO,EAAC;QACnB,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,GAAG,EAAE,mCAAgB,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC;QAC7C,MAAM,EAAE,QAAQ;QAChB,QAAQ,EAAE,IAAI;KACf,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;QACf,MAAM,IAAI,KAAK,CAAC,0BAA0B,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;IAC3D,CAAC,CAAC,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"PostsService.js","sourceRoot":"","sources":["../../src/services/PostsService.ts"],"names":[],"mappings":";;AA0BA,4BAOC;AAED,4BAYC;AAED,4BAQC;AAED,gCAOC;AAhED,qDAA2C;AAC3C,yDAAsD;AAuB/C,KAAK,UAAU,QAAQ,CAAC,MAAc;IAC3C,OAAO,MAAM,IAAA,wBAAO,EAAY;QAC9B,MAAM,EAAE,MAAM;QACd,GAAG,EAAE,mCAAgB,CAAC,QAAQ,EAAE;QAChC,MAAM,EAAE,KAAK;QACb,QAAQ,EAAE,IAAI;KACf,CAAC,CAAC;AACL,CAAC;AAEM,KAAK,UAAU,QAAQ,CAAC,IAAkB;IAC/C,OAAO,MAAM,IAAA,wBAAO,EAAU;QAC5B,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,GAAG,EAAE,mCAAgB,CAAC,QAAQ,EAAE;QAChC,MAAM,EAAE,MAAM;QACd,IAAI,EAAE;YACJ,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,iBAAiB,EAAE,IAAI,CAAC,iBAAiB;YACzC,IAAI,EAAE,IAAI,CAAC,IAAI;SAChB;QACD,QAAQ,EAAE,IAAI;KACf,CAAC,CAAC;AACL,CAAC;AAEM,KAAK,UAAU,QAAQ,CAAC,IAAkB;IAC/C,OAAO,MAAM,IAAA,wBAAO,EAAU;QAC5B,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,GAAG,EAAE,mCAAgB,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC;QAC3C,MAAM,EAAE,OAAO;QACf,IAAI,EAAE,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE;QAC/B,QAAQ,EAAE,IAAI;KACf,CAAC,CAAC;AACL,CAAC;AAEM,KAAK,UAAU,UAAU,CAAC,IAAoB;IACnD,OAAO,MAAM,IAAA,wBAAO,EAAC;QACnB,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,GAAG,EAAE,mCAAgB,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC;QAC7C,MAAM,EAAE,QAAQ;QAChB,QAAQ,EAAE,IAAI;KACf,CAAC,CAAC;AACL,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"ServerService.d.ts","sourceRoot":"","sources":["../../src/services/ServerService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAI3C,wBAAsB,eAAe,CACnC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,MAAM,gBAWhB;AAED,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,gBAUf;AACD,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,gBAUf"}
1
+ {"version":3,"file":"ServerService.d.ts","sourceRoot":"","sources":["../../src/services/ServerService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAI3C,wBAAsB,eAAe,CACnC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,MAAM,gBAShB;AAED,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,gBAQf;AACD,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,gBAQf"}
@@ -12,8 +12,6 @@ async function banServerMember(client, serverId, userId, reason) {
12
12
  method: "POST",
13
13
  useToken: true,
14
14
  body: { reason },
15
- }).catch((err) => {
16
- throw new Error(`Failed to ban server member. ${err.message}`);
17
15
  });
18
16
  }
19
17
  async function unbanServerMember(client, serverId, userId) {
@@ -22,8 +20,6 @@ async function unbanServerMember(client, serverId, userId) {
22
20
  url: serviceEndpoints_1.ServiceEndpoints.serverMemberBan(serverId, userId),
23
21
  method: "DELETE",
24
22
  useToken: true,
25
- }).catch((err) => {
26
- throw new Error(`Failed to unban server member. ${err.message}`);
27
23
  });
28
24
  }
29
25
  async function kickServerMember(client, serverId, userId) {
@@ -32,8 +28,6 @@ async function kickServerMember(client, serverId, userId) {
32
28
  url: serviceEndpoints_1.ServiceEndpoints.serverMemberKick(serverId, userId),
33
29
  method: "DELETE",
34
30
  useToken: true,
35
- }).catch((err) => {
36
- throw new Error(`Failed to kick server member. ${err.message}`);
37
31
  });
38
32
  }
39
33
  //# sourceMappingURL=ServerService.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ServerService.js","sourceRoot":"","sources":["../../src/services/ServerService.ts"],"names":[],"mappings":";;AAIA,0CAeC;AAED,8CAaC;AACD,4CAaC;AA/CD,qDAA2C;AAC3C,yDAAsD;AAE/C,KAAK,UAAU,eAAe,CACnC,MAAc,EACd,QAAgB,EAChB,MAAc,EACd,MAAe;IAEf,OAAO,MAAM,IAAA,wBAAO,EAAM;QACxB,MAAM,EAAE,MAAM;QACd,GAAG,EAAE,mCAAgB,CAAC,eAAe,CAAC,QAAQ,EAAE,MAAM,CAAC;QACvD,MAAM,EAAE,MAAM;QACd,QAAQ,EAAE,IAAI;QACd,IAAI,EAAE,EAAE,MAAM,EAAE;KACjB,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;QACf,MAAM,IAAI,KAAK,CAAC,gCAAgC,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;IACjE,CAAC,CAAC,CAAC;AACL,CAAC;AAEM,KAAK,UAAU,iBAAiB,CACrC,MAAc,EACd,QAAgB,EAChB,MAAc;IAEd,OAAO,MAAM,IAAA,wBAAO,EAAM;QACxB,MAAM,EAAE,MAAM;QACd,GAAG,EAAE,mCAAgB,CAAC,eAAe,CAAC,QAAQ,EAAE,MAAM,CAAC;QACvD,MAAM,EAAE,QAAQ;QAChB,QAAQ,EAAE,IAAI;KACf,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;QACf,MAAM,IAAI,KAAK,CAAC,kCAAkC,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;IACnE,CAAC,CAAC,CAAC;AACL,CAAC;AACM,KAAK,UAAU,gBAAgB,CACpC,MAAc,EACd,QAAgB,EAChB,MAAc;IAEd,OAAO,MAAM,IAAA,wBAAO,EAAM;QACxB,MAAM,EAAE,MAAM;QACd,GAAG,EAAE,mCAAgB,CAAC,gBAAgB,CAAC,QAAQ,EAAE,MAAM,CAAC;QACxD,MAAM,EAAE,QAAQ;QAChB,QAAQ,EAAE,IAAI;KACf,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;QACf,MAAM,IAAI,KAAK,CAAC,iCAAiC,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;IAClE,CAAC,CAAC,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"ServerService.js","sourceRoot":"","sources":["../../src/services/ServerService.ts"],"names":[],"mappings":";;AAIA,0CAaC;AAED,8CAWC;AACD,4CAWC;AAzCD,qDAA2C;AAC3C,yDAAsD;AAE/C,KAAK,UAAU,eAAe,CACnC,MAAc,EACd,QAAgB,EAChB,MAAc,EACd,MAAe;IAEf,OAAO,MAAM,IAAA,wBAAO,EAAM;QACxB,MAAM,EAAE,MAAM;QACd,GAAG,EAAE,mCAAgB,CAAC,eAAe,CAAC,QAAQ,EAAE,MAAM,CAAC;QACvD,MAAM,EAAE,MAAM;QACd,QAAQ,EAAE,IAAI;QACd,IAAI,EAAE,EAAE,MAAM,EAAE;KACjB,CAAC,CAAC;AACL,CAAC;AAEM,KAAK,UAAU,iBAAiB,CACrC,MAAc,EACd,QAAgB,EAChB,MAAc;IAEd,OAAO,MAAM,IAAA,wBAAO,EAAM;QACxB,MAAM,EAAE,MAAM;QACd,GAAG,EAAE,mCAAgB,CAAC,eAAe,CAAC,QAAQ,EAAE,MAAM,CAAC;QACvD,MAAM,EAAE,QAAQ;QAChB,QAAQ,EAAE,IAAI;KACf,CAAC,CAAC;AACL,CAAC;AACM,KAAK,UAAU,gBAAgB,CACpC,MAAc,EACd,QAAgB,EAChB,MAAc;IAEd,OAAO,MAAM,IAAA,wBAAO,EAAM;QACxB,MAAM,EAAE,MAAM;QACd,GAAG,EAAE,mCAAgB,CAAC,gBAAgB,CAAC,QAAQ,EAAE,MAAM,CAAC;QACxD,MAAM,EAAE,QAAQ;QAChB,QAAQ,EAAE,IAAI;KACf,CAAC,CAAC;AACL,CAAC"}
package/package.json CHANGED
@@ -1,38 +1,38 @@
1
- {
2
- "name": "@nerimity/nerimity.js",
3
- "version": "1.18.0",
4
- "description": "",
5
- "main": "build/index.js",
6
- "keywords": [],
7
- "author": "SupertigerDev",
8
- "license": "ISC",
9
- "devDependencies": {
10
- "@eslint/js": "^9.39.1",
11
- "@types/node-fetch": "^2.6.13",
12
- "@types/ws": "^8.18.1",
13
- "eslint": "^9.39.1",
14
- "globals": "^16.5.0",
15
- "nodemon": "^3.1.11",
16
- "ts-node": "^10.9.2",
17
- "typescript": "^5.9.3",
18
- "typescript-eslint": "^8.48.1"
19
- },
20
- "dependencies": {
21
- "eventemitter3": "^5.0.1",
22
- "node-fetch": "^2.7.0",
23
- "socket.io-client": "^4.8.1",
24
- "ws": "^8.18.3"
25
- },
26
- "repository": {
27
- "type": "git",
28
- "url": "git+https://github.com/Nerimity/nerimity.js.git"
29
- },
30
- "bugs": {
31
- "url": "https://github.com/Nerimity/nerimity.js/issues"
32
- },
33
- "homepage": "https://github.com/Nerimity/nerimity.js#readme",
34
- "scripts": {
35
- "build": "tsc",
36
- "dev": "tsc && node tests/test.js"
37
- }
38
- }
1
+ {
2
+ "name": "@nerimity/nerimity.js",
3
+ "version": "1.20.0",
4
+ "description": "",
5
+ "main": "build/index.js",
6
+ "scripts": {
7
+ "build": "tsc",
8
+ "prepublishOnly": "tsc",
9
+ "dev": "tsc && node tests/test.js"
10
+ },
11
+ "keywords": [],
12
+ "author": "SupertigerDev",
13
+ "license": "ISC",
14
+ "devDependencies": {
15
+ "@eslint/js": "^9.39.1",
16
+ "@types/node-fetch": "^2.6.13",
17
+ "@types/ws": "^8.18.1",
18
+ "eslint": "^9.39.1",
19
+ "globals": "^16.5.0",
20
+ "nodemon": "^3.1.11",
21
+ "ts-node": "^10.9.2",
22
+ "typescript": "^5.9.3",
23
+ "typescript-eslint": "^8.48.1"
24
+ },
25
+ "dependencies": {
26
+ "eventemitter3": "^5.0.1",
27
+ "socket.io-client": "^4.8.1",
28
+ "ws": "^8.18.3"
29
+ },
30
+ "repository": {
31
+ "type": "git",
32
+ "url": "git+https://github.com/Nerimity/nerimity.js.git"
33
+ },
34
+ "bugs": {
35
+ "url": "https://github.com/Nerimity/nerimity.js/issues"
36
+ },
37
+ "homepage": "https://github.com/Nerimity/nerimity.js#readme"
38
+ }
@@ -0,0 +1,115 @@
1
+ /**
2
+ * Interface for an item in the queue.
3
+ * @template T The type of the result that the async function resolves to.
4
+ */
5
+ interface QueueItem<T> {
6
+ asyncFunc: () => Promise<T>;
7
+ resolve: (value: T | PromiseLike<T>) => void;
8
+ reject: (reason?: unknown) => void;
9
+ }
10
+
11
+ /**
12
+ * A simple and fast async function queue for web environments, with TypeScript types.
13
+ * It ensures that asynchronous functions are executed one after another in the order they were added.
14
+ */
15
+ export class AsyncFunctionQueue {
16
+ /**
17
+ * The array that holds the queue items.
18
+ * Using `unknown` is a type-safe alternative to `any`.
19
+ * Type safety for individual items is handled by the generic `add` method.
20
+ * @private
21
+ */
22
+ private queue: QueueItem<unknown>[] = [];
23
+
24
+ /**
25
+ * A flag to indicate whether the queue is currently processing an item.
26
+ * @private
27
+ */
28
+ private isProcessing: boolean = false;
29
+
30
+ /**
31
+ * Adds an async function to the queue and returns a promise that resolves with the function's return value
32
+ * or rejects with its error.
33
+ * @template T The type of the result that the async function resolves to.
34
+ * @param {() => Promise<T>} asyncFunc - An async function to be added to the queue. It must be a function that returns a Promise.
35
+ * @returns {Promise<T>} A promise that resolves or rejects when the added function is executed.
36
+ */
37
+ public add<T>(asyncFunc: () => Promise<T>): Promise<T> {
38
+ return new Promise<T>((resolve, reject) => {
39
+ // Push the function along with its resolve/reject handlers to the queue.
40
+ // We cast here to satisfy TypeScript's strict checks on function parameter contravariance.
41
+ // This is safe because we ensure that the `resolve` function for a given `asyncFunc`
42
+ // is always called with the result of that specific function.
43
+ this.queue.push({
44
+ asyncFunc,
45
+ resolve,
46
+ reject,
47
+ } as QueueItem<unknown>);
48
+
49
+ // If not already processing, start processing the queue.
50
+ if (!this.isProcessing) {
51
+ this._processNext();
52
+ }
53
+ });
54
+ }
55
+
56
+ /**
57
+ * Processes the next item in the queue.
58
+ * This is a private method and should not be called directly.
59
+ * @private
60
+ */
61
+ private async _processNext(): Promise<void> {
62
+ // If there's nothing in the queue, stop processing.
63
+ if (this.queue.length === 0) {
64
+ this.isProcessing = false;
65
+ return;
66
+ }
67
+
68
+ // Set the flag to indicate that processing has started.
69
+ this.isProcessing = true;
70
+
71
+ // Get the next item from the front of the queue.
72
+ const item = this.queue.shift();
73
+
74
+ if (!item) {
75
+ // This case should not be hit due to the length check, but it's good practice for type safety.
76
+ this.isProcessing = false;
77
+ return;
78
+ }
79
+
80
+ try {
81
+ // Execute the async function.
82
+ const result = await item.asyncFunc();
83
+ // Resolve the promise associated with this function.
84
+ item.resolve(result);
85
+ } catch (error: unknown) {
86
+ // Reject the promise if the function throws an error.
87
+ item.reject(error);
88
+ } finally {
89
+ // After the function is done (either resolved or rejected),
90
+ // recursively call _processNext to handle the next item in the queue.
91
+ // Using requestAnimationFrame or setTimeout can prevent potential stack overflow with a very long queue of synchronous tasks.
92
+ if (typeof requestAnimationFrame !== "undefined") {
93
+ requestAnimationFrame(() => this._processNext());
94
+ } else {
95
+ setTimeout(() => this._processNext(), 0);
96
+ }
97
+ }
98
+ }
99
+
100
+ /**
101
+ * Gets the current size of the queue.
102
+ * @returns {number} The number of items currently in the queue.
103
+ */
104
+ public get size(): number {
105
+ return this.queue.length;
106
+ }
107
+
108
+ /**
109
+ * Checks if the queue is currently processing an item.
110
+ * @returns {boolean} True if processing, false otherwise.
111
+ */
112
+ public get isBusy(): boolean {
113
+ return this.isProcessing;
114
+ }
115
+ }
@@ -1,3 +1,4 @@
1
+ import { AsyncFunctionQueue } from "../AsyncFunctionQueue";
1
2
  import { ChannelType, RawChannel } from "../RawData";
2
3
  import {
3
4
  deleteMessage as requestMessageDelete,
@@ -11,6 +12,8 @@ export class Channel {
11
12
  client: Client;
12
13
  id: string;
13
14
 
15
+ messageSendQueue = new AsyncFunctionQueue();
16
+
14
17
  type: ChannelType;
15
18
  createdAt?: number;
16
19
  lastMessagedAt?: number;
@@ -26,19 +29,21 @@ export class Channel {
26
29
  }
27
30
 
28
31
  async send(content: string, opts?: MessageOpts) {
29
- const RawMessage = await postMessage({
30
- client: this.client,
31
- channelId: this.id,
32
- content: content,
33
- silent: opts?.silent,
34
- nerimityCdnFileId: opts?.nerimityCdnFileId,
35
- htmlEmbed: opts?.htmlEmbed,
36
- buttons: opts?.buttons,
37
- replyToMessageIds: opts?.replyToMessageIds,
38
- mentionReplies: opts?.mentionReplies,
32
+ return this.messageSendQueue.add(async () => {
33
+ const RawMessage = await postMessage({
34
+ client: this.client,
35
+ channelId: this.id,
36
+ content: content,
37
+ silent: opts?.silent,
38
+ nerimityCdnFileId: opts?.nerimityCdnFileId,
39
+ htmlEmbed: opts?.htmlEmbed,
40
+ buttons: opts?.buttons,
41
+ replyToMessageIds: opts?.replyToMessageIds,
42
+ mentionReplies: opts?.mentionReplies,
43
+ });
44
+ const message = new Message(this.client, RawMessage);
45
+ return message;
39
46
  });
40
- const message = new Message(this.client, RawMessage);
41
- return message;
42
47
  }
43
48
  toString() {
44
49
  return `[#:${this.id}]`;
@@ -184,7 +184,11 @@ class EventHandlers {
184
184
 
185
185
  for (let i = 0; i < payload.channels.length; i++) {
186
186
  const rawChannel = payload.channels[i];
187
- this.client.channels.setCache(rawChannel);
187
+ const channel = this.client.channels.setCache(rawChannel);
188
+ if ("serverId" in rawChannel && rawChannel.serverId) {
189
+ const server = this.client.servers.cache.get(rawChannel.serverId);
190
+ server?.channels.set(channel.id, channel);
191
+ }
188
192
  }
189
193
  for (let i = 0; i < payload.serverMembers.length; i++) {
190
194
  const member = payload.serverMembers[i];
@@ -254,6 +258,8 @@ class EventHandlers {
254
258
  }
255
259
  onServerChannelCreated(payload: { serverId: string; channel: RawChannel }) {
256
260
  const channel = this.client.channels.setCache(payload.channel);
261
+ const server = this.client.servers.cache.get(payload.serverId);
262
+ server?.channels.set(channel.id, channel);
257
263
  this.client.emit(
258
264
  ClientEvents.ServerChannelCreated,
259
265
  channel as ServerChannel
@@ -275,9 +281,13 @@ class EventHandlers {
275
281
  }
276
282
  }
277
283
  onServerChannelDeleted(payload: { serverId: string; channelId: string }) {
278
- const channel = this.client.channels.cache.has(payload.channelId);
284
+ const channel = this.client.channels.cache.get(payload.channelId);
279
285
  if (channel) {
280
286
  this.client.channels.cache.delete(payload.channelId);
287
+
288
+ const server = this.client.servers.cache.get(payload.serverId);
289
+ server?.channels.delete(payload.channelId);
290
+
281
291
  this.client.emit(ClientEvents.ServerChannelDeleted, {
282
292
  channelId: payload.channelId,
283
293
  serverId: payload.serverId,
@@ -59,6 +59,7 @@ export interface MessageOpts {
59
59
  }
60
60
  interface EditMessageOpts {
61
61
  htmlEmbed?: string;
62
+ buttons?: RawMessageButton[];
62
63
  }
63
64
  export class Message {
64
65
  client: Client;
@@ -136,6 +137,7 @@ export class Message {
136
137
  messageId: this.id,
137
138
  content: content,
138
139
  htmlEmbed: opts?.htmlEmbed,
140
+ buttons: opts?.buttons,
139
141
  });
140
142
  const message = new Message(this.client, RawMessage);
141
143
  return message;
@@ -4,6 +4,7 @@ import {
4
4
  kickServerMember,
5
5
  unbanServerMember,
6
6
  } from "../services/ServerService";
7
+ import { AllChannel } from "../types";
7
8
  import { Client } from "./Client";
8
9
  import { Collection } from "./Collection";
9
10
  import { ServerMembers } from "./ServerMember";
@@ -30,6 +31,7 @@ export class Server {
30
31
  avatar?: string;
31
32
  defaultRoleId: string;
32
33
  createdById: string;
34
+ channels: Collection<string, AllChannel> = new Collection();
33
35
 
34
36
  members: ServerMembers;
35
37
  roles: ServerRoles;
@@ -116,6 +116,9 @@ export class WebhookBuilder {
116
116
  * @throws If the request fails, is unauthorized, or returns invalid JSON.
117
117
  */
118
118
  public async send(content: string): Promise<any> {
119
+ const error = new Error();
120
+ Error.captureStackTrace(error, this.send);
121
+
119
122
  const url = `https://nerimity.com/api/webhooks/${this.channelId}/${this.token}`;
120
123
 
121
124
  try {
@@ -138,7 +141,11 @@ export class WebhookBuilder {
138
141
 
139
142
  return json;
140
143
  } catch (err: any) {
141
- throw new Error(`Failed to send webhook: ${err.message}`);
144
+ const message = err.message || err;
145
+ error.message = `Failed to send webhook: ${message}`;
146
+ (error as any).raw = message;
147
+
148
+ throw error;
142
149
  }
143
150
  }
144
151
  }
@@ -1,7 +1,6 @@
1
1
  import { Client } from "../classes/Client";
2
2
  import { RawMessage, RawMessageButton } from "../RawData";
3
3
  import { ServiceEndpoints } from "./serviceEndpoints";
4
- import fetch from "node-fetch";
5
4
 
6
5
  interface FetchMessageOpts {
7
6
  client: Client;
@@ -16,12 +15,6 @@ export async function fetchMessage(opts: FetchMessageOpts) {
16
15
  method: "GET",
17
16
 
18
17
  useToken: true,
19
- }).catch((err) => {
20
- const error = new Error(
21
- `Failed to get message. ${JSON.stringify(err.message)}`
22
- );
23
- (error as unknown as { raw: string }).raw = err.message;
24
- throw error;
25
18
  });
26
19
  }
27
20
 
@@ -52,12 +45,6 @@ export async function postMessage(opts: PostMessageOpts) {
52
45
  replyToMessageIds: opts.replyToMessageIds,
53
46
  },
54
47
  useToken: true,
55
- }).catch((err) => {
56
- const error = new Error(
57
- `Failed to send message. ${JSON.stringify(err.message)}`
58
- );
59
- (error as unknown as { raw: string }).raw = err.message;
60
- throw error;
61
48
  });
62
49
  }
63
50
 
@@ -67,6 +54,7 @@ interface EditMessageOpts {
67
54
  messageId: string;
68
55
  content: string;
69
56
  htmlEmbed?: string;
57
+ buttons?: RawMessageButton[];
70
58
  }
71
59
 
72
60
  export function editMessage(opts: EditMessageOpts) {
@@ -74,10 +62,12 @@ export function editMessage(opts: EditMessageOpts) {
74
62
  client: opts.client,
75
63
  url: ServiceEndpoints.EditMessage(opts.channelId, opts.messageId),
76
64
  method: "PATCH",
77
- body: { content: opts.content, htmlEmbed: opts.htmlEmbed },
65
+ body: {
66
+ content: opts.content,
67
+ htmlEmbed: opts.htmlEmbed,
68
+ buttons: opts.buttons,
69
+ },
78
70
  useToken: true,
79
- }).catch((err) => {
80
- throw err.message;
81
71
  });
82
72
  }
83
73
 
@@ -92,8 +82,6 @@ export function deleteMessage(opts: DeleteMessageOpts) {
92
82
  url: ServiceEndpoints.EditMessage(opts.channelId, opts.messageId),
93
83
  method: "DELETE",
94
84
  useToken: true,
95
- }).catch((err) => {
96
- throw err.message;
97
85
  });
98
86
  }
99
87
 
@@ -168,8 +156,6 @@ export function buttonClickCallback(opts: ButtonClickCallbackOpts) {
168
156
  userId: opts.userId,
169
157
  },
170
158
  useToken: true,
171
- }).catch((err) => {
172
- throw err.message;
173
159
  });
174
160
  }
175
161
 
@@ -184,6 +170,9 @@ interface RequestOpts {
184
170
  }
185
171
 
186
172
  export async function request<T>(opts: RequestOpts): Promise<T> {
173
+ const stackCapture: any = {};
174
+ Error.captureStackTrace(stackCapture, request);
175
+
187
176
  const url = new URL(opts.url);
188
177
  url.search = new URLSearchParams(opts.params || {}).toString();
189
178
 
@@ -195,7 +184,7 @@ export async function request<T>(opts: RequestOpts): Promise<T> {
195
184
  Authorization: opts.useToken ? opts.client.token! : "",
196
185
  },
197
186
  }).catch((err) => {
198
- throw { message: "Could not connect to server. " + err.message };
187
+ throw new Error("Could not connect to server. " + err.message);
199
188
  });
200
189
 
201
190
  const text = await response.text();
@@ -204,10 +193,16 @@ export async function request<T>(opts: RequestOpts): Promise<T> {
204
193
  try {
205
194
  const json = JSON.parse(text);
206
195
  if (!response.ok) {
207
- return Promise.reject(json);
196
+ throw new Error(JSON.stringify(json));
208
197
  }
209
198
  return json;
210
- } catch {
211
- throw { message: text };
199
+ } catch (err) {
200
+ if (err instanceof Error) {
201
+ // Remove the first line of the captured stack ("Error")
202
+ // and append the rest to the real error
203
+ const originalStack = stackCapture.stack?.split("\n").slice(1).join("\n");
204
+ err.stack += "\n -- caused by --\n" + originalStack;
205
+ }
206
+ throw err;
212
207
  }
213
208
  }
@@ -30,8 +30,6 @@ export async function getPosts(client: Client) {
30
30
  url: ServiceEndpoints.GetPosts(),
31
31
  method: "GET",
32
32
  useToken: true,
33
- }).catch((err) => {
34
- throw new Error(`Failed to get posts. ${err.message}`);
35
33
  });
36
34
  }
37
35
 
@@ -46,8 +44,6 @@ export async function postPost(opts: PostPostOpts) {
46
44
  poll: opts.poll,
47
45
  },
48
46
  useToken: true,
49
- }).catch((err) => {
50
- throw new Error(`Failed to send post. ${err.message}`);
51
47
  });
52
48
  }
53
49
 
@@ -58,8 +54,6 @@ export async function editPost(opts: EditPostOpts) {
58
54
  method: "PATCH",
59
55
  body: { content: opts.content },
60
56
  useToken: true,
61
- }).catch((err) => {
62
- throw new Error(`Failed to edit post. ${err.message}`);
63
57
  });
64
58
  }
65
59
 
@@ -69,7 +63,5 @@ export async function deletePost(opts: DeletePostOpts) {
69
63
  url: ServiceEndpoints.DeletePost(opts.postId),
70
64
  method: "DELETE",
71
65
  useToken: true,
72
- }).catch((err) => {
73
- throw new Error(`Failed to delete post. ${err.message}`);
74
66
  });
75
67
  }
@@ -14,8 +14,6 @@ export async function banServerMember(
14
14
  method: "POST",
15
15
  useToken: true,
16
16
  body: { reason },
17
- }).catch((err) => {
18
- throw new Error(`Failed to ban server member. ${err.message}`);
19
17
  });
20
18
  }
21
19
 
@@ -29,8 +27,6 @@ export async function unbanServerMember(
29
27
  url: ServiceEndpoints.serverMemberBan(serverId, userId),
30
28
  method: "DELETE",
31
29
  useToken: true,
32
- }).catch((err) => {
33
- throw new Error(`Failed to unban server member. ${err.message}`);
34
30
  });
35
31
  }
36
32
  export async function kickServerMember(
@@ -43,7 +39,5 @@ export async function kickServerMember(
43
39
  url: ServiceEndpoints.serverMemberKick(serverId, userId),
44
40
  method: "DELETE",
45
41
  useToken: true,
46
- }).catch((err) => {
47
- throw new Error(`Failed to kick server member. ${err.message}`);
48
42
  });
49
43
  }